commit
						d3e23c2fae
					
				|  | @ -12,5 +12,8 @@ gh-pages/ | |||
| site/_site/ | ||||
| coverage | ||||
| .ruby-version | ||||
| .ruby-gemset | ||||
| .sass-cache | ||||
| tmp/stackprof-* | ||||
| tmp/* | ||||
| .jekyll-metadata | ||||
| /vendor | ||||
|  |  | |||
							
								
								
									
										10
									
								
								.travis.yml
								
								
								
								
							
							
						
						
									
										10
									
								
								.travis.yml
								
								
								
								
							|  | @ -2,13 +2,13 @@ language: ruby | |||
| cache: bundler | ||||
| sudo: false | ||||
| rvm: | ||||
| - 2.2 | ||||
| - 2.1 | ||||
| - 2.0 | ||||
| - 1.9.3 | ||||
| env: | ||||
|   matrix: | ||||
|   - TEST_SUITE=test | ||||
|   - TEST_SUITE=cucumber | ||||
|     - TEST_SUITE=test | ||||
|     - TEST_SUITE=cucumber | ||||
| before_script: bundle update | ||||
| script: script/cibuild | ||||
| notifications: | ||||
|  | @ -16,9 +16,9 @@ notifications: | |||
|     on_success: change | ||||
|     on_failure: change | ||||
|     channels: | ||||
|     - irc.freenode.org#jekyll | ||||
|       - irc.freenode.org#jekyll | ||||
|     template: | ||||
|     - "%{repository}#%{build_number} (%{branch}) %{message} %{build_url}" | ||||
|       - "%{repository}#%{build_number} (%{branch}) %{message} %{build_url}" | ||||
|   email: | ||||
|     on_success: never | ||||
|     on_failure: never | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ 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 | ||||
|  | @ -67,7 +68,7 @@ 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 | ||||
| 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 | ||||
|  |  | |||
							
								
								
									
										33
									
								
								Gemfile
								
								
								
								
							
							
						
						
									
										33
									
								
								Gemfile
								
								
								
								
							|  | @ -1,7 +1,40 @@ | |||
| source 'https://rubygems.org' | ||||
| gemspec | ||||
| 
 | ||||
| gem 'pygments.rb', '~> 0.6.0' | ||||
| gem 'redcarpet', '~> 3.1' | ||||
| gem 'toml', '~> 0.1.0' | ||||
| gem 'jekyll-paginate', '~> 1.0' | ||||
| gem 'jekyll-gist', '~> 1.0' | ||||
| gem 'jekyll-coffeescript', '~> 1.0' | ||||
| gem 'classifier-reborn', '~> 2.0' | ||||
| 
 | ||||
| gem 'rake', '~> 10.1' | ||||
| gem 'rdoc', '~> 3.11' | ||||
| gem 'redgreen', '~> 1.2' | ||||
| gem 'shoulda', '~> 3.5' | ||||
| gem 'cucumber', '1.3.18' | ||||
| gem 'maruku', '~> 0.7.0' | ||||
| gem 'rdiscount', '~> 2.0' | ||||
| gem 'launchy', '~> 2.3' | ||||
| gem 'simplecov', '~> 0.9' | ||||
| gem 'mime-types', '~> 1.5' | ||||
| gem 'activesupport', '~> 3.2.13' | ||||
| gem 'jekyll_test_plugin' | ||||
| gem 'jekyll_test_plugin_malicious' | ||||
| gem 'liquid-c', '~> 3.0' | ||||
| gem 'minitest' | ||||
| gem 'minitest-reporters' | ||||
| gem 'minitest-profile' | ||||
| gem 'test-unit' if RUBY_PLATFORM =~ /cygwin/ || RUBY_VERSION.start_with?("2.2") | ||||
| gem 'rspec-mocks' | ||||
| 
 | ||||
| if ENV['BENCHMARK'] | ||||
|   gem 'rbtrace' | ||||
|   gem 'stackprof' | ||||
|   gem 'benchmark-ips' | ||||
| end | ||||
| 
 | ||||
| if ENV['PROOF'] | ||||
|   gem 'html-proofer', '~> 2.0' | ||||
| end | ||||
|  |  | |||
							
								
								
									
										149
									
								
								History.markdown
								
								
								
								
							
							
						
						
									
										149
									
								
								History.markdown
								
								
								
								
							|  | @ -2,25 +2,172 @@ | |||
| 
 | ||||
| ### Major Enhancements | ||||
| 
 | ||||
|   * Incremental regeneration (#3116) | ||||
|   * Drop support for Ruby 1.9.3. (#3235) | ||||
|   * Upgrade to Liquid 3.0.0 (#3002) | ||||
|   * Support Ruby v2.2 (#3234) | ||||
|   * Support RDiscount 2 (#2767) | ||||
|   * Remove most runtime deps (#3323) | ||||
|   * Move to Rouge as default highlighter (#3323) | ||||
|   * Mimic GitHub Pages `.html` extension stripping behavior in WEBrick (#3452) | ||||
|   * Always include file extension on output files (#3490) | ||||
|   * Improved permalinks for pages and collections (#3538) | ||||
| 
 | ||||
| ### Minor Enhancements | ||||
| 
 | ||||
|   * 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) | ||||
|   * Use relative path for `path` Liquid variable in Documents for consistency (#2908) | ||||
|   * Generalize `Utils#slugify` for any scripts (#3047) | ||||
|   * Added basic microdata to post template in site template (#3189) | ||||
|   * Store log messages in an array of messages. (#3244) | ||||
|   * Allow collection documents to override `output` property in front matter (#3172) | ||||
|   * Keep file modification times between builds for static files (#3220) | ||||
|   * Only downcase mixed-case categories for the URL (#2571) | ||||
|   * Added per post `excerpt_separator` functionality (#3274) | ||||
|   * Allow collections YAML to end with three dots (#3134) | ||||
|   * Add mode parameter to `slugify` Liquid filter (#2918) | ||||
|   * 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) | ||||
|   * 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) | ||||
|   * Add `pkill -f jekyll` to ways to kill. (#3397) | ||||
|   * Site template: collapsed, variable-driven font declaration (#3360) | ||||
|   * Site template: Don't always show the scrollbar in code blocks (#3419) | ||||
|   * Site template: Remove undefined `text` class from `p` element (#3440) | ||||
|   * Site template: Optimize text rendering for legibility (#3382) | ||||
|   * Add `draft?` method to identify if Post is a Draft & expose to Liquid (#3456) | ||||
|   * Write regeneration metadata even on full rebuild (#3464) | ||||
|   * Perf: Use `String#end_with?("/")` instead of regexp when checking paths (#3516) | ||||
|   * Docs: document 'ordinal' built-in permalink style (#3532) | ||||
|   * Upgrade liquid-c to 3.x (#3531) | ||||
|   * Use consistent syntax for deprecation warning (#3535) | ||||
|   * Added build --destination and --source flags (#3418) | ||||
|   * Site template: remove unused `page.meta` attribute (#3537) | ||||
|   * Improve the error message when sorting null objects (#3520) | ||||
| 
 | ||||
| ### Bug Fixes | ||||
| 
 | ||||
|   * Make permalink parsing consistent with pages (#3014) | ||||
|   * `time()`pre-filter method should accept a `Date` object (#3299) | ||||
|   * Remove unneeded end tag for `link` in site template (#3236) | ||||
|   * Kramdown: Use `enable_coderay` key instead of `use_coderay` (#3237) | ||||
|   * Unescape `Document` output path (#2924) | ||||
|   * Fix nav items alignment when on multiple rows (#3264) | ||||
|   * Highlight: Only Strip Newlines/Carriage Returns, not Spaces (#3278) | ||||
|   * Find variables in front matter defaults by searching with relative file path. (#2774) | ||||
|   * Allow variables (e.g `:categories`) in YAML front matter permalinks (#3320) | ||||
|   * Handle nil URL placeholders in permalinks (#3325) | ||||
|   * Template: Fix nav items alignment when in "burger" mode (#3329) | ||||
|   * Template: Remove `!important` from nav SCSS introduced in #3329 (#3375) | ||||
|   * The `:title` URL placeholder for collections should be the filename slug. (#3383) | ||||
|   * Trim the generate time diff to just 3 places past the decimal place (#3415) | ||||
|   * The highlight tag should only clip the newlines before and after the *entire* block, not in between (#3401) | ||||
|   * highlight: fix problem with linenos and rouge. (#3436) | ||||
|   * `Site#read_data_file`: read CSV's with proper file encoding (#3455) | ||||
|   * Ignore `.jekyll-metadata` in site template (#3496) | ||||
|   * Template: Point documentation link to the documentation pages (#3502) | ||||
|   * Removed the trailing slash from the example `/blog` baseurl comment (#3485) | ||||
| 
 | ||||
| ### Development Fixes | ||||
| 
 | ||||
|   * Improve the grammar in the documentation (#3233) | ||||
|   * Update the LICENSE text to match the MIT license exactly (#3253) | ||||
|   * Update rake task `site:publish` to fix minor bugs. (#3254) | ||||
|   * Switch to shields.io for the README badges. (#3255) | ||||
|   * Use `FileList` instead of `Dir.glob` in `site:publish` rake task (#3261) | ||||
|   * Fix test script to be platform-independent (#3279) | ||||
|   * Instead of symlinking `/tmp`, create and symlink a local `tmp` in the tests (#3258) | ||||
|   * Fix some spacing (#3312) | ||||
|   * Fix comment typo in `lib/jekyll/frontmatter_defaults.rb` (#3322) | ||||
|   * Move all `regenerate?` checking to `Regenerator` (#3326) | ||||
|   * Factor out a `read_data_file` call to keep things clean (#3380) | ||||
|   * Proof the site with CircleCI. (#3427) | ||||
|   * Update LICENSE to 2015. (#3477) | ||||
|   * Upgrade tests to use Minitest (#3492) | ||||
|   * Remove trailing whitespace (#3497) | ||||
|   * Use `fixture_site` for Document tests (#3511) | ||||
|   * Remove adapters deprecation warning (#3529) | ||||
|   * Minor fixes to `url.rb` to follow GitHub style guide (#3544) | ||||
|   * Minor changes to resolve deprecation warnings (#3547) | ||||
|   * Convert remaining textile test documents to markdown (#3528) | ||||
|   * Migrate the tests to use rspec-mocks (#3552) | ||||
| 
 | ||||
| ### Site Enhancements | ||||
| 
 | ||||
|   * Add blog post announcing Jekyll Help (#3523) | ||||
|   * Add Jekyll Talk to Help page on site (#3518) | ||||
|   * Fixing the default host on docs (#3229) | ||||
|   * Add `jekyll-thumbnail-filter` to list of third-party plugins (#2790) | ||||
|   * Add link to 'Adding Ajax pagination to Jekyll' to Resources page (#3186) | ||||
|   * Add a Resources link to tutorial on building dynamic navbars (#3185) | ||||
|   * Semantic structure improvements to the post and page layouts (#3251) | ||||
|   * Add new AsciiDoc plugin to list of third-party plugins. (#3277) | ||||
|   * Specify that all transformable collection documents must contain YAML front matter (#3271) | ||||
|   * Assorted accessibility fixes (#3256) | ||||
|   * Update configuration docs to mention `keep_files` for `destination` (#3288, #3296) | ||||
|   * Break when we successfully generate nav link to save CPU cycles. (#3291) | ||||
|   * Update usage docs to mention `keep_files` and a warning about `destination` cleaning (#3295) | ||||
|   * Add logic to automatically generate the `next_section` and `prev_section` navigation items (#3292) | ||||
|   * Some small fixes for the Plugins TOC. (#3306) | ||||
|   * Added versioning comment to configuration file (#3314) | ||||
|   * Add `jekyll-minifier` to list of third-party plugins (#3333) | ||||
|   * Add blog post about the Jekyll meet-up (#3332) | ||||
|   * Use `highlight` Liquid tag instead of the four-space tabs for code (#3336) | ||||
|   * 3.0.0.beta1 release post (#3346) | ||||
|   * Add `twa` to the list of third-party plugins (#3384) | ||||
|   * Remove extra spaces (#3388) | ||||
|   * Fix small grammar errors on a couple pages (#3396) | ||||
|   * Fix typo on Templates docs page (#3420) | ||||
|   * s/three/four for plugin type list (#3424) | ||||
|   * Release jekyllrb.com as a locally-compiled site. (#3426) | ||||
|   * Add a jekyllrb.com/help page which elucidates places from which to get help (#3428) | ||||
|   * Remove extraneous dash on Plugins doc page which caused a formatting error (#3431) | ||||
|   * Fix broken link to Jordan Thornquest's website. (#3438) | ||||
|   * Change the link to an extension (#3457) | ||||
|   * Fix Twitter link on the help page (#3466) | ||||
|   * Fix wording in code snippet highlighting section (#3475) | ||||
|   * Add a `/` to `paginate_path` in the Pagination documentation (#3479) | ||||
|   * Add a link on all the docs pages to "Improve this page". (#3510) | ||||
|   * Add jekyll-auto-image generator to the list of third-party plugins (#3489) | ||||
|   * Replace link to the proposed `picture` element spec (#3530) | ||||
|   * Add frontmatter date formatting information (#3469) | ||||
|   * Improve consistency and clarity of plugins options note (#3546) | ||||
|   * Add permalink warning to pagination docs (#3551) | ||||
|   * Fix grammar in Collections docs API stability warning (#3560) | ||||
| 
 | ||||
| ## 2.5.3 / 2014-12-22 | ||||
| 
 | ||||
| ### Bug Fixes | ||||
| 
 | ||||
|   * When checking a Markdown extname, include position of the `.` (#3147) | ||||
|   * Fix `jsonify` Liquid filter handling of boolean values (#3154) | ||||
|   * Add comma to value of `viewport` meta tag (#3170) | ||||
|   * Set the link type for the RSS feed to `application/rss+xml` (#3176) | ||||
|   * Refactor `#as_liquid` (#3158) | ||||
| 
 | ||||
| ### Development Fixes | ||||
| 
 | ||||
|   * Exclude built-in bundles from being added to coverage report (#3180) | ||||
| 
 | ||||
| ### Site Enhancements | ||||
| 
 | ||||
|   * Add `@alfredxing` to the `@jekyll/core` team. :tada: (#3218) | ||||
|   * Document the `-q` option for the `build` and `serve` commands (#3149) | ||||
|   * Fix some minor typos/flow fixes in documentation website content (#3165) | ||||
|   * Add `keep_files` to configuration documentation (#3162) | ||||
|   * Repeat warning about cleaning of the `destination` directory (#3161) | ||||
|   * Add jekyll-500px-embed to list of third-party plugins (#3163) | ||||
|   * Simplified platform detection in Gemfile example for Windows (#3177) | ||||
|   * Add the `jekyll-jalali` plugin added to the list of third-party plugins. (#3198) | ||||
|   * Add Table of Contents to Troubleshooting page (#3196) | ||||
|   * Add `inline_highlight` plugin to list of third-party plugins (#3212) | ||||
|   * Add `jekyll-mermaid` plugin to list of third-party plugins (#3222) | ||||
| 
 | ||||
| ## 2.5.2 / 2014-11-17 | ||||
| 
 | ||||
|  | @ -477,7 +624,7 @@ | |||
|   * 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) | ||||
|   * Return `utf-8` encoding in header for webrick error page response (#2289) | ||||
|   * Make template site easier to customize (#2268) | ||||
|   * Add two-digit year to permalink template option (#2301) | ||||
|   * Add `site.documents` to Liquid payload (list of all docs) (#2295) | ||||
|  |  | |||
							
								
								
									
										8
									
								
								LICENSE
								
								
								
								
							
							
						
						
									
										8
									
								
								LICENSE
								
								
								
								
							|  | @ -1,9 +1,9 @@ | |||
| (The MIT License) | ||||
| The MIT License (MIT) | ||||
| 
 | ||||
| Copyright (c) 2008-2014 Tom Preston-Werner | ||||
| Copyright (c) 2008-2015 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 | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
|  | @ -12,7 +12,7 @@ furnished to do so, subject to the following conditions: | |||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
| 
 | ||||
| THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  |  | |||
|  | @ -1,9 +1,9 @@ | |||
| # [Jekyll](http://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://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) | ||||
| 
 | ||||
| By Tom Preston-Werner, Nick Quaranto, Parker Moore, and many [awesome contributors](https://github.com/jekyll/jekyll/graphs/contributors)! | ||||
|  |  | |||
							
								
								
									
										51
									
								
								Rakefile
								
								
								
								
							
							
						
						
									
										51
									
								
								Rakefile
								
								
								
								
							|  | @ -26,7 +26,7 @@ def gemspec_file | |||
| end | ||||
| 
 | ||||
| def gem_file | ||||
|   "#{name}-#{version}.gem" | ||||
|   "#{name}-#{Gem::Version.new(version).to_s}.gem" | ||||
| end | ||||
| 
 | ||||
| def normalize_bullets(markdown) | ||||
|  | @ -89,6 +89,7 @@ end | |||
| 
 | ||||
| multitask :default => [:test, :features] | ||||
| 
 | ||||
| task :spec => :test | ||||
| require 'rake/testtask' | ||||
| Rake::TestTask.new(:test) do |test| | ||||
|   test.libs << 'lib' << 'test' | ||||
|  | @ -179,33 +180,44 @@ namespace :site do | |||
|     # Ensure the gh-pages dir exists so we can generate into it. | ||||
|     puts "Checking for gh-pages dir..." | ||||
|     unless File.exist?("./gh-pages") | ||||
|       puts "No gh-pages directory found. Run the following commands first:" | ||||
|       puts "  `git clone git@github.com:jekyll/jekyll gh-pages" | ||||
|       puts "  `cd gh-pages" | ||||
|       puts "  `git checkout gh-pages`" | ||||
|       exit(1) | ||||
|       puts "Creating gh-pages dir..." | ||||
|       sh "git clone git@github.com:jekyll/jekyll gh-pages" | ||||
|     end | ||||
| 
 | ||||
|     # Ensure gh-pages branch is up to date. | ||||
|     # Ensure latest gh-pages branch history. | ||||
|     Dir.chdir('gh-pages') do | ||||
|       sh "git checkout gh-pages" | ||||
|       sh "git pull origin gh-pages" | ||||
|     end | ||||
| 
 | ||||
|     # Copy to gh-pages dir. | ||||
|     puts "Copying site to gh-pages branch..." | ||||
|     Dir.glob("site/*") do |path| | ||||
|       next if path.include? "_site" | ||||
|       sh "cp -R #{path} gh-pages/" | ||||
|     # 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 | ||||
| 
 | ||||
|     # Change any configuration settings for production. | ||||
|     config = YAML.load_file("gh-pages/_config.yml") | ||||
|     config.merge!({'sass' => {'style' => 'compressed'}}) | ||||
|     File.write('gh-pages/_config.yml', YAML.dump(config)) | ||||
|     # 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 log`.match(/[a-z0-9]{40}/)[0] | ||||
|     sha = `git rev-parse HEAD`.strip | ||||
|     Dir.chdir('gh-pages') do | ||||
|       sh "git add ." | ||||
|       sh "git commit --allow-empty -m 'Updating to #{sha}.'" | ||||
|  | @ -221,8 +233,7 @@ namespace :site do | |||
|       front_matter = { | ||||
|         "layout" => "docs", | ||||
|         "title" => "History", | ||||
|         "permalink" => "/docs/history/", | ||||
|         "prev_section" => "contributing" | ||||
|         "permalink" => "/docs/history/" | ||||
|       } | ||||
|       Dir.chdir('site/_docs/') do | ||||
|         File.open("history.md", "w") do |file| | ||||
|  | @ -237,7 +248,7 @@ namespace :site do | |||
| 
 | ||||
|   desc "Write the site latest_version.txt file" | ||||
|   task :version_file do | ||||
|     File.open('site/latest_version.txt', 'wb') { |f| f.write(version) } | ||||
|     File.open('site/latest_version.txt', 'wb') { |f| f.puts(version) } unless version =~ /(beta|rc|alpha)/i | ||||
|   end | ||||
| 
 | ||||
|   namespace :releases do | ||||
|  |  | |||
|  | @ -0,0 +1,13 @@ | |||
| require 'benchmark/ips' | ||||
| 
 | ||||
| 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?("/")  } | ||||
| 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?("/")  } | ||||
| end | ||||
|  | @ -14,4 +14,3 @@ Benchmark.ips do |x| | |||
|   x.report('.map.flatten with no nested arrays') { enum.map { |i| do_thing(i) }.flatten(1) } | ||||
|   x.report('.flat_map with no nested arrays')    { enum.flat_map { |i| do_thing(i) } } | ||||
| end | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,6 +8,6 @@ Benchmark.ips do |x| | |||
|   x.report('#tr')    { str.tr('some', 'a')    } | ||||
|   x.report('#gsub')  { str.gsub('some', 'a')  } | ||||
|   x.report('#gsub!') { str.gsub!('some', 'a') } | ||||
|   x.report('#sub')   { str.sub('some', 'a')  } | ||||
|   x.report('#sub!')  { str.sub!('some', 'a') } | ||||
|   x.report('#sub')   { str.sub('some', 'a')   } | ||||
|   x.report('#sub!')  { str.sub!('some', 'a')  } | ||||
| end | ||||
|  |  | |||
							
								
								
									
										10
									
								
								bin/jekyll
								
								
								
								
							
							
						
						
									
										10
									
								
								bin/jekyll
								
								
								
								
							|  | @ -6,12 +6,9 @@ $:.unshift File.join(File.dirname(__FILE__), *%w{ .. lib }) | |||
| require 'jekyll' | ||||
| require 'mercenary' | ||||
| 
 | ||||
| %w[jekyll-import].each do |blessed_gem| | ||||
|   begin | ||||
|     require blessed_gem | ||||
|   rescue LoadError | ||||
|   end | ||||
| end | ||||
| Jekyll::External.require_if_present( | ||||
|   Jekyll::External.blessed_gems | ||||
| ) | ||||
| 
 | ||||
| Jekyll::PluginManager.require_from_bundler | ||||
| 
 | ||||
|  | @ -32,6 +29,7 @@ Mercenary.program(:jekyll) do |p| | |||
| 
 | ||||
|   p.action do |args, options| | ||||
|     if args.empty? | ||||
|       Jekyll.logger.error "A subcommand is required." | ||||
|       puts p | ||||
|     else | ||||
|       unless p.has_command?(args.first) | ||||
|  |  | |||
|  | @ -0,0 +1,14 @@ | |||
| machine: | ||||
|   timezone: UTC | ||||
|   ruby: | ||||
|     version: 2.1.5 | ||||
|   environment: | ||||
|     PROOF: true | ||||
| test: | ||||
|   override: | ||||
|     - script/proof -f | ||||
| general: | ||||
|   branches: | ||||
|     ignore: | ||||
|       - gh-pages # no proof script here | ||||
|       - master   # don't need to duplicate work | ||||
|  | @ -9,7 +9,7 @@ Feature: Collections | |||
|     And I have a configuration file with "collections" set to "['methods']" | ||||
|     When I run jekyll build | ||||
|     Then the _site directory should exist | ||||
|     And I should see "Collections: <p>Use <code>Jekyll.configuration</code> to build a full configuration for use w/Jekyll.</p>\n\n<p>Whatever: foo.bar</p>\n<p><code>Jekyll.sanitized_path</code> is used to make sure your path is in your source.</p>\n<p>Run your generators! default</p>\n<p>Page without title.</p>\n<p>Run your generators! default</p>" in "_site/index.html" | ||||
|     And I should see "Collections: <p>Use <code>Jekyll.configuration</code> to build a full configuration for use w/Jekyll.</p>\n\n<p>Whatever: foo.bar</p>\n<p>Signs are nice</p>\n<p><code>Jekyll.sanitized_path</code> is used to make sure your path is in your source.</p>\n<p>Run your generators! default</p>\n<p>Page without title.</p>\n<p>Run your generators! default</p>" in "_site/index.html" | ||||
|     And the "_site/methods/configuration.html" file should not exist | ||||
| 
 | ||||
|   Scenario: Rendered collection | ||||
|  | @ -70,7 +70,7 @@ Feature: Collections | |||
|     """ | ||||
|     When I run jekyll build | ||||
|     Then the _site directory should exist | ||||
|     And I should see "Collections: _methods/configuration.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/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 %}" | ||||
|  | @ -82,7 +82,7 @@ Feature: Collections | |||
|     """ | ||||
|     When I run jekyll build | ||||
|     Then the _site directory should exist | ||||
|     And I should see "Collections: _methods/configuration.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/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 %}" | ||||
|  | @ -94,7 +94,7 @@ Feature: Collections | |||
|     """ | ||||
|     When I run jekyll build | ||||
|     Then the _site directory should exist | ||||
|     And I should see "All documents: _methods/configuration.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/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 }}" | ||||
|  | @ -118,7 +118,7 @@ Feature: Collections | |||
|     """ | ||||
|     When I run jekyll build | ||||
|     Then the _site directory should exist | ||||
|     And I should see "Item count: 1" in "_site/index.html" | ||||
|     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 }}" | ||||
|  | @ -130,7 +130,7 @@ Feature: Collections | |||
|     """ | ||||
|     When I run jekyll build | ||||
|     Then the _site directory should exist | ||||
|     And I should see "1. of 5: <p>Page without title.</p>" in "_site/index.html" | ||||
|     And I should see "1. of 7: <p>Page without title.</p>" 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 %}" | ||||
|  | @ -142,4 +142,4 @@ Feature: Collections | |||
|     """ | ||||
|     When I run jekyll build | ||||
|     Then the _site directory should exist | ||||
|     And I should see "Collections: Jekyll.configuration, Jekyll.sanitized_path, Site#generate, , Site#generate," in "_site/index.html" | ||||
|     And I should see "Collections: Jekyll.configuration, Jekyll.escape, Jekyll.sanitized_path, Site#generate, , Site#generate," in "_site/index.html" | ||||
|  |  | |||
|  | @ -43,4 +43,4 @@ Feature: Draft Posts | |||
|       | Recipe | 2009-03-27 | simple | Post path: {{ page.path }} | | ||||
|     When I run jekyll build --drafts | ||||
|     Then the _site directory should exist | ||||
|     And I should see "Post path: _drafts/recipe.textile" in "_site/recipe.html" | ||||
|     And I should see "Post path: _drafts/recipe.markdown" in "_site/recipe.html" | ||||
|  |  | |||
|  | @ -20,8 +20,6 @@ Feature: Embed filters | |||
|     And I have the following post: | ||||
|       | title       | date       | layout  | content                                     | | ||||
|       | 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 | ||||
|  | @ -33,7 +31,7 @@ Feature: Embed filters | |||
|     And I have the following post: | ||||
|       | title     | date       | layout  | content                                     | | ||||
|       | Star Wars | 2009-03-27 | default | These aren't the droids you're looking for. | | ||||
|     And I have a default layout that contains "{{ content | xml_escape }}" | ||||
|     And I have a default layout that contains "{{ content | number_of_words }}" | ||||
|     When I run jekyll build | ||||
|     Then the _site directory should exist | ||||
|     And I should see "7" in "_site/2009/03/27/star-wars.html" | ||||
|  | @ -49,13 +47,13 @@ Feature: Embed filters | |||
|     Then the _site directory should exist | ||||
|     And I should see "scifi, movies, and force" in "_site/2009/03/27/star-wars.html" | ||||
| 
 | ||||
|   Scenario: Textilize a given string | ||||
|   Scenario: Markdownify a given string | ||||
|     Given I have a _posts directory | ||||
|     And I have a _layouts directory | ||||
|     And I have the following post: | ||||
|       | title     | date       | layout  | content                                     | | ||||
|       | Star Wars | 2009-03-27 | default | These aren't the droids you're looking for. | | ||||
|     And I have a default layout that contains "By {{ '_Obi-wan_' | textilize }}" | ||||
|     And I have a default layout that contains "By {{ '_Obi-wan_' | markdownify }}" | ||||
|     When I run jekyll build | ||||
|     Then the _site directory should exist | ||||
|     And I should see "By <p><em>Obi-wan</em></p>" in "_site/2009/03/27/star-wars.html" | ||||
|  |  | |||
|  | @ -25,7 +25,7 @@ Feature: frontmatter defaults | |||
|     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 | ||||
|     And I should see "<p>some special data</p><div>Ben</div>" in "_site/2013/09/11/default-data.html" | ||||
|     And I should see "<p>some special data</p>\n<div>Ben</div>" in "_site/2013/09/11/default-data.html" | ||||
|     And I should see "just some special data by Ben" in "_site/index.html" | ||||
| 
 | ||||
|   Scenario: Override frontmatter defaults by path | ||||
|  | @ -54,6 +54,28 @@ Feature: frontmatter defaults | |||
|     And I should see "root: Overview for the webpage" in "_site/index.html" | ||||
|     And I should see "subfolder: Overview for the special section" in "_site/special/index.html" | ||||
| 
 | ||||
|   Scenario: Use frontmatter variables by relative path | ||||
|     Given I have a _layouts directory | ||||
|     And I have a main layout that contains "main: {{ content }}" | ||||
| 
 | ||||
|     And I have a _posts directory | ||||
|     And I have the following post: | ||||
|       | title | date       | content                               | | ||||
|       | about | 2013-10-14 | content of site/2013/10/14/about.html | | ||||
|     And I have a special/_posts directory | ||||
|     And I have the following post in "special": | ||||
|       | title  | date       | path  | content                                        | | ||||
|       | about1 | 2013-10-14 | local | content of site/special/2013/10/14/about1.html | | ||||
|       | about2 | 2013-10-14 | local | content of site/special/2013/10/14/about2.html | | ||||
| 
 | ||||
|     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 | ||||
|     And I should see "main: <p>content of site/2013/10/14/about.html</p>" in "_site/2013/10/14/about.html" | ||||
|     And I should see "main: <p>content of site/special/2013/10/14/about1.html</p>" in "_site/special/2013/10/14/about1.html" | ||||
|     And I should see "main: <p>content of site/special/2013/10/14/about2.html</p>" in "_site/special/2013/10/14/about2.html" | ||||
| 
 | ||||
|   Scenario: Override frontmatter defaults by type | ||||
|     Given I have a _posts directory | ||||
|     And I have the following post: | ||||
|  | @ -78,10 +100,19 @@ Feature: frontmatter defaults | |||
|     And I should see "nothing" in "_site/override.html" | ||||
|     But the "_site/perma.html" file should not exist | ||||
| 
 | ||||
|   Scenario: Define permalink default for posts | ||||
|     Given I have a _posts directory | ||||
|     And I have the following post: | ||||
|       | title          | date       | category | content | | ||||
|       | testpost       | 2013-10-14 | blog     | blabla  | | ||||
|     And I have a configuration file with "defaults" set to "[{scope: {path: "", type: "posts"}, values: {permalink: "/:categories/:title/"}}]" | ||||
|     When I run jekyll build | ||||
|     Then I should see "blabla" in "_site/blog/testpost/index.html" | ||||
| 
 | ||||
|   Scenario: Use frontmatter defaults in collections | ||||
|     Given I have a _slides directory | ||||
|     And I have a "index.html" file that contains "nothing" | ||||
|     And I have a "_slides/slide1.html" file with content:  | ||||
|     And I have a "_slides/slide1.html" file with content: | ||||
|     """ | ||||
|     --- | ||||
|     --- | ||||
|  | @ -107,7 +138,7 @@ Feature: frontmatter defaults | |||
|   Scenario: Override frontmatter defaults inside a collection | ||||
|     Given I have a _slides directory | ||||
|     And I have a "index.html" file that contains "nothing" | ||||
|     And I have a "_slides/slide2.html" file with content:  | ||||
|     And I have a "_slides/slide2.html" file with content: | ||||
|     """ | ||||
|     --- | ||||
|     myval: Override | ||||
|  |  | |||
|  | @ -9,15 +9,15 @@ Feature: Include tags | |||
|     And I have an "_includes/params.html" file that contains "Parameters:<ul>{% for param in include %}<li>{{param[0]}} = {{param[1]}}</li>{% endfor %}</ul>" | ||||
|     And I have an "_includes/ignore.html" file that contains "<footer>My blog footer</footer>" | ||||
|     And I have a _posts directory | ||||
|     And I have the following post: | ||||
|       | title                               | date       | layout  | content                                                                                                                 | | ||||
|       | Include Files                       | 2013-03-21 | default | {% include header.html param="myparam" %}                                                                               | | ||||
|       | Ignore params if unused             | 2013-03-21 | default | {% include ignore.html date="today" %}                                                                                  | | ||||
|       | List multiple parameters            | 2013-03-21 | default | {% include params.html date="today" start="tomorrow" %}                                                                 | | ||||
|       | Dont keep parameters                | 2013-03-21 | default | {% include ignore.html param="test" %}\n{% include header.html %}                                                       | | ||||
|       | Allow params with spaces and quotes | 2013-04-07 | default | {% include params.html cool="param with spaces" super="\"quoted\"" single='has "quotes"' escaped='\'single\' quotes' %} | | ||||
|       | Parameter syntax                    | 2013-04-12 | default | {% include params.html param1_or_2="value" %}                                                                           | | ||||
|       | Pass a variable                     | 2013-06-22 | default | {% assign var = 'some text' %}{% include params.html local=var layout=page.layout %}                                    | | ||||
|     And I have the following posts: | ||||
|       | title                               | date       | type | content                                                                                                                 | | ||||
|       | Include Files                       | 2013-03-21 | html | {% include header.html param="myparam" %}                                                                               | | ||||
|       | 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' %} | | ||||
|       | 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 | ||||
|     And I should see "<header>My awesome blog header: myparam</header>" in "_site/2013/03/21/include-files.html" | ||||
|  | @ -27,12 +27,12 @@ Feature: Include tags | |||
|     And I should not see "<header>My awesome blog header: myparam</header>" in "_site/2013/03/21/dont-keep-parameters.html" | ||||
|     But I should see "<header>My awesome blog header: </header>" in "_site/2013/03/21/dont-keep-parameters.html" | ||||
|     And I should see "<li>cool = param with spaces</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html" | ||||
|     And I should see "<li>super = “quoted”</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html" | ||||
|     And I should see "<li>single = has “quotes”</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html" | ||||
|     And I should see "<li>escaped = ‘single’ quotes</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html" | ||||
|     And I should see "<li>super = \"quoted\"</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html" | ||||
|     And I should see "<li>single = has \"quotes\"</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html" | ||||
|     And I should see "<li>escaped = 'single' quotes</li>" in "_site/2013/04/07/allow-params-with-spaces-and-quotes.html" | ||||
|     And I should see "<li>param1_or_2 = value</li>" in "_site/2013/04/12/parameter-syntax.html" | ||||
|     And I should see "<li>local = some text</li>" in "_site/2013/06/22/pass-a-variable.html" | ||||
|     And I should see "<li>layout = default</li>" in "_site/2013/06/22/pass-a-variable.html" | ||||
|     And I should see "<li>title = Pass a variable</li>" in "_site/2013/06/22/pass-a-variable.html" | ||||
| 
 | ||||
|   Scenario: Include a file from a variable | ||||
|     Given I have an _includes directory | ||||
|  |  | |||
|  | @ -0,0 +1,60 @@ | |||
| Feature: Incremental rebuild | ||||
|   As an impatient hacker who likes to blog | ||||
|   I want to be able to make a static site | ||||
|   Without waiting too long for it to build | ||||
| 
 | ||||
|   Scenario: Produce correct output site | ||||
|     Given I have a _layouts directory | ||||
|     And I have a _posts directory | ||||
|     And I have the following posts: | ||||
|       | title    | date       | layout  | content                               | | ||||
|       | Wargames | 2009-03-27 | 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 | ||||
|     And I should see "Post Layout: <p>The only winning move is not to play.</p>" in "_site/2009/03/27/wargames.html" | ||||
|     When I run jekyll build | ||||
|     Then the _site directory should exist | ||||
|     And I should see "Post Layout: <p>The only winning move is not to play.</p>" in "_site/2009/03/27/wargames.html" | ||||
| 
 | ||||
|   Scenario: Generate a metadata file | ||||
|     Given I have an "index.html" file that contains "Basic Site" | ||||
|     When I run jekyll build | ||||
|     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 | ||||
|     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 | ||||
|     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 | ||||
|     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 | ||||
|     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 | ||||
|     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 | ||||
|     And I should see "Basic Site with include tag: Regenerated by Jekyll" in "_site/index.html" | ||||
|  | @ -17,7 +17,10 @@ Feature: Markdown | |||
|     And I should see "<h1 id=\"my-title\">My Title</h1>" in "_site/index.html" | ||||
| 
 | ||||
|   Scenario: Markdown in pagination on index | ||||
|     Given I have a configuration file with "paginate" set to "5" | ||||
|     Given I have a configuration file with: | ||||
|       | key      | value             | | ||||
|       | paginate | 5                 | | ||||
|       | gems     | [jekyll-paginate] | | ||||
|     And I have an "index.html" page that contains "Index - {% for post in paginator.posts %} {{ post.content }} {% endfor %}" | ||||
|     And I have a _posts directory | ||||
|     And I have the following post: | ||||
|  | @ -47,7 +50,7 @@ Feature: Markdown | |||
|     And I should see "My awesome code" in "_site/index.html" | ||||
|     And I should see "<pre><code>My awesome code</code></pre>" in "_site/index.html" | ||||
| 
 | ||||
|   Scenario: Maruku fenced codeblocks | ||||
|   Scenario: Maruku fenced codeblocks with syntax highlighting | ||||
|     Given I have a configuration file with "markdown" set to "maruku" | ||||
|     And I have an "index.markdown" file with content: | ||||
|        """ | ||||
|  |  | |||
|  | @ -4,7 +4,10 @@ Feature: Site pagination | |||
|   I want divide the posts in several pages | ||||
| 
 | ||||
|   Scenario Outline: Paginate with N posts per page | ||||
|     Given I have a configuration file with "paginate" set to "<num>" | ||||
|     Given I have a configuration file with: | ||||
|       | key      | value             | | ||||
|       | paginate | <num>             | | ||||
|       | gems     | [jekyll-paginate] | | ||||
|     And I have a _layouts directory | ||||
|     And I have an "index.html" page that contains "{{ paginator.posts.size }}" | ||||
|     And I have a _posts directory | ||||
|  | @ -32,6 +35,7 @@ Feature: Site pagination | |||
|       | paginate      | 1                              | | ||||
|       | paginate_path | /blog/page-:num                | | ||||
|       | permalink     | /blog/:year/:month/:day/:title | | ||||
|       | gems          | [jekyll-paginate]              | | ||||
|     And I have a blog directory | ||||
|     And I have an "blog/index.html" page that contains "{{ paginator.posts.size }}" | ||||
|     And I have a _posts directory | ||||
|  | @ -59,6 +63,7 @@ Feature: Site pagination | |||
|       | paginate      | 1                              | | ||||
|       | paginate_path | /blog/page/:num                | | ||||
|       | permalink     | /blog/:year/:month/:day/:title | | ||||
|       | gems          | [jekyll-paginate]              | | ||||
|     And I have a blog directory | ||||
|     And I have an "blog/index.html" page that contains "{{ paginator.posts.size }}" | ||||
|     And I have an "index.html" page that contains "Don't pick me!" | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ Feature: Fancy permalinks | |||
|     And I have the following post: | ||||
|       | title                   | category | date       | content         | | ||||
|       | Custom Permalink Schema | stuff    | 2009-03-27 | Totally custom. | | ||||
|     And I have a configuration file with "permalink" set to "/blog/:year/:month/:day/:title" | ||||
|     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 | ||||
|     And I should see "Totally custom." in "_site/blog/2009/03/27/custom-permalink-schema/index.html" | ||||
|  | @ -68,7 +68,7 @@ Feature: Fancy permalinks | |||
|     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 | | ||||
|       | Some post | 2013-04-14 | /custom/posts/1/ | bla bla | | ||||
|     When I run jekyll build | ||||
|     Then the _site directory should exist | ||||
|     And the _site/custom/posts/1 directory should exist | ||||
|  | @ -83,13 +83,3 @@ Feature: Fancy permalinks | |||
|     Then the _site directory should exist | ||||
|     And the _site/custom/posts directory should exist | ||||
|     And I should see "bla bla" in "_site/custom/posts/some.html" | ||||
| 
 | ||||
|   Scenario: Use per-post ending in .htm | ||||
|     Given I have a _posts directory | ||||
|     And I have the following post: | ||||
|       | title     | date       | permalink               | content | | ||||
|       | Some post | 2013-04-14 | /custom/posts/some.htm  | bla bla | | ||||
|     When I run jekyll build | ||||
|     Then the _site directory should exist | ||||
|     And the _site/custom/posts directory should exist | ||||
|     And I should see "bla bla" in "_site/custom/posts/some.htm" | ||||
|  |  | |||
|  | @ -141,7 +141,7 @@ Feature: Post data | |||
|     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 | ||||
|     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/2009/03/27/star-wars.html" | ||||
| 
 | ||||
|   Scenario: Use post.categories variable when category is in YAML | ||||
|     Given I have a _posts directory | ||||
|  | @ -163,7 +163,7 @@ Feature: Post data | |||
|     And I have a simple layout that contains "Post category: {{ page.categories }}" | ||||
|     When I run jekyll build | ||||
|     Then the _site directory should exist | ||||
|     And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html" | ||||
|     And I should see "Post category: Movies" in "_site/movies/2009/03/27/star-wars.html" | ||||
| 
 | ||||
|   Scenario: Use post.categories variable when categories are in YAML | ||||
|     Given I have a _posts directory | ||||
|  | @ -197,8 +197,8 @@ Feature: Post data | |||
|     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 | ||||
|     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" | ||||
|     And I should see "Post categories: scifi and Movies" in "_site/scifi/movies/2009/03/27/star-wars.html" | ||||
|     And I should see "Post categories: SciFi and movies" in "_site/scifi/movies/2013/03/17/star-trek.html" | ||||
| 
 | ||||
|   Scenario Outline: Use page.path variable | ||||
|     Given I have a <dir>/_posts directory | ||||
|  |  | |||
|  | @ -46,5 +46,5 @@ Feature: Post excerpts | |||
|     And the _site/2007/12 directory should exist | ||||
|     And the _site/2007/12/31 directory should exist | ||||
|     And the "_site/2007/12/31/entry1.html" file should exist | ||||
|     And I should see exactly "<p>content for entry1.</p>" in "_site/index.html" | ||||
|     And I should see exactly "<html><head></head><body><p>content for entry1.</p></body></html>" in "_site/2007/12/31/entry1.html" | ||||
|     And I should see "<p>content for entry1.</p>" in "_site/index.html" | ||||
|     And I should see "<html><head></head><body><p>content for entry1.</p>\n\n</body></html>" in "_site/2007/12/31/entry1.html" | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ Feature: Rendering | |||
|   Scenario: Don't place asset files in layout | ||||
|     Given I have an "index.scss" page with layout "simple" that contains ".foo-bar { color:black; }" | ||||
|     And I have an "index.coffee" page with layout "simple" that contains "whatever()" | ||||
|     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 | ||||
|  | @ -28,8 +29,15 @@ Feature: Rendering | |||
|     Then the _site directory should exist | ||||
|     And I should see ".foo-bar {\n  color: red; }" in "_site/index.css" | ||||
| 
 | ||||
|   Scenario: Render liquid in CoffeeScript | ||||
|   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 | ||||
|     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 | ||||
|     And I should see "hey = 'for cicada';" in "_site/index.js" | ||||
|  |  | |||
|  | @ -170,8 +170,8 @@ Feature: Site configuration | |||
|       When I run jekyll build | ||||
|       Then the _site directory should exist | ||||
|       And I should see "Page Layout: 2" in "_site/index.html" | ||||
|       And I should see "Post Layout: <p>content for entry1.</p> built at 2013-04-09T23:22:00-04:00" in "_site/2013/04/09/entry1.html" | ||||
|       And I should see "Post Layout: <p>content for entry2.</p> built at 2013-04-10T03:14:00-04:00" in "_site/2013/04/10/entry2.html" | ||||
|       And I should see "Post Layout: <p>content for entry1.</p>\n built at 2013-04-09T23:22:00-04:00" in "_site/2013/04/09/entry1.html" | ||||
|       And I should see "Post Layout: <p>content for entry2.</p>\n built at 2013-04-10T03:14:00-04:00" in "_site/2013/04/10/entry2.html" | ||||
| 
 | ||||
|     Scenario: Generate proper dates with explicitly set timezone (different than posts' time) | ||||
|       Given I have a _layouts directory | ||||
|  | @ -180,19 +180,19 @@ Feature: Site configuration | |||
|       And I have an "index.html" page with layout "page" that contains "site index page" | ||||
|       And I have a configuration file with: | ||||
|         | key         | value               | | ||||
|         | timezone    | Australia/Melbourne | | ||||
|         | timezone    | Pacific/Honolulu    | | ||||
|       And I have a _posts directory | ||||
|       And I have the following posts: | ||||
|         | title     | date                   | layout  | content             | | ||||
|         | entry1    | 2013-04-09 23:22 -0400 | post    | content for entry1. | | ||||
|         | entry2    | 2013-04-10 03:14 -0400 | post    | content for entry2. | | ||||
|         | 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 | ||||
|       And I should see "Page Layout: 2" in "_site/index.html" | ||||
|       And the "_site/2013/04/10/entry1.html" file should exist | ||||
|       And the "_site/2013/04/10/entry2.html" file should exist | ||||
|       And I should see escaped "Post Layout: <p>content for entry1.</p> built at 2013-04-10T13:22:00+10:00" in "_site/2013/04/10/entry1.html" | ||||
|       And I should see escaped "Post Layout: <p>content for entry2.</p> built at 2013-04-10T17:14:00+10:00" in "_site/2013/04/10/entry2.html" | ||||
|       And the "_site/2013/04/09/entry1.html" file should exist | ||||
|       And the "_site/2013/04/09/entry2.html" file should exist | ||||
|       And I should see "Post Layout: <p>content for entry1.</p>\n built at 2013-04-09T09:22:00-10:00" in "_site/2013/04/09/entry1.html" | ||||
|       And I should see "Post Layout: <p>content for entry2.</p>\n built at 2013-04-09T13:14:00-10:00" in "_site/2013/04/09/entry2.html" | ||||
| 
 | ||||
|   Scenario: Limit the number of posts generated by most recent date | ||||
|     Given I have a _posts directory | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ def file_content_from_hash(input_hash) | |||
|     input_hash['content'] | ||||
|   end | ||||
| 
 | ||||
|   <<EOF | ||||
|   <<-EOF | ||||
| --- | ||||
| #{matter} | ||||
| --- | ||||
|  | @ -24,9 +24,10 @@ 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(Test::Unit::Assertions) | ||||
| World(Minitest::Assertions) | ||||
| 
 | ||||
| Given /^I have a blank site in "(.*)"$/ do |path| | ||||
|   FileUtils.mkdir_p(path) unless File.exist?(path) | ||||
|  | @ -39,7 +40,7 @@ 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 | ||||
|     f.write <<-EOF | ||||
| --- | ||||
| #{key || 'layout'}: #{value || 'nil'} | ||||
| --- | ||||
|  | @ -83,7 +84,7 @@ 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'] || 'textile' | ||||
|     ext = input_hash['type'] || 'markdown' | ||||
|     before, after = location(folder, direction) | ||||
| 
 | ||||
|     case status | ||||
|  | @ -133,6 +134,10 @@ 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 | ||||
|  | @ -163,6 +168,12 @@ 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 | ||||
|  | @ -180,7 +191,7 @@ Then /^I should see exactly "(.*)" in "(.*)"$/ do |text, file| | |||
| end | ||||
| 
 | ||||
| Then /^I should not see "(.*)" in "(.*)"$/ do |text, file| | ||||
|   assert_no_match Regexp.new(text, Regexp::MULTILINE), file_contents(file) | ||||
|   refute_match Regexp.new(text, Regexp::MULTILINE), file_contents(file) | ||||
| end | ||||
| 
 | ||||
| Then /^I should see escaped "(.*)" in "(.*)"$/ do |text, file| | ||||
|  | @ -188,7 +199,15 @@ Then /^I should see escaped "(.*)" in "(.*)"$/ do |text, file| | |||
| end | ||||
| 
 | ||||
| Then /^the "(.*)" file should +exist$/ do |file| | ||||
|   assert File.file?(file), "The file \"#{file}\" does not exist" | ||||
|   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| | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| require 'fileutils' | ||||
| require 'posix-spawn' | ||||
| require 'rr' | ||||
| require 'test/unit' | ||||
| require 'minitest/assertions' | ||||
| require 'time' | ||||
| 
 | ||||
| JEKYLL_SOURCE_DIR = File.dirname(File.dirname(File.dirname(__FILE__))) | ||||
|  | @ -13,6 +12,17 @@ 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 | ||||
|  |  | |||
|  | @ -5,64 +5,35 @@ require 'jekyll/version' | |||
| 
 | ||||
| Gem::Specification.new do |s| | ||||
|   s.specification_version = 2 if s.respond_to? :specification_version= | ||||
|   s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= | ||||
|   s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version= | ||||
|   s.rubygems_version = '2.2.2' | ||||
|   s.required_ruby_version = '>= 1.9.3' | ||||
|   s.required_ruby_version = '>= 2.0.0' | ||||
| 
 | ||||
|   s.name              = 'jekyll' | ||||
|   s.version           = Jekyll::VERSION | ||||
|   s.license           = 'MIT' | ||||
|   s.name          = 'jekyll' | ||||
|   s.version       = Jekyll::VERSION | ||||
|   s.license       = 'MIT' | ||||
| 
 | ||||
|   s.summary     = "A simple, blog aware, static site generator." | ||||
|   s.description = "Jekyll is a simple, blog aware, static site generator." | ||||
|   s.summary       = 'A simple, blog aware, static site generator.' | ||||
|   s.description   = 'Jekyll is a simple, blog aware, static site generator.' | ||||
| 
 | ||||
|   s.authors  = ["Tom Preston-Werner"] | ||||
|   s.email    = 'tom@mojombo.com' | ||||
|   s.homepage = 'https://github.com/jekyll/jekyll' | ||||
|   s.authors       = ['Tom Preston-Werner'] | ||||
|   s.email         = 'tom@mojombo.com' | ||||
|   s.homepage      = 'https://github.com/jekyll/jekyll' | ||||
| 
 | ||||
|   all_files       = `git ls-files -z`.split("\x0") | ||||
|   s.files         = all_files.grep(%r{^(bin|lib)/}) | ||||
|   s.executables   = all_files.grep(%r{^bin/}) { |f| File.basename(f) } | ||||
|   s.require_paths = ["lib"] | ||||
|   s.require_paths = ['lib'] | ||||
| 
 | ||||
|   s.rdoc_options = ["--charset=UTF-8"] | ||||
|   s.rdoc_options = ['--charset=UTF-8'] | ||||
|   s.extra_rdoc_files = %w[README.markdown LICENSE] | ||||
| 
 | ||||
|   s.add_runtime_dependency('liquid',    "~> 2.6.1") | ||||
|   s.add_runtime_dependency('kramdown',  "~> 1.3") | ||||
|   s.add_runtime_dependency('mercenary', "~> 0.3.3") | ||||
|   s.add_runtime_dependency('safe_yaml', "~> 1.0") | ||||
|   s.add_runtime_dependency('colorator', "~> 0.1") | ||||
| 
 | ||||
|   # Before 3.0 drops, phase the following gems out as dev dependencies | ||||
|   # and gracefully handle their absence. | ||||
|   s.add_runtime_dependency('pygments.rb', "~> 0.6.0") | ||||
|   s.add_runtime_dependency('redcarpet', "~> 3.1") | ||||
|   s.add_runtime_dependency('toml', '~> 0.1.0') | ||||
|   s.add_runtime_dependency('jekyll-paginate', '~> 1.0') | ||||
|   s.add_runtime_dependency('jekyll-gist', '~> 1.0') | ||||
|   s.add_runtime_dependency('jekyll-coffeescript', '~> 1.0') | ||||
|   s.add_runtime_dependency('liquid',    '~> 3.0') | ||||
|   s.add_runtime_dependency('kramdown',  '~> 1.3') | ||||
|   s.add_runtime_dependency('mercenary', '~> 0.3.3') | ||||
|   s.add_runtime_dependency('safe_yaml', '~> 1.0') | ||||
|   s.add_runtime_dependency('colorator', '~> 0.1') | ||||
|   s.add_runtime_dependency('rouge', '~> 1.7') | ||||
|   s.add_runtime_dependency('jekyll-sass-converter', '~> 1.0') | ||||
|   s.add_runtime_dependency('jekyll-watch', '~> 1.1') | ||||
|   s.add_runtime_dependency('classifier-reborn', "~> 2.0") | ||||
| 
 | ||||
|   s.add_development_dependency('rake', "~> 10.1") | ||||
|   s.add_development_dependency('rdoc', "~> 3.11") | ||||
|   s.add_development_dependency('redgreen', "~> 1.2") | ||||
|   s.add_development_dependency('shoulda', "~> 3.5") | ||||
|   s.add_development_dependency('rr', "~> 1.1") | ||||
|   s.add_development_dependency('cucumber', "1.3.11") | ||||
|   s.add_development_dependency('RedCloth', "~> 4.2") | ||||
|   s.add_development_dependency('maruku', "~> 0.7.0") | ||||
|   s.add_development_dependency('rdiscount', "~> 1.6") | ||||
|   s.add_development_dependency('launchy', "~> 2.3") | ||||
|   s.add_development_dependency('simplecov', "~> 0.9") | ||||
|   s.add_development_dependency('simplecov-gem-adapter', "~> 1.0.1") | ||||
|   s.add_development_dependency('mime-types', "~> 1.5") | ||||
|   s.add_development_dependency('activesupport', '~> 3.2.13') | ||||
|   s.add_development_dependency('jekyll_test_plugin') | ||||
|   s.add_development_dependency('jekyll_test_plugin_malicious') | ||||
|   s.add_development_dependency('rouge', '~> 1.7') | ||||
|   s.add_development_dependency('minitest') if RUBY_PLATFORM =~ /cygwin/ | ||||
|   s.add_development_dependency('test-unit') if RUBY_PLATFORM =~ /cygwin/ | ||||
| end | ||||
|  |  | |||
|  | @ -21,6 +21,7 @@ require 'time' | |||
| require 'English' | ||||
| require 'pathname' | ||||
| require 'logger' | ||||
| require 'set' | ||||
| 
 | ||||
| # 3rd party | ||||
| require 'safe_yaml/load' | ||||
|  | @ -29,6 +30,7 @@ require 'kramdown' | |||
| require 'colorator' | ||||
| 
 | ||||
| SafeYAML::OPTIONS[:suppress_warnings] = true | ||||
| Liquid::Template.error_mode = :strict | ||||
| 
 | ||||
| module Jekyll | ||||
| 
 | ||||
|  | @ -43,6 +45,7 @@ module Jekyll | |||
|   autoload :EntryFilter,         'jekyll/entry_filter' | ||||
|   autoload :Errors,              'jekyll/errors' | ||||
|   autoload :Excerpt,             'jekyll/excerpt' | ||||
|   autoload :External,            'jekyll/external' | ||||
|   autoload :Filters,             'jekyll/filters' | ||||
|   autoload :FrontmatterDefaults, 'jekyll/frontmatter_defaults' | ||||
|   autoload :Layout,              'jekyll/layout' | ||||
|  | @ -52,6 +55,7 @@ module Jekyll | |||
|   autoload :PluginManager,       'jekyll/plugin_manager' | ||||
|   autoload :Post,                'jekyll/post' | ||||
|   autoload :Publisher,           'jekyll/publisher' | ||||
|   autoload :Regenerator,         'jekyll/regenerator' | ||||
|   autoload :RelatedPosts,        'jekyll/related_posts' | ||||
|   autoload :Renderer,            'jekyll/renderer' | ||||
|   autoload :Site,                'jekyll/site' | ||||
|  | @ -153,6 +157,9 @@ module Jekyll | |||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Conditional optimizations | ||||
|     Jekyll::External.require_if_present('liquid-c') | ||||
| 
 | ||||
|   end | ||||
| end | ||||
| 
 | ||||
|  | @ -162,11 +169,4 @@ require_all 'jekyll/converters/markdown' | |||
| require_all 'jekyll/generators' | ||||
| require_all 'jekyll/tags' | ||||
| 
 | ||||
| # Eventually remove these for 3.0 as non-core | ||||
| Jekyll::Deprecator.gracefully_require(%w[ | ||||
|   toml | ||||
|   jekyll-paginate | ||||
|   jekyll-gist | ||||
|   jekyll-coffeescript | ||||
|   jekyll-sass-converter | ||||
| ]) | ||||
| require 'jekyll-sass-converter' | ||||
|  |  | |||
|  | @ -1,95 +1,101 @@ | |||
| require 'set' | ||||
| 
 | ||||
| module Jekyll | ||||
|   class Site | ||||
|     # Handles the cleanup of a site's destination before it is built. | ||||
|     class Cleaner | ||||
|       attr_reader :site | ||||
|   # Handles the cleanup of a site's destination before it is built. | ||||
|   class Cleaner | ||||
|     attr_reader :site | ||||
| 
 | ||||
|       def initialize(site) | ||||
|         @site = site | ||||
|     def initialize(site) | ||||
|       @site = site | ||||
|     end | ||||
| 
 | ||||
|     # Cleans up the site's destination directory | ||||
|     def cleanup! | ||||
|       FileUtils.rm_rf(obsolete_files) | ||||
|       FileUtils.rm_rf(metadata_file) if @site.full_rebuild? | ||||
|     end | ||||
| 
 | ||||
|     private | ||||
| 
 | ||||
|     # Private: The list of files and directories to be deleted during cleanup process | ||||
|     # | ||||
|     # Returns an Array of the file and directory paths | ||||
|     def obsolete_files | ||||
|       (existing_files - new_files - new_dirs + replaced_files).to_a | ||||
|     end | ||||
| 
 | ||||
|     # Private: The metadata file storing dependency tree and build history | ||||
|     # | ||||
|     # Returns an Array with the metdata file as the only item | ||||
|     def metadata_file | ||||
|       [site.regenerator.metadata_file] | ||||
|     end | ||||
| 
 | ||||
|     # Private: The list of existing files, apart from those included in keep_files and hidden files. | ||||
|     # | ||||
|     # Returns a Set with the file paths | ||||
|     def existing_files | ||||
|       files = Set.new | ||||
|       Dir.glob(site.in_dest_dir("**", "*"), File::FNM_DOTMATCH) do |file| | ||||
|         files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex || keep_dirs.include?(file) | ||||
|       end | ||||
|       files | ||||
|     end | ||||
| 
 | ||||
|       # Cleans up the site's destination directory | ||||
|       def cleanup! | ||||
|         FileUtils.rm_rf(obsolete_files) | ||||
|     # Private: The list of files to be created when site is built. | ||||
|     # | ||||
|     # Returns a Set with the file paths | ||||
|     def new_files | ||||
|       files = Set.new | ||||
|       site.each_site_file { |item| files << item.destination(site.dest) } | ||||
|       files | ||||
|     end | ||||
| 
 | ||||
|     # Private: The list of directories to be created when site is built. | ||||
|     # These are the parent directories of the files in #new_files. | ||||
|     # | ||||
|     # Returns a Set with the directory paths | ||||
|     def new_dirs | ||||
|       new_files.map { |file| parent_dirs(file) }.flatten.to_set | ||||
|     end | ||||
| 
 | ||||
|     # Private: The list of parent directories of a given file | ||||
|     # | ||||
|     # Returns an Array with the directory paths | ||||
|     def parent_dirs(file) | ||||
|       parent_dir = File.dirname(file) | ||||
|       if parent_dir == site.dest | ||||
|         [] | ||||
|       else | ||||
|         [parent_dir] + parent_dirs(parent_dir) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|       private | ||||
|     # Private: The list of existing files that will be replaced by a directory during build | ||||
|     # | ||||
|     # Returns a Set with the file paths | ||||
|     def replaced_files | ||||
|       new_dirs.select { |dir| File.file?(dir) }.to_set | ||||
|     end | ||||
| 
 | ||||
|       # Private: The list of files and directories to be deleted during cleanup process | ||||
|       # | ||||
|       # Returns an Array of the file and directory paths | ||||
|       def obsolete_files | ||||
|         (existing_files - new_files - new_dirs + replaced_files).to_a | ||||
|       end | ||||
|     # Private: The list of directories that need to be kept because they are parent directories | ||||
|     # of files specified in keep_files | ||||
|     # | ||||
|     # Returns a Set with the directory paths | ||||
|     def keep_dirs | ||||
|       site.keep_files.map { |file| parent_dirs(site.in_dest_dir(file)) }.flatten.to_set | ||||
|     end | ||||
| 
 | ||||
|       # Private: The list of existing files, apart from those included in keep_files and hidden files. | ||||
|       # | ||||
|       # Returns a Set with the file paths | ||||
|       def existing_files | ||||
|         files = Set.new | ||||
|         Dir.glob(site.in_dest_dir("**", "*"), File::FNM_DOTMATCH) do |file| | ||||
|           files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex || keep_dirs.include?(file) | ||||
|         end | ||||
|         files | ||||
|       end | ||||
| 
 | ||||
|       # Private: The list of files to be created when site is built. | ||||
|       # | ||||
|       # Returns a Set with the file paths | ||||
|       def new_files | ||||
|         files = Set.new | ||||
|         site.each_site_file { |item| files << item.destination(site.dest) } | ||||
|         files | ||||
|       end | ||||
| 
 | ||||
|       # Private: The list of directories to be created when site is built. | ||||
|       # These are the parent directories of the files in #new_files. | ||||
|       # | ||||
|       # Returns a Set with the directory paths | ||||
|       def new_dirs | ||||
|         new_files.map { |file| parent_dirs(file) }.flatten.to_set | ||||
|       end | ||||
| 
 | ||||
|       # Private: The list of parent directories of a given file | ||||
|       # | ||||
|       # Returns an Array with the directory paths | ||||
|       def parent_dirs(file) | ||||
|         parent_dir = File.dirname(file) | ||||
|         if parent_dir == site.dest | ||||
|           [] | ||||
|         else | ||||
|           [parent_dir] + parent_dirs(parent_dir) | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       # Private: The list of existing files that will be replaced by a directory during build | ||||
|       # | ||||
|       # Returns a Set with the file paths | ||||
|       def replaced_files | ||||
|         new_dirs.select { |dir| File.file?(dir) }.to_set | ||||
|       end | ||||
| 
 | ||||
|       # Private: The list of directories that need to be kept because they are parent directories | ||||
|       # of files specified in keep_files | ||||
|       # | ||||
|       # Returns a Set with the directory paths | ||||
|       def keep_dirs | ||||
|         site.keep_files.map { |file| parent_dirs(site.in_dest_dir(file)) }.flatten.to_set | ||||
|       end | ||||
| 
 | ||||
|       # Private: Creates a regular expression from the config's keep_files array | ||||
|       # | ||||
|       # Examples | ||||
|       #   ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/ | ||||
|       # | ||||
|       # Returns the regular expression | ||||
|       def keep_file_regex | ||||
|         or_list = site.keep_files.join("|") | ||||
|         pattern = "\/(#{or_list.gsub(".", "\.")})" | ||||
|         Regexp.new pattern | ||||
|       end | ||||
|     # Private: Creates a regular expression from the config's keep_files array | ||||
|     # | ||||
|     # Examples | ||||
|     #   ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/ | ||||
|     # | ||||
|     # Returns the regular expression | ||||
|     def keep_file_regex | ||||
|       or_list = site.keep_files.join("|") | ||||
|       pattern = "\/(#{or_list.gsub(".", "\.")})" | ||||
|       Regexp.new pattern | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ module Jekyll | |||
|         if Utils.has_yaml_header? full_path | ||||
|           doc = Jekyll::Document.new(full_path, { site: site, collection: self }) | ||||
|           doc.read | ||||
|           docs << doc | ||||
|           docs << doc if site.publisher.publish?(doc) | ||||
|         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) | ||||
|  | @ -170,7 +170,9 @@ module Jekyll | |||
|     # | ||||
|     # Returns the URL template to render collection's documents at. | ||||
|     def url_template | ||||
|       metadata.fetch('permalink', "/:collection/:path:output_ext") | ||||
|       metadata.fetch('permalink') do | ||||
|           Utils.add_permalink_suffix("/:collection/:path", site.permalink_style) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Extract options for this collection from the site configuration. | ||||
|  | @ -183,6 +185,5 @@ module Jekyll | |||
|         {} | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|   end | ||||
| end | ||||
|  |  | |||
|  | @ -49,6 +49,8 @@ module Jekyll | |||
|       # Returns nothing | ||||
|       def add_build_options(c) | ||||
|         c.option 'config',  '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file' | ||||
|         c.option 'destination', '-d', '--destination DESTINATION', 'The current folder will be generated into DESTINATION' | ||||
|         c.option 'source', '-s', '--source SOURCE', 'Custom source directory' | ||||
|         c.option 'future',  '--future', 'Publishes posts with a future date' | ||||
|         c.option 'limit_posts', '--limit_posts MAX_POSTS', Integer, 'Limits the number of posts to parse and publish' | ||||
|         c.option 'watch',   '-w', '--[no-]watch', 'Watch for changes and rebuild' | ||||
|  | @ -58,6 +60,7 @@ 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.' | ||||
|       end | ||||
| 
 | ||||
|     end | ||||
|  |  | |||
|  | @ -48,13 +48,16 @@ module Jekyll | |||
|         # | ||||
|         # Returns nothing. | ||||
|         def build(site, options) | ||||
|           t = Time.now | ||||
|           source      = options['source'] | ||||
|           destination = options['destination'] | ||||
|           full_build  = options['full_rebuild'] | ||||
|           Jekyll.logger.info "Source:", source | ||||
|           Jekyll.logger.info "Destination:", destination | ||||
|           Jekyll.logger.info "Incremental build:", (full_build ? "disabled" : "enabled") | ||||
|           Jekyll.logger.info "Generating..." | ||||
|           process_site(site) | ||||
|           Jekyll.logger.info "", "done." | ||||
|           Jekyll.logger.info "", "done in #{(Time.now - t).round(3)} seconds." | ||||
|         end | ||||
| 
 | ||||
|         # Private: Watch for file changes and rebuild the site. | ||||
|  | @ -64,7 +67,7 @@ module Jekyll | |||
|         # | ||||
|         # Returns nothing. | ||||
|         def watch(site, options) | ||||
|           Deprecator.gracefully_require 'jekyll-watch' | ||||
|           External.require_with_graceful_fail 'jekyll-watch' | ||||
|           Jekyll::Watcher.watch(options) | ||||
|         end | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,42 @@ | |||
| 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({}) | ||||
|             end | ||||
|           end | ||||
|         end | ||||
| 
 | ||||
|         def process(options) | ||||
|           options = configuration_from_options(options) | ||||
|           destination = options['destination'] | ||||
|           metadata_file = File.join(options['source'], '.jekyll-metadata') | ||||
| 
 | ||||
|           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 | ||||
|         end | ||||
| 
 | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  | @ -1,30 +0,0 @@ | |||
| module Jekyll | ||||
|   module Commands | ||||
|     class Docs < Command | ||||
| 
 | ||||
|       class << self | ||||
| 
 | ||||
|         def init_with_program(prog) | ||||
|           prog.command(:docs) do |c| | ||||
|             c.syntax 'docs' | ||||
|             c.description "Launch local server with docs for Jekyll v#{Jekyll::VERSION}" | ||||
| 
 | ||||
|             c.option 'port', '-P', '--port [PORT]', 'Port to listen on' | ||||
|             c.option 'host', '-H', '--host [HOST]', 'Host to bind to' | ||||
| 
 | ||||
|             c.action do |args, options| | ||||
|               options.merge!({ | ||||
|                 'source'      => File.expand_path("../../../site", File.dirname(__FILE__)), | ||||
|                 'destination' => File.expand_path("../../../site/_site", File.dirname(__FILE__)) | ||||
|               }) | ||||
|               Jekyll::Commands::Build.process(options) | ||||
|               Jekyll::Commands::Serve.process(options) | ||||
|             end | ||||
|           end | ||||
|         end | ||||
| 
 | ||||
|       end | ||||
| 
 | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  | @ -39,7 +39,7 @@ module Jekyll | |||
|           contains_deprecated_pages = false | ||||
|           site.pages.each do |page| | ||||
|             if page.uses_relative_permalinks | ||||
|               Jekyll.logger.warn "Deprecation:", "'#{page.path}' uses relative" + | ||||
|               Jekyll::Deprecator.deprecation_message "'#{page.path}' uses relative" + | ||||
|                                   " permalinks which will be deprecated in" + | ||||
|                                   " Jekyll v2.0.0 and beyond." | ||||
|               contains_deprecated_pages = true | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ require 'erb' | |||
| module Jekyll | ||||
|   module Commands | ||||
|     class New < Command | ||||
|       class << self  | ||||
|       class << self | ||||
|         def init_with_program(prog) | ||||
|           prog.command(:new) do |c| | ||||
|             c.syntax 'new PATH' | ||||
|  | @ -11,7 +11,7 @@ module Jekyll | |||
| 
 | ||||
|             c.option 'force', '--force', 'Force creation even if PATH already exists' | ||||
|             c.option 'blank', '--blank', 'Creates scaffolding but with empty files' | ||||
|              | ||||
| 
 | ||||
|             c.action do |args, options| | ||||
|               Jekyll::Commands::New.process(args, options) | ||||
|             end | ||||
|  | @ -76,7 +76,7 @@ module Jekyll | |||
|         def scaffold_path | ||||
|           "_posts/0000-00-00-welcome-to-jekyll.markdown.erb" | ||||
|         end | ||||
|       end   | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  |  | |||
|  | @ -40,7 +40,7 @@ module Jekyll | |||
| 
 | ||||
|           s.mount( | ||||
|             options['baseurl'], | ||||
|             WEBrick::HTTPServlet::FileHandler, | ||||
|             custom_file_handler, | ||||
|             destination, | ||||
|             file_handler_options | ||||
|           ) | ||||
|  | @ -50,7 +50,7 @@ module Jekyll | |||
|           if options['detach'] # detach the server | ||||
|             pid = Process.fork { s.start } | ||||
|             Process.detach(pid) | ||||
|             Jekyll.logger.info "Server detached with pid '#{pid}'.", "Run `kill -9 #{pid}' to stop the server." | ||||
|             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 } | ||||
|  | @ -99,6 +99,21 @@ module Jekyll | |||
|           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 | ||||
|         end | ||||
| 
 | ||||
|         def start_callback(detached) | ||||
|           unless detached | ||||
|             Proc.new { Jekyll.logger.info "Server running...", "press ctrl-c to stop." } | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ module Jekyll | |||
|       'keep_files'    => ['.git','.svn'], | ||||
|       'encoding'      => 'utf-8', | ||||
|       'markdown_ext'  => 'markdown,mkdown,mkdn,mkd,md', | ||||
|       'textile_ext'   => 'textile', | ||||
|       'full_rebuild'  => false, | ||||
| 
 | ||||
|       # Filtering Content | ||||
|       'show_drafts'   => nil, | ||||
|  | @ -35,7 +35,7 @@ module Jekyll | |||
| 
 | ||||
|       # Conversion | ||||
|       'markdown'      => 'kramdown', | ||||
|       'highlighter'   => 'pygments', | ||||
|       'highlighter'   => 'rouge', | ||||
|       'lsi'           => false, | ||||
|       'excerpt_separator' => "\n\n", | ||||
| 
 | ||||
|  | @ -74,12 +74,12 @@ module Jekyll | |||
|       }, | ||||
| 
 | ||||
|       'kramdown' => { | ||||
|         'auto_ids'      => true, | ||||
|         'footnote_nr'   => 1, | ||||
|         'entity_output' => 'as_char', | ||||
|         'toc_levels'    => '1..6', | ||||
|         'smart_quotes'  => 'lsquo,rsquo,ldquo,rdquo', | ||||
|         'use_coderay'   => false, | ||||
|         'auto_ids'       => true, | ||||
|         'footnote_nr'    => 1, | ||||
|         'entity_output'  => 'as_char', | ||||
|         'toc_levels'     => '1..6', | ||||
|         'smart_quotes'   => 'lsquo,rsquo,ldquo,rdquo', | ||||
|         'enable_coderay' => false, | ||||
| 
 | ||||
|         'coderay' => { | ||||
|           'coderay_wrap'              => 'div', | ||||
|  | @ -89,10 +89,6 @@ module Jekyll | |||
|           'coderay_bold_every'        => 10, | ||||
|           'coderay_css'               => 'style' | ||||
|         } | ||||
|       }, | ||||
| 
 | ||||
|       'redcloth' => { | ||||
|         'hard_breaks' => true | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|  | @ -119,6 +115,7 @@ module Jekyll | |||
|     def safe_load_file(filename) | ||||
|       case File.extname(filename) | ||||
|       when /\.toml/i | ||||
|         Jekyll::External.require_with_graceful_fail('toml') unless defined?(TOML) | ||||
|         TOML.load_file(filename) | ||||
|       when /\.ya?ml/i | ||||
|         SafeYAML.load_file(filename) | ||||
|  | @ -140,7 +137,7 @@ module Jekyll | |||
|       config_files = override.delete('config') | ||||
|       if config_files.to_s.empty? | ||||
|         default = %w[yml yaml].find(Proc.new { 'yml' }) do |ext| | ||||
|           File.exists? Jekyll.sanitized_path(source(override), "_config.#{ext}") | ||||
|           File.exist?(Jekyll.sanitized_path(source(override), "_config.#{ext}")) | ||||
|         end | ||||
|         config_files = Jekyll.sanitized_path(source(override), "_config.#{default}") | ||||
|         @default_config_file = true | ||||
|  | @ -209,7 +206,7 @@ module Jekyll | |||
|       config = clone | ||||
|       # Provide backwards-compatibility | ||||
|       if config.key?('auto') || config.key?('watch') | ||||
|         Jekyll.logger.warn "Deprecation:", "Auto-regeneration can no longer" + | ||||
|         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') | ||||
|  | @ -217,14 +214,14 @@ module Jekyll | |||
|       end | ||||
| 
 | ||||
|       if config.key? 'server' | ||||
|         Jekyll.logger.warn "Deprecation:", "The 'server' configuration option" + | ||||
|         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.logger.warn "Deprecation:", "The 'server_port' configuration option" + | ||||
|         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: | ||||
|  | @ -233,7 +230,7 @@ module Jekyll | |||
|       end | ||||
| 
 | ||||
|       if config.key? 'pygments' | ||||
|         Jekyll.logger.warn "Deprecation:", "The 'pygments' configuration option" + | ||||
|         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." | ||||
|  | @ -244,7 +241,7 @@ module Jekyll | |||
| 
 | ||||
|       %w[include exclude].each do |option| | ||||
|         if config.fetch(option, []).is_a?(String) | ||||
|           Jekyll.logger.warn "Deprecation:", "The '#{option}' configuration option" + | ||||
|           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." | ||||
|  | @ -253,11 +250,23 @@ module Jekyll | |||
|         config[option].map!(&:to_s) | ||||
|       end | ||||
| 
 | ||||
|       if (config['kramdown'] || {}).key?('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::Deprecator.deprecation_message "You're using the 'maruku' " + | ||||
|           "Markdown processor. Maruku support has been deprecated and will " + | ||||
|           "be removed in 3.0.0. We recommend you switch to Kramdown." | ||||
|       end | ||||
| 
 | ||||
|       if config.key?('paginate') && config['paginate'] && !(config['gems'] || []).include?('jekyll-paginate') | ||||
|         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 | ||||
|       config | ||||
|     end | ||||
| 
 | ||||
|  |  | |||
|  | @ -46,15 +46,12 @@ module Jekyll | |||
|         ].map(&:to_sym) | ||||
|       end | ||||
| 
 | ||||
|       def extname_matches_regexp | ||||
|         @extname_matches_regexp ||= Regexp.new( | ||||
|           '^\.(' + @config['markdown_ext'].gsub(',','|') +')$', | ||||
|           Regexp::IGNORECASE | ||||
|         ) | ||||
|       def extname_list | ||||
|         @extname_list ||= @config['markdown_ext'].split(',').map { |e| ".#{e.downcase}" } | ||||
|       end | ||||
| 
 | ||||
|       def matches(ext) | ||||
|         ext =~ extname_matches_regexp | ||||
|         extname_list.include? ext.downcase | ||||
|       end | ||||
| 
 | ||||
|       def output_ext(ext) | ||||
|  |  | |||
|  | @ -13,14 +13,14 @@ module Jekyll | |||
| 
 | ||||
|         def convert(content) | ||||
|           # Check for use of coderay | ||||
|           if @config['kramdown']['use_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, Utils.symbolize_hash_keys(@config['kramdown'])).to_html | ||||
|         end | ||||
| 
 | ||||
|       end | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ module Jekyll | |||
|     class Markdown | ||||
|       class RDiscountParser | ||||
|         def initialize(config) | ||||
|           Jekyll::Deprecator.gracefully_require "rdiscount" | ||||
|           Jekyll::External.require_with_graceful_fail "rdiscount" | ||||
|           @config = config | ||||
|           @rdiscount_extensions = @config['rdiscount']['extensions'].map { |e| e.to_sym } | ||||
|         end | ||||
|  |  | |||
|  | @ -14,7 +14,7 @@ module Jekyll | |||
|         module WithPygments | ||||
|           include CommonMethods | ||||
|           def block_code(code, lang) | ||||
|             Jekyll::Deprecator.gracefully_require("pygments") | ||||
|             Jekyll::External.require_with_graceful_fail("pygments") | ||||
|             lang = lang && lang.split.first || "text" | ||||
|             add_code_tags( | ||||
|               Pygments.highlight(code, :lexer => lang, :options => { :encoding => 'utf-8' }), | ||||
|  | @ -55,7 +55,7 @@ module Jekyll | |||
| 
 | ||||
| 
 | ||||
|         def initialize(config) | ||||
|           Deprecator.gracefully_require("redcarpet") | ||||
|           External.require_with_graceful_fail("redcarpet") | ||||
|           @config = config | ||||
|           @redcarpet_extensions = {} | ||||
|           @config['redcarpet']['extensions'].each { |e| @redcarpet_extensions[e.to_sym] = true } | ||||
|  | @ -71,7 +71,7 @@ module Jekyll | |||
|             end | ||||
|           when "rouge" | ||||
|             Class.new(Redcarpet::Render::HTML) do | ||||
|               Jekyll::Deprecator.gracefully_require(%w[ | ||||
|               Jekyll::External.require_with_graceful_fail(%w[ | ||||
|                 rouge | ||||
|                 rouge/plugins/redcarpet | ||||
|               ]) | ||||
|  |  | |||
|  | @ -1,56 +0,0 @@ | |||
| module Jekyll | ||||
|   module Converters | ||||
|     class Textile < Converter | ||||
|       safe true | ||||
| 
 | ||||
|       highlighter_prefix '<notextile>' | ||||
|       highlighter_suffix '</notextile>' | ||||
| 
 | ||||
|       def setup | ||||
|         return if @setup | ||||
|         require 'redcloth' | ||||
|         @setup = true | ||||
|       rescue LoadError | ||||
|         STDERR.puts 'You are missing a library required for Textile. Please run:' | ||||
|         STDERR.puts '  $ [sudo] gem install RedCloth' | ||||
|         raise Errors::FatalException.new("Missing dependency: RedCloth") | ||||
|       end | ||||
| 
 | ||||
|       def extname_matches_regexp | ||||
|         @extname_matches_regexp ||= Regexp.new( | ||||
|           '(' + @config['textile_ext'].gsub(',','|') +')$', | ||||
|           Regexp::IGNORECASE | ||||
|         ) | ||||
|       end | ||||
| 
 | ||||
|       def matches(ext) | ||||
|         ext =~ extname_matches_regexp | ||||
|       end | ||||
| 
 | ||||
|       def output_ext(ext) | ||||
|         ".html" | ||||
|       end | ||||
| 
 | ||||
|       def convert(content) | ||||
|         setup | ||||
| 
 | ||||
|         # Shortcut if config doesn't contain RedCloth section | ||||
|         return RedCloth.new(content).to_html if @config['redcloth'].nil? | ||||
| 
 | ||||
|         # List of attributes defined on RedCloth | ||||
|         # (from https://github.com/jgarber/redcloth/blob/master/lib/redcloth/textile_doc.rb) | ||||
|         attrs = ['filter_classes', 'filter_html', 'filter_ids', 'filter_styles', | ||||
|                 'hard_breaks', 'lite_mode', 'no_span_caps', 'sanitize_html'] | ||||
| 
 | ||||
|         r = RedCloth.new(content) | ||||
| 
 | ||||
|         # Set attributes in r if they are NOT nil in the config | ||||
|         attrs.each do |attr| | ||||
|           r.instance_variable_set("@#{attr}".to_sym, @config['redcloth'][attr]) unless @config['redcloth'][attr].nil? | ||||
|         end | ||||
| 
 | ||||
|         r.to_html | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  | @ -207,6 +207,12 @@ module Jekyll | |||
|                                          info, | ||||
|                                          File.join(site.config['layouts'], layout.name)) | ||||
| 
 | ||||
|         # Add layout to dependency tree | ||||
|         site.regenerator.add_dependency( | ||||
|           site.in_source_dir(path), | ||||
|           site.in_source_dir(layout.path) | ||||
|         ) | ||||
| 
 | ||||
|         if layout = layouts[layout.data["layout"]] | ||||
|           if used.include?(layout) | ||||
|             layout = nil # avoid recursive chain | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ module Jekyll | |||
|     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." | ||||
|                             switches. Run `jekyll --help` to find out more." | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|  | @ -40,22 +40,5 @@ module Jekyll | |||
|       Jekyll.logger.warn "Defaults:", "Please update your front-matter defaults to use 'type: #{current}'." | ||||
|     end | ||||
| 
 | ||||
|     def gracefully_require(gem_name) | ||||
|       Array(gem_name).each do |name| | ||||
|         begin | ||||
|           require name | ||||
|         rescue LoadError => e | ||||
|           Jekyll.logger.error "Dependency Error:", <<-MSG | ||||
|   Yikes! It looks like you don't have #{name} or one of its dependencies installed. | ||||
|   In order to use Jekyll as currently configured, you'll need to install this gem. | ||||
| 
 | ||||
|   The full error message from Ruby is: '#{e.message}' | ||||
| 
 | ||||
|   If you run into trouble, you can find helpful resources at http://jekyllrb.com/help/! | ||||
| MSG | ||||
|           raise Errors::MissingDependencyException.new(name) | ||||
|         end | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  |  | |||
|  | @ -4,9 +4,11 @@ module Jekyll | |||
|   class Document | ||||
|     include Comparable | ||||
| 
 | ||||
|     attr_reader   :path, :site, :extname | ||||
|     attr_reader   :path, :site, :extname, :output_ext | ||||
|     attr_accessor :content, :collection, :output | ||||
| 
 | ||||
|     YAML_FRONT_MATTER_REGEXP = /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m | ||||
| 
 | ||||
|     # Create a new Document. | ||||
|     # | ||||
|     # site - the Jekyll::Site instance to which this Document belongs | ||||
|  | @ -17,6 +19,7 @@ module Jekyll | |||
|       @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 | ||||
|  | @ -128,9 +131,9 @@ module Jekyll | |||
|       { | ||||
|         collection: collection.label, | ||||
|         path:       cleaned_relative_path, | ||||
|         output_ext: Jekyll::Renderer.new(site, self).output_ext, | ||||
|         output_ext: output_ext, | ||||
|         name:       Utils.slugify(basename_without_ext), | ||||
|         title:      Utils.slugify(data['title']) || Utils.slugify(basename_without_ext) | ||||
|         title:      Utils.slugify(data['slug']) || Utils.slugify(basename_without_ext) | ||||
|       } | ||||
|     end | ||||
| 
 | ||||
|  | @ -160,8 +163,9 @@ module Jekyll | |||
|     # Returns the full path to the output file of this document. | ||||
|     def destination(base_directory) | ||||
|       dest = site.in_dest_dir(base_directory) | ||||
|       path = site.in_dest_dir(dest, url) | ||||
|       path = File.join(path, "index.html") if url =~ /\/$/ | ||||
|       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 | ||||
|     end | ||||
| 
 | ||||
|  | @ -210,7 +214,7 @@ module Jekyll | |||
|             @data = defaults | ||||
|           end | ||||
|           @content = File.read(path, merged_file_read_opts(opts)) | ||||
|           if content =~ /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m | ||||
|           if content =~ YAML_FRONT_MATTER_REGEXP | ||||
|             @content = $POSTMATCH | ||||
|             data_file = SafeYAML.load($1) | ||||
|             unless data_file.nil? | ||||
|  | @ -233,8 +237,8 @@ module Jekyll | |||
|         Utils.deep_merge_hashes data, { | ||||
|           "output"        => output, | ||||
|           "content"       => content, | ||||
|           "path"          => path, | ||||
|           "relative_path" => relative_path, | ||||
|           "path"          => relative_path, | ||||
|           "url"           => url, | ||||
|           "collection"    => collection.label | ||||
|         } | ||||
|  |  | |||
|  | @ -105,8 +105,7 @@ module Jekyll | |||
|     # | ||||
|     # Returns excerpt String | ||||
|     def extract_excerpt(post_content) | ||||
|       separator     = site.config['excerpt_separator'] | ||||
|       head, _, tail = post_content.to_s.partition(separator) | ||||
|       head, _, tail = post_content.to_s.partition(post.excerpt_separator) | ||||
| 
 | ||||
|       "" << head << "\n\n" << tail.scan(/^\[[^\]]+\]:.+$/).join("\n") | ||||
|     end | ||||
|  |  | |||
|  | @ -0,0 +1,59 @@ | |||
| module Jekyll | ||||
|   module External | ||||
|     class << self | ||||
| 
 | ||||
|       # | ||||
|       # Gems that, if installed, should be loaded. | ||||
|       # Usually contain subcommands. | ||||
|       # | ||||
|       def blessed_gems | ||||
|         %w{ | ||||
|           jekyll-docs | ||||
|           jekyll-import | ||||
|         } | ||||
|       end | ||||
| 
 | ||||
|       # | ||||
|       # Require a gem or file if it's present, otherwise silently fail. | ||||
|       # | ||||
|       # names - a string gem name or array of gem names | ||||
|       # | ||||
|       def require_if_present(names) | ||||
|         Array(names).each do |name| | ||||
|           begin | ||||
|             require name | ||||
|           rescue LoadError | ||||
|             Jekyll.logger.debug "Couldn't load #{name}. Skipping." | ||||
|             false | ||||
|           end | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       # | ||||
|       # Require a gem or gems. If it's not present, show a very nice error | ||||
|       # message that explains everything and is much more helpful than the | ||||
|       # normal LoadError. | ||||
|       # | ||||
|       # names - a string gem name or array of gem names | ||||
|       # | ||||
|       def require_with_graceful_fail(names) | ||||
|         Array(names).each do |name| | ||||
|           begin | ||||
|             require name | ||||
|           rescue LoadError => e | ||||
|             Jekyll.logger.error "Dependency Error:", <<-MSG | ||||
| Yikes! It looks like you don't have #{name} or one of its dependencies installed. | ||||
| In order to use Jekyll as currently configured, you'll need to install this gem. | ||||
| 
 | ||||
| The full error message from Ruby is: '#{e.message}' | ||||
| 
 | ||||
| If you run into trouble, you can find helpful resources at http://jekyllrb.com/help/! | ||||
|             MSG | ||||
|             raise Jekyll::Errors::MissingDependencyException.new(name) | ||||
|           end | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  | @ -1,19 +1,9 @@ | |||
| require 'uri' | ||||
| require 'json' | ||||
| require 'date' | ||||
| 
 | ||||
| module Jekyll | ||||
|   module Filters | ||||
|     # Convert a Textile string into HTML output. | ||||
|     # | ||||
|     # input - The Textile String to convert. | ||||
|     # | ||||
|     # Returns the HTML formatted String. | ||||
|     def textilize(input) | ||||
|       site = @context.registers[:site] | ||||
|       converter = site.getConverterImpl(Jekyll::Converters::Textile) | ||||
|       converter.convert(input) | ||||
|     end | ||||
| 
 | ||||
|     # Convert a Markdown string into HTML output. | ||||
|     # | ||||
|     # input - The Markdown String to convert. | ||||
|  | @ -21,7 +11,7 @@ module Jekyll | |||
|     # Returns the HTML formatted String. | ||||
|     def markdownify(input) | ||||
|       site = @context.registers[:site] | ||||
|       converter = site.getConverterImpl(Jekyll::Converters::Markdown) | ||||
|       converter = site.find_converter_instance(Jekyll::Converters::Markdown) | ||||
|       converter.convert(input) | ||||
|     end | ||||
| 
 | ||||
|  | @ -32,7 +22,7 @@ module Jekyll | |||
|     # Returns the CSS formatted String. | ||||
|     def sassify(input) | ||||
|       site = @context.registers[:site] | ||||
|       converter = site.getConverterImpl(Jekyll::Converters::Sass) | ||||
|       converter = site.find_converter_instance(Jekyll::Converters::Sass) | ||||
|       converter.convert(input) | ||||
|     end | ||||
| 
 | ||||
|  | @ -43,19 +33,19 @@ module Jekyll | |||
|     # Returns the CSS formatted String. | ||||
|     def scssify(input) | ||||
|       site = @context.registers[:site] | ||||
|       converter = site.getConverterImpl(Jekyll::Converters::Scss) | ||||
|       converter = site.find_converter_instance(Jekyll::Converters::Scss) | ||||
|       converter.convert(input) | ||||
|     end | ||||
| 
 | ||||
|     # Slugify a filename or title. | ||||
|     # | ||||
|     # input - The filename or title to slugify. | ||||
|     # mode - how string is slugified | ||||
|     # | ||||
|     # Returns the given filename or title as a lowercase String, with every | ||||
|     # sequence of spaces and non-alphanumeric characters replaced with a | ||||
|     # hyphen. | ||||
|     def slugify(input) | ||||
|       Utils.slugify(input) | ||||
|     # 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) | ||||
|     end | ||||
| 
 | ||||
|     # Format a date in short format e.g. "27 Jan 2011". | ||||
|  | @ -232,6 +222,9 @@ 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.") | ||||
|       end | ||||
|       if property.nil? | ||||
|         input.sort | ||||
|       else | ||||
|  | @ -302,6 +295,8 @@ module Jekyll | |||
|       case input | ||||
|       when Time | ||||
|         input | ||||
|       when Date | ||||
|         input.to_time | ||||
|       when String | ||||
|         Time.parse(input) rescue Time.at(input.to_i) | ||||
|       when Numeric | ||||
|  | @ -309,7 +304,7 @@ module Jekyll | |||
|       else | ||||
|         Jekyll.logger.error "Invalid Date:", "'#{input}' is not a valid datetime." | ||||
|         exit(1) | ||||
|       end | ||||
|       end.localtime | ||||
|     end | ||||
| 
 | ||||
|     def groupable?(element) | ||||
|  | @ -328,14 +323,23 @@ module Jekyll | |||
| 
 | ||||
|     def as_liquid(item) | ||||
|       case item | ||||
|       when String, Numeric, true, false, nil | ||||
|         item.to_liquid | ||||
|       when Hash | ||||
|         Hash[item.map { |k, v| [as_liquid(k), as_liquid(v)] }] | ||||
|         pairs = item.map { |k, v| as_liquid([k, v]) } | ||||
|         Hash[pairs] | ||||
|       when Array | ||||
|         item.map{ |i| as_liquid(i) } | ||||
|       else | ||||
|         item.respond_to?(:to_liquid) ? as_liquid(item.to_liquid) : item | ||||
|         if item.respond_to?(:to_liquid) | ||||
|           liquidated = item.to_liquid | ||||
|           # prevent infinite recursion for simple types (which return `self`) | ||||
|           if liquidated == item | ||||
|             item | ||||
|           else | ||||
|             as_liquid(liquidated) | ||||
|           end | ||||
|         else | ||||
|           item | ||||
|         end | ||||
|       end | ||||
|     end | ||||
|   end | ||||
|  |  | |||
|  | @ -168,7 +168,7 @@ module Jekyll | |||
|       end.compact | ||||
|     end | ||||
| 
 | ||||
|     # Sanitizes the given path by removing a leading and addding a trailing slash | ||||
|     # Sanitizes the given path by removing a leading and adding a trailing slash | ||||
|     def sanitize_path(path) | ||||
|       if path.nil? || path.empty? | ||||
|         "" | ||||
|  |  | |||
|  | @ -8,6 +8,9 @@ module Jekyll | |||
|     # Gets the name of this layout. | ||||
|     attr_reader :name | ||||
| 
 | ||||
|     # Gets the path to this layout. | ||||
|     attr_reader :path | ||||
| 
 | ||||
|     # Gets/Sets the extension of this layout. | ||||
|     attr_accessor :ext | ||||
| 
 | ||||
|  | @ -26,6 +29,7 @@ module Jekyll | |||
|       @site = site | ||||
|       @base = base | ||||
|       @name = name | ||||
|       @path = site.in_source_dir(base, name) | ||||
| 
 | ||||
|       self.data = {} | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| module Jekyll | ||||
|   class LogAdapter | ||||
|     attr_reader :writer | ||||
|     attr_reader :writer, :messages | ||||
| 
 | ||||
|     LOG_LEVELS = { | ||||
|       :debug => ::Logger::DEBUG, | ||||
|  | @ -16,6 +16,7 @@ module Jekyll | |||
|     # | ||||
|     # Returns nothing | ||||
|     def initialize(writer, level = :info) | ||||
|       @messages = [] | ||||
|       @writer = writer | ||||
|       self.log_level = level | ||||
|     end | ||||
|  | @ -87,7 +88,9 @@ module Jekyll | |||
|     # | ||||
|     # Returns the formatted message | ||||
|     def message(topic, message) | ||||
|       formatted_topic(topic) + message.to_s.gsub(/\s+/, ' ') | ||||
|       msg = formatted_topic(topic) + message.to_s.gsub(/\s+/, ' ') | ||||
|       messages << msg | ||||
|       msg | ||||
|     end | ||||
| 
 | ||||
|     # Internal: Format the topic | ||||
|  |  | |||
|  | @ -63,16 +63,12 @@ module Jekyll | |||
|     # | ||||
|     # Returns the template String. | ||||
|     def template | ||||
|       if site.permalink_style == :pretty | ||||
|         if index? && html? | ||||
|           "/:path/" | ||||
|         elsif html? | ||||
|           "/:path/:basename/" | ||||
|         else | ||||
|           "/:path/:basename:output_ext" | ||||
|         end | ||||
|       else | ||||
|       if !html? | ||||
|         "/:path/:basename:output_ext" | ||||
|       elsif index? | ||||
|         "/:path/" | ||||
|       else | ||||
|         Utils.add_permalink_suffix("/:path/:basename", site.permalink_style) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|  | @ -141,7 +137,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 =~ /\/$/ | ||||
|       path = File.join(path, "index.html") if url.end_with?("/") | ||||
|       path << output_ext unless path.end_with?(output_ext) | ||||
|       path | ||||
|     end | ||||
| 
 | ||||
|  |  | |||
|  | @ -23,6 +23,8 @@ module Jekyll | |||
|     ATTRIBUTES_FOR_LIQUID = EXCERPT_ATTRIBUTES_FOR_LIQUID + %w[ | ||||
|       content | ||||
|       excerpt | ||||
|       excerpt_separator | ||||
|       draft? | ||||
|     ] | ||||
| 
 | ||||
|     # Post name validator. Post filenames must be like: | ||||
|  | @ -52,12 +54,12 @@ module Jekyll | |||
|       @base = containing_dir(dir) | ||||
|       @name = name | ||||
| 
 | ||||
|       self.categories = dir.downcase.split('/').reject { |x| x.empty? } | ||||
|       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(File.join(dir, name), type, key) | ||||
|         site.frontmatter_defaults.find(relative_path, type, key) | ||||
|       end | ||||
| 
 | ||||
|       if data.key?('date') | ||||
|  | @ -80,7 +82,7 @@ module Jekyll | |||
|       categories_from_data = Utils.pluralized_array_from_hash(data, 'category', 'categories') | ||||
|       self.categories = ( | ||||
|         Array(categories) + categories_from_data | ||||
|       ).map {|c| c.to_s.downcase}.flatten.uniq | ||||
|       ).map { |c| c.to_s }.flatten.uniq | ||||
|     end | ||||
| 
 | ||||
|     def populate_tags | ||||
|  | @ -118,6 +120,14 @@ module Jekyll | |||
|       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(' ') | ||||
|  | @ -218,7 +228,7 @@ module Jekyll | |||
|         :title       => slug, | ||||
|         :i_day       => date.strftime("%-d"), | ||||
|         :i_month     => date.strftime("%-m"), | ||||
|         :categories  => (categories || []).map { |c| c.to_s }.join('/'), | ||||
|         :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"), | ||||
|  | @ -269,7 +279,8 @@ module Jekyll | |||
|     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 path[/\.html?$/].nil? | ||||
|       path = File.join(path, "index.html") if self.url.end_with?("/") | ||||
|       path << output_ext unless path.end_with?(output_ext) | ||||
|       path | ||||
|     end | ||||
| 
 | ||||
|  | @ -296,6 +307,11 @@ module Jekyll | |||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Returns if this Post is a Draft | ||||
|     def draft? | ||||
|       is_a?(Jekyll::Draft) | ||||
|     end | ||||
| 
 | ||||
|     protected | ||||
| 
 | ||||
|     def extract_excerpt | ||||
|  | @ -307,7 +323,7 @@ module Jekyll | |||
|     end | ||||
| 
 | ||||
|     def generate_excerpt? | ||||
|       !(site.config['excerpt_separator'].to_s.empty?) | ||||
|       !excerpt_separator.empty? | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  |  | |||
|  | @ -0,0 +1,141 @@ | |||
| module Jekyll | ||||
|   class Regenerator | ||||
|     attr_reader :site, :metadata, :cache | ||||
| 
 | ||||
|     def initialize(site) | ||||
|       @site = site | ||||
| 
 | ||||
|       # Read metadata from file | ||||
|       read_metadata | ||||
| 
 | ||||
|       # Initialize cache to an empty hash | ||||
|       @cache = {} | ||||
|     end | ||||
| 
 | ||||
|     # Checks if a renderable object needs to be regenerated | ||||
|     # | ||||
|     # Returns a boolean. | ||||
|     def regenerate?(document) | ||||
|       case document | ||||
|       when Post, Page | ||||
|         document.asset_file? || document.data['regenerate'] || | ||||
|           modified?(site.in_source_dir(document.relative_path)) | ||||
|       when Document | ||||
|         !document.write? || document.data['regenerate'] || modified?(document.path) | ||||
|       else | ||||
|         if document.respond_to?(:path) | ||||
|           modified?(document.path) | ||||
|         else | ||||
|           true | ||||
|         end | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Add a path to the metadata | ||||
|     # | ||||
|     # Returns true, also on failure. | ||||
|     def add(path) | ||||
|       return true unless File.exist?(path) | ||||
| 
 | ||||
|       metadata[path] = { | ||||
|         "mtime" => File.mtime(path), | ||||
|         "deps" => [] | ||||
|       } | ||||
|       cache[path] = true | ||||
|     end | ||||
| 
 | ||||
|     # Force a path to regenerate | ||||
|     # | ||||
|     # Returns true. | ||||
|     def force(path) | ||||
|       cache[path] = true | ||||
|     end | ||||
| 
 | ||||
|     # Clear the metadata and cache | ||||
|     # | ||||
|     # Returns nothing | ||||
|     def clear | ||||
|       @metadata = {} | ||||
|       @cache = {} | ||||
|     end | ||||
| 
 | ||||
|     # Checks if a path's (or one of its dependencies) | ||||
|     # mtime has changed | ||||
|     # | ||||
|     # Returns a boolean. | ||||
|     def modified?(path) | ||||
|       return true if disabled? | ||||
| 
 | ||||
|       # Check for path in cache | ||||
|       if cache.has_key? path | ||||
|         return cache[path] | ||||
|       end | ||||
| 
 | ||||
|       # Check path that exists in metadata | ||||
|       data = metadata[path] | ||||
|       if data | ||||
|         data["deps"].each do |dependency| | ||||
|           if modified?(dependency) | ||||
|             return cache[dependency] = cache[path] = true | ||||
|           end | ||||
|         end | ||||
|         if data["mtime"].eql? File.mtime(path) | ||||
|           return cache[path] = false | ||||
|         else | ||||
|           return add(path) | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       # Path does not exist in metadata, add it | ||||
|       return add(path) | ||||
|     end | ||||
| 
 | ||||
|     # Add a dependency of a path | ||||
|     # | ||||
|     # Returns nothing. | ||||
|     def add_dependency(path, dependency) | ||||
|       return if (metadata[path].nil? || @disabled) | ||||
| 
 | ||||
|       metadata[path]["deps"] << dependency unless metadata[path]["deps"].include? dependency | ||||
|       regenerate? dependency | ||||
|     end | ||||
| 
 | ||||
|     # Write the metadata to disk | ||||
|     # | ||||
|     # Returns nothing. | ||||
|     def write_metadata | ||||
|       File.open(metadata_file, 'w') do |f| | ||||
|         f.write(metadata.to_yaml) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Produce the absolute path of the metadata file | ||||
|     # | ||||
|     # Returns the String path of the file. | ||||
|     def metadata_file | ||||
|       site.in_source_dir('.jekyll-metadata') | ||||
|     end | ||||
| 
 | ||||
|     # Check if metadata has been disabled | ||||
|     # | ||||
|     # Returns a Boolean (true for disabled, false for enabled). | ||||
|     def disabled? | ||||
|       @disabled = site.full_rebuild? if @disabled.nil? | ||||
|       @disabled | ||||
|     end | ||||
| 
 | ||||
|     private | ||||
| 
 | ||||
|     # Read metadata from the metadata file, if no file is found, | ||||
|     # initialize with an empty hash | ||||
|     # | ||||
|     # Returns the read metadata. | ||||
|     def read_metadata | ||||
|       @metadata = if !disabled? && File.file?(metadata_file) | ||||
|         SafeYAML.load(File.read(metadata_file)) | ||||
|       else | ||||
|         {} | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  | @ -10,7 +10,7 @@ module Jekyll | |||
|     def initialize(post) | ||||
|       @post = post | ||||
|       @site = post.site | ||||
|       require 'classifier-reborn' if site.lsi | ||||
|       Jekyll::External.require_with_graceful_fail('classifier-reborn') if site.lsi | ||||
|     end | ||||
| 
 | ||||
|     def build | ||||
|  |  | |||
|  | @ -3,11 +3,12 @@ | |||
| module Jekyll | ||||
|   class Renderer | ||||
| 
 | ||||
|     attr_reader :document, :site | ||||
|     attr_reader :document, :site, :site_payload | ||||
| 
 | ||||
|     def initialize(site, document) | ||||
|       @site     = site | ||||
|       @document = document | ||||
|     def initialize(site, document, site_payload = nil) | ||||
|       @site         = site | ||||
|       @document     = document | ||||
|       @site_payload = site_payload | ||||
|     end | ||||
| 
 | ||||
|     # Determine which converters to use based on this document's | ||||
|  | @ -32,7 +33,7 @@ module Jekyll | |||
|     def run | ||||
|       payload = Utils.deep_merge_hashes({ | ||||
|         "page" => document.to_liquid | ||||
|       }, site.site_payload) | ||||
|       }, site_payload || site.site_payload) | ||||
| 
 | ||||
|       info = { | ||||
|         filters:   [Jekyll::Filters], | ||||
|  | @ -138,6 +139,12 @@ module Jekyll | |||
|           File.join(site.config['layouts'], layout.name) | ||||
|         ) | ||||
| 
 | ||||
|         # Add layout to dependency tree | ||||
|         site.regenerator.add_dependency( | ||||
|           site.in_source_dir(document.path), | ||||
|           site.in_source_dir(layout.path) | ||||
|         ) if document.write? | ||||
| 
 | ||||
|         if layout = site.layouts[layout.data["layout"]] | ||||
|           if used.include?(layout) | ||||
|             layout = nil # avoid recursive chain | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ module Jekyll | |||
|                   :gems, :plugin_manager | ||||
| 
 | ||||
|     attr_accessor :converters, :generators | ||||
|     attr_reader   :regenerator | ||||
| 
 | ||||
|     # Public: Initialize a new Site. | ||||
|     # | ||||
|  | @ -27,6 +28,9 @@ module Jekyll | |||
|       @source              = File.expand_path(config['source']).freeze | ||||
|       @dest                = File.expand_path(config['destination']).freeze | ||||
| 
 | ||||
|       # Initialize incremental regenerator | ||||
|       @regenerator = Regenerator.new(self) | ||||
| 
 | ||||
|       self.plugin_manager = Jekyll::PluginManager.new(self) | ||||
|       self.plugins        = plugin_manager.plugins_path | ||||
| 
 | ||||
|  | @ -183,6 +187,7 @@ module Jekyll | |||
|       end | ||||
| 
 | ||||
|       pages.sort_by!(&:name) | ||||
|       static_files.sort_by!(&:relative_path) | ||||
|     end | ||||
| 
 | ||||
|     # Read all the files in <source>/<dir>/_posts and create a new Post | ||||
|  | @ -253,16 +258,26 @@ module Jekyll | |||
|         if File.directory?(path) | ||||
|           read_data_to(path, data[key] = {}) | ||||
|         else | ||||
|           case File.extname(path).downcase | ||||
|           when '.csv' | ||||
|             data[key] = CSV.read(path, :headers => true).map(&:to_hash) | ||||
|           else | ||||
|             data[key] = SafeYAML.load_file(path) | ||||
|           end | ||||
|           data[key] = read_data_file(path) | ||||
|         end | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Determines how to read a data file. | ||||
|     # | ||||
|     # 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 => config['encoding'] | ||||
|         }).map(&:to_hash) | ||||
|       else | ||||
|         SafeYAML.load_file(path) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Read in all collections specified in the configuration | ||||
|     # | ||||
|     # Returns nothing. | ||||
|  | @ -287,17 +302,22 @@ module Jekyll | |||
|     def render | ||||
|       relative_permalinks_deprecation_method | ||||
| 
 | ||||
|       payload = site_payload | ||||
|       collections.each do |label, collection| | ||||
|         collection.docs.each do |document| | ||||
|           document.output = Jekyll::Renderer.new(self, document).run | ||||
|           if regenerator.regenerate?(document) | ||||
|             document.output = Jekyll::Renderer.new(self, document, payload).run | ||||
|           end | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       payload = site_payload | ||||
|       [posts, pages].flatten.each do |page_or_post| | ||||
|         page_or_post.render(layouts, payload) | ||||
|         if regenerator.regenerate?(page_or_post) | ||||
|           page_or_post.render(layouts, payload) | ||||
|         end | ||||
|       end | ||||
|     rescue Errno::ENOENT => e | ||||
|     rescue Errno::ENOENT | ||||
|       # ignore missing layout dir | ||||
|     end | ||||
| 
 | ||||
|  | @ -312,7 +332,10 @@ module Jekyll | |||
|     # | ||||
|     # Returns nothing. | ||||
|     def write | ||||
|       each_site_file { |item| item.write(dest) } | ||||
|       each_site_file { |item| | ||||
|         item.write(dest) if regenerator.regenerate?(item) | ||||
|       } | ||||
|       regenerator.write_metadata | ||||
|     end | ||||
| 
 | ||||
|     # Construct a Hash of Posts indexed by the specified Post attribute. | ||||
|  | @ -377,7 +400,7 @@ module Jekyll | |||
|             "time"         => time, | ||||
|             "posts"        => posts.sort { |a, b| b <=> a }, | ||||
|             "pages"        => pages, | ||||
|             "static_files" => static_files.sort { |a, b| a.relative_path <=> b.relative_path }, | ||||
|             "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'), | ||||
|  | @ -405,13 +428,8 @@ module Jekyll | |||
|     # klass - The Class of the Converter to fetch. | ||||
|     # | ||||
|     # Returns the Converter instance implementing the given Converter. | ||||
|     def getConverterImpl(klass) | ||||
|       matches = converters.select { |c| c.class == klass } | ||||
|       if impl = matches.first | ||||
|         impl | ||||
|       else | ||||
|         raise "Converter implementation not found for #{klass}" | ||||
|       end | ||||
|     def find_converter_instance(klass) | ||||
|       converters.find { |c| c.class == klass } || proc { raise "No converter for #{klass}" }.call | ||||
|     end | ||||
| 
 | ||||
|     # Create array of instances of the subclasses of the class or module | ||||
|  | @ -453,7 +471,7 @@ module Jekyll | |||
| 
 | ||||
|     def relative_permalinks_deprecation_method | ||||
|       if config['relative_permalinks'] && has_relative_page? | ||||
|         Jekyll.logger.warn "Deprecation:", "Starting in 2.0, permalinks for pages" + | ||||
|         Jekyll::Deprecator.deprecation_message "Since v2.0, permalinks for pages" + | ||||
|                                             " in subfolders must be relative to the" + | ||||
|                                             " site source directory, not the parent" + | ||||
|                                             " directory. Check http://jekyllrb.com/docs/upgrading/"+ | ||||
|  | @ -483,6 +501,17 @@ module Jekyll | |||
|       @frontmatter_defaults ||= FrontmatterDefaults.new(self) | ||||
|     end | ||||
| 
 | ||||
|     # 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'] | ||||
|     end | ||||
| 
 | ||||
|     def publisher | ||||
|       @publisher ||= Publisher.new(self) | ||||
|     end | ||||
| 
 | ||||
|     private | ||||
| 
 | ||||
|     def has_relative_page? | ||||
|  | @ -499,13 +528,9 @@ module Jekyll | |||
|     end | ||||
| 
 | ||||
|     def sanitize_filename(name) | ||||
|       name.gsub!(/[^\w\s_-]+/, '') | ||||
|       name.gsub!(/[^\w\s-]+/, '') | ||||
|       name.gsub!(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2') | ||||
|       name.gsub(/\s+/, '_') | ||||
|     end | ||||
| 
 | ||||
|     def publisher | ||||
|       @publisher ||= Publisher.new(self) | ||||
|     end | ||||
|   end | ||||
| end | ||||
|  |  | |||
|  | @ -3,6 +3,8 @@ module Jekyll | |||
|     # The cache of last modification times [path] -> mtime. | ||||
|     @@mtimes = Hash.new | ||||
| 
 | ||||
|     attr_reader :relative_path | ||||
| 
 | ||||
|     # Initialize a new StaticFile. | ||||
|     # | ||||
|     # site - The Site. | ||||
|  | @ -15,6 +17,7 @@ module Jekyll | |||
|       @dir  = dir | ||||
|       @name = name | ||||
|       @collection = collection | ||||
|       @relative_path = File.join(*[@dir, @name].compact) | ||||
|     end | ||||
| 
 | ||||
|     # Returns source file path. | ||||
|  | @ -22,11 +25,6 @@ module Jekyll | |||
|       File.join(*[@base, @dir, @name].compact) | ||||
|     end | ||||
| 
 | ||||
|     # Returns the source file path relative to the site source | ||||
|     def relative_path | ||||
|       @relative_path ||= File.join(*[@dir, @name].compact) | ||||
|     end | ||||
| 
 | ||||
|     def extname | ||||
|       File.extname(path) | ||||
|     end | ||||
|  | @ -81,6 +79,7 @@ module Jekyll | |||
|       FileUtils.mkdir_p(File.dirname(dest_path)) | ||||
|       FileUtils.rm(dest_path) if File.exist?(dest_path) | ||||
|       FileUtils.cp(path, dest_path) | ||||
|       File.utime(@@mtimes[path], @@mtimes[path], dest_path) | ||||
| 
 | ||||
|       true | ||||
|     end | ||||
|  |  | |||
|  | @ -42,7 +42,7 @@ eos | |||
|       def render(context) | ||||
|         prefix = context["highlighter_prefix"] || "" | ||||
|         suffix = context["highlighter_suffix"] || "" | ||||
|         code = super.to_s.strip | ||||
|         code = super.to_s.gsub(/\A(\n|\r)+|(\n|\r)+\z/, '') | ||||
| 
 | ||||
|         is_safe = !!context.registers[:site].safe | ||||
| 
 | ||||
|  | @ -75,9 +75,7 @@ eos | |||
|       end | ||||
| 
 | ||||
|       def render_pygments(code, is_safe) | ||||
|         require 'pygments' | ||||
| 
 | ||||
|         @options[:encoding] = 'utf-8' | ||||
|         Jekyll::External.require_with_graceful_fail('pygments') | ||||
| 
 | ||||
|         highlighted_code = Pygments.highlight( | ||||
|           code, | ||||
|  | @ -96,26 +94,26 @@ eos | |||
|           raise ArgumentError.new("Pygments.rb returned an unacceptable value when attempting to highlight some code.") | ||||
|         end | ||||
| 
 | ||||
|         highlighted_code | ||||
|         highlighted_code.sub('<div class="highlight"><pre>', '').sub('</pre></div>', '') | ||||
|       end | ||||
| 
 | ||||
|       def render_rouge(code) | ||||
|         require 'rouge' | ||||
|         Jekyll::External.require_with_graceful_fail('rouge') | ||||
|         formatter = Rouge::Formatters::HTML.new(line_numbers: @options[:linenos], wrap: false) | ||||
|         lexer = Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText | ||||
|         code = formatter.format(lexer.lex(code)) | ||||
|         "<div class=\"highlight\"><pre>#{code}</pre></div>" | ||||
|         formatter.format(lexer.lex(code)) | ||||
|       end | ||||
| 
 | ||||
|       def render_codehighlighter(code) | ||||
|         "<div class=\"highlight\"><pre>#{h(code).strip}</pre></div>" | ||||
|         h(code).strip | ||||
|       end | ||||
| 
 | ||||
|       def add_code_tag(code) | ||||
|         # Add nested <code> tags to code blocks | ||||
|         code = code.sub(/<pre>\n*/,'<pre><code class="language-' + @lang.to_s.gsub("+", "-") + '" data-lang="' + @lang.to_s + '">') | ||||
|         code = code.sub(/\n*<\/pre>/,"</code></pre>") | ||||
|         code.strip | ||||
|         code_attributes = [ | ||||
|           "class=\"language-#{@lang.to_s.gsub('+', '-')}\"", | ||||
|           "data-lang=\"#{@lang.to_s}\"" | ||||
|         ].join(" ") | ||||
|         "<div class=\"highlight\"><pre><code #{code_attributes}>#{code.chomp}</code></pre></div>" | ||||
|       end | ||||
| 
 | ||||
|     end | ||||
|  |  | |||
|  | @ -101,20 +101,29 @@ eos | |||
|       end | ||||
| 
 | ||||
|       def tag_includes_dir | ||||
|         '_includes' | ||||
|         '_includes'.freeze | ||||
|       end | ||||
| 
 | ||||
|       def render(context) | ||||
|         site = context.registers[:site] | ||||
|         dir = resolved_includes_dir(context) | ||||
| 
 | ||||
|         file = render_variable(context) || @file | ||||
|         validate_file_name(file) | ||||
| 
 | ||||
|         path = File.join(dir, file) | ||||
|         validate_path(path, dir, context.registers[:site].safe) | ||||
|         validate_path(path, dir, site.safe) | ||||
| 
 | ||||
|         # Add include to dependency tree | ||||
|         if context.registers[:page] and context.registers[:page].has_key? "path" | ||||
|           site.regenerator.add_dependency( | ||||
|             site.in_source_dir(context.registers[:page]["path"]), | ||||
|             path | ||||
|           ) | ||||
|         end | ||||
| 
 | ||||
|         begin | ||||
|           partial = Liquid::Template.parse(source(path, context)) | ||||
|           partial = Liquid::Template.parse(read_file(path, context)) | ||||
| 
 | ||||
|           context.stack do | ||||
|             context['include'] = parse_params(context) if @params | ||||
|  | @ -126,7 +135,7 @@ eos | |||
|       end | ||||
| 
 | ||||
|       def resolved_includes_dir(context) | ||||
|         File.join(File.realpath(context.registers[:site].source), @includes_dir) | ||||
|         context.registers[:site].in_source_dir(@includes_dir) | ||||
|       end | ||||
| 
 | ||||
|       def validate_path(path, dir, safe) | ||||
|  | @ -146,14 +155,14 @@ eos | |||
|       end | ||||
| 
 | ||||
|       # This method allows to modify the file content by inheriting from the class. | ||||
|       def source(file, context) | ||||
|       def read_file(file, context) | ||||
|         File.read(file, file_read_opts(context)) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     class IncludeRelativeTag < IncludeTag | ||||
|       def tag_includes_dir | ||||
|         '.' | ||||
|         '.'.freeze | ||||
|       end | ||||
| 
 | ||||
|       def page_path(context) | ||||
|  |  | |||
|  | @ -44,12 +44,12 @@ module Jekyll | |||
|     # | ||||
|     # Returns the _unsanitized String URL | ||||
|     def generated_permalink | ||||
|       (@generated_permlink ||= generate_url(@permalink)) if @permalink | ||||
|       (@generated_permalink ||= generate_url(@permalink)) if @permalink | ||||
|     end | ||||
| 
 | ||||
|     # Generates a URL from the template | ||||
|     # | ||||
|     # Returns the _unsanitized String URL | ||||
|     # Returns the unsanitized String URL | ||||
|     def generated_url | ||||
|       @generated_url ||= generate_url(@template) | ||||
|     end | ||||
|  | @ -57,11 +57,16 @@ module Jekyll | |||
|     # Internal: Generate the URL by replacing all placeholders with their | ||||
|     # respective values in the given template | ||||
|     # | ||||
|     # Returns the _unsanitizied_ String URL | ||||
|     # Returns the unsanitized String URL | ||||
|     def generate_url(template) | ||||
|       @placeholders.inject(template) do |result, token| | ||||
|         break result if result.index(':').nil? | ||||
|         result.gsub(/:#{token.first}/, self.class.escape_path(token.last)) | ||||
|         if token.last.nil? | ||||
|           # Remove leading '/' to avoid generating urls with `//` | ||||
|           result.gsub(/\/:#{token.first}/, '') | ||||
|         else | ||||
|           result.gsub(/:#{token.first}/, self.class.escape_path(token.last)) | ||||
|         end | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|  | @ -76,7 +81,7 @@ module Jekyll | |||
|         .gsub(/\A([^\/])/, '/\1') | ||||
| 
 | ||||
|       # Append a trailing slash to the URL if the unsanitized URL had one | ||||
|       url << "/" if in_url[-1].eql?('/') | ||||
|       url << "/" if in_url.end_with?("/") | ||||
| 
 | ||||
|       url | ||||
|     end | ||||
|  | @ -102,7 +107,7 @@ module Jekyll | |||
|       #   pct-encoded   = "%" HEXDIG HEXDIG | ||||
|       #   sub-delims    = "!" / "$" / "&" / "'" / "(" / ")" | ||||
|       #                 / "*" / "+" / "," / ";" / "=" | ||||
|       URI.escape(path, /[^a-zA-Z\d\-._~!$&\'()*+,;=:@\/]/).encode('utf-8') | ||||
|       URI.escape(path, /[^a-zA-Z\d\-._~!$&'()*+,;=:@\/]/).encode('utf-8') | ||||
|     end | ||||
| 
 | ||||
|     # Unescapes a URL path segment | ||||
|  |  | |||
|  | @ -2,6 +2,12 @@ module Jekyll | |||
|   module Utils | ||||
|     extend self | ||||
| 
 | ||||
|     # Constants for use in #slugify | ||||
|     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 | ||||
| 
 | ||||
|     # Merges a master hash with another hash, recursively. | ||||
|     # | ||||
|     # master_hash - the "parent" hash whose values will be overridden | ||||
|  | @ -90,7 +96,7 @@ module Jekyll | |||
|     # Returns the parsed date if successful, throws a FatalException | ||||
|     # if not | ||||
|     def parse_date(input, msg = "Input could not be parsed.") | ||||
|       Time.parse(input) | ||||
|       Time.parse(input).localtime | ||||
|     rescue ArgumentError | ||||
|       raise Errors::FatalException.new("Invalid date '#{input}': " + msg) | ||||
|     end | ||||
|  | @ -104,21 +110,92 @@ module Jekyll | |||
| 
 | ||||
|     # Slugify a filename or title. | ||||
|     # | ||||
|     # name - the filename or title to slugify | ||||
|     # string - the filename or title to slugify | ||||
|     # mode - how string is slugified | ||||
|     # | ||||
|     # Returns the given filename or title in lowercase, with every | ||||
|     # sequence of spaces and non-alphanumeric characters replaced with a | ||||
|     # hyphen. | ||||
|     def slugify(string) | ||||
|       unless string.nil? | ||||
|         string \ | ||||
|           # Replace each non-alphanumeric character sequence with a hyphen | ||||
|           .gsub(/[^a-z0-9]+/i, '-') \ | ||||
|           # Remove leading/trailing hyphen | ||||
|           .gsub(/^\-|\-$/i, '') \ | ||||
|           # Downcase it | ||||
|           .downcase | ||||
|     # When mode is "none", return the given string in lowercase. | ||||
|     # | ||||
|     # When mode is "raw", return the given string in lowercase, | ||||
|     # with every sequence of spaces characters replaced with a hyphen. | ||||
|     # | ||||
|     # When mode is "default" or nil, non-alphabetic characters are | ||||
|     # replaced with a hyphen too. | ||||
|     # | ||||
|     # When mode is "pretty", some non-alphabetic characters (._~!$&'()+,;=@) | ||||
|     # are not replaced with hyphen. | ||||
|     # | ||||
|     # Examples: | ||||
|     #   slugify("The _config.yml file") | ||||
|     #   # => "the-config-yml-file" | ||||
|     # | ||||
|     #   slugify("The _config.yml file", "pretty") | ||||
|     #   # => "the-_config.yml-file" | ||||
|     # | ||||
|     # Returns the slugified string. | ||||
|     def slugify(string, mode=nil) | ||||
|       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 | ||||
|       end | ||||
| 
 | ||||
|       string. | ||||
|         # Strip according to the mode | ||||
|         gsub(re, '-'). | ||||
|         # Remove leading/trailing hyphen | ||||
|         gsub(/^\-|\-$/i, ''). | ||||
|         # Downcase | ||||
|         downcase | ||||
|     end | ||||
| 
 | ||||
|     # Add an appropriate suffix to template so that it matches the specified | ||||
|     # permalink style. | ||||
|     # | ||||
|     # template - permalink template without trailing slash or file extension | ||||
|     # permalink_style - permalink style, either built-in or custom | ||||
|     # | ||||
|     # The returned permalink template will use the same ending style as | ||||
|     # specified in permalink_style.  For example, if permalink_style contains a | ||||
|     # trailing slash (or is :pretty, which indirectly has a trailing slash), | ||||
|     # then so will the returned template.  If permalink_style has a trailing | ||||
|     # ":output_ext" (or is :none, :date, or :ordinal) then so will the returned | ||||
|     # template.  Otherwise, template will be returned without modification. | ||||
|     # | ||||
|     # Examples: | ||||
|     #   add_permalink_suffix("/:basename", :pretty) | ||||
|     #   # => "/:basename/" | ||||
|     # | ||||
|     #   add_permalink_suffix("/:basename", :date) | ||||
|     #   # => "/:basename:output_ext" | ||||
|     # | ||||
|     #   add_permalink_suffix("/:basename", "/:year/:month/:title/") | ||||
|     #   # => "/:basename/" | ||||
|     # | ||||
|     #   add_permalink_suffix("/:basename", "/:year/:month/:title") | ||||
|     #   # => "/:basename" | ||||
|     # | ||||
|     # Returns the updated permalink template | ||||
|     def add_permalink_suffix(template, permalink_style) | ||||
|       case permalink_style | ||||
|       when :pretty | ||||
|         template << "/" | ||||
|       when :date, :ordinal, :none | ||||
|         template << ":output_ext" | ||||
|       else | ||||
|         template << "/" if permalink_style.to_s.end_with?("/") | ||||
|         template << ":output_ext" if permalink_style.to_s.end_with?(":output_ext") | ||||
|       end | ||||
|       template | ||||
|     end | ||||
| 
 | ||||
|   end | ||||
|  |  | |||
|  | @ -1,3 +1,3 @@ | |||
| module Jekyll | ||||
|   VERSION = '2.5.2' | ||||
|   VERSION = '3.0.0.beta2' | ||||
| end | ||||
|  |  | |||
|  | @ -1,2 +1,3 @@ | |||
| _site | ||||
| .sass-cache | ||||
| .jekyll-metadata | ||||
|  |  | |||
|  | @ -5,7 +5,7 @@ description: > # this means to ignore newlines until "baseurl:" | |||
|   Write an awesome description for your new site here. You can edit this | ||||
|   line in _config.yml. It will appear in your document head meta (for | ||||
|   Google search results) and in your feed.xml site description. | ||||
| baseurl: "" # the subpath of your site, e.g. /blog/ | ||||
| baseurl: "" # the subpath of your site, e.g. /blog | ||||
| url: "http://yourdomain.com" # the base hostname & protocol for your site | ||||
| twitter_username: jekyllrb | ||||
| github_username:  jekyll | ||||
|  |  | |||
|  | @ -5,19 +5,19 @@ | |||
|     <h2 class="footer-heading">{{ site.title }}</h2> | ||||
| 
 | ||||
|     <div class="footer-col-wrapper"> | ||||
|       <div class="footer-col  footer-col-1"> | ||||
|       <div class="footer-col footer-col-1"> | ||||
|         <ul class="contact-list"> | ||||
|           <li>{{ site.title }}</li> | ||||
|           <li><a href="mailto:{{ site.email }}">{{ site.email }}</a></li> | ||||
|         </ul> | ||||
|       </div> | ||||
| 
 | ||||
|       <div class="footer-col  footer-col-2"> | ||||
|       <div class="footer-col footer-col-2"> | ||||
|         <ul class="social-media-list"> | ||||
|           {% if site.github_username %} | ||||
|           <li> | ||||
|             <a href="https://github.com/{{ site.github_username }}"> | ||||
|               <span class="icon  icon--github"> | ||||
|               <span class="icon icon--github"> | ||||
|                 <svg viewBox="0 0 16 16"> | ||||
|                   <path fill="#828282" d="M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761 c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32 c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472 c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037 C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65 c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261 c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082 c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129 c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z"/> | ||||
|                 </svg> | ||||
|  | @ -31,7 +31,7 @@ | |||
|           {% if site.twitter_username %} | ||||
|           <li> | ||||
|             <a href="https://twitter.com/{{ site.twitter_username }}"> | ||||
|               <span class="icon  icon--twitter"> | ||||
|               <span class="icon icon--twitter"> | ||||
|                 <svg viewBox="0 0 16 16"> | ||||
|                   <path fill="#828282" d="M15.969,3.058c-0.586,0.26-1.217,0.436-1.878,0.515c0.675-0.405,1.194-1.045,1.438-1.809 | ||||
|                   c-0.632,0.375-1.332,0.647-2.076,0.793c-0.596-0.636-1.446-1.033-2.387-1.033c-1.806,0-3.27,1.464-3.27,3.27 c0,0.256,0.029,0.506,0.085,0.745C5.163,5.404,2.753,4.102,1.14,2.124C0.859,2.607,0.698,3.168,0.698,3.767 c0,1.134,0.577,2.135,1.455,2.722C1.616,6.472,1.112,6.325,0.671,6.08c0,0.014,0,0.027,0,0.041c0,1.584,1.127,2.906,2.623,3.206 C3.02,9.402,2.731,9.442,2.433,9.442c-0.211,0-0.416-0.021-0.615-0.059c0.416,1.299,1.624,2.245,3.055,2.271 c-1.119,0.877-2.529,1.4-4.061,1.4c-0.264,0-0.524-0.015-0.78-0.046c1.447,0.928,3.166,1.469,5.013,1.469 c6.015,0,9.304-4.983,9.304-9.304c0-0.142-0.003-0.283-0.009-0.423C14.976,4.29,15.531,3.714,15.969,3.058z"/> | ||||
|  | @ -45,8 +45,8 @@ | |||
|         </ul> | ||||
|       </div> | ||||
| 
 | ||||
|       <div class="footer-col  footer-col-3"> | ||||
|         <p class="text">{{ site.description }}</p> | ||||
|       <div class="footer-col footer-col-3"> | ||||
|         <p>{{ site.description }}</p> | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,5 +8,5 @@ | |||
| 
 | ||||
|   <link rel="stylesheet" href="{{ "/css/main.css" | prepend: site.baseurl }}"> | ||||
|   <link rel="canonical" href="{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}"> | ||||
|   <link rel="alternate" type="application/rss+xml" title="{{ site.title }}" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" /> | ||||
|   <link rel="alternate" type="application/rss+xml" title="{{ site.title }}" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}"> | ||||
| </head> | ||||
|  |  | |||
|  | @ -1,14 +1,14 @@ | |||
| --- | ||||
| layout: default | ||||
| --- | ||||
| <div class="post"> | ||||
| <article class="post"> | ||||
| 
 | ||||
|   <header class="post-header"> | ||||
|     <h1 class="post-title">{{ page.title }}</h1> | ||||
|   </header> | ||||
| 
 | ||||
|   <article class="post-content"> | ||||
|   <div class="post-content"> | ||||
|     {{ content }} | ||||
|   </article> | ||||
|   </div> | ||||
| 
 | ||||
| </div> | ||||
| </article> | ||||
|  |  | |||
|  | @ -1,15 +1,15 @@ | |||
| --- | ||||
| layout: default | ||||
| --- | ||||
| <div class="post"> | ||||
| <article class="post" itemscope itemtype="http://schema.org/BlogPosting"> | ||||
| 
 | ||||
|   <header class="post-header"> | ||||
|     <h1 class="post-title">{{ page.title }}</h1> | ||||
|     <p class="post-meta">{{ page.date | date: "%b %-d, %Y" }}{% if page.author %} • {{ page.author }}{% endif %}{% if page.meta %} • {{ page.meta }}{% endif %}</p> | ||||
|     <h1 class="post-title" itemprop="name headline">{{ page.title }}</h1> | ||||
|     <p class="post-meta"><time datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">{{ page.date | date: "%b %-d, %Y" }}</time>{% if page.author %} • <span itemprop="author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">{{ page.author }}</span></span>{% endif %}</p> | ||||
|   </header> | ||||
| 
 | ||||
|   <article class="post-content"> | ||||
|   <div class="post-content" itemprop="articleBody"> | ||||
|     {{ content }} | ||||
|   </article> | ||||
|   </div> | ||||
| 
 | ||||
| </div> | ||||
| </article> | ||||
|  |  | |||
|  | @ -18,8 +18,8 @@ print_hi('Tom') | |||
| #=> prints 'Hi, Tom' to STDOUT. | ||||
| {% endhighlight %} | ||||
| 
 | ||||
| Check out the [Jekyll docs][jekyll] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll’s dedicated Help repository][jekyll-help]. | ||||
| Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll’s dedicated Help repository][jekyll-help]. | ||||
| 
 | ||||
| [jekyll]:      http://jekyllrb.com | ||||
| [jekyll-docs]: http://jekyllrb.com/docs/home | ||||
| [jekyll-gh]:   https://github.com/jekyll/jekyll | ||||
| [jekyll-help]: https://github.com/jekyll/jekyll-help | ||||
|  |  | |||
|  | @ -14,13 +14,15 @@ dl, dd, ol, ul, figure { | |||
|  * Basic styling | ||||
|  */ | ||||
| body { | ||||
|     font-family: $base-font-family; | ||||
|     font-size: $base-font-size; | ||||
|     line-height: $base-line-height; | ||||
|     font-weight: 300; | ||||
|     font: $base-font-weight #{$base-font-size}/#{$base-line-height} $base-font-family; | ||||
|     color: $text-color; | ||||
|     background-color: $background-color; | ||||
|     -webkit-text-size-adjust: 100%; | ||||
|     -webkit-font-feature-settings: "kern" 1; | ||||
|     -moz-font-feature-settings: "kern" 1; | ||||
|     -o-font-feature-settings: "kern" 1; | ||||
|     font-feature-settings: "kern" 1; | ||||
|     font-kerning: normal; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -80,7 +82,7 @@ li { | |||
|  * Headings | ||||
|  */ | ||||
| h1, h2, h3, h4, h5, h6 { | ||||
|     font-weight: 300; | ||||
|     font-weight: $base-font-weight; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -139,7 +141,7 @@ code { | |||
| 
 | ||||
| pre { | ||||
|     padding: 8px 12px; | ||||
|     overflow-x: scroll; | ||||
|     overflow-x: auto; | ||||
| 
 | ||||
|     > code { | ||||
|         border: 0; | ||||
|  |  | |||
|  | @ -35,16 +35,16 @@ | |||
|         color: $text-color; | ||||
|         line-height: $base-line-height; | ||||
| 
 | ||||
|         // Gaps between nav items, but not on the first one | ||||
|         &:not(:first-child) { | ||||
|             margin-left: 20px; | ||||
|         // Gaps between nav items, but not on the last one | ||||
|         &:not(:last-child) { | ||||
|             margin-right: 20px; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @include media-query($on-palm) { | ||||
|         position: absolute; | ||||
|         top: 9px; | ||||
|         right: 30px; | ||||
|         right: $spacing-unit / 2; | ||||
|         background-color: $background-color; | ||||
|         border: 1px solid $grey-color-light; | ||||
|         border-radius: 5px; | ||||
|  | @ -82,6 +82,11 @@ | |||
|         .page-link { | ||||
|             display: block; | ||||
|             padding: 5px 10px; | ||||
| 
 | ||||
|             &:not(:last-child) { | ||||
|                 margin-right: 0; | ||||
|             } | ||||
|             margin-left: 20px; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -6,8 +6,9 @@ | |||
| 
 | ||||
| 
 | ||||
| // Our variables | ||||
| $base-font-family: Helvetica, Arial, sans-serif; | ||||
| $base-font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | ||||
| $base-font-size:   16px; | ||||
| $base-font-weight: 300; | ||||
| $small-font-size:  $base-font-size * 0.875; | ||||
| $base-line-height: 1.5; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| #!/bin/sh | ||||
| 
 | ||||
| script/branding | ||||
| bundle install | ||||
| bundle install -j8 | ||||
|  |  | |||
							
								
								
									
										39
									
								
								script/proof
								
								
								
								
							
							
						
						
									
										39
									
								
								script/proof
								
								
								
								
							|  | @ -5,20 +5,29 @@ | |||
| 
 | ||||
| set -e | ||||
| 
 | ||||
| if [[ "$1" != "-f" ]]; then | ||||
|   git diff --name-only ..master | grep '^site/' || { | ||||
|     echo "No site files changed. We'll skip proofing. Run with -f to force." | ||||
|     exit 0 | ||||
|   } | ||||
| fi | ||||
| 
 | ||||
| echo "Some site files have been changed! Proofing..." | ||||
| 
 | ||||
| command -v htmlproof || { | ||||
|     echo "Installing HTML::Proofer!" | ||||
|     gem install html-proofer -- --use-system-libraries | ||||
| function msg { | ||||
| 	printf "\e[0;37m==> $1\e[0m\n" | ||||
| } | ||||
| 
 | ||||
| bundle exec jekyll build -s site -d _site --trace | ||||
| printf "\e[0;36mProofing begins now!\e[0m\n" | ||||
| htmlproof ./_site | ||||
| INGORE_HREFS=$(ruby -e 'puts %w{ | ||||
| 	Chrononaut | ||||
| 	twitter.com | ||||
| 	nearlyfreespeech.net | ||||
| }.map{|h| "/#{h}/"}.join(",")') | ||||
| SOURCE="site" | ||||
| DESTINATION="_site" | ||||
| 
 | ||||
| export PROOF=true | ||||
| export NOKOGIRI_USE_SYSTEM_LIBRARIES=true | ||||
| 
 | ||||
| # 1. | ||||
| msg "Installing..." | ||||
| bundle install -j8 > /dev/null || bundle install > /dev/null | ||||
| 
 | ||||
| # 2. | ||||
| msg "Building..." | ||||
| bundle exec jekyll build -s $SOURCE -d $DESTINATION --full-rebuild --trace | ||||
| 
 | ||||
| # 3. | ||||
| msg "Proofing..." | ||||
| time bundle exec htmlproof ./$DESTINATION --href-ignore $INGORE_HREFS | ||||
|  |  | |||
|  | @ -5,12 +5,12 @@ set -e | |||
| export BENCHMARK=true | ||||
| command -v stackprof > /dev/null || script/bootstrap | ||||
| 
 | ||||
| TEST_SCRIPT="Jekyll::Commands::Build.process({'source' => 'site'})" | ||||
| PROF_OUTPUT_FILE=tmp/stackprof-$(date +%Y%m%d).dump | ||||
| TEST_SCRIPT="Jekyll::Commands::Build.process({'source' => 'site', 'full_rebuild' => true})" | ||||
| PROF_OUTPUT_FILE=tmp/stackprof-$(date +%Y%m%d%H%M).dump | ||||
| 
 | ||||
| test -f "$PROF_OUTPUT_FILE" || { | ||||
|   bundle exec ruby -r./lib/jekyll -rstackprof \ | ||||
|     -e "StackProf.run(mode: :cpu, out: '${PROF_OUTPUT_FILE}') { ${TEST_SCRIPT} }" | ||||
|     -e "StackProf.run(mode: :cpu, interval: 100, out: '${PROF_OUTPUT_FILE}') { ${TEST_SCRIPT} }" | ||||
| } | ||||
| 
 | ||||
| bundle exec stackprof $PROF_OUTPUT_FILE $@ | ||||
|  |  | |||
							
								
								
									
										17
									
								
								script/test
								
								
								
								
							
							
						
						
									
										17
									
								
								script/test
								
								
								
								
							|  | @ -4,17 +4,20 @@ | |||
| #   script/test | ||||
| #   script/test <test_file> | ||||
| 
 | ||||
| if [ ! -d tmp ]; then | ||||
|   mkdir tmp | ||||
| fi | ||||
| 
 | ||||
| if [ -d test/dest ]; then | ||||
|   rm -r test/dest | ||||
| fi | ||||
| 
 | ||||
| if [ -z "$1" ]; then | ||||
|   TEST_FILES="./test/test_*.rb" | ||||
|   TEST_FILES=$(ruby -e "puts Dir.glob('test/test_*.rb')") | ||||
| else | ||||
|   TEST_FILES="$@" | ||||
| fi | ||||
| 
 | ||||
| RAKE_LIB_DIR=$(ruby -e "puts Gem::Specification.find_by_name('rake').gem_dir + '/lib'") | ||||
| 
 | ||||
| set -x | ||||
| 
 | ||||
| time bundle exec ruby -I"lib:test" \ | ||||
|   -I"${RAKE_LIB_DIR}" \ | ||||
|   "${RAKE_LIB_DIR}/rake/rake_test_loader.rb" \ | ||||
|   $TEST_FILES | ||||
| time bundle exec ruby -Ilib -Itest -rloader $TEST_FILES --profile | ||||
|  |  | |||
|  | @ -1 +0,0 @@ | |||
| Jekyll's awesome website. | ||||
|  | @ -0,0 +1,15 @@ | |||
| # Jekyll docs site | ||||
| 
 | ||||
| This directory contains the code for the Jekyll docs site, [jekyllrb.com](http://jekyllrb.com/). | ||||
| 
 | ||||
| ## Contributing | ||||
| 
 | ||||
| For information about contributing, see the [Contributing page](http://jekyllrb.com/docs/contributing/). | ||||
| 
 | ||||
| ## Running locally | ||||
| 
 | ||||
| You can preview your contributions before opening a pull request by running from within the directory: | ||||
| 1. `bundle install` | ||||
| 2. `bundle exec rake site:preview` | ||||
| 
 | ||||
| It's just a jekyll site, afterall! :wink: | ||||
|  | @ -1,8 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Assets | ||||
| prev_section: datafiles | ||||
| next_section: migrations | ||||
| permalink: /docs/assets/ | ||||
| --- | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,15 +1,13 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Collections | ||||
| prev_section: variables | ||||
| next_section: datafiles | ||||
| permalink: /docs/collections/ | ||||
| --- | ||||
| 
 | ||||
| <div class="note warning"> | ||||
|   <h5>Collections support is unstable and may change</h5> | ||||
|   <p> | ||||
|     This is an experimental feature and that the API may likely change until the feature stabilizes. | ||||
|     This is an experimental feature and the API may change until the feature stabilizes. | ||||
|   </p> | ||||
| </div> | ||||
| 
 | ||||
|  | @ -37,7 +35,7 @@ collections: | |||
| ### Step 2: Add your content | ||||
| 
 | ||||
| Create a corresponding folder (e.g. `<source>/_my_collection`) and add documents. | ||||
| YAML Front Matter is read in as data if it exists, if not, then everything is just stuck in the Document's `content` attribute. | ||||
| YAML Front Matter is read in as data if it exists, and everything after it is stuck in the Document's `content` attribute. If no YAML Front Matter is provided, Jekyll will not generate the file in your collection. | ||||
| 
 | ||||
| Note: the folder must be named identically to the collection you defined in your `_config.yml` file, with the addition of the preceding `_` character. | ||||
| 
 | ||||
|  | @ -211,8 +209,7 @@ In addition to any YAML Front Matter provided in the document's corresponding fi | |||
|       </td> | ||||
|       <td> | ||||
|         <p> | ||||
|           The (unrendered) content of the document. If no YAML Front Matter is provided, | ||||
|           this is the entirety of the file contents. If YAML Front Matter | ||||
|           The (unrendered) content of the document. If no YAML Front Matter is provided, Jekyll will not generate the file in your collection. If YAML Front Matter | ||||
|           is used, then this is all the contents of the file after the terminating | ||||
|           `---` of the front matter. | ||||
|         </p> | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Configuration | ||||
| prev_section: structure | ||||
| next_section: frontmatter | ||||
| permalink: /docs/configuration/ | ||||
| --- | ||||
| 
 | ||||
|  | @ -155,9 +153,12 @@ class="flag">flags</code> (specified on the command-line) that control them. | |||
|   <h5>Destination folders are cleaned on site builds</h5> | ||||
|   <p> | ||||
|     The contents of <code><destination></code> are automatically | ||||
|     cleaned when the site is built. Files or folders that are not | ||||
|     created by your site will be removed.  Do not use an important | ||||
|     location for <code><destination></code>; instead, use it as | ||||
|     cleaned, by default, when the site is built. Files or folders that are not | ||||
|     created by your site will be removed. Some files could be retained | ||||
|     by specifying them within the <code><keep_files></code> configuration directive. | ||||
|   </p> | ||||
|   <p> | ||||
|     Do not use an important location for <code><destination></code>; instead, use it as | ||||
|     a staging area and copy files from there to your web server. | ||||
|   </p> | ||||
| </div> | ||||
|  | @ -387,7 +388,7 @@ defaults: | |||
|   - | ||||
|     scope: | ||||
|       path: "projects" | ||||
|       type: "pages" | ||||
|       type: "pages" # previously `page` in Jekyll 2.2. | ||||
|     values: | ||||
|       layout: "project" # overrides previous default layout | ||||
|       author: "Mr. Hyde" | ||||
|  | @ -409,7 +410,7 @@ 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 | ||||
| 
 | ||||
|  | @ -447,9 +448,9 @@ The `projects/foo_project.md` would have the `layout` set to `foobar` instead of | |||
| 
 | ||||
| ## Default Configuration | ||||
| 
 | ||||
| Jekyll runs with the following configuration options by default. Unless | ||||
| alternative settings for these options are explicitly specified in the | ||||
| configuration file or on the command-line, Jekyll will run using these options. | ||||
| Jekyll runs with the following configuration options by default. Alternative | ||||
| settings for these options can be explicitly specified in the configuration | ||||
| file or on the command-line. | ||||
| 
 | ||||
| <div class="note warning"> | ||||
|   <h5>There are two unsupported kramdown options</h5> | ||||
|  | @ -476,7 +477,6 @@ exclude:      [] | |||
| keep_files:   [".git", ".svn"] | ||||
| encoding:     "utf-8" | ||||
| markdown_ext: "markdown,mkdown,mkdn,mkd,md" | ||||
| textile_ext:  "textile" | ||||
| 
 | ||||
| # Filtering Content | ||||
| show_drafts: null | ||||
|  | @ -490,14 +490,14 @@ gems:      [] | |||
| 
 | ||||
| # Conversion | ||||
| markdown:    kramdown | ||||
| highlighter: pygments | ||||
| highlighter: rouge | ||||
| lsi:         false | ||||
| excerpt_separator: "\n\n" | ||||
| 
 | ||||
| # Serving | ||||
| detach:  false | ||||
| port:    4000 | ||||
| host:    0.0.0.0 | ||||
| host:    127.0.0.1 | ||||
| baseurl: "" # does not include hostname | ||||
| 
 | ||||
| # Backwards-compatibility | ||||
|  | @ -527,12 +527,12 @@ redcarpet: | |||
|   extensions: [] | ||||
| 
 | ||||
| kramdown: | ||||
|   auto_ids:      true | ||||
|   footnote_nr:   1 | ||||
|   entity_output: as_char | ||||
|   toc_levels:    1..6 | ||||
|   smart_quotes:  lsquo,rsquo,ldquo,rdquo | ||||
|   use_coderay:   false | ||||
|   auto_ids:       true | ||||
|   footnote_nr:    1 | ||||
|   entity_output:  as_char | ||||
|   toc_levels:     1..6 | ||||
|   smart_quotes:   lsquo,rsquo,ldquo,rdquo | ||||
|   enable_coderay: false | ||||
| 
 | ||||
|   coderay: | ||||
|     coderay_wrap:              div | ||||
|  | @ -541,9 +541,6 @@ kramdown: | |||
|     coderay_tab_width:         4 | ||||
|     coderay_bold_every:        10 | ||||
|     coderay_css:               style | ||||
| 
 | ||||
| redcloth: | ||||
|   hard_breaks: true | ||||
| {% endhighlight %} | ||||
| 
 | ||||
| ## Markdown Options | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Continuous Integration | ||||
| prev_section: deployment-methods | ||||
| next_section: troubleshooting | ||||
| permalink: /docs/continuous-integration/ | ||||
| --- | ||||
| 
 | ||||
|  | @ -62,7 +60,7 @@ HTML::Proofer.new("./_site").run | |||
| {% endhighlight %} | ||||
| 
 | ||||
| Options are given as a second argument to `.new`, and are encoded in a | ||||
| symbol-keyed Ruby Hash. More information about the configuration options, | ||||
| symbol-keyed Ruby Hash. For more information about the configuration options, | ||||
| check out `html-proofer`'s README file. | ||||
| 
 | ||||
| [2]: https://github.com/gjtorikian/html-proofer | ||||
|  | @ -71,7 +69,7 @@ check out `html-proofer`'s README file. | |||
| 
 | ||||
| This file is used to configure your Travis builds. Because Jekyll is built | ||||
| with Ruby and requires RubyGems to install, we use the Ruby language build | ||||
| environment. Below is a sample `.travis.yml` file, and what follows that is | ||||
| environment. Below is a sample `.travis.yml` file, followed by | ||||
| an explanation of each line. | ||||
| 
 | ||||
| {% highlight yaml %} | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Contributing | ||||
| prev_section: upgrading | ||||
| next_section: history | ||||
| permalink: /docs/contributing/ | ||||
| --- | ||||
| 
 | ||||
|  | @ -99,7 +97,7 @@ You can find the documentation for jekyllrb.com in the | |||
| [site]({{ site.repository }}/tree/master/site) directory of | ||||
| Jekyll's repo on GitHub.com. | ||||
| 
 | ||||
| All documentation pull requests should be directed at `master`.  Pull | ||||
| All documentation pull requests should be directed at `master`. Pull | ||||
| requests directed at another branch will not be accepted. | ||||
| 
 | ||||
| The [Jekyll wiki]({{ site.repository }}/wiki) on GitHub | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Data Files | ||||
| prev_section: collections | ||||
| next_section: assets | ||||
| permalink: /docs/datafiles/ | ||||
| --- | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Deployment methods | ||||
| prev_section: github-pages | ||||
| next_section: continuous-integration | ||||
| permalink: /docs/deployment-methods/ | ||||
| --- | ||||
| 
 | ||||
|  | @ -93,7 +91,7 @@ Another way to deploy your Jekyll site is to use [Rake](https://github.com/jimwe | |||
| 
 | ||||
| ### 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/tasks/deploy). You’d obviously need to change the values to reflect your site’s details. There is even [a matching TextMate command](http://gist.github.com/214959) that will help you run | ||||
| 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. | ||||
| 
 | ||||
| 
 | ||||
|  | @ -109,9 +107,10 @@ If you want to maintain Jekyll inside your existing Rails app, [Jekyll-Admin](ht | |||
| 
 | ||||
| ## Amazon S3 | ||||
| 
 | ||||
| If you want to host your site in Amazon S3, you can do so with | ||||
| [s3_website](https://github.com/laurilehmijoki/s3_website) application. It will | ||||
| push your site to Amazon S3 where it can be served like any web server, | ||||
| If you want to host your site in Amazon S3, you can do so by | ||||
| using the [s3_website](https://github.com/laurilehmijoki/s3_website) | ||||
| application. It will push your site to Amazon S3 where it can be served like | ||||
| any web server, | ||||
| dynamically scaling to almost unlimited traffic. This approach has the | ||||
| benefit of being about the cheapest hosting option available for | ||||
| low-volume blogs as you only pay for what you use. | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Working with drafts | ||||
| prev_section: posts | ||||
| next_section: pages | ||||
| permalink: /docs/drafts/ | ||||
| --- | ||||
| 
 | ||||
|  | @ -17,5 +15,5 @@ first draft: | |||
| {% endhighlight %} | ||||
| 
 | ||||
| To preview your site with drafts, simply run `jekyll serve` or `jekyll build` with | ||||
| the `--drafts` switch.  Each will be assigned the value modification time of the draft file | ||||
| the `--drafts` switch. Each will be assigned the value modification time of the draft file | ||||
| for its date, and thus you will see currently edited drafts as the latest posts. | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Extras | ||||
| prev_section: plugins | ||||
| next_section: github-pages | ||||
| permalink: /docs/extras/ | ||||
| --- | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Front Matter | ||||
| prev_section: configuration | ||||
| next_section: posts | ||||
| permalink: /docs/frontmatter/ | ||||
| --- | ||||
| 
 | ||||
|  | @ -172,7 +170,9 @@ These are available out-of-the-box to be used in the front matter for a post. | |||
|       <td> | ||||
|         <p> | ||||
|           A date here overrides the date from the name of the post. This can be | ||||
|           used to ensure correct sorting of posts. | ||||
|           used to ensure correct sorting of posts. A date is specified in the format | ||||
|           <code>YYYY-MM-DD HH:MM:SS +/-TTTT</code>; hours, minutes, seconds, and timezone offset | ||||
|           are optional. | ||||
|         </p> | ||||
|       </td> | ||||
|     </tr> | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: GitHub Pages | ||||
| prev_section: extras | ||||
| next_section: deployment-methods | ||||
| permalink: /docs/github-pages/ | ||||
| --- | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,9 +2,41 @@ | |||
| layout: docs | ||||
| title: History | ||||
| permalink: "/docs/history/" | ||||
| prev_section: contributing | ||||
| --- | ||||
| 
 | ||||
| ## 2.5.3 / 2014-12-22 | ||||
| {: #v2-5-3} | ||||
| 
 | ||||
| ### Bug Fixes | ||||
| {: #bug-fixes-v2-5-3} | ||||
| 
 | ||||
| - When checking a Markdown extname, include position of the `.` ([#3147]({{ site.repository }}/issues/3147)) | ||||
| - Fix `jsonify` Liquid filter handling of boolean values ([#3154]({{ site.repository }}/issues/3154)) | ||||
| - Add comma to value of `viewport` meta tag ([#3170]({{ site.repository }}/issues/3170)) | ||||
| - Set the link type for the RSS feed to `application/rss+xml` ([#3176]({{ site.repository }}/issues/3176)) | ||||
| - Refactor `#as_liquid` ([#3158]({{ site.repository }}/issues/3158)) | ||||
| 
 | ||||
| ### Development Fixes | ||||
| {: #development-fixes-v2-5-3} | ||||
| 
 | ||||
| - Exclude built-in bundles from being added to coverage report ([#3180]({{ site.repository }}/issues/3180)) | ||||
| 
 | ||||
| ### Site Enhancements | ||||
| {: #site-enhancements-v2-5-3} | ||||
| 
 | ||||
| - Add `[@alfredxing](https://github.com/alfredxing)` to the `[@jekyll](https://github.com/jekyll)/core` team. :tada: ([#3218]({{ site.repository }}/issues/3218)) | ||||
| - Document the `-q` option for the `build` and `serve` commands ([#3149]({{ site.repository }}/issues/3149)) | ||||
| - Fix some minor typos/flow fixes in documentation website content ([#3165]({{ site.repository }}/issues/3165)) | ||||
| - Add `keep_files` to configuration documentation ([#3162]({{ site.repository }}/issues/3162)) | ||||
| - Repeat warning about cleaning of the `destination` directory ([#3161]({{ site.repository }}/issues/3161)) | ||||
| - Add jekyll-500px-embed to list of third-party plugins ([#3163]({{ site.repository }}/issues/3163)) | ||||
| - Simplified platform detection in Gemfile example for Windows ([#3177]({{ site.repository }}/issues/3177)) | ||||
| - Add the `jekyll-jalali` plugin added to the list of third-party plugins. ([#3198]({{ site.repository }}/issues/3198)) | ||||
| - Add Table of Contents to Troubleshooting page ([#3196]({{ site.repository }}/issues/3196)) | ||||
| - Add `inline_highlight` plugin to list of third-party plugins ([#3212]({{ site.repository }}/issues/3212)) | ||||
| - Add `jekyll-mermaid` plugin to list of third-party plugins ([#3222]({{ site.repository }}/issues/3222)) | ||||
| 
 | ||||
| 
 | ||||
| ## 2.5.2 / 2014-11-17 | ||||
| {: #v2-5-2} | ||||
| 
 | ||||
|  | @ -517,7 +549,7 @@ prev_section: contributing | |||
| - 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)) | ||||
| - 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)) | ||||
| - Add two-digit year to permalink template option ([#2301]({{ site.repository }}/issues/2301)) | ||||
| - Add `site.documents` to Liquid payload (list of all docs) ([#2295]({{ site.repository }}/issues/2295)) | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Welcome | ||||
| next_section: quickstart | ||||
| permalink: /docs/home/ | ||||
| --- | ||||
| 
 | ||||
|  | @ -15,10 +14,9 @@ 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 | ||||
| [Markdown](http://daringfireball.net/projects/markdown/) (or | ||||
| [Textile](http://redcloth.org/textile)) and | ||||
| [Liquid](https://github.com/Shopify/liquid/wiki) | ||||
| converters, and spits out a complete, ready-to-publish static website suitable | ||||
| a converter (like [Markdown](http://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 | ||||
| to host your project’s page, blog, or website from GitHub’s servers **for | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Installation | ||||
| prev_section: quickstart | ||||
| next_section: usage | ||||
| permalink: /docs/installation/ | ||||
| --- | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Blog migrations | ||||
| prev_section: assets | ||||
| next_section: templates | ||||
| permalink: /docs/migrations/ | ||||
| --- | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Creating pages | ||||
| prev_section: drafts | ||||
| next_section: variables | ||||
| permalink: /docs/pages/ | ||||
| --- | ||||
| 
 | ||||
|  | @ -60,7 +58,7 @@ and associated URLs might look like: | |||
| 
 | ||||
| ### Named folders containing index HTML files | ||||
| 
 | ||||
| There is nothing wrong with the above method, however some people like to keep | ||||
| There is nothing wrong with the above method. However, some people like to keep | ||||
| their URLs free from things like filename extensions. To achieve clean URLs for | ||||
| pages using Jekyll, you simply need to create a folder for each top-level page | ||||
| you want, and then place an `index.html` file in each page’s folder. This way | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Pagination | ||||
| prev_section: permalinks | ||||
| next_section: plugins | ||||
| permalink: /docs/pagination/ | ||||
| --- | ||||
| 
 | ||||
|  | @ -32,10 +30,10 @@ paginate: 5 | |||
| The number should be the maximum number of Posts you’d like to be displayed per- | ||||
| page in the generated site. | ||||
| 
 | ||||
| You may also specify where the destination of the pagination pages: | ||||
| You may also specify the destination of the pagination pages: | ||||
| 
 | ||||
| {% highlight yaml %} | ||||
| paginate_path: "blog/page:num/" | ||||
| paginate_path: "/blog/page:num/" | ||||
| {% endhighlight %} | ||||
| 
 | ||||
| This will read in `blog/index.html`, send it each pagination page in Liquid as `paginator` | ||||
|  | @ -44,6 +42,13 @@ starting with `2`. If a site has 12 posts and specifies `paginate: 5`, Jekyll wi | |||
| `blog/index.html` with the first 5 posts, `blog/page2/index.html` with the next 5 posts | ||||
| and `blog/page3/index.html` with the last 2 posts into the destination directory. | ||||
| 
 | ||||
| <div class="note warning"> | ||||
|   <h5>Don't set a permalink</h5> | ||||
|   <p> | ||||
|     Setting a permalink in the front matter of your blog page will cause pagination to break. Just omit the permalink. | ||||
|   </p> | ||||
| </div> | ||||
| 
 | ||||
| ## Liquid Attributes Available | ||||
| 
 | ||||
| The pagination plugin exposes the `paginator` liquid object with the following | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| --- | ||||
| layout: docs | ||||
| title: Permalinks | ||||
| prev_section: templates | ||||
| next_section: pagination | ||||
| permalink: /docs/permalinks/ | ||||
| --- | ||||
| 
 | ||||
|  | @ -80,7 +78,10 @@ permalink is defined as `/:categories/:year/:month/:day/:title.html`. | |||
|         <p><code>title</code></p> | ||||
|       </td> | ||||
|       <td> | ||||
|         <p>Title from the Post’s filename</p> | ||||
|         <p> | ||||
|             Title from the document’s filename. May be overridden via the | ||||
|             document’s <code>slug</code> YAML front matter. | ||||
|         </p> | ||||
|       </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|  | @ -137,6 +138,14 @@ enough to fix it all! | |||
|         <p><code>/:categories/:year/:month/:day/:title/</code></p> | ||||
|       </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|       <td> | ||||
|         <p><code>ordinal</code></p> | ||||
|       </td> | ||||
|       <td> | ||||
|         <p><code>/:categories/:year/:y_day/:title.html</code></p> | ||||
|       </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|       <td> | ||||
|         <p><code>none</code></p> | ||||
|  | @ -151,7 +160,7 @@ enough to fix it all! | |||
| 
 | ||||
| ## Permalink style examples | ||||
| 
 | ||||
| Given a post named: `/2009-04-29-slap-chop.textile` | ||||
| Given a post named: `/2009-04-29-slap-chop.md` | ||||
| 
 | ||||
| <div class="mobile-side-scroller"> | ||||
| <table> | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue