mirror of
https://github.com/jekyll/jekyll.git
synced 2026-04-28 03:01:03 -04:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf71631c34 | ||
|
|
6c0e4b37b9 |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -6,9 +6,3 @@ pkg/
|
||||
*~
|
||||
_site/
|
||||
.bundle/
|
||||
.DS_Store
|
||||
bbin/
|
||||
gh-pages/
|
||||
site/_site/
|
||||
coverage
|
||||
.ruby-version
|
||||
|
||||
14
.travis.yml
14
.travis.yml
@@ -1,14 +0,0 @@
|
||||
language: ruby
|
||||
before_install:
|
||||
- gem install bundler
|
||||
rvm:
|
||||
- 2.0.0
|
||||
- 1.9.3
|
||||
- 1.9.2
|
||||
- 1.8.7
|
||||
script: bundle exec rake
|
||||
notifications:
|
||||
irc: "irc.freenode.org#jekyll"
|
||||
email:
|
||||
on_success: never
|
||||
on_failure: never
|
||||
@@ -1,68 +0,0 @@
|
||||
Contribute
|
||||
==========
|
||||
|
||||
So you've got an awesome idea to throw into Jekyll. Great! Please keep the
|
||||
following in mind:
|
||||
|
||||
* **Contributions will not be accepted without tests.**
|
||||
* If you're creating a small fix or patch to an existing feature, just a simple
|
||||
test will do. Please stay in the confines of the current test suite and use
|
||||
[Shoulda](http://github.com/thoughtbot/shoulda/tree/master) and
|
||||
[RR](http://github.com/btakita/rr/tree/master).
|
||||
* If it's a brand new feature, make sure to create a new
|
||||
[Cucumber](https://github.com/cucumber/cucumber/) feature and reuse steps
|
||||
where appropriate. Also, whipping up some documentation in your fork's wiki
|
||||
would be appreciated, and once merged it will be transferred over to the main
|
||||
wiki.
|
||||
* If your contribution changes any Jekyll behavior, make sure to update the
|
||||
documentation. It lives in `site/_posts`. If the docs are missing information,
|
||||
please feel free to add it in. Great docs make a great project!
|
||||
* Please follow the [GitHub Ruby Styleguide](https://github.com/styleguide/ruby)
|
||||
when modifying Ruby code.
|
||||
|
||||
Test Dependencies
|
||||
-----------------
|
||||
|
||||
To run the test suite and build the gem you'll need to install Jekyll's
|
||||
dependencies. Jekyll uses Bundler, so a quick run of the bundle command and
|
||||
you're all set!
|
||||
|
||||
$ bundle
|
||||
|
||||
Before you start, run the tests and make sure that they pass (to confirm your
|
||||
environment is configured properly):
|
||||
|
||||
$ rake test
|
||||
$ rake features
|
||||
|
||||
Workflow
|
||||
--------
|
||||
|
||||
Here's the most direct way to get your work merged into the project:
|
||||
|
||||
* Fork the project.
|
||||
* Clone down your fork ( `git clone git@github.com:<username>/jekyll.git` ).
|
||||
* Create a topic branch to contain your change ( `git checkout -b my_awesome_feature` ).
|
||||
* Hack away, add tests. Not necessarily in that order.
|
||||
* Make sure everything still passes by running `rake`.
|
||||
* If necessary, rebase your commits into logical chunks, without errors.
|
||||
* Push the branch up ( `git push origin my_awesome_feature` ).
|
||||
* Create a pull request against mojombo/jekyll and describe what your change
|
||||
does and the why you think it should be merged.
|
||||
|
||||
Gotchas
|
||||
-------
|
||||
|
||||
* If you want to bump the gem version, please put that in a separate commit.
|
||||
This way, the maintainers can control when the gem gets released.
|
||||
* Try to keep your patch(es) based from the latest commit on mojombo/jekyll.
|
||||
The easier it is to apply your work, the less work the maintainers have to do,
|
||||
which is always a good thing.
|
||||
* Please don't tag your GitHub issue with [fix], [feature], etc. The maintainers
|
||||
actively read the issues and will label it once they come across it.
|
||||
|
||||
Finally...
|
||||
----------
|
||||
|
||||
Thanks! Hacking on Jekyll should be fun. If you find any of this hard to figure
|
||||
out, let us know so we can improve our process or documentation!
|
||||
499
History.markdown
499
History.markdown
@@ -1,499 +0,0 @@
|
||||
## HEAD
|
||||
### Major Enhancements
|
||||
### Minor Enhancements
|
||||
### Bug Fixes
|
||||
### Site Enhancements
|
||||
### Development Fixes
|
||||
|
||||
## 1.0.2 / 2013-05-12
|
||||
|
||||
### Major Enhancements
|
||||
* Add `jekyll doctor` command to check site for any known compatibility problems (#1081)
|
||||
* Backwards-compatibilize relative permalinks (#1081)
|
||||
|
||||
### Minor Enhancements
|
||||
* Add a `data-lang="<lang>"` attribute to Redcarpet code blocks (#1066)
|
||||
* Deprecate old config `server_port`, match to `port` if `port` isn't set (#1084)
|
||||
* Update pygments.rb version to 0.5.0 (#1061)
|
||||
* Update Kramdown version to 1.0.2 (#1067)
|
||||
|
||||
### Bug Fixes
|
||||
* Fix issue when categories are numbers (#1078)
|
||||
* Catching that Redcarpet gem isn't installed (#1059)
|
||||
|
||||
### Site Enhancements
|
||||
* Add documentation about `relative_permalinks` (#1081)
|
||||
* Remove pygments-installation instructions, as pygments.rb is bundled with it (#1079)
|
||||
* Move pages to be Pages for realz (#985)
|
||||
* Updated links to Liquid documentation (#1073)
|
||||
|
||||
## 1.0.1 / 2013-05-08
|
||||
|
||||
### Minor Enhancements
|
||||
* Do not force use of toc_token when using generate_tok in RDiscount (#1048)
|
||||
* Add newer `language-` class name prefix to code blocks (#1037)
|
||||
* Commander error message now preferred over process abort with incorrect args (#1040)
|
||||
|
||||
### Bug Fixes
|
||||
* Make Redcarpet respect the pygments configuration option (#1053)
|
||||
* Fix the index build with LSI (#1045)
|
||||
* Don't print deprecation warning when no arguments are specified. (#1041)
|
||||
* Add missing `</div>` to site template used by `new` subcommand, fixed typos in code (#1032)
|
||||
|
||||
### Site Enhancements
|
||||
* Changed https to http in the GitHub Pages link (#1051)
|
||||
* Remove CSS cruft, fix typos, fix HTML errors (#1028)
|
||||
* Removing manual install of Pip and Distribute (#1025)
|
||||
* Updated URL for Markdown references plugin (#1022)
|
||||
|
||||
### Development Fixes
|
||||
* Markdownify history file (#1027)
|
||||
* Update links on README to point to new jekyllrb.com (#1018)
|
||||
|
||||
## 1.0.0 / 2013-05-06
|
||||
|
||||
### Major Enhancements
|
||||
* Add `jekyll new` subcommand: generate a jekyll scaffold (#764)
|
||||
* Refactored jekyll commands into subcommands: build, serve, and migrate. (#690)
|
||||
* Removed importers/migrators from main project, migrated to jekyll-import sub-gem (#793)
|
||||
* Added ability to render drafts in `_drafts` folder via command line (#833)
|
||||
* Add ordinal date permalink style (/:categories/:year/:y_day/:title.html) (#928)
|
||||
|
||||
### Minor Enhancements
|
||||
* Site template HTML5-ified (#964)
|
||||
* Use post's directory path when matching for the post_url tag (#998)
|
||||
* Loosen dependency on Pygments so it's only required when it's needed (#1015)
|
||||
* Parse strings into Time objects for date-related Liquid filters (#1014)
|
||||
* Tell the user if there is no subcommand specified (#1008)
|
||||
* Freak out if the destination of `jekyll new` exists and is non-empty (#981)
|
||||
* Add `timezone` configuration option for compilation (#957)
|
||||
* Add deprecation messages for pre-1.0 CLI options (#959)
|
||||
* Refactor and colorize logging (#959)
|
||||
* Refactor Markdown parsing (#955)
|
||||
* Added application/vnd.apple.pkpass to mime.types served by WEBrick (#907)
|
||||
* Move template site to default markdown renderer (#961)
|
||||
* Expose new attribute to Liquid via `page`: `page.path` (#951)
|
||||
* Accept multiple config files from command line (#945)
|
||||
* Add page variable to liquid custom tags and blocks (#413)
|
||||
* Add paginator.previous_page_path and paginator.next_page_path (#942)
|
||||
* Backwards compatibility for 'auto' (#821, #934)
|
||||
* Added date_to_rfc822 used on RSS feeds (#892)
|
||||
* Upgrade version of pygments.rb to 0.4.2 (#927)
|
||||
* Added short month (e.g. "Sep") to permalink style options for posts (#890)
|
||||
* Expose site.baseurl to Liquid templates (#869)
|
||||
* Adds excerpt attribute to posts which contains first paragraph of content (#837)
|
||||
* Accept custom configuration file via CLI (#863)
|
||||
* Load in GitHub Pages MIME Types on `jekyll serve` (#847, #871)
|
||||
* Improve debugability of error message for a malformed highlight tag (#785)
|
||||
* Allow symlinked files in unsafe mode (#824)
|
||||
* Add 'gist' Liquid tag to core (#822, #861)
|
||||
* New format of Jekyll output (#795)
|
||||
* Reinstate --limit_posts and --future switches (#788)
|
||||
* Remove ambiguity from command descriptions (#815)
|
||||
* Fix SafeYAML Warnings (#807)
|
||||
* Relaxed Kramdown version to 0.14 (#808)
|
||||
* Aliased `jekyll server` to `jekyll serve`. (#792)
|
||||
* Updated gem versions for Kramdown, Rake, Shoulda, Cucumber, and RedCarpet. (#744)
|
||||
* Refactored jekyll subcommands into Jekyll::Commands submodule, which now contains them (#768)
|
||||
* Rescue from import errors in Wordpress.com migrator (#671)
|
||||
* Massively accelerate LSI performance (#664)
|
||||
* Truncate post slugs when importing from Tumblr (#496)
|
||||
* Add glob support to include, exclude option (#743)
|
||||
* Layout of Page or Post defaults to 'page' or 'post', respectively (#580)
|
||||
REPEALED by (#977)
|
||||
* "Keep files" feature (#685)
|
||||
* Output full path & name for files that don't parse (#745)
|
||||
* Add source and destination directory protection (#535)
|
||||
* Better YAML error message (#718)
|
||||
* Bug Fixes
|
||||
* Paginate in subdirectories properly (#1016)
|
||||
* Ensure post and page URLs have a leading slash (#992)
|
||||
* Catch all exceptions, not just StandardError descendents (#1007)
|
||||
* Bullet-proof limit_posts option (#1004)
|
||||
* Read in YAML as UTF-8 to accept non-ASCII chars (#836)
|
||||
* Fix the CLI option --plugins to actually accept dirs and files (#993)
|
||||
* Allow 'excerpt' in YAML Front-Matter to override the extracted excerpt (#946)
|
||||
* Fix cascade problem with site.baseurl, site.port and site.host. (#935)
|
||||
* Filter out directories with valid post names (#875)
|
||||
* Fix symlinked static files not being correctly built in unsafe mode (#909)
|
||||
* Fix integration with directory_watcher 1.4.x (#916)
|
||||
* Accepting strings as arguments to jekyll-import command (#910)
|
||||
* Force usage of older directory_watcher gem as 1.5 is broken (#883)
|
||||
* Ensure all Post categories are downcase (#842, #872)
|
||||
* Force encoding of the rdiscount TOC to UTF8 to avoid conversion errors (#555)
|
||||
* Patch for multibyte URI problem with jekyll serve (#723)
|
||||
* Order plugin execution by priority (#864)
|
||||
* Fixed Page#dir and Page#url for edge cases (#536)
|
||||
* Fix broken post_url with posts with a time in their YAML Front-Matter (#831)
|
||||
* Look for plugins under the source directory (#654)
|
||||
* Tumblr Migrator: finds _posts dir correctly, fixes truncation of long
|
||||
post names (#775)
|
||||
* Force Categories to be Strings (#767)
|
||||
* Safe YAML plugin to prevent vulnerability (#777)
|
||||
* Add SVG support to Jekyll/WEBrick. (#407, #406)
|
||||
* Prevent custom destination from causing continuous regen on watch (#528, #820, #862)
|
||||
|
||||
### Site Enhancements
|
||||
* Responsify (#860)
|
||||
* Fix spelling, punctuation and phrasal errors (#989)
|
||||
* Update quickstart instructions with `new` command (#966)
|
||||
* Add docs for page.excerpt (#956)
|
||||
* Add docs for page.path (#951)
|
||||
* Clean up site docs to prepare for 1.0 release (#918)
|
||||
* Bring site into master branch with better preview/deploy (#709)
|
||||
* Redesigned site (#583)
|
||||
|
||||
### Development Fixes
|
||||
* Exclude Cucumber 1.2.4, which causes tests to fail in 1.9.2 (#938)
|
||||
* Added "features:html" rake task for debugging purposes, cleaned up
|
||||
cucumber profiles (#832)
|
||||
* Explicitly require HTTPS rubygems source in Gemfile (#826)
|
||||
* Changed Ruby version for development to 1.9.3-p374 from p362 (#801)
|
||||
* Including a link to the GitHub Ruby style guide in CONTRIBUTING.md (#806)
|
||||
* Added script/bootstrap (#776)
|
||||
* Running Simplecov under 2 conditions: ENV(COVERAGE)=true and with Ruby version
|
||||
of greater than 1.9 (#771)
|
||||
* Switch to Simplecov for coverage report (#765)
|
||||
|
||||
## 0.12.1 / 2013-02-19
|
||||
### Minor Enhancements
|
||||
* Update Kramdown version to 0.14.1 (#744)
|
||||
* Test Enhancements
|
||||
* Update Rake version to 10.0.3 (#744)
|
||||
* Update Shoulda version to 3.3.2 (#744)
|
||||
* Update Redcarpet version to 2.2.2 (#744)
|
||||
|
||||
## 0.12.0 / 2012-12-22
|
||||
### Minor Enhancements
|
||||
* Add ability to explicitly specify included files (#261)
|
||||
* Add --default-mimetype option (#279)
|
||||
* Allow setting of RedCloth options (#284)
|
||||
* Add post_url Liquid tag for internal post linking (#369)
|
||||
* Allow multiple plugin dirs to be specified (#438)
|
||||
* Inline TOC token support for RDiscount (#333)
|
||||
* Add the option to specify the paginated url format (#342)
|
||||
* Swap out albino for pygments.rb (#569)
|
||||
* Support Redcarpet 2 and fenced code blocks (#619)
|
||||
* Better reporting of Liquid errors (#624)
|
||||
* Bug Fixes
|
||||
* Allow some special characters in highlight names
|
||||
* URL escape category names in URL generation (#360)
|
||||
* Fix error with limit_posts (#442)
|
||||
* Properly select dotfile during directory scan (#363, #431, #377)
|
||||
* Allow setting of Kramdown smart_quotes (#482)
|
||||
* Ensure front-matter is at start of file (#562)
|
||||
|
||||
## 0.11.2 / 2011-12-27
|
||||
* Bug Fixes
|
||||
* Fix gemspec
|
||||
|
||||
## 0.11.1 / 2011-12-27
|
||||
* Bug Fixes
|
||||
* Fix extra blank line in highlight blocks (#409)
|
||||
* Update dependencies
|
||||
|
||||
## 0.11.0 / 2011-07-10
|
||||
### Major Enhancements
|
||||
* Add command line importer functionality (#253)
|
||||
* Add Redcarpet Markdown support (#318)
|
||||
* Make markdown/textile extensions configurable (#312)
|
||||
* Add `markdownify` filter
|
||||
|
||||
### Minor Enhancements
|
||||
* Switch to Albino gem
|
||||
* Bundler support
|
||||
* Use English library to avoid hoops (#292)
|
||||
* Add Posterous importer (#254)
|
||||
* Fixes for Wordpress importer (#274, #252, #271)
|
||||
* Better error message for invalid post date (#291)
|
||||
* Print formatted fatal exceptions to stdout on build failure
|
||||
* Add Tumblr importer (#323)
|
||||
* Add Enki importer (#320)
|
||||
* Bug Fixes
|
||||
* Secure additional path exploits
|
||||
|
||||
## 0.10.0 / 2010-12-16
|
||||
* Bug Fixes
|
||||
* Add --no-server option.
|
||||
|
||||
## 0.9.0 / 2010-12-15
|
||||
### Minor Enhancements
|
||||
* Use OptionParser's [no-] functionality for better boolean parsing.
|
||||
* Add Drupal migrator (#245)
|
||||
* Complain about YAML and Liquid errors (#249)
|
||||
* Remove orphaned files during regeneration (#247)
|
||||
* Add Marley migrator (#28)
|
||||
|
||||
## 0.8.0 / 2010-11-22
|
||||
### Minor Enhancements
|
||||
* Add wordpress.com importer (#207)
|
||||
* Add --limit-posts cli option (#212)
|
||||
* Add uri_escape filter (#234)
|
||||
* Add --base-url cli option (#235)
|
||||
* Improve MT migrator (#238)
|
||||
* Add kramdown support (#239)
|
||||
* Bug Fixes
|
||||
* Fixed filename basename generation (#208)
|
||||
* Set mode to UTF8 on Sequel connections (#237)
|
||||
* Prevent _includes dir from being a symlink
|
||||
|
||||
## 0.7.0 / 2010-08-24
|
||||
### Minor Enhancements
|
||||
* Add support for rdiscount extensions (#173)
|
||||
* Bug Fixes
|
||||
* Highlight should not be able to render local files
|
||||
* The site configuration may not always provide a 'time' setting (#184)
|
||||
|
||||
## 0.6.2 / 2010-06-25
|
||||
* Bug Fixes
|
||||
* Fix Rakefile 'release' task (tag pushing was missing origin)
|
||||
* Ensure that RedCloth is loaded when textilize filter is used (#183)
|
||||
* Expand source, destination, and plugin paths (#180)
|
||||
* Fix page.url to include full relative path (#181)
|
||||
|
||||
## 0.6.1 / 2010-06-24
|
||||
* Bug Fixes
|
||||
* Fix Markdown Pygments prefix and suffix (#178)
|
||||
|
||||
## 0.6.0 / 2010-06-23
|
||||
### Major Enhancements
|
||||
* Proper plugin system (#19, #100)
|
||||
* Add safe mode so unsafe converters/generators can be added
|
||||
* Maruku is now the only processor dependency installed by default.
|
||||
Other processors will be lazy-loaded when necessary (and prompt the
|
||||
user to install them when necessary) (#57)
|
||||
|
||||
### Minor Enhancements
|
||||
* Inclusion/exclusion of future dated posts (#59)
|
||||
* Generation for a specific time (#59)
|
||||
* Allocate site.time on render not per site_payload invocation (#59)
|
||||
* Pages now present in the site payload and can be used through the
|
||||
site.pages and site.html_pages variables
|
||||
* Generate phase added to site#process and pagination is now a generator
|
||||
* Switch to RakeGem for build/test process
|
||||
* Only regenerate static files when they have changed (#142)
|
||||
* Allow arbitrary options to Pygments (#31)
|
||||
* Allow URL to be set via command line option (#147)
|
||||
* Bug Fixes
|
||||
* Render highlighted code for non markdown/textile pages (#116)
|
||||
* Fix highlighting on Ruby 1.9 (#65)
|
||||
* Fix extension munging when pretty permalinks are enabled (#64)
|
||||
* Stop sorting categories (#33)
|
||||
* Preserve generated attributes over front matter (#119)
|
||||
* Fix source directory binding using Dir.pwd (#75)
|
||||
|
||||
## 0.5.7 / 2010-01-12
|
||||
### Minor Enhancements
|
||||
* Allow overriding of post date in the front matter (#62, #38)
|
||||
* Bug Fixes
|
||||
* Categories isn't always an array (#73)
|
||||
* Empty tags causes error in read_posts (#84)
|
||||
* Fix pagination to adhere to read/render/write paradigm
|
||||
* Test Enhancement
|
||||
* cucumber features no longer use site.posts.first where a better
|
||||
alternative is available
|
||||
|
||||
## 0.5.6 / 2010-01-08
|
||||
* Bug Fixes
|
||||
* Require redcloth >= 4.2.1 in tests (#92)
|
||||
* Don't break on triple dashes in yaml frontmatter (#93)
|
||||
|
||||
### Minor Enhancements
|
||||
* Allow .mkd as markdown extension
|
||||
* Use $stdout/err instead of constants (#99)
|
||||
* Properly wrap code blocks (#91)
|
||||
* Add javascript mime type for webrick (#98)
|
||||
|
||||
## 0.5.5 / 2010-01-08
|
||||
* Bug Fixes
|
||||
* Fix pagination % 0 bug (#78)
|
||||
* Ensure all posts are processed first (#71)
|
||||
|
||||
## NOTE
|
||||
* After this point I will no longer be giving credit in the history;
|
||||
that is what the commit log is for.
|
||||
|
||||
## 0.5.4 / 2009-08-23
|
||||
* Bug Fixes
|
||||
* Do not allow symlinks (security vulnerability)
|
||||
|
||||
## 0.5.3 / 2009-07-14
|
||||
* Bug Fixes
|
||||
* Solving the permalink bug where non-html files wouldn't work
|
||||
[github.com/jeffrydegrande]
|
||||
|
||||
## 0.5.2 / 2009-06-24
|
||||
* Enhancements
|
||||
* Added --paginate option to the executable along with a paginator object
|
||||
for the payload [github.com/calavera]
|
||||
* Upgraded RedCloth to 4.2.1, which makes <notextile> tags work once
|
||||
again.
|
||||
* Configuration options set in config.yml are now available through the
|
||||
site payload [github.com/vilcans]
|
||||
* Posts can now have an empty YAML front matter or none at all
|
||||
[github.com/bahuvrihi]
|
||||
* Bug Fixes
|
||||
* Fixing Ruby 1.9 issue that requires to_s on the err object
|
||||
[github.com/Chrononaut]
|
||||
* Fixes for pagination and ordering posts on the same day [github.com/ujh]
|
||||
* Made pages respect permalinks style and permalinks in yml front matter
|
||||
[github.com/eugenebolshakov]
|
||||
* Index.html file should always have index.html permalink
|
||||
[github.com/eugenebolshakov]
|
||||
* Added trailing slash to pretty permalink style so Apache is happy
|
||||
[github.com/eugenebolshakov]
|
||||
* Bad markdown processor in config fails sooner and with better message
|
||||
[github.com/gcnovus]
|
||||
* Allow CRLFs in yaml frontmatter [github.com/juretta]
|
||||
* Added Date#xmlschema for Ruby versions < 1.9
|
||||
|
||||
## 0.5.1 / 2009-05-06
|
||||
### Major Enhancements
|
||||
* Next/previous posts in site payload [github.com/pantulis,
|
||||
github.com/tomo]
|
||||
* Permalink templating system
|
||||
* Moved most of the README out to the GitHub wiki
|
||||
* Exclude option in configuration so specified files won't be brought over
|
||||
with generated site [github.com/duritong]
|
||||
* Bug Fixes
|
||||
* Making sure config.yaml references are all gone, using only config.yml
|
||||
* Fixed syntax highlighting breaking for UTF-8 code [github.com/henrik]
|
||||
* Worked around RDiscount bug that prevents Markdown from getting parsed
|
||||
after highlight [github.com/henrik]
|
||||
* CGI escaped post titles [github.com/Chrononaut]
|
||||
|
||||
## 0.5.0 / 2009-04-07
|
||||
### Minor Enhancements
|
||||
* Ability to set post categories via YAML [github.com/qrush]
|
||||
* Ability to set prevent a post from publishing via YAML
|
||||
[github.com/qrush]
|
||||
* Add textilize filter [github.com/willcodeforfoo]
|
||||
* Add 'pretty' permalink style for wordpress-like urls
|
||||
[github.com/dysinger]
|
||||
* Made it possible to enter categories from YAML as an array
|
||||
[github.com/Chrononaut]
|
||||
* Ignore Emacs autosave files [github.com/Chrononaut]
|
||||
* Bug Fixes
|
||||
* Use block syntax of popen4 to ensure that subprocesses are properly
|
||||
disposed [github.com/jqr]
|
||||
* Close open4 streams to prevent zombies [github.com/rtomayko]
|
||||
* Only query required fields from the WP Database [github.com/ariejan]
|
||||
* Prevent _posts from being copied to the destination directory
|
||||
[github.com/bdimcheff]
|
||||
* Refactors
|
||||
* Factored the filtering code into a method [github.com/Chrononaut]
|
||||
* Fix tests and convert to Shoulda [github.com/qrush,
|
||||
github.com/technicalpickles]
|
||||
* Add Cucumber acceptance test suite [github.com/qrush,
|
||||
github.com/technicalpickles]
|
||||
|
||||
## 0.4.1
|
||||
### Minor Enhancements
|
||||
* Changed date format on wordpress converter (zeropadding)
|
||||
[github.com/dysinger]
|
||||
* Bug Fixes
|
||||
* Add jekyll binary as executable to gemspec [github.com/dysinger]
|
||||
|
||||
## 0.4.0 / 2009-02-03
|
||||
### Major Enhancements
|
||||
* Switch to Jeweler for packaging tasks
|
||||
|
||||
### Minor Enhancements
|
||||
* Type importer [github.com/codeslinger]
|
||||
* site.topics accessor [github.com/baz]
|
||||
* Add array_to_sentence_string filter [github.com/mchung]
|
||||
* Add a converter for textpattern [github.com/PerfectlyNormal]
|
||||
* Add a working Mephisto / MySQL converter [github.com/ivey]
|
||||
* Allowing .htaccess files to be copied over into the generated site
|
||||
[github.com/briandoll]
|
||||
* Add option to not put file date in permalink URL [github.com/mreid]
|
||||
* Add line number capabilities to highlight blocks [github.com/jcon]
|
||||
* Bug Fixes
|
||||
* Fix permalink behavior [github.com/cavalle]
|
||||
* Fixed an issue with pygments, markdown, and newlines
|
||||
[github.com/zpinter]
|
||||
* Ampersands need to be escaped [github.com/pufuwozu, github.com/ap]
|
||||
* Test and fix the site.categories hash [github.com/zzot]
|
||||
* Fix site payload available to files [github.com/matrix9180]
|
||||
|
||||
## 0.3.0 / 2008-12-24
|
||||
### Major Enhancements
|
||||
* Added --server option to start a simple WEBrick server on destination
|
||||
directory [github.com/johnreilly and github.com/mchung]
|
||||
|
||||
### Minor Enhancements
|
||||
* Added post categories based on directories containing _posts
|
||||
[github.com/mreid]
|
||||
* Added post topics based on directories underneath _posts
|
||||
* Added new date filter that shows the full month name [github.com/mreid]
|
||||
* Merge Post's YAML front matter into its to_liquid payload
|
||||
[github.com/remi]
|
||||
* Restrict includes to regular files underneath _includes
|
||||
* Bug Fixes
|
||||
* Change YAML delimiter matcher so as to not chew up 2nd level markdown
|
||||
headers [github.com/mreid]
|
||||
* Fix bug that meant page data (such as the date) was not available in
|
||||
templates [github.com/mreid]
|
||||
* Properly reject directories in _layouts
|
||||
|
||||
## 0.2.1 / 2008-12-15
|
||||
* Major Changes
|
||||
* Use Maruku (pure Ruby) for Markdown by default [github.com/mreid]
|
||||
* Allow use of RDiscount with --rdiscount flag
|
||||
|
||||
### Minor Enhancements
|
||||
* Don't load directory_watcher unless it's needed [github.com/pjhyett]
|
||||
|
||||
## 0.2.0 / 2008-12-14
|
||||
* Major Changes
|
||||
* related_posts is now found in site.related_posts
|
||||
|
||||
## 0.1.6 / 2008-12-13
|
||||
* Major Features
|
||||
* Include files in _includes with {% include x.textile %}
|
||||
|
||||
## 0.1.5 / 2008-12-12
|
||||
### Major Enhancements
|
||||
* Code highlighting with Pygments if --pygments is specified
|
||||
* Disable true LSI by default, enable with --lsi
|
||||
|
||||
### Minor Enhancements
|
||||
* Output informative message if RDiscount is not available
|
||||
[github.com/JackDanger]
|
||||
* Bug Fixes
|
||||
* Prevent Jekyll from picking up the output directory as a source
|
||||
[github.com/JackDanger]
|
||||
* Skip related_posts when there is only one post [github.com/JackDanger]
|
||||
|
||||
## 0.1.4 / 2008-12-08
|
||||
* Bug Fixes
|
||||
* DATA does not work properly with rubygems
|
||||
|
||||
## 0.1.3 / 2008-12-06
|
||||
* Major Features
|
||||
* Markdown support [github.com/vanpelt]
|
||||
* Mephisto and CSV converters [github.com/vanpelt]
|
||||
* Code hilighting [github.com/vanpelt]
|
||||
* Autobuild
|
||||
* Bug Fixes
|
||||
* Accept both \r\n and \n in YAML header [github.com/vanpelt]
|
||||
|
||||
## 0.1.2 / 2008-11-22
|
||||
* Major Features
|
||||
* Add a real "related posts" implementation using Classifier
|
||||
* Command Line Changes
|
||||
* Allow cli to be called with 0, 1, or 2 args intuiting dir paths
|
||||
if they are omitted
|
||||
|
||||
## 0.1.1 / 2008-11-22
|
||||
* Minor Additions
|
||||
* Posts now support introspectional data e.g. {{ page.url }}
|
||||
|
||||
## 0.1.0 / 2008-11-05
|
||||
* First release
|
||||
* Converts posts written in Textile
|
||||
* Converts regular site pages
|
||||
* Simple copy of binary files
|
||||
|
||||
## 0.0.0 / 2008-10-19
|
||||
* Birthday!
|
||||
294
History.txt
Normal file
294
History.txt
Normal file
@@ -0,0 +1,294 @@
|
||||
== HEAD
|
||||
* Major Enhancements
|
||||
* Add command line importer functionality (#253)
|
||||
* Minor Enhancements
|
||||
* Switch to Albino gem
|
||||
* Bundler support
|
||||
* Use English library to avoid hoops (#292)
|
||||
* Add Posterous importer (#254)
|
||||
* Fixes for Wordpress importer (#274, #252, #271)
|
||||
* Better error message for invalid post date (#291)
|
||||
* Print formatted fatal exceptions to stdout on build failure
|
||||
* Bug Fixes
|
||||
* Secure additional path exploits
|
||||
|
||||
== 0.10.0 / 2010-12-16
|
||||
* Bug Fixes
|
||||
* Add --no-server option.
|
||||
|
||||
== 0.9.0 / 2010-12-15
|
||||
* Minor Enhancements
|
||||
* Use OptionParser's [no-] functionality for better boolean parsing.
|
||||
* Add Drupal migrator (#245)
|
||||
* Complain about YAML and Liquid errors (#249)
|
||||
* Remove orphaned files during regeneration (#247)
|
||||
* Add Marley migrator (#28)
|
||||
|
||||
== 0.8.0 / 2010-11-22
|
||||
* Minor Enhancements
|
||||
* Add wordpress.com importer (#207)
|
||||
* Add --limit-posts cli option (#212)
|
||||
* Add uri_escape filter (#234)
|
||||
* Add --base-url cli option (#235)
|
||||
* Improve MT migrator (#238)
|
||||
* Add kramdown support (#239)
|
||||
* Bug Fixes
|
||||
* Fixed filename basename generation (#208)
|
||||
* Set mode to UTF8 on Sequel connections (#237)
|
||||
* Prevent _includes dir from being a symlink
|
||||
|
||||
== 0.7.0 / 2010-08-24
|
||||
* Minor Enhancements
|
||||
* Add support for rdiscount extensions (#173)
|
||||
* Bug Fixes
|
||||
* Highlight should not be able to render local files
|
||||
* The site configuration may not always provide a 'time' setting (#184)
|
||||
|
||||
== 0.6.2 / 2010-06-25
|
||||
* Bug Fixes
|
||||
* Fix Rakefile 'release' task (tag pushing was missing origin)
|
||||
* Ensure that RedCloth is loaded when textilize filter is used (#183)
|
||||
* Expand source, destination, and plugin paths (#180)
|
||||
* Fix page.url to include full relative path (#181)
|
||||
|
||||
== 0.6.1 / 2010-06-24
|
||||
* Bug Fixes
|
||||
* Fix Markdown Pygments prefix and suffix (#178)
|
||||
|
||||
== 0.6.0 / 2010-06-23
|
||||
* Major Enhancements
|
||||
* Proper plugin system (#19, #100)
|
||||
* Add safe mode so unsafe converters/generators can be added
|
||||
* Maruku is now the only processor dependency installed by default.
|
||||
Other processors will be lazy-loaded when necessary (and prompt the
|
||||
user to install them when necessary) (#57)
|
||||
* Minor Enhancements
|
||||
* Inclusion/exclusion of future dated posts (#59)
|
||||
* Generation for a specific time (#59)
|
||||
* Allocate site.time on render not per site_payload invocation (#59)
|
||||
* Pages now present in the site payload and can be used through the
|
||||
site.pages and site.html_pages variables
|
||||
* Generate phase added to site#process and pagination is now a generator
|
||||
* Switch to RakeGem for build/test process
|
||||
* Only regenerate static files when they have changed (#142)
|
||||
* Allow arbitrary options to Pygments (#31)
|
||||
* Allow URL to be set via command line option (#147)
|
||||
* Bug Fixes
|
||||
* Render highlighted code for non markdown/textile pages (#116)
|
||||
* Fix highlighting on Ruby 1.9 (#65)
|
||||
* Fix extension munging when pretty permalinks are enabled (#64)
|
||||
* Stop sorting categories (#33)
|
||||
* Preserve generated attributes over front matter (#119)
|
||||
* Fix source directory binding using Dir.pwd (#75)
|
||||
|
||||
== 0.5.7 / 2010-01-12
|
||||
* Minor Enhancements
|
||||
* Allow overriding of post date in the front matter (#62, #38)
|
||||
* Bug Fixes
|
||||
* Categories isn't always an array (#73)
|
||||
* Empty tags causes error in read_posts (#84)
|
||||
* Fix pagination to adhere to read/render/write paradigm
|
||||
* Test Enhancement
|
||||
* cucumber features no longer use site.posts.first where a better
|
||||
alternative is available
|
||||
|
||||
== 0.5.6 / 2010-01-08
|
||||
* Bug Fixes
|
||||
* Require redcloth >= 4.2.1 in tests (#92)
|
||||
* Don't break on triple dashes in yaml frontmatter (#93)
|
||||
* Minor Enhancements
|
||||
* Allow .mkd as markdown extension
|
||||
* Use $stdout/err instead of constants (#99)
|
||||
* Properly wrap code blocks (#91)
|
||||
* Add javascript mime type for webrick (#98)
|
||||
|
||||
== 0.5.5 / 2010-01-08
|
||||
* Bug Fixes
|
||||
* Fix pagination % 0 bug (#78)
|
||||
* Ensure all posts are processed first (#71)
|
||||
|
||||
== NOTE
|
||||
* After this point I will no longer be giving credit in the history;
|
||||
that is what the commit log is for.
|
||||
|
||||
== 0.5.4 / 2009-08-23
|
||||
* Bug Fixes
|
||||
* Do not allow symlinks (security vulnerability)
|
||||
|
||||
== 0.5.3 / 2009-07-14
|
||||
* Bug Fixes
|
||||
* Solving the permalink bug where non-html files wouldn't work
|
||||
[github.com/jeffrydegrande]
|
||||
|
||||
== 0.5.2 / 2009-06-24
|
||||
* Enhancements
|
||||
* Added --paginate option to the executable along with a paginator object
|
||||
for the payload [github.com/calavera]
|
||||
* Upgraded RedCloth to 4.2.1, which makes <notextile> tags work once
|
||||
again.
|
||||
* Configuration options set in config.yml are now available through the
|
||||
site payload [github.com/vilcans]
|
||||
* Posts can now have an empty YAML front matter or none at all
|
||||
[github.com/bahuvrihi]
|
||||
* Bug Fixes
|
||||
* Fixing Ruby 1.9 issue that requires to_s on the err object
|
||||
[github.com/Chrononaut]
|
||||
* Fixes for pagination and ordering posts on the same day [github.com/ujh]
|
||||
* Made pages respect permalinks style and permalinks in yml front matter
|
||||
[github.com/eugenebolshakov]
|
||||
* Index.html file should always have index.html permalink
|
||||
[github.com/eugenebolshakov]
|
||||
* Added trailing slash to pretty permalink style so Apache is happy
|
||||
[github.com/eugenebolshakov]
|
||||
* Bad markdown processor in config fails sooner and with better message
|
||||
[github.com/gcnovus]
|
||||
* Allow CRLFs in yaml frontmatter [github.com/juretta]
|
||||
* Added Date#xmlschema for Ruby versions < 1.9
|
||||
|
||||
== 0.5.1 / 2009-05-06
|
||||
* Major Enhancements
|
||||
* Next/previous posts in site payload [github.com/pantulis,
|
||||
github.com/tomo]
|
||||
* Permalink templating system
|
||||
* Moved most of the README out to the GitHub wiki
|
||||
* Exclude option in configuration so specified files won't be brought over
|
||||
with generated site [github.com/duritong]
|
||||
* Bug Fixes
|
||||
* Making sure config.yaml references are all gone, using only config.yml
|
||||
* Fixed syntax highlighting breaking for UTF-8 code [github.com/henrik]
|
||||
* Worked around RDiscount bug that prevents Markdown from getting parsed
|
||||
after highlight [github.com/henrik]
|
||||
* CGI escaped post titles [github.com/Chrononaut]
|
||||
|
||||
== 0.5.0 / 2009-04-07
|
||||
* Minor Enhancements
|
||||
* Ability to set post categories via YAML [github.com/qrush]
|
||||
* Ability to set prevent a post from publishing via YAML
|
||||
[github.com/qrush]
|
||||
* Add textilize filter [github.com/willcodeforfoo]
|
||||
* Add 'pretty' permalink style for wordpress-like urls
|
||||
[github.com/dysinger]
|
||||
* Made it possible to enter categories from YAML as an array
|
||||
[github.com/Chrononaut]
|
||||
* Ignore Emacs autosave files [github.com/Chrononaut]
|
||||
* Bug Fixes
|
||||
* Use block syntax of popen4 to ensure that subprocesses are properly
|
||||
disposed [github.com/jqr]
|
||||
* Close open4 streams to prevent zombies [github.com/rtomayko]
|
||||
* Only query required fields from the WP Database [github.com/ariejan]
|
||||
* Prevent _posts from being copied to the destination directory
|
||||
[github.com/bdimcheff]
|
||||
* Refactors
|
||||
* Factored the filtering code into a method [github.com/Chrononaut]
|
||||
* Fix tests and convert to Shoulda [github.com/qrush,
|
||||
github.com/technicalpickles]
|
||||
* Add Cucumber acceptance test suite [github.com/qrush,
|
||||
github.com/technicalpickles]
|
||||
|
||||
== 0.4.1
|
||||
* Minor Enhancements
|
||||
* Changed date format on wordpress converter (zeropadding)
|
||||
[github.com/dysinger]
|
||||
* Bug Fixes
|
||||
* Add jekyll binary as executable to gemspec [github.com/dysinger]
|
||||
|
||||
== 0.4.0 / 2009-02-03
|
||||
* Major Enhancements
|
||||
* Switch to Jeweler for packaging tasks
|
||||
* Minor Enhancements
|
||||
* Type importer [github.com/codeslinger]
|
||||
* site.topics accessor [github.com/baz]
|
||||
* Add array_to_sentence_string filter [github.com/mchung]
|
||||
* Add a converter for textpattern [github.com/PerfectlyNormal]
|
||||
* Add a working Mephisto / MySQL converter [github.com/ivey]
|
||||
* Allowing .htaccess files to be copied over into the generated site
|
||||
[github.com/briandoll]
|
||||
* Add option to not put file date in permalink URL [github.com/mreid]
|
||||
* Add line number capabilities to highlight blocks [github.com/jcon]
|
||||
* Bug Fixes
|
||||
* Fix permalink behavior [github.com/cavalle]
|
||||
* Fixed an issue with pygments, markdown, and newlines
|
||||
[github.com/zpinter]
|
||||
* Ampersands need to be escaped [github.com/pufuwozu, github.com/ap]
|
||||
* Test and fix the site.categories hash [github.com/zzot]
|
||||
* Fix site payload available to files [github.com/matrix9180]
|
||||
|
||||
== 0.3.0 / 2008-12-24
|
||||
* Major Enhancements
|
||||
* Added --server option to start a simple WEBrick server on destination
|
||||
directory [github.com/johnreilly and github.com/mchung]
|
||||
* Minor Enhancements
|
||||
* Added post categories based on directories containing _posts
|
||||
[github.com/mreid]
|
||||
* Added post topics based on directories underneath _posts
|
||||
* Added new date filter that shows the full month name [github.com/mreid]
|
||||
* Merge Post's YAML front matter into its to_liquid payload
|
||||
[github.com/remi]
|
||||
* Restrict includes to regular files underneath _includes
|
||||
* Bug Fixes
|
||||
* Change YAML delimiter matcher so as to not chew up 2nd level markdown
|
||||
headers [github.com/mreid]
|
||||
* Fix bug that meant page data (such as the date) was not available in
|
||||
templates [github.com/mreid]
|
||||
* Properly reject directories in _layouts
|
||||
|
||||
== 0.2.1 / 2008-12-15
|
||||
* Major Changes
|
||||
* Use Maruku (pure Ruby) for Markdown by default [github.com/mreid]
|
||||
* Allow use of RDiscount with --rdiscount flag
|
||||
* Minor Enhancements
|
||||
* Don't load directory_watcher unless it's needed [github.com/pjhyett]
|
||||
|
||||
== 0.2.0 / 2008-12-14
|
||||
* Major Changes
|
||||
* related_posts is now found in site.related_posts
|
||||
|
||||
== 0.1.6 / 2008-12-13
|
||||
* Major Features
|
||||
* Include files in _includes with {% include x.textile %}
|
||||
|
||||
== 0.1.5 / 2008-12-12
|
||||
* Major Features
|
||||
* Code highlighting with Pygments if --pygments is specified
|
||||
* Disable true LSI by default, enable with --lsi
|
||||
* Minor Enhancements
|
||||
* Output informative message if RDiscount is not available
|
||||
[github.com/JackDanger]
|
||||
* Bug Fixes
|
||||
* Prevent Jekyll from picking up the output directory as a source
|
||||
[github.com/JackDanger]
|
||||
* Skip related_posts when there is only one post [github.com/JackDanger]
|
||||
|
||||
== 0.1.4 / 2008-12-08
|
||||
* Bug Fixes
|
||||
* DATA does not work properly with rubygems
|
||||
|
||||
== 0.1.3 / 2008-12-06
|
||||
* Major Features
|
||||
* Markdown support [github.com/vanpelt]
|
||||
* Mephisto and CSV converters [github.com/vanpelt]
|
||||
* Code hilighting [github.com/vanpelt]
|
||||
* Autobuild
|
||||
* Bug Fixes
|
||||
* Accept both \r\n and \n in YAML header [github.com/vanpelt]
|
||||
|
||||
== 0.1.2 / 2008-11-22
|
||||
* Major Features
|
||||
* Add a real "related posts" implementation using Classifier
|
||||
* Command Line Changes
|
||||
* Allow cli to be called with 0, 1, or 2 args intuiting dir paths
|
||||
if they are omitted
|
||||
|
||||
== 0.1.1 / 2008-11-22
|
||||
* Minor Additions
|
||||
* Posts now support introspectional data e.g. {{ page.url }}
|
||||
|
||||
== 0.1.0 / 2008-11-05
|
||||
* First release
|
||||
* Converts posts written in Textile
|
||||
* Converts regular site pages
|
||||
* Simple copy of binary files
|
||||
|
||||
== 0.0.0 / 2008-10-19
|
||||
* Birthday!
|
||||
|
||||
@@ -1,45 +1,40 @@
|
||||
h1. Jekyll
|
||||
|
||||
!https://travis-ci.org/mojombo/jekyll.png?branch=master!:https://travis-ci.org/mojombo/jekyll
|
||||
"!https://codeclimate.com/github/mojombo/jekyll.png!":https://codeclimate.com/github/mojombo/jekyll
|
||||
|
||||
By Tom Preston-Werner, Nick Quaranto, and many awesome contributors!
|
||||
|
||||
Jekyll is a simple, blog aware, static site generator. It takes a template directory (representing the raw form of a website), runs it through Textile or Markdown and Liquid converters, and spits out a complete, static website suitable for serving with Apache or your favorite web server. This is also the engine behind "GitHub Pages":http://pages.github.com, which you can use to host your project's page or blog right here from GitHub.
|
||||
|
||||
h2. Getting Started
|
||||
|
||||
* "Install":http://jekyllrb.com/docs/installation/ the gem
|
||||
* Read up about its "Usage":http://jekyllrb.com/docs/usage/ and "Configuration":http://jekyllrb.com/docs/configuration/
|
||||
* "Install":http://wiki.github.com/mojombo/jekyll/install the gem
|
||||
* Read up about its "Usage":http://wiki.github.com/mojombo/jekyll/usage and "Configuration":http://wiki.github.com/mojombo/jekyll/configuration
|
||||
* Take a gander at some existing "Sites":http://wiki.github.com/mojombo/jekyll/sites
|
||||
* Fork and "Contribute":https://github.com/mojombo/jekyll/blob/master/CONTRIBUTING.md your own modifications
|
||||
* Fork and "Contribute":http://wiki.github.com/mojombo/jekyll/contribute your own modifications
|
||||
* Have questions? Post them on the "Mailing List":http://groups.google.com/group/jekyll-rb
|
||||
|
||||
h2. Diving In
|
||||
|
||||
* "Migrate":http://jekyllrb.com/docs/migrations/ from your previous system
|
||||
* Learn how the "YAML Front Matter":http://jekyllrb.com/docs/frontmatter/ works
|
||||
* Put information on your site with "Variables":http://jekyllrb.com/docs/variables/
|
||||
* Customize the "Permalinks":http://jekyllrb.com/docs/permalinks/ your posts are generated with
|
||||
* Use the built-in "Liquid Extensions":http://jekyllrb.com/docs/templates/ to make your life easier
|
||||
* Use custom "Plugins":http://jekyllrb.com/docs/plugins/ to generate content specific to your site
|
||||
* "Migrate":http://wiki.github.com/mojombo/jekyll/blog-migrations from your previous system
|
||||
* Learn how the "YAML Front Matter":http://wiki.github.com/mojombo/jekyll/yaml-front-matter works
|
||||
* Put information on your site with "Template Data":http://wiki.github.com/mojombo/jekyll/template-data
|
||||
* Customize the "Permalinks":http://wiki.github.com/mojombo/jekyll/permalinks your posts are generated with
|
||||
* Use the built-in "Liquid Extensions":http://wiki.github.com/mojombo/jekyll/liquid-extensions to make your life easier
|
||||
|
||||
h2. Runtime Dependencies
|
||||
|
||||
* Classifier: Generating related posts (Ruby)
|
||||
* Directory Watcher: Auto-regeneration of sites (Ruby)
|
||||
* Kramdown: Markdown-superset converter (Ruby)
|
||||
* RedCloth: Textile support (Ruby)
|
||||
* Liquid: Templating system (Ruby)
|
||||
* Classifier: Generating related posts (Ruby)
|
||||
* Maruku: Default markdown engine (Ruby)
|
||||
* Directory Watcher: Auto-regeneration of sites (Ruby)
|
||||
* Pygments: Syntax highlighting (Python)
|
||||
|
||||
h2. Developer Dependencies
|
||||
|
||||
* RDiscount: Discount Markdown Processor (Ruby)
|
||||
* RedCloth: Textile support (Ruby)
|
||||
* RedGreen: Nicer test output (Ruby)
|
||||
* RR: Mocking (Ruby)
|
||||
* Shoulda: Test framework (Ruby)
|
||||
* RR: Mocking (Ruby)
|
||||
* RedGreen: Nicer test output (Ruby)
|
||||
|
||||
h2. License
|
||||
|
||||
See "LICENSE":https://github.com/mojombo/jekyll/blob/master/LICENSE.
|
||||
See LICENSE.
|
||||
|
||||
107
Rakefile
107
Rakefile
@@ -1,10 +1,7 @@
|
||||
require 'rubygems'
|
||||
require 'rake'
|
||||
require 'rdoc'
|
||||
require 'date'
|
||||
|
||||
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), *%w[lib]))
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# Helper functions
|
||||
@@ -55,7 +52,15 @@ Rake::TestTask.new(:test) do |test|
|
||||
test.verbose = true
|
||||
end
|
||||
|
||||
require 'rdoc/task'
|
||||
desc "Generate RCov test coverage and open in your browser"
|
||||
task :coverage do
|
||||
require 'rcov'
|
||||
sh "rm -fr coverage"
|
||||
sh "rcov test/test_*.rb"
|
||||
sh "open coverage/index.html"
|
||||
end
|
||||
|
||||
require 'rake/rdoctask'
|
||||
Rake::RDocTask.new do |rdoc|
|
||||
rdoc.rdoc_dir = 'rdoc'
|
||||
rdoc.title = "#{name} #{version}"
|
||||
@@ -63,21 +68,6 @@ Rake::RDocTask.new do |rdoc|
|
||||
rdoc.rdoc_files.include('lib/**/*.rb')
|
||||
end
|
||||
|
||||
begin
|
||||
require 'cucumber/rake/task'
|
||||
Cucumber::Rake::Task.new(:features) do |t|
|
||||
t.profile = "travis"
|
||||
end
|
||||
Cucumber::Rake::Task.new(:"features:html", "Run Cucumber features and produce HTML output") do |t|
|
||||
t.profile = "html_report"
|
||||
end
|
||||
rescue LoadError
|
||||
desc 'Cucumber rake task not available'
|
||||
task :features do
|
||||
abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
|
||||
end
|
||||
end
|
||||
|
||||
desc "Open an irb session preloaded with this library"
|
||||
task :console do
|
||||
sh "irb -rubygems -r ./lib/#{name}.rb"
|
||||
@@ -85,63 +75,34 @@ end
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
# Site tasks - http://jekyllrb.com
|
||||
# Custom tasks (add your own tasks here)
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
namespace :site do
|
||||
desc "Generate and view the site locally"
|
||||
task :preview do
|
||||
require "launchy"
|
||||
|
||||
# Yep, it's a hack! Wait a few seconds for the Jekyll site to generate and
|
||||
# then open it in a browser. Someday we can do better than this, I hope.
|
||||
Thread.new do
|
||||
sleep 4
|
||||
puts "Opening in browser..."
|
||||
Launchy.open("http://localhost:4000")
|
||||
end
|
||||
|
||||
# Generate the site in server mode.
|
||||
puts "Running Jekyll..."
|
||||
Dir.chdir("site") do
|
||||
sh "#{File.expand_path('bin/jekyll', File.dirname(__FILE__))} serve --watch"
|
||||
end
|
||||
namespace :migrate do
|
||||
desc "Migrate from mephisto in the current directory"
|
||||
task :mephisto do
|
||||
sh %q(ruby -r './lib/jekyll/migrators/mephisto' -e 'Jekyll::Mephisto.postgres(:database => "#{ENV["DB"]}")')
|
||||
end
|
||||
desc "Migrate from Movable Type in the current directory"
|
||||
task :mt do
|
||||
sh %q(ruby -r './lib/jekyll/migrators/mt' -e 'Jekyll::MT.process("#{ENV["DB"]}", "#{ENV["USER"]}", "#{ENV["PASS"]}")')
|
||||
end
|
||||
desc "Migrate from Typo in the current directory"
|
||||
task :typo do
|
||||
sh %q(ruby -r './lib/jekyll/migrators/typo' -e 'Jekyll::Typo.process("#{ENV["DB"]}", "#{ENV["USER"]}", "#{ENV["PASS"]}")')
|
||||
end
|
||||
end
|
||||
|
||||
desc "Commit the local site to the gh-pages branch and publish to GitHub Pages"
|
||||
task :publish 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:mojombo/jekyll gh-pages"
|
||||
puts " `cd gh-pages"
|
||||
puts " `git checkout gh-pages`"
|
||||
exit(1)
|
||||
end
|
||||
|
||||
# Ensure gh-pages branch is up to date.
|
||||
Dir.chdir('gh-pages') do
|
||||
sh "git pull origin gh-pages"
|
||||
end
|
||||
|
||||
# Copy to gh-pages dir.
|
||||
puts "Copying site to gh-pages branch..."
|
||||
Dir.glob("site/*") do |path|
|
||||
next if path == "_site"
|
||||
sh "cp -R #{path} gh-pages/"
|
||||
end
|
||||
|
||||
# Commit and push.
|
||||
puts "Committing and pushing to GitHub Pages..."
|
||||
sha = `git log`.match(/[a-z0-9]{40}/)[0]
|
||||
Dir.chdir('gh-pages') do
|
||||
sh "git add ."
|
||||
sh "git commit -m 'Updating to #{sha}.'"
|
||||
sh "git push origin gh-pages"
|
||||
end
|
||||
puts 'Done.'
|
||||
begin
|
||||
require 'cucumber/rake/task'
|
||||
Cucumber::Rake::Task.new(:features) do |t|
|
||||
t.cucumber_opts = "--format progress"
|
||||
end
|
||||
rescue LoadError
|
||||
desc 'Cucumber rake task not available'
|
||||
task :features do
|
||||
abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -156,7 +117,7 @@ task :release => :build do
|
||||
puts "You must be on the master branch to release!"
|
||||
exit!
|
||||
end
|
||||
sh "git commit --allow-empty -m 'Release #{version}'"
|
||||
sh "git commit --allow-empty -a -m 'Release #{version}'"
|
||||
sh "git tag v#{version}"
|
||||
sh "git push origin master"
|
||||
sh "git push origin v#{version}"
|
||||
@@ -195,4 +156,4 @@ task :gemspec do
|
||||
spec = [head, manifest, tail].join(" # = MANIFEST =\n")
|
||||
File.open(gemspec_file, 'w') { |io| io.write(spec) }
|
||||
puts "Updated #{gemspec_file}"
|
||||
end
|
||||
end
|
||||
363
bin/jekyll
363
bin/jekyll
@@ -1,125 +1,276 @@
|
||||
#!/usr/bin/env ruby
|
||||
STDOUT.sync = true
|
||||
|
||||
$:.unshift File.join(File.dirname(__FILE__), *%w{ .. lib })
|
||||
$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
|
||||
|
||||
require 'commander/import'
|
||||
help = <<HELP
|
||||
Jekyll is a blog-aware, static site generator.
|
||||
|
||||
Basic Command Line Usage:
|
||||
jekyll # . -> ./_site
|
||||
jekyll <path to write generated site> # . -> <path>
|
||||
jekyll <path to source> <path to write generated site> # <path> -> <path>
|
||||
jekyll import <importer name> <options> # imports posts using named import script
|
||||
|
||||
Configuration is read from '<source>/_config.yml' but can be overriden
|
||||
using the following options:
|
||||
|
||||
HELP
|
||||
|
||||
require 'optparse'
|
||||
require 'jekyll'
|
||||
|
||||
Jekyll::Deprecator.process(ARGV)
|
||||
|
||||
program :name, 'jekyll'
|
||||
program :version, Jekyll::VERSION
|
||||
program :description, 'Jekyll is a blog-aware, static site generator in Ruby'
|
||||
exec = {}
|
||||
options = {}
|
||||
opts = OptionParser.new do |opts|
|
||||
opts.banner = help
|
||||
|
||||
default_command :help
|
||||
|
||||
global_option '-s', '--source [DIR]', 'Source directory (defaults to ./)'
|
||||
global_option '-d', '--destination [DIR]', 'Destination directory (defaults to ./_site)'
|
||||
global_option '--safe', 'Safe mode (defaults to false)'
|
||||
global_option '--plugins PLUGINS_DIR1[,PLUGINS_DIR2[,...]]', Array, 'Plugins directory (defaults to ./_plugins)'
|
||||
global_option '--layouts', 'Layouts directory (defaults to ./_layouts)'
|
||||
|
||||
# Option names don't always directly match the configuration value we'd like.
|
||||
# This method will rename options to match what Jekyll configuration expects.
|
||||
#
|
||||
# options - The Hash of options from Commander.
|
||||
#
|
||||
# Returns the normalized Hash.
|
||||
def normalize_options(options)
|
||||
if drafts_state = options.delete(:drafts)
|
||||
options[:show_drafts] = drafts_state
|
||||
opts.on("--file [PATH]", "File to import from") do |import_file|
|
||||
options['file'] = import_file
|
||||
end
|
||||
options
|
||||
end
|
||||
|
||||
command :new do |c|
|
||||
c.syntax = 'jekyll new PATH'
|
||||
c.description = 'Creates a new Jekyll site scaffold in PATH'
|
||||
|
||||
c.action do |args, options|
|
||||
Jekyll::Commands::New.process(args)
|
||||
|
||||
opts.on("--dbname [TEXT]", "DB to import from") do |import_dbname|
|
||||
options['dbname'] = import_dbname
|
||||
end
|
||||
end
|
||||
|
||||
command :build do |c|
|
||||
c.syntax = 'jekyll build [options]'
|
||||
c.description = 'Build your site'
|
||||
|
||||
c.option '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
|
||||
c.option '--future', 'Publishes posts with a future date'
|
||||
c.option '--limit_posts MAX_POSTS', Integer, 'Limits the number of posts to parse and publish'
|
||||
c.option '-w', '--watch', 'Watch for changes and rebuild'
|
||||
c.option '--lsi', 'Use LSI for improved related posts'
|
||||
c.option '--drafts', 'Render posts in the _drafts folder'
|
||||
|
||||
c.action do |args, options|
|
||||
options = normalize_options(options.__hash__)
|
||||
options = Jekyll.configuration(options)
|
||||
Jekyll::Commands::Build.process(options)
|
||||
|
||||
opts.on("--user [TEXT]", "Username to use when importing") do |import_user|
|
||||
options['user'] = import_user
|
||||
end
|
||||
end
|
||||
|
||||
command :serve do |c|
|
||||
c.syntax = 'jekyll serve [options]'
|
||||
c.description = 'Serve your site locally'
|
||||
|
||||
c.option '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
|
||||
c.option '--future', 'Publishes posts with a future date'
|
||||
c.option '--limit_posts MAX_POSTS', Integer, 'Limits the number of posts to parse and publish'
|
||||
c.option '-w', '--watch', 'Watch for changes and rebuild'
|
||||
c.option '--lsi', 'Use LSI for improved related posts'
|
||||
c.option '--drafts', 'Render posts in the _drafts folder'
|
||||
|
||||
c.option '-p', '--port [PORT]', 'Port to listen on'
|
||||
c.option '-h', '--host [HOST]', 'Host to bind to'
|
||||
c.option '-b', '--baseurl [URL]', 'Base URL'
|
||||
|
||||
c.action do |args, options|
|
||||
options.default :serving => true
|
||||
|
||||
options = normalize_options(options.__hash__)
|
||||
options = Jekyll.configuration(options)
|
||||
Jekyll::Commands::Build.process(options)
|
||||
Jekyll::Commands::Serve.process(options)
|
||||
|
||||
opts.on("--pass [TEXT]", "Password to use when importing") do |import_pass|
|
||||
options['pass'] = import_pass
|
||||
end
|
||||
end
|
||||
alias_command :server, :serve
|
||||
|
||||
command :doctor do |c|
|
||||
c.syntax = 'jekyll doctor'
|
||||
c.description = 'Search site and print specific deprecation warnings'
|
||||
|
||||
c.option '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
|
||||
|
||||
c.action do |args, options|
|
||||
options = normalize_options(options.__hash__)
|
||||
options = Jekyll.configuration(options)
|
||||
Jekyll::Commands::Doctor.process(options)
|
||||
|
||||
opts.on("--host [HOST ADDRESS]", "Host to import from") do |import_host|
|
||||
options['host'] = import_host
|
||||
end
|
||||
end
|
||||
alias_command :hyde, :doctor
|
||||
|
||||
opts.on("--site [SITE NAME]", "Site to import from") do |import_site|
|
||||
options['site'] = import_site
|
||||
end
|
||||
|
||||
|
||||
command :import do |c|
|
||||
c.syntax = 'jekyll import <platform> [options]'
|
||||
c.description = 'Import your old blog to Jekyll'
|
||||
opts.on("--[no-]safe", "Safe mode (default unsafe)") do |safe|
|
||||
options['safe'] = safe
|
||||
end
|
||||
|
||||
c.option '--source STRING', 'Source file or URL to migrate from'
|
||||
c.option '--file STRING', 'File to migrate from'
|
||||
c.option '--dbname STRING', 'Database name to migrate from'
|
||||
c.option '--user STRING', 'Username to use when migrating'
|
||||
c.option '--pass STRING', 'Password to use when migrating'
|
||||
c.option '--host STRING', 'Host address to use when migrating'
|
||||
opts.on("--[no-]auto", "Auto-regenerate") do |auto|
|
||||
options['auto'] = auto
|
||||
end
|
||||
|
||||
c.action do |args, options|
|
||||
opts.on("--server [PORT]", "Start web server (default port 4000)") do |port|
|
||||
options['server'] = true
|
||||
options['server_port'] = port unless port.nil?
|
||||
end
|
||||
|
||||
opts.on("--no-server", "Do not start a web server") do |part|
|
||||
options['server'] = false
|
||||
end
|
||||
|
||||
opts.on("--base-url [BASE_URL]", "Serve website from a given base URL (default '/'") do |baseurl|
|
||||
options['baseurl'] = baseurl
|
||||
end
|
||||
|
||||
opts.on("--[no-]lsi", "Use LSI for better related posts") do |lsi|
|
||||
options['lsi'] = lsi
|
||||
end
|
||||
|
||||
opts.on("--[no-]pygments", "Use pygments to highlight code") do |pygments|
|
||||
options['pygments'] = pygments
|
||||
end
|
||||
|
||||
opts.on("--rdiscount", "Use rdiscount gem for Markdown") do
|
||||
options['markdown'] = 'rdiscount'
|
||||
end
|
||||
|
||||
opts.on("--kramdown", "Use kramdown gem for Markdown") do
|
||||
options['markdown'] = 'kramdown'
|
||||
end
|
||||
|
||||
opts.on("--time [TIME]", "Time to generate the site for") do |time|
|
||||
options['time'] = Time.parse(time)
|
||||
end
|
||||
|
||||
opts.on("--[no-]future", "Render future dated posts") do |future|
|
||||
options['future'] = future
|
||||
end
|
||||
|
||||
opts.on("--permalink [TYPE]", "Use 'date' (default) for YYYY/MM/DD") do |style|
|
||||
options['permalink'] = style unless style.nil?
|
||||
end
|
||||
|
||||
opts.on("--paginate [POSTS_PER_PAGE]", "Paginate a blog's posts") do |per_page|
|
||||
begin
|
||||
require 'jekyll-import'
|
||||
rescue LoadError
|
||||
msg = "You must install the 'jekyll-import' gem before continuing.\n"
|
||||
msg += "* Do this by running `gem install jekyll-import`.\n"
|
||||
msg += "* Or if you need root privileges, run `sudo gem install jekyll-import`."
|
||||
abort msg
|
||||
options['paginate'] = per_page.to_i
|
||||
raise ArgumentError if options['paginate'] == 0
|
||||
rescue
|
||||
puts 'you must specify a number of posts by page bigger than 0'
|
||||
exit 0
|
||||
end
|
||||
Jekyll::Commands::Import.process(args.first, options)
|
||||
end
|
||||
|
||||
opts.on("--limit_posts [MAX_POSTS]", "Limit the number of posts to publish") do |limit_posts|
|
||||
begin
|
||||
options['limit_posts'] = limit_posts.to_i
|
||||
raise ArgumentError if options['limit_posts'] < 1
|
||||
rescue
|
||||
puts 'you must specify a number of posts by page bigger than 0'
|
||||
exit 0
|
||||
end
|
||||
end
|
||||
|
||||
opts.on("--url [URL]", "Set custom site.url") do |url|
|
||||
options['url'] = url
|
||||
end
|
||||
|
||||
opts.on("--version", "Display current version") do
|
||||
puts "Jekyll " + Jekyll::VERSION
|
||||
exit 0
|
||||
end
|
||||
end
|
||||
|
||||
# Read command line options into `options` hash
|
||||
opts.parse!
|
||||
|
||||
|
||||
# Check for import stuff
|
||||
if ARGV.size > 0
|
||||
if ARGV[0] == 'import'
|
||||
migrator = ARGV[1]
|
||||
|
||||
if migrator.nil?
|
||||
puts "Invalid options. Run `jekyll --help` for assistance."
|
||||
exit(1)
|
||||
else
|
||||
migrator = migrator.downcase
|
||||
end
|
||||
|
||||
cmd_options = []
|
||||
['file', 'dbname', 'user', 'pass', 'host', 'site'].each do |p|
|
||||
cmd_options << "\"#{options[p]}\"" unless options[p].nil?
|
||||
end
|
||||
|
||||
# It's import time
|
||||
puts "Importing..."
|
||||
|
||||
# Ideally, this shouldn't be necessary. Maybe parse the actual
|
||||
# src files for the migrator name?
|
||||
migrators = {
|
||||
:posterous => 'Posterous',
|
||||
:wordpressdotcom => 'WordpressDotCom',
|
||||
:wordpress => 'Wordpress',
|
||||
:csv => 'CSV',
|
||||
:drupal => 'Drupal',
|
||||
:mephisto => 'Mephisto',
|
||||
:mt => 'MT',
|
||||
:textpattern => 'TextPattern',
|
||||
:typo => 'Typo'
|
||||
}
|
||||
|
||||
app_root = File.join(File.dirname(__FILE__), '..')
|
||||
|
||||
require "#{app_root}/lib/jekyll/migrators/#{migrator}"
|
||||
|
||||
if Jekyll.const_defined?(migrators[migrator.to_sym])
|
||||
migrator_class = Jekyll.const_get(migrators[migrator.to_sym])
|
||||
migrator_class.process(*cmd_options)
|
||||
else
|
||||
puts "Invalid migrator. Run `jekyll --help` for assistance."
|
||||
exit(1)
|
||||
end
|
||||
|
||||
exit(0)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
# Get source and destintation from command line
|
||||
case ARGV.size
|
||||
when 0
|
||||
when 1
|
||||
options['destination'] = ARGV[0]
|
||||
when 2
|
||||
options['source'] = ARGV[0]
|
||||
options['destination'] = ARGV[1]
|
||||
else
|
||||
puts "Invalid options. Run `jekyll --help` for assistance."
|
||||
exit(1)
|
||||
end
|
||||
|
||||
options = Jekyll.configuration(options)
|
||||
|
||||
# Get source and destination directories (possibly set by config file)
|
||||
source = options['source']
|
||||
destination = options['destination']
|
||||
|
||||
# Files to watch
|
||||
def globs(source)
|
||||
Dir.chdir(source) do
|
||||
dirs = Dir['*'].select { |x| File.directory?(x) }
|
||||
dirs -= ['_site']
|
||||
dirs = dirs.map { |x| "#{x}/**/*" }
|
||||
dirs += ['*']
|
||||
end
|
||||
end
|
||||
|
||||
# Create the Site
|
||||
site = Jekyll::Site.new(options)
|
||||
|
||||
# Run the directory watcher for auto-generation, if required
|
||||
if options['auto']
|
||||
require 'directory_watcher'
|
||||
|
||||
puts "Auto-regenerating enabled: #{source} -> #{destination}"
|
||||
|
||||
dw = DirectoryWatcher.new(source)
|
||||
dw.interval = 1
|
||||
dw.glob = globs(source)
|
||||
|
||||
dw.add_observer do |*args|
|
||||
t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
||||
puts "[#{t}] regeneration: #{args.size} files changed"
|
||||
site.process
|
||||
end
|
||||
|
||||
dw.start
|
||||
|
||||
unless options['server']
|
||||
loop { sleep 1000 }
|
||||
end
|
||||
else
|
||||
puts "Building site: #{source} -> #{destination}"
|
||||
begin
|
||||
site.process
|
||||
rescue Jekyll::FatalException => e
|
||||
puts
|
||||
puts "ERROR: YOUR SITE COULD NOT BE BUILT:"
|
||||
puts "------------------------------------"
|
||||
puts e.message
|
||||
exit(1)
|
||||
end
|
||||
puts "Successfully generated site: #{source} -> #{destination}"
|
||||
end
|
||||
|
||||
# Run the server on the specified port, if required
|
||||
if options['server']
|
||||
require 'webrick'
|
||||
include WEBrick
|
||||
|
||||
FileUtils.mkdir_p(destination)
|
||||
|
||||
mime_types = WEBrick::HTTPUtils::DefaultMimeTypes
|
||||
mime_types.store 'js', 'application/javascript'
|
||||
|
||||
s = HTTPServer.new(
|
||||
:Port => options['server_port'],
|
||||
:MimeTypes => mime_types
|
||||
)
|
||||
s.mount(options['baseurl'], HTTPServlet::FileHandler, destination)
|
||||
t = Thread.new {
|
||||
s.start
|
||||
}
|
||||
|
||||
trap("INT") { s.shutdown }
|
||||
t.join()
|
||||
end
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
default: --format pretty
|
||||
travis: --format progress
|
||||
html_report: --format progress --format html --out=features_report.html
|
||||
default: --format progress
|
||||
1
doc/.gitignore
vendored
Normal file
1
doc/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
output
|
||||
7
doc/.gitscribe
Normal file
7
doc/.gitscribe
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
publish: true
|
||||
edition: 0.1
|
||||
language: en
|
||||
version: 1.0
|
||||
author: Your Name
|
||||
cover: image/cover.jpg
|
||||
9
doc/README.asciidoc
Normal file
9
doc/README.asciidoc
Normal file
@@ -0,0 +1,9 @@
|
||||
This Book
|
||||
=========
|
||||
|
||||
This book is written using using the git-scribe toolchain, which can be found at:
|
||||
|
||||
http://github.com/schacon/git-scribe
|
||||
|
||||
Instructions on how to install the tool and use it for things like editing this book,
|
||||
submitting errata and providing translations can be found at that site.
|
||||
10
doc/book/book.asc
Normal file
10
doc/book/book.asc
Normal file
@@ -0,0 +1,10 @@
|
||||
Jekyll
|
||||
======
|
||||
:Author: Tom Preston-Werner
|
||||
:Email: <tom@mojombo.com>
|
||||
|
||||
include::ch00-preface.asc[]
|
||||
|
||||
include::ch01-quick-start.asc[]
|
||||
|
||||
include::ch02-directory-layout.asc[]
|
||||
41
doc/book/ch00-preface.asc
Normal file
41
doc/book/ch00-preface.asc
Normal file
@@ -0,0 +1,41 @@
|
||||
== Preface
|
||||
|
||||
Jekyll was born out the desire to create a blog engine that would make it
|
||||
possible to write posts in my local text editor, version those posts with Git,
|
||||
and keep up with my desire to tweak the styles and layout of my site.
|
||||
|
||||
In other words, I wanted something that fit into my existing software
|
||||
development workflow and toolchain. Jekyll handles not only this case, but a
|
||||
wide variety of other situations that call for static site generation based on
|
||||
converted content and layout templates.
|
||||
|
||||
At its core, Jekyll is a text transformation engine. The concept behind the
|
||||
system is this: you give it text written in your favorite markup language, be
|
||||
that Markdown, Textile, or just plain HTML, and it churns that through a
|
||||
layout or series of layout files. Throughout that process you can tweak how
|
||||
you want the site URLs to look, what data gets displayed on the layout and
|
||||
much more.
|
||||
|
||||
If you're looking for a simple, yet powerful solution to your blogging or
|
||||
static site needs, Jekyll may be just what you've been looking for.
|
||||
|
||||
|
||||
=== What this book covers
|
||||
|
||||
_Chapter 1, Quick Start_ covers installation, introduces the Jekyll command
|
||||
line interface, and runs through a quick example demonstrating the site
|
||||
generator, post generator and how to convert your Jekyll site into a static
|
||||
site.
|
||||
|
||||
_Chapter 2, Directory Layout_ covers the various files and directories that
|
||||
comprise a Jekyll site.
|
||||
|
||||
_Chapter 3, Tags and Filters_
|
||||
|
||||
_Chapter X, Deploying your Jekyll Site_
|
||||
|
||||
_Chapter X, Customizing Jekyll with Plugins_
|
||||
|
||||
_Chapter X, Migrating to Jekyll from your Existing Blog_
|
||||
|
||||
_Chapter X, Configuration Reference_
|
||||
153
doc/book/ch01-quick-start.asc
Normal file
153
doc/book/ch01-quick-start.asc
Normal file
@@ -0,0 +1,153 @@
|
||||
== Chapter 1: Quick Start
|
||||
|
||||
This chapter is designed to get you up and running with Jekyll as quickly as
|
||||
possible.
|
||||
|
||||
|
||||
=== Installation
|
||||
|
||||
The best way to install Jekyll is via RubyGems:
|
||||
|
||||
----
|
||||
gem install jekyll
|
||||
----
|
||||
|
||||
This is all you need in order to get started with a basic Jekyll site. Some
|
||||
options require additional packages to be installed.
|
||||
|
||||
If you encounter errors during gem installation, you may need to install the
|
||||
header files for compiling extension modules for ruby 1.8:
|
||||
|
||||
.Debian
|
||||
----
|
||||
sudo apt-get install ruby1.8-dev
|
||||
----
|
||||
|
||||
.Red Hat / CentOS / Fedora systems
|
||||
----
|
||||
sudo yum install ruby-devel
|
||||
----
|
||||
|
||||
.NearlyFreeSpeech
|
||||
----
|
||||
RB_USER_INSTALL=true gem install jekyll
|
||||
----
|
||||
|
||||
If you encounter errors like +Failed to build gem native extension+ on Windows
|
||||
you may need to install http://wiki.github.com/oneclick/rubyinstaller/development-kit[RubyInstaller
|
||||
DevKit].
|
||||
|
||||
==== LaTeX to PNG
|
||||
|
||||
Maruku comes with optional support for LaTeX to PNG rendering via blahtex
|
||||
(Version 0.6) which must be in your $PATH along with @dvips@.
|
||||
|
||||
(NOTE: "remi's fork of Maruku":http://github.com/remi/maruku/tree/master does
|
||||
not assume a fixed location for @dvips@ if you need that fixed)
|
||||
|
||||
==== RDiscount
|
||||
|
||||
If you prefer to use
|
||||
http://github.com/rtomayko/rdiscount/tree/master[RDiscount] instead of
|
||||
http://maruku.rubyforge.org/[Maruku] for markdown, just make sure it's
|
||||
installed:
|
||||
|
||||
----
|
||||
sudo gem install rdiscount
|
||||
----
|
||||
|
||||
And run Jekyll with the following option:
|
||||
|
||||
----
|
||||
jekyll --rdiscount
|
||||
----
|
||||
|
||||
Or, in your @_config.yml@ file put the following so you don't have to specify the flag:
|
||||
|
||||
----
|
||||
markdown: rdiscount
|
||||
----
|
||||
|
||||
==== Pygments
|
||||
|
||||
If you want syntax highlighting via the @{% highlight %}@ tag in your posts,
|
||||
you'll need to install http://pygments.org/[Pygments].
|
||||
|
||||
.On OSX with Homebrew
|
||||
----
|
||||
brew install pip && pip install pygments
|
||||
----
|
||||
|
||||
.On OSX with MacPorts
|
||||
----
|
||||
sudo port install python25 py25-pygments
|
||||
----
|
||||
|
||||
.Bare OS X Leopard
|
||||
----
|
||||
sudo easy_install Pygments
|
||||
----
|
||||
|
||||
.Archlinux
|
||||
----
|
||||
sudo pacman -S python-pygments
|
||||
----
|
||||
|
||||
.Archlinux python2 for Pygments
|
||||
----
|
||||
$ sudo pacman -S python2-pygments
|
||||
----
|
||||
|
||||
NOTE: python2 pygments version creates a `pygmentize2` executable, while
|
||||
Jekyll tries to find `pygmentize`. Either create a symlink `# ln -s
|
||||
/usr/bin/pygmentize2 /usr/bin/pygmentize` or use the python3 version.
|
||||
|
||||
.Ubuntu and Debian
|
||||
----
|
||||
sudo apt-get install python-pygments
|
||||
----
|
||||
|
||||
.Gentoo
|
||||
----
|
||||
$ sudo emerge -av dev-python/pygments
|
||||
----
|
||||
|
||||
|
||||
=== Creating your First Site
|
||||
|
||||
Jekyll comes with a handy generator that will create a barebones skeleton site
|
||||
to help you get up and running in no time. Simply create an empty directory to
|
||||
contain your site, navigate to it, and run the generator command:
|
||||
|
||||
----
|
||||
$ mkdir mysite
|
||||
$ cd mysite
|
||||
$ jekyll gen
|
||||
----
|
||||
|
||||
Make sure the directory is empty or Jekyll will refuse to run. If everything
|
||||
was successful, you'll be left with a complete, valid Jekyll site that's ready
|
||||
to be converted into a static site.
|
||||
|
||||
To perform the conversion, make sure you're in the root of your Jekyll site
|
||||
directory and run:
|
||||
|
||||
----
|
||||
$ jekyll --server
|
||||
----
|
||||
|
||||
If all goes well, you should get a few lines with information about config
|
||||
file detection, source and destination paths, and a success message.
|
||||
|
||||
The `--server` command line option fires up a simple web server that will
|
||||
serve the static site we just generated so that we can easily preview what it
|
||||
will look like once we deploy it to a production environment.
|
||||
|
||||
Open up your favorite web browser and navigate to:
|
||||
|
||||
----
|
||||
http://localhost:4000
|
||||
----
|
||||
|
||||
Congratulations! You have now successfully created and converted your first
|
||||
Jekyll site!
|
||||
90
doc/book/ch02-directory-layout.asc
Normal file
90
doc/book/ch02-directory-layout.asc
Normal file
@@ -0,0 +1,90 @@
|
||||
== Chapter 2: Directory Layout
|
||||
|
||||
If you followed the Quick Start in the last chapter, you have a Jekyll site on
|
||||
your local machine. Let's take a closer look at it and see what makes it tick.
|
||||
The file layout should look something like this:
|
||||
|
||||
----
|
||||
.
|
||||
|-- _config.yml
|
||||
|-- _layouts
|
||||
| |-- default.html
|
||||
| `-- post.html
|
||||
|-- _posts
|
||||
| |-- 2007-10-29-why-every-programmer-should-play-nethack.textile
|
||||
| `-- 2009-04-26-barcamp-boston-4-roundup.textile
|
||||
|-- _site
|
||||
|-- images
|
||||
| `-- logo.png
|
||||
`-- index.html
|
||||
----
|
||||
|
||||
Notice that some of the files and directories begin with an underscore. These
|
||||
have special meaning to Jekyll. The underscore ensures that they will not
|
||||
interfere with the rest of your site's normal content. It also means that if
|
||||
any of your normal files start with an underscore, they will cause problems,
|
||||
so try to avoid this.
|
||||
|
||||
=== _config.yml
|
||||
|
||||
This file stores configuration data. A majority of these options can be
|
||||
specified from the command line executable but it's easier to throw them in
|
||||
here so you don't have to type them out every time. Detailed explanations of
|
||||
configuration directives can be found in Chapter X.
|
||||
|
||||
=== _layouts
|
||||
|
||||
Files in this directory represent templates that can be used to wrap converted
|
||||
pages. Layouts are defined on a page-by-page basis in the YAML front matter.
|
||||
The liquid tag +{{ content }}+ specifies where the content will be placed
|
||||
during the conversion process.
|
||||
|
||||
=== _posts
|
||||
|
||||
If you're using Jekyll as a blog engine, this is where you'll place your blog
|
||||
posts. A post's filename contains several pieces of data, so you must be very
|
||||
careful about how these files are named. The filename format is:
|
||||
+YEAR-MONTH-DATE-SLUG.MARKUP+. The YEAR must be four numbers and the MONTH and
|
||||
DATE must be two numbers each. The SLUG is what will appear in the URL. The
|
||||
MARKUP tells Jekyll the format of the post. The date and slug will be used
|
||||
along with any permalink options you specify (See Chapter X) to construct the
|
||||
final URL of the post.
|
||||
|
||||
=== _site
|
||||
|
||||
This is where the generated site will be placed (by default) once Jekyll is
|
||||
done transforming it. If you're using version control, you'll want to add this
|
||||
directory to the list of files to be ignored.
|
||||
|
||||
=== Normal Files with YAML Front Matter
|
||||
|
||||
All files outside of the special underscore directories and that do not
|
||||
themselves begin with an underscore will be scanned by Jekyll and subjected to
|
||||
conversion if they contain any YAML front matter.
|
||||
|
||||
=== Everything Else
|
||||
|
||||
Any files and directories that do not fall into one of the above categories
|
||||
will be copied to the static site as-is without modification. In this example,
|
||||
+images/logo.png+ will be copied to the same location in the generated site.
|
||||
|
||||
|
||||
|
||||
|
||||
h2. Running Jekyll
|
||||
|
||||
Usually this is done through the @jekyll@ executable, which is installed with
|
||||
the gem. In order to get a server up and running with your Jekyll site, run:
|
||||
|
||||
@jekyll --server@
|
||||
|
||||
and then browse to http://0.0.0.0:4000. There's plenty of [[configuration
|
||||
options|Configuration]] available to you as well.
|
||||
|
||||
On Debian or Ubuntu, you may need to add @/var/lib/gems/1.8/bin/@ to your path.
|
||||
|
||||
h2. Deployment
|
||||
|
||||
Since Jekyll simply generates a folder filled with HTML files, it can be
|
||||
served using practically any available web server out there. Please check the
|
||||
[[Deployment]] page for more information regarding specific scenarios.
|
||||
@@ -89,24 +89,6 @@ Feature: Create sites
|
||||
And I have an "_includes/about.textile" file that contains "Generated by {% include jekyll.textile %}"
|
||||
And I have an "_includes/jekyll.textile" file that contains "Jekyll"
|
||||
And I have an "index.html" page that contains "Basic Site with include tag: {% include about.textile %}"
|
||||
When I run jekyll
|
||||
When I debug jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "Basic Site with include tag: Generated by Jekyll" in "_site/index.html"
|
||||
|
||||
Scenario: Basic site with internal post linking
|
||||
Given I have an "index.html" page that contains "URL: {% post_url 2020-01-31-entry2 %}"
|
||||
And I have a configuration file with "permalink" set to "pretty"
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 12/31/2007 | post | content for entry1. |
|
||||
| entry2 | 01/31/2020 | post | content for entry2. |
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "URL: /2020/01/31/entry2/" in "_site/index.html"
|
||||
|
||||
Scenario: Basic site with whitelisted dotfile
|
||||
Given I have an ".htaccess" file that contains "SomeDirective"
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "SomeDirective" in "_site/.htaccess"
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
Feature: Draft Posts
|
||||
As a hacker who likes to blog
|
||||
I want to be able to preview drafts locally
|
||||
In order to see if they look alright before publishing
|
||||
|
||||
Scenario: Preview a draft
|
||||
Given I have a configuration file with "permalink" set to "none"
|
||||
And I have a _drafts directory
|
||||
And I have the following draft:
|
||||
| title | date | layout | content |
|
||||
| Recipe | 3/27/2009 | default | Not baked yet. |
|
||||
When I run jekyll with drafts
|
||||
Then the _site directory should exist
|
||||
And I should see "Not baked yet." in "_site/recipe.html"
|
||||
|
||||
Scenario: Don't preview a draft
|
||||
Given I have a configuration file with "permalink" set to "none"
|
||||
And I have an "index.html" page that contains "Totally index"
|
||||
And I have a _drafts directory
|
||||
And I have the following draft:
|
||||
| title | date | layout | content |
|
||||
| Recipe | 3/27/2009 | default | Not baked yet. |
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And the "_site/recipe.html" file should not exist
|
||||
@@ -2,13 +2,13 @@ Feature: Site pagination
|
||||
In order to paginate my blog
|
||||
As a blog's user
|
||||
I want divide the posts in several pages
|
||||
|
||||
|
||||
Scenario Outline: Paginate with N posts per page
|
||||
Given I have a configuration file with "paginate" set to "<num>"
|
||||
And I have a _layouts directory
|
||||
And I have an "index.html" page that contains "{{ paginator.posts.size }}"
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| Wargames | 3/27/2009 | default | The only winning move is not to play. |
|
||||
| Wargames2 | 4/27/2009 | default | The only winning move is not to play2. |
|
||||
@@ -19,36 +19,9 @@ Feature: Site pagination
|
||||
And the "_site/page<exist>/index.html" file should exist
|
||||
And I should see "<posts>" in "_site/page<exist>/index.html"
|
||||
And the "_site/page<not_exist>/index.html" file should not exist
|
||||
|
||||
|
||||
Examples:
|
||||
| num | exist | posts | not_exist |
|
||||
| 1 | 4 | 1 | 5 |
|
||||
| 2 | 2 | 2 | 3 |
|
||||
| 3 | 2 | 1 | 3 |
|
||||
|
||||
Scenario Outline: Setting a custom pagination path
|
||||
Given I have a configuration file with:
|
||||
| key | value |
|
||||
| paginate | 1 |
|
||||
| paginate_path | /blog/page-:num |
|
||||
| permalink | /blog/:year/:month/:day/:title |
|
||||
And I have a blog directory
|
||||
And I have an "blog/index.html" page that contains "{{ paginator.posts.size }}"
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| Wargames | 3/27/2009 | default | The only winning move is not to play. |
|
||||
| Wargames2 | 4/27/2009 | default | The only winning move is not to play2. |
|
||||
| Wargames3 | 5/27/2009 | default | The only winning move is not to play3. |
|
||||
| Wargames4 | 6/27/2009 | default | The only winning move is not to play4. |
|
||||
When I run jekyll
|
||||
Then the _site/blog/page-<exist> directory should exist
|
||||
And the "_site/blog/page-<exist>/index.html" file should exist
|
||||
And I should see "<posts>" in "_site/blog/page-<exist>/index.html"
|
||||
And the "_site/blog/page-<not_exist>/index.html" file should not exist
|
||||
|
||||
Examples:
|
||||
| exist | posts | not_exist |
|
||||
| 2 | 1 | 5 |
|
||||
| 3 | 1 | 6 |
|
||||
| 4 | 1 | 7 |
|
||||
|
||||
@@ -31,10 +31,10 @@ Feature: Post data
|
||||
And I have the following post:
|
||||
| title | date | layout | content |
|
||||
| Star Wars | 3/27/2009 | simple | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post date: {{ page.date | date_to_string }}"
|
||||
And I have a simple layout that contains "Post date: {{ page.date }}"
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "Post date: 27 Mar 2009" in "_site/2009/03/27/star-wars.html"
|
||||
And I should see "Post date: Fri Mar 27" in "_site/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.id variable
|
||||
Given I have a _posts directory
|
||||
@@ -94,41 +94,6 @@ Feature: Post data
|
||||
Then the _site directory should exist
|
||||
And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when categories are in folders with mixed case
|
||||
Given I have a scifi directory
|
||||
And I have a scifi/Movies directory
|
||||
And I have a scifi/Movies/_posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post in "scifi/Movies":
|
||||
| title | date | layout | content |
|
||||
| Star Wars | 3/27/2009 | simple | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post categories: {{ page.categories | array_to_sentence_string }}"
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when category is in YAML
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | category | content |
|
||||
| Star Wars | 3/27/2009 | simple | movies | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post category: {{ page.categories }}"
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when category is in YAML and is mixed-case
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | category | content |
|
||||
| Star Wars | 3/27/2009 | simple | Movies | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post category: {{ page.categories }}"
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when category is in YAML
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
@@ -140,42 +105,16 @@ Feature: Post data
|
||||
Then the _site directory should exist
|
||||
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when categories are in YAML with mixed case
|
||||
Scenario: Use post.categories variable when categories are in YAML
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | categories | content |
|
||||
| Star Wars | 3/27/2009 | simple | ['scifi', 'Movies'] | Luke, I am your father. |
|
||||
| Star Trek | 3/17/2013 | simple | ['SciFi', 'movies'] | Jean Luc, I am your father. |
|
||||
And I have the following post:
|
||||
| title | date | layout | categories | content |
|
||||
| Star Wars | 3/27/2009 | simple | ['scifi', 'movies'] | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post categories: {{ page.categories | array_to_sentence_string }}"
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2009/03/27/star-wars.html"
|
||||
And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2013/03/17/star-trek.html"
|
||||
|
||||
Scenario Outline: Use page.path variable
|
||||
Given I have a <dir>/_posts directory
|
||||
And I have the following post in "<dir>":
|
||||
| title | type | date | content |
|
||||
| my-post | html | 4/12/2013 | Source path: {{ page.path }} |
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "Source path: <path_prefix>_posts/2013-04-12-my-post.html" in "_site/<dir>/2013/04/12/my-post.html"
|
||||
|
||||
Examples:
|
||||
| dir | path_prefix |
|
||||
| . | |
|
||||
| dir | dir/ |
|
||||
| dir/nested | dir/nested/ |
|
||||
|
||||
Scenario: Override page.path variable
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | path | content |
|
||||
| override | 4/12/2013 | override-path.html | Custom path: {{ page.path }} |
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "Custom path: override-path.html" in "_site/2013/04/12/override.html"
|
||||
|
||||
Scenario: Disable a post from being published
|
||||
Given I have a _posts directory
|
||||
|
||||
@@ -3,7 +3,7 @@ Feature: Site configuration
|
||||
I want to be able to configure jekyll
|
||||
In order to make setting up a site easier
|
||||
|
||||
Scenario: Change source directory
|
||||
Scenario: Change destination directory
|
||||
Given I have a blank site in "_sourcedir"
|
||||
And I have an "_sourcedir/index.html" file that contains "Changing source directory"
|
||||
And I have a configuration file with "source" set to "_sourcedir"
|
||||
@@ -22,7 +22,7 @@ Feature: Site configuration
|
||||
Given I have an "Rakefile" file that contains "I want to be excluded"
|
||||
And I have an "README" file that contains "I want to be excluded"
|
||||
And I have an "index.html" file that contains "I want to be included"
|
||||
And I have a configuration file with "exclude" set to "['Rakefile', 'README']"
|
||||
And I have a configuration file with "exclude" set to "Rakefile", "README"
|
||||
When I run jekyll
|
||||
Then I should see "I want to be included" in "_site/index.html"
|
||||
And the "_site/Rakefile" file should not exist
|
||||
@@ -55,13 +55,6 @@ Feature: Site configuration
|
||||
Then the _site directory should exist
|
||||
And I should see "<a href="http://google.com">Google</a>" in "_site/index.html"
|
||||
|
||||
Scenario: Use Redcarpet for markup
|
||||
Given I have an "index.markdown" page that contains "[Google](http://google.com)"
|
||||
And I have a configuration file with "markdown" set to "redcarpet"
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "<a href="http://google.com">Google</a>" in "_site/index.html"
|
||||
|
||||
Scenario: Use Maruku for markup
|
||||
Given I have an "index.markdown" page that contains "[Google](http://google.com)"
|
||||
And I have a configuration file with "markdown" set to "maruku"
|
||||
@@ -116,46 +109,6 @@ Feature: Site configuration
|
||||
And I should see "Post Layout: <p>content for entry1.</p>" in "_site/2007/12/31/entry1.html"
|
||||
And I should see "Post Layout: <p>content for entry2.</p>" in "_site/2020/01/31/entry2.html"
|
||||
|
||||
Scenario: Generate proper dates with explicitly set timezone (same as posts' time)
|
||||
Given I have a _layouts directory
|
||||
And I have a page layout that contains "Page Layout: {{ site.posts.size }}"
|
||||
And I have a post layout that contains "Post Layout: {{ content }} built at {{ page.date | date_to_xmlschema }}"
|
||||
And I have an "index.html" page with layout "page" that contains "site index page"
|
||||
And I have a configuration file with:
|
||||
| key | value |
|
||||
| timezone | America/New_York |
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2013-04-09 23:22 -0400 | post | content for entry1. |
|
||||
| entry2 | 2013-04-10 03:14 -0400 | post | content for entry2. |
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "Page Layout: 2" in "_site/index.html"
|
||||
And I should see "Post Layout: <p>content for entry1.</p> built at 2013-04-09T23:22:00-04:00" in "_site/2013/04/09/entry1.html"
|
||||
And I should see "Post Layout: <p>content for entry2.</p> built at 2013-04-10T03:14:00-04:00" in "_site/2013/04/10/entry2.html"
|
||||
|
||||
Scenario: Generate proper dates with explicitly set timezone (different than posts' time)
|
||||
Given I have a _layouts directory
|
||||
And I have a page layout that contains "Page Layout: {{ site.posts.size }}"
|
||||
And I have a post layout that contains "Post Layout: {{ content }} built at {{ page.date | date_to_xmlschema }}"
|
||||
And I have an "index.html" page with layout "page" that contains "site index page"
|
||||
And I have a configuration file with:
|
||||
| key | value |
|
||||
| timezone | Australia/Melbourne |
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 2013-04-09 23:22 -0400 | post | content for entry1. |
|
||||
| entry2 | 2013-04-10 03:14 -0400 | post | content for entry2. |
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "Page Layout: 2" in "_site/index.html"
|
||||
And the "_site/2013/04/10/entry1.html" file should exist
|
||||
And the "_site/2013/04/10/entry2.html" file should exist
|
||||
And I should see escaped "Post Layout: <p>content for entry1.</p> built at 2013-04-10T13:22:00+10:00" in "_site/2013/04/10/entry1.html"
|
||||
And I should see escaped "Post Layout: <p>content for entry2.</p> built at 2013-04-10T17:14:00+10:00" in "_site/2013/04/10/entry2.html"
|
||||
|
||||
Scenario: Limit the number of posts generated by most recent date
|
||||
Given I have a _posts directory
|
||||
And I have a configuration file with:
|
||||
@@ -171,36 +124,3 @@ Feature: Site configuration
|
||||
And the "_site/2009/04/05/bananas.html" file should exist
|
||||
And the "_site/2009/04/01/oranges.html" file should exist
|
||||
And the "_site/2009/03/27/apples.html" file should not exist
|
||||
|
||||
Scenario: Copy over normally excluded files when they are explicitly included
|
||||
Given I have a ".gitignore" file that contains ".DS_Store"
|
||||
And I have an ".htaccess" file that contains "SomeDirective"
|
||||
And I have a configuration file with "include" set to:
|
||||
| value |
|
||||
| .gitignore |
|
||||
| .foo |
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see ".DS_Store" in "_site/.gitignore"
|
||||
And the "_site/.htaccess" file should not exist
|
||||
|
||||
Scenario: Using a different layouts directory
|
||||
Given I have a _theme directory
|
||||
And I have a page theme that contains "Page Layout: {{ site.posts.size }} on {{ site.time | date: "%Y-%m-%d" }}"
|
||||
And I have a post theme that contains "Post Layout: {{ content }}"
|
||||
And I have an "index.html" page with layout "page" that contains "site index page"
|
||||
And I have a configuration file with:
|
||||
| key | value |
|
||||
| time | 2010-01-01 |
|
||||
| future | true |
|
||||
| layouts | _theme |
|
||||
And I have a _posts directory
|
||||
And I have the following posts:
|
||||
| title | date | layout | content |
|
||||
| entry1 | 12/31/2007 | post | content for entry1. |
|
||||
| entry2 | 01/31/2020 | post | content for entry2. |
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "Page Layout: 2 on 2010-01-01" in "_site/index.html"
|
||||
And I should see "Post Layout: <p>content for entry1.</p>" in "_site/2007/12/31/entry1.html"
|
||||
And I should see "Post Layout: <p>content for entry2.</p>" in "_site/2020/01/31/entry2.html"
|
||||
|
||||
@@ -9,25 +9,6 @@ Feature: Site data
|
||||
Then the _site directory should exist
|
||||
And I should see "Contact: email@me.com" in "_site/contact.html"
|
||||
|
||||
Scenario Outline: Use page.path variable in a page
|
||||
Given I have a <dir> directory
|
||||
And I have a "<path>" page that contains "Source path: {{ page.path }}"
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "Source path: <path>" in "_site/<path>"
|
||||
|
||||
Examples:
|
||||
| dir | path |
|
||||
| . | index.html |
|
||||
| dir | dir/about.html |
|
||||
| dir/nested | dir/nested/page.html |
|
||||
|
||||
Scenario: Override page.path
|
||||
Given I have an "override.html" page with path "custom-override.html" that contains "Custom path: {{ page.path }}"
|
||||
When I run jekyll
|
||||
Then the _site directory should exist
|
||||
And I should see "Custom path: custom-override.html" in "_site/override.html"
|
||||
|
||||
Scenario: Use site.time variable
|
||||
Given I have an "index.html" page that contains "{{ site.time }}"
|
||||
When I run jekyll
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
Before do
|
||||
FileUtils.rm_rf(TEST_DIR)
|
||||
FileUtils.mkdir(TEST_DIR)
|
||||
Dir.chdir(TEST_DIR)
|
||||
end
|
||||
|
||||
After do
|
||||
Dir.chdir(File.expand_path("..", TEST_DIR))
|
||||
Dir.chdir(TEST_DIR)
|
||||
FileUtils.rm_rf(TEST_DIR)
|
||||
end
|
||||
|
||||
@@ -22,24 +21,21 @@ Given /^I have an? "(.*)" page(?: with (.*) "(.*)")? that contains "(.*)"$/ do |
|
||||
---
|
||||
#{text}
|
||||
EOF
|
||||
f.close
|
||||
end
|
||||
end
|
||||
|
||||
Given /^I have an? "(.*)" file that contains "(.*)"$/ do |file, text|
|
||||
File.open(file, 'w') do |f|
|
||||
f.write(text)
|
||||
f.close
|
||||
end
|
||||
end
|
||||
|
||||
Given /^I have a (.*) layout that contains "(.*)"$/ do |layout, text|
|
||||
File.open(File.join('_layouts', layout + '.html'), 'w') do |f|
|
||||
f.write(text)
|
||||
end
|
||||
end
|
||||
|
||||
Given /^I have a (.*) theme that contains "(.*)"$/ do |layout, text|
|
||||
File.open(File.join('_theme', layout + '.html'), 'w') do |f|
|
||||
f.write(text)
|
||||
f.close
|
||||
end
|
||||
end
|
||||
|
||||
@@ -47,8 +43,9 @@ Given /^I have an? (.*) directory$/ do |dir|
|
||||
FileUtils.mkdir_p(dir)
|
||||
end
|
||||
|
||||
Given /^I have the following (draft|post)s?(?: (.*) "(.*)")?:$/ do |status, direction, folder, table|
|
||||
Given /^I have the following posts?(?: (.*) "(.*)")?:$/ do |direction, folder, table|
|
||||
table.hashes.each do |post|
|
||||
date = Date.strptime(post['date'], '%m/%d/%Y').strftime('%Y-%m-%d')
|
||||
title = post['title'].downcase.gsub(/[^\w]/, " ").strip.gsub(/\s+/, '-')
|
||||
|
||||
if direction && direction == "in"
|
||||
@@ -57,29 +54,12 @@ Given /^I have the following (draft|post)s?(?: (.*) "(.*)")?:$/ do |status, dire
|
||||
after = folder || '.'
|
||||
end
|
||||
|
||||
ext = post['type'] || 'textile'
|
||||
|
||||
if "draft" == status
|
||||
path = File.join(before || '.', '_drafts', after || '.', "#{title}.#{ext}")
|
||||
else
|
||||
format = if has_time_component?(post['date'])
|
||||
'%Y-%m-%d %H:%M %z'
|
||||
else
|
||||
'%m/%d/%Y' # why even
|
||||
end
|
||||
parsed_date = DateTime.strptime(post['date'], format)
|
||||
post['date'] = parsed_date.to_s
|
||||
date = parsed_date.strftime('%Y-%m-%d')
|
||||
path = File.join(before || '.', '_posts', after || '.', "#{date}-#{title}.#{ext}")
|
||||
end
|
||||
path = File.join(before || '.', '_posts', after || '.', "#{date}-#{title}.#{post['type'] || 'textile'}")
|
||||
|
||||
matter_hash = {}
|
||||
%w(title layout tag tags category categories published author path).each do |key|
|
||||
%w(title layout tag tags category categories published author).each do |key|
|
||||
matter_hash[key] = post[key] if post[key]
|
||||
end
|
||||
if "post" == status
|
||||
matter_hash["date"] = post["date"] if post["date"]
|
||||
end
|
||||
matter = matter_hash.map { |k, v| "#{k}: #{v}\n" }.join.chomp
|
||||
|
||||
content = post['content']
|
||||
@@ -94,6 +74,7 @@ Given /^I have the following (draft|post)s?(?: (.*) "(.*)")?:$/ do |status, dire
|
||||
---
|
||||
#{content}
|
||||
EOF
|
||||
f.close
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -101,6 +82,7 @@ end
|
||||
Given /^I have a configuration file with "(.*)" set to "(.*)"$/ do |key, value|
|
||||
File.open('_config.yml', 'w') do |f|
|
||||
f.write("#{key}: #{value}\n")
|
||||
f.close
|
||||
end
|
||||
end
|
||||
|
||||
@@ -109,6 +91,7 @@ Given /^I have a configuration file with:$/ do |table|
|
||||
table.hashes.each do |row|
|
||||
f.write("#{row["key"]}: #{row["value"]}\n")
|
||||
end
|
||||
f.close
|
||||
end
|
||||
end
|
||||
|
||||
@@ -118,6 +101,7 @@ Given /^I have a configuration file with "([^\"]*)" set to:$/ do |key, table|
|
||||
table.hashes.each do |row|
|
||||
f.write("- #{row["value"]}\n")
|
||||
end
|
||||
f.close
|
||||
end
|
||||
end
|
||||
|
||||
@@ -126,10 +110,6 @@ When /^I run jekyll$/ do
|
||||
run_jekyll
|
||||
end
|
||||
|
||||
When /^I run jekyll with drafts$/ do
|
||||
run_jekyll(:drafts => true)
|
||||
end
|
||||
|
||||
When /^I debug jekyll$/ do
|
||||
run_jekyll(:debug => true)
|
||||
end
|
||||
@@ -141,15 +121,11 @@ When /^I change "(.*)" to contain "(.*)"$/ do |file, text|
|
||||
end
|
||||
|
||||
Then /^the (.*) directory should exist$/ do |dir|
|
||||
assert File.directory?(dir), "The directory \"#{dir}\" does not exist"
|
||||
assert File.directory?(dir)
|
||||
end
|
||||
|
||||
Then /^I should see "(.*)" in "(.*)"$/ do |text, file|
|
||||
assert Regexp.new(text).match(File.open(file).readlines.join)
|
||||
end
|
||||
|
||||
Then /^I should see escaped "(.*)" in "(.*)"$/ do |text, file|
|
||||
assert Regexp.new(Regexp.escape(text)).match(File.open(file).readlines.join)
|
||||
assert_match Regexp.new(text), File.open(file).readlines.join
|
||||
end
|
||||
|
||||
Then /^the "(.*)" file should exist$/ do |file|
|
||||
|
||||
@@ -7,19 +7,13 @@ World do
|
||||
end
|
||||
|
||||
TEST_DIR = File.join('/', 'tmp', 'jekyll')
|
||||
JEKYLL_PATH = File.join(File.dirname(__FILE__), '..', '..', 'bin', 'jekyll')
|
||||
JEKYLL_PATH = File.join(ENV['PWD'], 'bin', 'jekyll')
|
||||
|
||||
def run_jekyll(opts = {})
|
||||
command = JEKYLL_PATH.clone
|
||||
command << " build"
|
||||
command << " --drafts" if opts[:drafts]
|
||||
command = JEKYLL_PATH
|
||||
command << " >> /dev/null 2>&1" if opts[:debug].nil?
|
||||
system command
|
||||
end
|
||||
|
||||
def has_time_component?(date_string)
|
||||
date_string.split(" ").size > 1
|
||||
end
|
||||
|
||||
# work around "invalid option: --format" cucumber bug (see #296)
|
||||
Test::Unit.run = true if RUBY_VERSION < '1.9'
|
||||
Test::Unit.run = true
|
||||
|
||||
154
jekyll.gemspec
154
jekyll.gemspec
@@ -4,9 +4,8 @@ Gem::Specification.new do |s|
|
||||
s.rubygems_version = '1.3.5'
|
||||
|
||||
s.name = 'jekyll'
|
||||
s.version = '1.0.2'
|
||||
s.license = 'MIT'
|
||||
s.date = '2013-05-12'
|
||||
s.version = '0.10.0'
|
||||
s.date = '2010-12-16'
|
||||
s.rubyforge_project = 'jekyll'
|
||||
|
||||
s.summary = "A simple, blog aware, static site generator."
|
||||
@@ -19,45 +18,34 @@ Gem::Specification.new do |s|
|
||||
s.require_paths = %w[lib]
|
||||
|
||||
s.executables = ["jekyll"]
|
||||
s.default_executable = 'jekyll'
|
||||
|
||||
s.rdoc_options = ["--charset=UTF-8"]
|
||||
s.extra_rdoc_files = %w[README.textile LICENSE]
|
||||
|
||||
s.add_runtime_dependency('liquid', "~> 2.3")
|
||||
s.add_runtime_dependency('classifier', "~> 1.3")
|
||||
s.add_runtime_dependency('directory_watcher', "~> 1.4.1")
|
||||
s.add_runtime_dependency('maruku', "~> 0.5")
|
||||
s.add_runtime_dependency('kramdown', "~> 1.0.2")
|
||||
s.add_runtime_dependency('pygments.rb', "~> 0.5.0")
|
||||
s.add_runtime_dependency('commander', "~> 4.1.3")
|
||||
s.add_runtime_dependency('safe_yaml', "~> 0.7.0")
|
||||
s.add_runtime_dependency('colorator', "~> 0.1")
|
||||
s.add_runtime_dependency('liquid', ">= 1.9.0")
|
||||
s.add_runtime_dependency('classifier', ">= 1.3.1")
|
||||
s.add_runtime_dependency('directory_watcher', ">= 1.1.1")
|
||||
s.add_runtime_dependency('maruku', ">= 0.5.9")
|
||||
s.add_runtime_dependency('kramdown', ">= 0.13.2")
|
||||
s.add_runtime_dependency('albino', ">= 1.3.2")
|
||||
|
||||
s.add_development_dependency('rake', "~> 10.0.3")
|
||||
s.add_development_dependency('rdoc', "~> 3.11")
|
||||
s.add_development_dependency('redgreen', "~> 1.2")
|
||||
s.add_development_dependency('shoulda', "~> 3.3.2")
|
||||
s.add_development_dependency('rr', "~> 1.0")
|
||||
s.add_development_dependency('cucumber', "~> 1.2.1", '!= 1.2.4')
|
||||
s.add_development_dependency('RedCloth', "~> 4.2")
|
||||
s.add_development_dependency('rdiscount', "~> 1.6")
|
||||
s.add_development_dependency('redcarpet', "~> 2.2.2")
|
||||
s.add_development_dependency('launchy', "~> 2.1.2")
|
||||
s.add_development_dependency('simplecov', "~> 0.7")
|
||||
s.add_development_dependency('simplecov-gem-adapter', "~> 1.0.1")
|
||||
s.add_development_dependency('redgreen', ">= 1.2.2")
|
||||
s.add_development_dependency('shoulda', ">= 2.11.3")
|
||||
s.add_development_dependency('rr', ">= 1.0.2")
|
||||
s.add_development_dependency('cucumber', ">= 0.10.0")
|
||||
s.add_development_dependency('RedCloth', ">= 4.2.1")
|
||||
s.add_development_dependency('rdiscount', ">= 1.6.5")
|
||||
|
||||
# = MANIFEST =
|
||||
s.files = %w[
|
||||
CONTRIBUTING.md
|
||||
Gemfile
|
||||
History.markdown
|
||||
History.txt
|
||||
LICENSE
|
||||
README.textile
|
||||
Rakefile
|
||||
bin/jekyll
|
||||
cucumber.yml
|
||||
features/create_sites.feature
|
||||
features/drafts.feature
|
||||
features/embed_filters.feature
|
||||
features/markdown.feature
|
||||
features/pagination.feature
|
||||
@@ -69,111 +57,39 @@ Gem::Specification.new do |s|
|
||||
features/support/env.rb
|
||||
jekyll.gemspec
|
||||
lib/jekyll.rb
|
||||
lib/jekyll/command.rb
|
||||
lib/jekyll/commands/build.rb
|
||||
lib/jekyll/commands/doctor.rb
|
||||
lib/jekyll/commands/new.rb
|
||||
lib/jekyll/commands/serve.rb
|
||||
lib/jekyll/configuration.rb
|
||||
lib/jekyll/albino.rb
|
||||
lib/jekyll/converter.rb
|
||||
lib/jekyll/converters/identity.rb
|
||||
lib/jekyll/converters/markdown.rb
|
||||
lib/jekyll/converters/markdown/kramdown_parser.rb
|
||||
lib/jekyll/converters/markdown/maruku_parser.rb
|
||||
lib/jekyll/converters/markdown/rdiscount_parser.rb
|
||||
lib/jekyll/converters/markdown/redcarpet_parser.rb
|
||||
lib/jekyll/converters/textile.rb
|
||||
lib/jekyll/convertible.rb
|
||||
lib/jekyll/core_ext.rb
|
||||
lib/jekyll/deprecator.rb
|
||||
lib/jekyll/draft.rb
|
||||
lib/jekyll/errors.rb
|
||||
lib/jekyll/filters.rb
|
||||
lib/jekyll/generator.rb
|
||||
lib/jekyll/generators/pagination.rb
|
||||
lib/jekyll/layout.rb
|
||||
lib/jekyll/logger.rb
|
||||
lib/jekyll/mime.types
|
||||
lib/jekyll/migrators/csv.rb
|
||||
lib/jekyll/migrators/drupal.rb
|
||||
lib/jekyll/migrators/marley.rb
|
||||
lib/jekyll/migrators/mephisto.rb
|
||||
lib/jekyll/migrators/mt.rb
|
||||
lib/jekyll/migrators/textpattern.rb
|
||||
lib/jekyll/migrators/typo.rb
|
||||
lib/jekyll/migrators/wordpress.com.rb
|
||||
lib/jekyll/migrators/wordpress.rb
|
||||
lib/jekyll/page.rb
|
||||
lib/jekyll/plugin.rb
|
||||
lib/jekyll/post.rb
|
||||
lib/jekyll/site.rb
|
||||
lib/jekyll/static_file.rb
|
||||
lib/jekyll/tags/gist.rb
|
||||
lib/jekyll/tags/highlight.rb
|
||||
lib/jekyll/tags/include.rb
|
||||
lib/jekyll/tags/post_url.rb
|
||||
lib/site_template/.gitignore
|
||||
lib/site_template/_config.yml
|
||||
lib/site_template/_layouts/default.html
|
||||
lib/site_template/_layouts/post.html
|
||||
lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb
|
||||
lib/site_template/css/main.css
|
||||
lib/site_template/css/syntax.css
|
||||
lib/site_template/index.html
|
||||
script/bootstrap
|
||||
site/.gitignore
|
||||
site/CNAME
|
||||
site/README
|
||||
site/_config.yml
|
||||
site/_includes/analytics.html
|
||||
site/_includes/docs_contents.html
|
||||
site/_includes/docs_contents_mobile.html
|
||||
site/_includes/footer.html
|
||||
site/_includes/header.html
|
||||
site/_includes/primary-nav-items.html
|
||||
site/_includes/section_nav.html
|
||||
site/_includes/top.html
|
||||
site/_layouts/default.html
|
||||
site/_layouts/docs.html
|
||||
site/css/gridism.css
|
||||
site/css/normalize.css
|
||||
site/css/pygments.css
|
||||
site/css/style.css
|
||||
site/docs/configuration.md
|
||||
site/docs/contributing.md
|
||||
site/docs/deployment-methods.md
|
||||
site/docs/extras.md
|
||||
site/docs/frontmatter.md
|
||||
site/docs/github-pages.md
|
||||
site/docs/heroku.md
|
||||
site/docs/index.md
|
||||
site/docs/installation.md
|
||||
site/docs/migrations.md
|
||||
site/docs/pages.md
|
||||
site/docs/pagination.md
|
||||
site/docs/permalinks.md
|
||||
site/docs/plugins.md
|
||||
site/docs/posts.md
|
||||
site/docs/resources.md
|
||||
site/docs/sites.md
|
||||
site/docs/structure.md
|
||||
site/docs/templates.md
|
||||
site/docs/troubleshooting.md
|
||||
site/docs/upgrading.md
|
||||
site/docs/usage.md
|
||||
site/docs/variables.md
|
||||
site/favicon.png
|
||||
site/img/article-footer.png
|
||||
site/img/footer-arrow.png
|
||||
site/img/footer-logo.png
|
||||
site/img/logo-2x.png
|
||||
site/img/octojekyll.png
|
||||
site/img/tube.png
|
||||
site/img/tube1x.png
|
||||
site/index.html
|
||||
site/js/modernizr-2.5.3.min.js
|
||||
test/fixtures/broken_front_matter1.erb
|
||||
test/fixtures/broken_front_matter2.erb
|
||||
test/fixtures/broken_front_matter3.erb
|
||||
test/fixtures/exploit_front_matter.erb
|
||||
test/fixtures/front_matter.erb
|
||||
test/helper.rb
|
||||
test/source/.htaccess
|
||||
test/source/_includes/sig.markdown
|
||||
test/source/_layouts/default.html
|
||||
test/source/_layouts/simple.html
|
||||
test/source/_plugins/dummy.rb
|
||||
test/source/_posts/2008-02-02-not-published.textile
|
||||
test/source/_posts/2008-02-02-published.textile
|
||||
test/source/_posts/2008-10-18-foo-bar.textile
|
||||
@@ -197,44 +113,26 @@ Gem::Specification.new do |s|
|
||||
test/source/_posts/2010-01-09-time-override.textile
|
||||
test/source/_posts/2010-01-09-timezone-override.textile
|
||||
test/source/_posts/2010-01-16-override-data.textile
|
||||
test/source/_posts/2011-04-12-md-extension.md
|
||||
test/source/_posts/2011-04-12-text-extension.text
|
||||
test/source/_posts/2013-01-02-post-excerpt.markdown
|
||||
test/source/_posts/2013-01-12-nil-layout.textile
|
||||
test/source/_posts/2013-01-12-no-layout.textile
|
||||
test/source/_posts/2013-03-19-not-a-post.markdown/.gitkeep
|
||||
test/source/_posts/2013-04-11-custom-excerpt.markdown
|
||||
test/source/_posts/2013-05-10-number-category.textile
|
||||
test/source/_posts/es/2008-11-21-nested.textile
|
||||
test/source/about.html
|
||||
test/source/category/_posts/2008-9-23-categories.textile
|
||||
test/source/contacts.html
|
||||
test/source/contacts/bar.html
|
||||
test/source/contacts/index.html
|
||||
test/source/css/screen.css
|
||||
test/source/deal.with.dots.html
|
||||
test/source/foo/_posts/bar/2008-12-12-topical-post.textile
|
||||
test/source/index.html
|
||||
test/source/sitemap.xml
|
||||
test/source/symlink-test/symlinked-dir
|
||||
test/source/symlink-test/symlinked-file
|
||||
test/source/win/_posts/2009-05-24-yaml-linebreak.markdown
|
||||
test/source/z_category/_posts/2008-9-23-categories.textile
|
||||
test/suite.rb
|
||||
test/test_command.rb
|
||||
test/test_configuration.rb
|
||||
test/test_convertible.rb
|
||||
test/test_core_ext.rb
|
||||
test/test_filters.rb
|
||||
test/test_generated_site.rb
|
||||
test/test_kramdown.rb
|
||||
test/test_new_command.rb
|
||||
test/test_page.rb
|
||||
test/test_pager.rb
|
||||
test/test_post.rb
|
||||
test/test_rdiscount.rb
|
||||
test/test_redcarpet.rb
|
||||
test/test_redcloth.rb
|
||||
test/test_site.rb
|
||||
test/test_tags.rb
|
||||
]
|
||||
|
||||
101
lib/jekyll.rb
101
lib/jekyll.rb
@@ -18,25 +18,21 @@ require 'rubygems'
|
||||
# stdlib
|
||||
require 'fileutils'
|
||||
require 'time'
|
||||
require 'safe_yaml'
|
||||
require 'yaml'
|
||||
require 'English'
|
||||
|
||||
# 3rd party
|
||||
require 'liquid'
|
||||
require 'maruku'
|
||||
require 'colorator'
|
||||
require 'albino'
|
||||
|
||||
# internal requires
|
||||
require 'jekyll/core_ext'
|
||||
require 'jekyll/logger'
|
||||
require 'jekyll/deprecator'
|
||||
require 'jekyll/configuration'
|
||||
require 'jekyll/site'
|
||||
require 'jekyll/convertible'
|
||||
require 'jekyll/layout'
|
||||
require 'jekyll/page'
|
||||
require 'jekyll/post'
|
||||
require 'jekyll/draft'
|
||||
require 'jekyll/filters'
|
||||
require 'jekyll/static_file'
|
||||
require 'jekyll/errors'
|
||||
@@ -45,45 +41,86 @@ require 'jekyll/errors'
|
||||
require 'jekyll/plugin'
|
||||
require 'jekyll/converter'
|
||||
require 'jekyll/generator'
|
||||
require 'jekyll/command'
|
||||
|
||||
require_all 'jekyll/commands'
|
||||
require_all 'jekyll/converters'
|
||||
require_all 'jekyll/converters/markdown'
|
||||
require_all 'jekyll/generators'
|
||||
require_all 'jekyll/tags'
|
||||
|
||||
SafeYAML::OPTIONS[:suppress_warnings] = true
|
||||
|
||||
module Jekyll
|
||||
VERSION = '1.0.2'
|
||||
VERSION = '0.10.0'
|
||||
|
||||
# Public: Generate a Jekyll configuration Hash by merging the default
|
||||
# options with anything in _config.yml, and adding the given options on top.
|
||||
# Default options. Overriden by values in _config.yml or command-line opts.
|
||||
# (Strings rather symbols used for compatability with YAML).
|
||||
DEFAULTS = {
|
||||
'safe' => false,
|
||||
'auto' => false,
|
||||
'server' => false,
|
||||
'server_port' => 4000,
|
||||
|
||||
'source' => Dir.pwd,
|
||||
'destination' => File.join(Dir.pwd, '_site'),
|
||||
'plugins' => File.join(Dir.pwd, '_plugins'),
|
||||
|
||||
'future' => true,
|
||||
'lsi' => false,
|
||||
'pygments' => false,
|
||||
'markdown' => 'maruku',
|
||||
'permalink' => 'date',
|
||||
|
||||
'maruku' => {
|
||||
'use_tex' => false,
|
||||
'use_divs' => false,
|
||||
'png_engine' => 'blahtex',
|
||||
'png_dir' => 'images/latex',
|
||||
'png_url' => '/images/latex'
|
||||
},
|
||||
'rdiscount' => {
|
||||
'extensions' => []
|
||||
},
|
||||
'kramdown' => {
|
||||
'auto_ids' => true,
|
||||
'footnote_nr' => 1,
|
||||
'entity_output' => 'as_char',
|
||||
'toc_levels' => '1..6',
|
||||
'use_coderay' => false,
|
||||
|
||||
'coderay' => {
|
||||
'coderay_wrap' => 'div',
|
||||
'coderay_line_numbers' => 'inline',
|
||||
'coderay_line_number_start' => 1,
|
||||
'coderay_tab_width' => 4,
|
||||
'coderay_bold_every' => 10,
|
||||
'coderay_css' => 'style'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Generate a Jekyll configuration Hash by merging the default options
|
||||
# with anything in _config.yml, and adding the given options on top.
|
||||
#
|
||||
# override - A Hash of config directives that override any options in both
|
||||
# the defaults and the config file. See Jekyll::Configuration::DEFAULTS for a
|
||||
# the defaults and the config file. See Jekyll::DEFAULTS for a
|
||||
# list of option names and their defaults.
|
||||
#
|
||||
# Returns the final configuration Hash.
|
||||
def self.configuration(override)
|
||||
config = Configuration[Configuration::DEFAULTS]
|
||||
override = Configuration[override].stringify_keys
|
||||
config = config.read_config_files(config.config_files(override))
|
||||
# _config.yml may override default source location, but until
|
||||
# then, we need to know where to look for _config.yml
|
||||
source = override['source'] || Jekyll::DEFAULTS['source']
|
||||
|
||||
# Get configuration from <source>/_config.yml
|
||||
config_file = File.join(source, '_config.yml')
|
||||
begin
|
||||
config = YAML.load_file(config_file)
|
||||
raise "Invalid configuration - #{config_file}" if !config.is_a?(Hash)
|
||||
$stdout.puts "Configuration from #{config_file}"
|
||||
rescue => err
|
||||
$stderr.puts "WARNING: Could not read configuration. " +
|
||||
"Using defaults (and options)."
|
||||
$stderr.puts "\t" + err.to_s
|
||||
config = {}
|
||||
end
|
||||
|
||||
# Merge DEFAULTS < _config.yml < override
|
||||
config = config.deep_merge(override).stringify_keys
|
||||
set_timezone(config['timezone']) if config['timezone']
|
||||
|
||||
config
|
||||
end
|
||||
|
||||
# Static: Set the TZ environment variable to use the timezone specified
|
||||
#
|
||||
# timezone - the IANA Time Zone
|
||||
#
|
||||
# Returns nothing
|
||||
def self.set_timezone(timezone)
|
||||
ENV['TZ'] = timezone
|
||||
Jekyll::DEFAULTS.deep_merge(config).deep_merge(override)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
module Jekyll
|
||||
class Command
|
||||
def self.globs(source, destination)
|
||||
Dir.chdir(source) do
|
||||
dirs = Dir['*'].select { |x| File.directory?(x) }
|
||||
dirs -= [destination, File.expand_path(destination), File.basename(destination)]
|
||||
dirs = dirs.map { |x| "#{x}/**/*" }
|
||||
dirs += ['*']
|
||||
end
|
||||
end
|
||||
|
||||
# Static: Run Site#process and catch errors
|
||||
#
|
||||
# site - the Jekyll::Site object
|
||||
#
|
||||
# Returns nothing
|
||||
def self.process_site(site)
|
||||
site.process
|
||||
rescue Jekyll::FatalException => e
|
||||
puts
|
||||
Jekyll::Logger.error "ERROR:", "YOUR SITE COULD NOT BE BUILT:"
|
||||
Jekyll::Logger.error "", "------------------------------------"
|
||||
Jekyll::Logger.error "", e.message
|
||||
exit(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,64 +0,0 @@
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Build < Command
|
||||
def self.process(options)
|
||||
site = Jekyll::Site.new(options)
|
||||
|
||||
self.build(site, options)
|
||||
self.watch(site, options) if options['watch']
|
||||
end
|
||||
|
||||
# Private: Build the site from source into destination.
|
||||
#
|
||||
# site - A Jekyll::Site instance
|
||||
# options - A Hash of options passed to the command
|
||||
#
|
||||
# Returns nothing.
|
||||
def self.build(site, options)
|
||||
source = options['source']
|
||||
destination = options['destination']
|
||||
Jekyll::Logger.info "Source:", source
|
||||
Jekyll::Logger.info "Destination:", destination
|
||||
print Jekyll::Logger.formatted_topic "Generating..."
|
||||
self.process_site(site)
|
||||
puts "done."
|
||||
end
|
||||
|
||||
# Private: Watch for file changes and rebuild the site.
|
||||
#
|
||||
# site - A Jekyll::Site instance
|
||||
# options - A Hash of options passed to the command
|
||||
#
|
||||
# Returns nothing.
|
||||
def self.watch(site, options)
|
||||
require 'directory_watcher'
|
||||
|
||||
source = options['source']
|
||||
destination = options['destination']
|
||||
|
||||
Jekyll::Logger.info "Auto-regeneration:", "enabled"
|
||||
|
||||
dw = DirectoryWatcher.new(source, :glob => self.globs(source, destination), :pre_load => true)
|
||||
dw.interval = 1
|
||||
|
||||
dw.add_observer do |*args|
|
||||
t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
||||
print Jekyll::Logger.formatted_topic("Regenerating:") + "#{args.size} files at #{t} "
|
||||
self.process_site(site)
|
||||
puts "...done."
|
||||
end
|
||||
|
||||
dw.start
|
||||
|
||||
unless options['serving']
|
||||
trap("INT") do
|
||||
puts " Halting auto-regeneration."
|
||||
exit 0
|
||||
end
|
||||
|
||||
loop { sleep 1000 }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,29 +0,0 @@
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Doctor < Command
|
||||
class << self
|
||||
def process(options)
|
||||
site = Jekyll::Site.new(options)
|
||||
site.read
|
||||
|
||||
unless deprecated_relative_permalinks(site)
|
||||
Jekyll::Logger.info "Your test results", "are in. Everything looks fine."
|
||||
end
|
||||
end
|
||||
|
||||
def deprecated_relative_permalinks(site)
|
||||
contains_deprecated_pages = false
|
||||
site.pages.each do |page|
|
||||
if page.uses_relative_permalinks
|
||||
Jekyll::Logger.warn "Deprecation:", "'#{page.path}' uses relative" +
|
||||
" permalinks which will be deprecated in" +
|
||||
" Jekyll v1.1 and beyond."
|
||||
contains_deprecated_pages = true
|
||||
end
|
||||
end
|
||||
contains_deprecated_pages
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,50 +0,0 @@
|
||||
require 'erb'
|
||||
|
||||
module Jekyll
|
||||
module Commands
|
||||
class New < Command
|
||||
def self.process(args)
|
||||
raise ArgumentError.new('You must specify a path.') if args.empty?
|
||||
|
||||
new_blog_path = File.expand_path(args.join(" "), Dir.pwd)
|
||||
FileUtils.mkdir_p new_blog_path
|
||||
unless Dir["#{new_blog_path}/**/*"].empty?
|
||||
Jekyll::Logger.error "Conflict:", "#{new_blog_path} exists and is not empty."
|
||||
exit(1)
|
||||
end
|
||||
|
||||
create_sample_files new_blog_path
|
||||
|
||||
File.open(File.expand_path(self.initialized_post_name, new_blog_path), "w") do |f|
|
||||
f.write(self.scaffold_post_content(site_template))
|
||||
end
|
||||
puts "New jekyll site installed in #{new_blog_path}."
|
||||
end
|
||||
|
||||
def self.scaffold_post_content(template_site)
|
||||
ERB.new(File.read(File.expand_path(scaffold_path, site_template))).result
|
||||
end
|
||||
|
||||
# Internal: Gets the filename of the sample post to be created
|
||||
#
|
||||
# Returns the filename of the sample post, as a String
|
||||
def self.initialized_post_name
|
||||
"_posts/#{Time.now.strftime('%Y-%m-%d')}-welcome-to-jekyll.markdown"
|
||||
end
|
||||
|
||||
private
|
||||
def self.create_sample_files(path)
|
||||
FileUtils.cp_r site_template + '/.', path
|
||||
FileUtils.rm File.expand_path(scaffold_path, path)
|
||||
end
|
||||
|
||||
def self.site_template
|
||||
File.expand_path("../../site_template", File.dirname(__FILE__))
|
||||
end
|
||||
|
||||
def self.scaffold_path
|
||||
"_posts/0000-00-00-welcome-to-jekyll.markdown.erb"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,33 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Serve < Command
|
||||
def self.process(options)
|
||||
require 'webrick'
|
||||
include WEBrick
|
||||
|
||||
destination = options['destination']
|
||||
|
||||
FileUtils.mkdir_p(destination)
|
||||
|
||||
mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
|
||||
mime_types = WEBrick::HTTPUtils::load_mime_types(mime_types_file)
|
||||
|
||||
# recreate NondisclosureName under utf-8 circumstance
|
||||
fh_option = WEBrick::Config::FileHandler
|
||||
fh_option[:NondisclosureName] = ['.ht*','~*']
|
||||
|
||||
s = HTTPServer.new(
|
||||
:Port => options['port'],
|
||||
:BindAddress => options['host'],
|
||||
:MimeTypes => mime_types
|
||||
)
|
||||
|
||||
s.mount(options['baseurl'], HTTPServlet::FileHandler, destination, fh_option)
|
||||
t = Thread.new { s.start }
|
||||
trap("INT") { s.shutdown }
|
||||
t.join()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,183 +0,0 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
module Jekyll
|
||||
class Configuration < Hash
|
||||
|
||||
# Default options. Overridden by values in _config.yml.
|
||||
# Strings rather than symbols are used for compatibility with YAML.
|
||||
DEFAULTS = {
|
||||
'source' => Dir.pwd,
|
||||
'destination' => File.join(Dir.pwd, '_site'),
|
||||
'plugins' => '_plugins',
|
||||
'layouts' => '_layouts',
|
||||
'keep_files' => ['.git','.svn'],
|
||||
|
||||
'timezone' => nil, # use the local timezone
|
||||
|
||||
'safe' => false,
|
||||
'show_drafts' => nil,
|
||||
'limit_posts' => 0,
|
||||
'lsi' => false,
|
||||
'future' => true, # remove and make true just default
|
||||
'pygments' => true,
|
||||
|
||||
'relative_permalinks' => true, # backwards-compatibility with < 1.0
|
||||
# will be set to false once 1.1 hits
|
||||
|
||||
'markdown' => 'maruku',
|
||||
'permalink' => 'date',
|
||||
'baseurl' => '/',
|
||||
'include' => ['.htaccess'],
|
||||
'exclude' => [],
|
||||
'paginate_path' => 'page:num',
|
||||
|
||||
'markdown_ext' => 'markdown,mkd,mkdn,md',
|
||||
'textile_ext' => 'textile',
|
||||
|
||||
'port' => '4000',
|
||||
'host' => '0.0.0.0',
|
||||
|
||||
'excerpt_separator' => "\n\n",
|
||||
|
||||
'maruku' => {
|
||||
'use_tex' => false,
|
||||
'use_divs' => false,
|
||||
'png_engine' => 'blahtex',
|
||||
'png_dir' => 'images/latex',
|
||||
'png_url' => '/images/latex'
|
||||
},
|
||||
|
||||
'rdiscount' => {
|
||||
'extensions' => []
|
||||
},
|
||||
|
||||
'redcarpet' => {
|
||||
'extensions' => []
|
||||
},
|
||||
|
||||
'kramdown' => {
|
||||
'auto_ids' => true,
|
||||
'footnote_nr' => 1,
|
||||
'entity_output' => 'as_char',
|
||||
'toc_levels' => '1..6',
|
||||
'smart_quotes' => 'lsquo,rsquo,ldquo,rdquo',
|
||||
'use_coderay' => false,
|
||||
|
||||
'coderay' => {
|
||||
'coderay_wrap' => 'div',
|
||||
'coderay_line_numbers' => 'inline',
|
||||
'coderay_line_number_start' => 1,
|
||||
'coderay_tab_width' => 4,
|
||||
'coderay_bold_every' => 10,
|
||||
'coderay_css' => 'style'
|
||||
}
|
||||
},
|
||||
|
||||
'redcloth' => {
|
||||
'hard_breaks' => true
|
||||
}
|
||||
}
|
||||
|
||||
# Public: Turn all keys into string
|
||||
#
|
||||
# Return a copy of the hash where all its keys are strings
|
||||
def stringify_keys
|
||||
reduce({}) { |hsh,(k,v)| hsh.merge(k.to_s => v) }
|
||||
end
|
||||
|
||||
# Public: Directory of the Jekyll source folder
|
||||
#
|
||||
# override - the command-line options hash
|
||||
#
|
||||
# Returns the path to the Jekyll source directory
|
||||
def source(override)
|
||||
override['source'] || self['source'] || DEFAULTS['source']
|
||||
end
|
||||
|
||||
# Public: Generate list of configuration files from the override
|
||||
#
|
||||
# override - the command-line options hash
|
||||
#
|
||||
# Returns an Array of config files
|
||||
def config_files(override)
|
||||
# Get configuration from <source>/_config.yml or <source>/<config_file>
|
||||
config_files = override.delete('config')
|
||||
config_files = File.join(source(override), "_config.yml") if config_files.to_s.empty?
|
||||
config_files = [config_files] unless config_files.is_a? Array
|
||||
config_files
|
||||
end
|
||||
|
||||
# Public: Read configuration and return merged Hash
|
||||
#
|
||||
# file - the path to the YAML file to be read in
|
||||
#
|
||||
# Returns this configuration, overridden by the values in the file
|
||||
def read_config_file(file)
|
||||
next_config = YAML.safe_load_file(file)
|
||||
raise "Configuration file: (INVALID) #{file}".yellow if !next_config.is_a?(Hash)
|
||||
Jekyll::Logger.info "Configuration file:", file
|
||||
next_config
|
||||
end
|
||||
|
||||
# Public: Read in a list of configuration files and merge with this hash
|
||||
#
|
||||
# files - the list of configuration file paths
|
||||
#
|
||||
# Returns the full configuration, with the defaults overridden by the values in the
|
||||
# configuration files
|
||||
def read_config_files(files)
|
||||
configuration = clone
|
||||
|
||||
begin
|
||||
files.each do |config_file|
|
||||
new_config = read_config_file(config_file)
|
||||
configuration = configuration.deep_merge(new_config)
|
||||
end
|
||||
rescue SystemCallError
|
||||
# Errno:ENOENT = file not found
|
||||
Jekyll::Logger.warn "Configuration file:", "none"
|
||||
rescue => err
|
||||
Jekyll::Logger.warn "WARNING:", "Error reading configuration. " +
|
||||
"Using defaults (and options)."
|
||||
$stderr.puts "#{err}"
|
||||
end
|
||||
|
||||
configuration.backwards_compatibilize
|
||||
end
|
||||
|
||||
# Public: Ensure the proper options are set in the configuration to allow for
|
||||
# backwards-compatibility with Jekyll pre-1.0
|
||||
#
|
||||
# Returns the backwards-compatible configuration
|
||||
def backwards_compatibilize
|
||||
config = clone
|
||||
# Provide backwards-compatibility
|
||||
if config.has_key?('auto') || config.has_key?('watch')
|
||||
Jekyll::Logger.warn "Deprecation:", "Auto-regeneration can no longer" +
|
||||
" be set from your configuration file(s). Use the"+
|
||||
" --watch/-w command-line option instead."
|
||||
config.delete('auto')
|
||||
config.delete('watch')
|
||||
end
|
||||
|
||||
if config.has_key? 'server'
|
||||
Jekyll::Logger.warn "Deprecation:", "The 'server' configuration option" +
|
||||
" is no longer accepted. Use the 'jekyll serve'" +
|
||||
" subcommand to serve your site with WEBrick."
|
||||
config.delete('server')
|
||||
end
|
||||
|
||||
if config.has_key? 'server_port'
|
||||
Jekyll::Logger.warn "Deprecation:", "The 'server_port' configuration option" +
|
||||
" has been renamed to 'port'. Please update your config" +
|
||||
" file accordingly."
|
||||
# copy but don't overwrite:
|
||||
config['port'] = config['server_port'] unless config.has_key?('port')
|
||||
config.delete('server_port')
|
||||
end
|
||||
|
||||
config
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -1,4 +1,5 @@
|
||||
module Jekyll
|
||||
|
||||
class Converter < Plugin
|
||||
# Public: Get or set the pygments prefix. When an argument is specified,
|
||||
# the prefix will be set. If no argument is specified, the current prefix
|
||||
@@ -45,4 +46,5 @@ module Jekyll
|
||||
self.class.pygments_suffix
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,21 +1,22 @@
|
||||
module Jekyll
|
||||
module Converters
|
||||
class Identity < Converter
|
||||
safe true
|
||||
|
||||
priority :lowest
|
||||
class IdentityConverter < Converter
|
||||
safe true
|
||||
|
||||
def matches(ext)
|
||||
true
|
||||
end
|
||||
priority :lowest
|
||||
|
||||
def output_ext(ext)
|
||||
ext
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
content
|
||||
end
|
||||
def matches(ext)
|
||||
true
|
||||
end
|
||||
|
||||
def output_ext(ext)
|
||||
ext
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
content
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,43 +1,113 @@
|
||||
module Jekyll
|
||||
module Converters
|
||||
class Markdown < Converter
|
||||
safe true
|
||||
|
||||
pygments_prefix "\n"
|
||||
pygments_suffix "\n"
|
||||
class MarkdownConverter < Converter
|
||||
safe true
|
||||
|
||||
def setup
|
||||
return if @setup
|
||||
@parser = case @config['markdown']
|
||||
when 'redcarpet'
|
||||
RedcarpetParser.new @config
|
||||
when 'kramdown'
|
||||
KramdownParser.new @config
|
||||
when 'rdiscount'
|
||||
RDiscountParser.new @config
|
||||
when 'maruku'
|
||||
MarukuParser.new @config
|
||||
pygments_prefix "\n"
|
||||
pygments_suffix "\n"
|
||||
|
||||
def setup
|
||||
return if @setup
|
||||
# Set the Markdown interpreter (and Maruku self.config, if necessary)
|
||||
case @config['markdown']
|
||||
when 'kramdown'
|
||||
begin
|
||||
require 'kramdown'
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Markdown. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install kramdown'
|
||||
raise FatalException.new("Missing dependency: kramdown")
|
||||
end
|
||||
when 'rdiscount'
|
||||
begin
|
||||
require 'rdiscount'
|
||||
|
||||
# Load rdiscount extensions
|
||||
@rdiscount_extensions = @config['rdiscount']['extensions'].map { |e| e.to_sym }
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Markdown. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install rdiscount'
|
||||
raise FatalException.new("Missing dependency: rdiscount")
|
||||
end
|
||||
when 'maruku'
|
||||
begin
|
||||
require 'maruku'
|
||||
|
||||
if @config['maruku']['use_divs']
|
||||
require 'maruku/ext/div'
|
||||
STDERR.puts 'Maruku: Using extended syntax for div elements.'
|
||||
end
|
||||
|
||||
if @config['maruku']['use_tex']
|
||||
require 'maruku/ext/math'
|
||||
STDERR.puts "Maruku: Using LaTeX extension. Images in `#{@config['maruku']['png_dir']}`."
|
||||
|
||||
# Switch off MathML output
|
||||
MaRuKu::Globals[:html_math_output_mathml] = false
|
||||
MaRuKu::Globals[:html_math_engine] = 'none'
|
||||
|
||||
# Turn on math to PNG support with blahtex
|
||||
# Resulting PNGs stored in `images/latex`
|
||||
MaRuKu::Globals[:html_math_output_png] = true
|
||||
MaRuKu::Globals[:html_png_engine] = @config['maruku']['png_engine']
|
||||
MaRuKu::Globals[:html_png_dir] = @config['maruku']['png_dir']
|
||||
MaRuKu::Globals[:html_png_url] = @config['maruku']['png_url']
|
||||
end
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Markdown. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install maruku'
|
||||
raise FatalException.new("Missing dependency: maruku")
|
||||
end
|
||||
else
|
||||
STDERR.puts "Invalid Markdown processor: #{@config['markdown']}"
|
||||
STDERR.puts " Valid options are [ maruku | rdiscount | kramdown ]"
|
||||
raise FatalException.new("Invalid Markdown process: #{@config['markdown']}")
|
||||
end
|
||||
@setup = true
|
||||
end
|
||||
|
||||
def matches(ext)
|
||||
ext =~ /(markdown|mkdn?|md)/i
|
||||
end
|
||||
|
||||
def output_ext(ext)
|
||||
".html"
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
setup
|
||||
case @config['markdown']
|
||||
when 'kramdown'
|
||||
# Check for use of coderay
|
||||
if @config['kramdown']['use_coderay']
|
||||
Kramdown::Document.new(content, {
|
||||
:auto_ids => @config['kramdown']['auto_ids'],
|
||||
:footnote_nr => @config['kramdown']['footnote_nr'],
|
||||
:entity_output => @config['kramdown']['entity_output'],
|
||||
:toc_levels => @config['kramdown']['toc_levels'],
|
||||
|
||||
:coderay_wrap => @config['kramdown']['coderay']['coderay_wrap'],
|
||||
:coderay_line_numbers => @config['kramdown']['coderay']['coderay_line_numbers'],
|
||||
:coderay_line_number_start => @config['kramdown']['coderay']['coderay_line_number_start'],
|
||||
:coderay_tab_width => @config['kramdown']['coderay']['coderay_tab_width'],
|
||||
:coderay_bold_every => @config['kramdown']['coderay']['coderay_bold_every'],
|
||||
:coderay_css => @config['kramdown']['coderay']['coderay_css']
|
||||
}).to_html
|
||||
else
|
||||
STDERR.puts "Invalid Markdown processor: #{@config['markdown']}"
|
||||
STDERR.puts " Valid options are [ maruku | rdiscount | kramdown | redcarpet ]"
|
||||
raise FatalException.new("Invalid Markdown process: #{@config['markdown']}")
|
||||
end
|
||||
@setup = true
|
||||
end
|
||||
|
||||
def matches(ext)
|
||||
rgx = '(' + @config['markdown_ext'].gsub(',','|') +')'
|
||||
ext =~ Regexp.new(rgx, Regexp::IGNORECASE)
|
||||
end
|
||||
|
||||
def output_ext(ext)
|
||||
".html"
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
setup
|
||||
@parser.convert(content)
|
||||
# not using coderay
|
||||
Kramdown::Document.new(content, {
|
||||
:auto_ids => @config['kramdown']['auto_ids'],
|
||||
:footnote_nr => @config['kramdown']['footnote_nr'],
|
||||
:entity_output => @config['kramdown']['entity_output'],
|
||||
:toc_levels => @config['kramdown']['toc_levels']
|
||||
}).to_html
|
||||
end
|
||||
when 'rdiscount'
|
||||
RDiscount.new(content, *@rdiscount_extensions).to_html
|
||||
when 'maruku'
|
||||
Maruku.new(content).to_html
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
module Jekyll
|
||||
module Converters
|
||||
class Markdown
|
||||
class KramdownParser
|
||||
def initialize(config)
|
||||
require 'kramdown'
|
||||
@config = config
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Markdown. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install kramdown'
|
||||
raise FatalException.new("Missing dependency: kramdown")
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
# Check for use of coderay
|
||||
kramdown_configs = if @config['kramdown']['use_coderay']
|
||||
base_kramdown_configs.merge({
|
||||
:coderay_wrap => @config['kramdown']['coderay']['coderay_wrap'],
|
||||
:coderay_line_numbers => @config['kramdown']['coderay']['coderay_line_numbers'],
|
||||
:coderay_line_number_start => @config['kramdown']['coderay']['coderay_line_number_start'],
|
||||
:coderay_tab_width => @config['kramdown']['coderay']['coderay_tab_width'],
|
||||
:coderay_bold_every => @config['kramdown']['coderay']['coderay_bold_every'],
|
||||
:coderay_css => @config['kramdown']['coderay']['coderay_css']
|
||||
})
|
||||
else
|
||||
# not using coderay
|
||||
base_kramdown_configs
|
||||
end
|
||||
Kramdown::Document.new(content, kramdown_configs).to_html
|
||||
end
|
||||
|
||||
def base_kramdown_configs
|
||||
{
|
||||
:auto_ids => @config['kramdown']['auto_ids'],
|
||||
:footnote_nr => @config['kramdown']['footnote_nr'],
|
||||
:entity_output => @config['kramdown']['entity_output'],
|
||||
:toc_levels => @config['kramdown']['toc_levels'],
|
||||
:smart_quotes => @config['kramdown']['smart_quotes']
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,47 +0,0 @@
|
||||
module Jekyll
|
||||
module Converters
|
||||
class Markdown
|
||||
class MarukuParser
|
||||
def initialize(config)
|
||||
require 'maruku'
|
||||
@config = config
|
||||
if @config['maruku']['use_divs']
|
||||
load_divs_library
|
||||
end
|
||||
if @config['maruku']['use_tex']
|
||||
load_blahtext_library
|
||||
end
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Markdown. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install maruku'
|
||||
raise FatalException.new("Missing dependency: maruku")
|
||||
end
|
||||
|
||||
def load_divs_library
|
||||
require 'maruku/ext/div'
|
||||
STDERR.puts 'Maruku: Using extended syntax for div elements.'
|
||||
end
|
||||
|
||||
def load_blahtext_library
|
||||
require 'maruku/ext/math'
|
||||
STDERR.puts "Maruku: Using LaTeX extension. Images in `#{@config['maruku']['png_dir']}`."
|
||||
|
||||
# Switch off MathML output
|
||||
MaRuKu::Globals[:html_math_output_mathml] = false
|
||||
MaRuKu::Globals[:html_math_engine] = 'none'
|
||||
|
||||
# Turn on math to PNG support with blahtex
|
||||
# Resulting PNGs stored in `images/latex`
|
||||
MaRuKu::Globals[:html_math_output_png] = true
|
||||
MaRuKu::Globals[:html_png_engine] = @config['maruku']['png_engine']
|
||||
MaRuKu::Globals[:html_png_dir] = @config['maruku']['png_dir']
|
||||
MaRuKu::Globals[:html_png_url] = @config['maruku']['png_url']
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
Maruku.new(content).to_html
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,35 +0,0 @@
|
||||
module Jekyll
|
||||
module Converters
|
||||
class Markdown
|
||||
class RDiscountParser
|
||||
def initialize(config)
|
||||
require 'rdiscount'
|
||||
@config = config
|
||||
@rdiscount_extensions = @config['rdiscount']['extensions'].map { |e| e.to_sym }
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Markdown. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install rdiscount'
|
||||
raise FatalException.new("Missing dependency: rdiscount")
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
rd = RDiscount.new(content, *@rdiscount_extensions)
|
||||
html = rd.to_html
|
||||
if @config['rdiscount']['toc_token']
|
||||
html = replace_generated_toc(rd, html, @config['rdiscount']['toc_token'])
|
||||
end
|
||||
html
|
||||
end
|
||||
|
||||
private
|
||||
def replace_generated_toc(rd, html, toc_token)
|
||||
if rd.generate_toc && html.include?(toc_token)
|
||||
html.gsub(toc_token, rd.toc_content.force_encoding('utf-8'))
|
||||
else
|
||||
html
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,70 +0,0 @@
|
||||
module Jekyll
|
||||
module Converters
|
||||
class Markdown
|
||||
class RedcarpetParser
|
||||
|
||||
module CommonMethods
|
||||
def add_code_tags(code, lang)
|
||||
code = code.sub(/<pre>/, "<pre><code class=\"#{lang} language-#{lang}\" data-lang=\"#{lang}\">")
|
||||
code = code.sub(/<\/pre>/,"</code></pre>")
|
||||
end
|
||||
end
|
||||
|
||||
module WithPygments
|
||||
include CommonMethods
|
||||
def block_code(code, lang)
|
||||
require 'pygments'
|
||||
lang = lang && lang.split.first || "text"
|
||||
output = add_code_tags(
|
||||
Pygments.highlight(code, :lexer => lang, :options => { :encoding => 'utf-8' }),
|
||||
lang
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
module WithoutPygments
|
||||
require 'cgi'
|
||||
|
||||
include CommonMethods
|
||||
|
||||
def code_wrap(code)
|
||||
"<div class=\"highlight\"><pre>#{CGI::escapeHTML(code)}</pre></div>"
|
||||
end
|
||||
|
||||
def block_code(code, lang)
|
||||
lang = lang && lang.split.first || "text"
|
||||
output = add_code_tags(code_wrap(code), lang)
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(config)
|
||||
require 'redcarpet'
|
||||
@config = config
|
||||
@redcarpet_extensions = {}
|
||||
@config['redcarpet']['extensions'].each { |e| @redcarpet_extensions[e.to_sym] = true }
|
||||
|
||||
@renderer ||= if @config['pygments']
|
||||
Class.new(Redcarpet::Render::HTML) do
|
||||
include WithPygments
|
||||
end
|
||||
else
|
||||
Class.new(Redcarpet::Render::HTML) do
|
||||
include WithoutPygments
|
||||
end
|
||||
end
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Markdown. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install redcarpet'
|
||||
raise FatalException.new("Missing dependency: redcarpet")
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
@redcarpet_extensions[:fenced_code_blocks] = !@redcarpet_extensions[:no_fenced_code_blocks]
|
||||
@renderer.send :include, Redcarpet::Render::SmartyPants if @redcarpet_extensions[:smart]
|
||||
markdown = Redcarpet::Markdown.new(@renderer.new(@redcarpet_extensions), @redcarpet_extensions)
|
||||
markdown.render(content)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,50 +1,33 @@
|
||||
module Jekyll
|
||||
module Converters
|
||||
class Textile < Converter
|
||||
safe true
|
||||
|
||||
pygments_prefix '<notextile>'
|
||||
pygments_suffix '</notextile>'
|
||||
class TextileConverter < Converter
|
||||
safe true
|
||||
|
||||
def setup
|
||||
return if @setup
|
||||
require 'redcloth'
|
||||
@setup = true
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Textile. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install RedCloth'
|
||||
raise FatalException.new("Missing dependency: RedCloth")
|
||||
end
|
||||
pygments_prefix '<notextile>'
|
||||
pygments_suffix '</notextile>'
|
||||
|
||||
def matches(ext)
|
||||
rgx = '(' + @config['textile_ext'].gsub(',','|') +')'
|
||||
ext =~ Regexp.new(rgx, Regexp::IGNORECASE)
|
||||
end
|
||||
def setup
|
||||
return if @setup
|
||||
require 'redcloth'
|
||||
@setup = true
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Textile. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install RedCloth'
|
||||
raise FatalException.new("Missing dependency: RedCloth")
|
||||
end
|
||||
|
||||
def output_ext(ext)
|
||||
".html"
|
||||
end
|
||||
def matches(ext)
|
||||
ext =~ /textile/i
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
setup
|
||||
def output_ext(ext)
|
||||
".html"
|
||||
end
|
||||
|
||||
# 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 http://redcloth.rubyforge.org/classes/RedCloth/TextileDoc.html)
|
||||
attrs = ['filter_classes', 'filter_html', 'filter_ids', 'filter_styles',
|
||||
'hard_breaks', 'lite_mode', 'no_span_caps', 'sanitize_html']
|
||||
|
||||
r = RedCloth.new(content)
|
||||
|
||||
# Set attributes in r if they are NOT nil in the config
|
||||
attrs.each do |attr|
|
||||
r.instance_variable_set("@#{attr}".to_sym, @config['redcloth'][attr]) unless @config['redcloth'][attr].nil?
|
||||
end
|
||||
|
||||
r.to_html
|
||||
end
|
||||
def convert(content)
|
||||
setup
|
||||
RedCloth.new(content).to_html
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
require 'set'
|
||||
|
||||
# Convertible provides methods for converting a pagelike item
|
||||
# from a certain type of markup into actual content
|
||||
#
|
||||
@@ -12,7 +8,6 @@ require 'set'
|
||||
# self.data=
|
||||
# self.ext=
|
||||
# self.output=
|
||||
# self.name
|
||||
module Jekyll
|
||||
module Convertible
|
||||
# Returns the contents as a String.
|
||||
@@ -27,17 +22,16 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_yaml(base, name)
|
||||
begin
|
||||
self.content = File.read(File.join(base, name))
|
||||
self.content = File.read(File.join(base, name))
|
||||
|
||||
if self.content =~ /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
||||
self.content = $POSTMATCH
|
||||
self.data = YAML.safe_load($1)
|
||||
if self.content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m
|
||||
self.content = $POSTMATCH
|
||||
|
||||
begin
|
||||
self.data = YAML.load($1)
|
||||
rescue => e
|
||||
puts "YAML Exception: #{e.message}"
|
||||
end
|
||||
rescue SyntaxError => e
|
||||
puts "YAML Exception reading #{File.join(base, name)}: #{e.message}"
|
||||
rescue Exception => e
|
||||
puts "Error reading file #{File.join(base, name)}: #{e.message}"
|
||||
end
|
||||
|
||||
self.data ||= {}
|
||||
@@ -66,52 +60,6 @@ module Jekyll
|
||||
@converter ||= self.site.converters.find { |c| c.matches(self.ext) }
|
||||
end
|
||||
|
||||
# Render Liquid in the content
|
||||
#
|
||||
# content - the raw Liquid content to render
|
||||
# payload - the payload for Liquid
|
||||
# info - the info for Liquid
|
||||
#
|
||||
# Returns the converted content
|
||||
def render_liquid(content, payload, info)
|
||||
Liquid::Template.parse(content).render!(payload, info)
|
||||
rescue Exception => e
|
||||
Jekyll::Logger.error "Liquid Exception:", "#{e.message} in #{payload[:file]}"
|
||||
e.backtrace.each do |backtrace|
|
||||
puts backtrace
|
||||
end
|
||||
abort("Build Failed")
|
||||
end
|
||||
|
||||
# Recursively render layouts
|
||||
#
|
||||
# layouts - a list of the layouts
|
||||
# payload - the payload for Liquid
|
||||
# info - the info for Liquid
|
||||
#
|
||||
# Returns nothing
|
||||
def render_all_layouts(layouts, payload, info)
|
||||
# recursively render layouts
|
||||
layout = layouts[self.data["layout"]]
|
||||
used = Set.new([layout])
|
||||
|
||||
while layout
|
||||
payload = payload.deep_merge({"content" => self.output, "page" => layout.data})
|
||||
|
||||
self.output = self.render_liquid(layout.content,
|
||||
payload.merge({:file => self.data["layout"]}),
|
||||
info)
|
||||
|
||||
if layout = layouts[layout.data["layout"]]
|
||||
if used.include?(layout)
|
||||
layout = nil # avoid recursive chain
|
||||
else
|
||||
used << layout
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Add any necessary layouts to this convertible document.
|
||||
#
|
||||
# payload - The site payload Hash.
|
||||
@@ -119,33 +67,35 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def do_layout(payload, layouts)
|
||||
info = { :filters => [Jekyll::Filters], :registers => { :site => self.site, :page => payload['page'] } }
|
||||
info = { :filters => [Jekyll::Filters], :registers => { :site => self.site } }
|
||||
|
||||
# render and transform content (this becomes the final content of the object)
|
||||
payload["pygments_prefix"] = converter.pygments_prefix
|
||||
payload["pygments_suffix"] = converter.pygments_suffix
|
||||
|
||||
self.content = self.render_liquid(self.content,
|
||||
payload.merge({:file => self.name}),
|
||||
info)
|
||||
begin
|
||||
self.content = Liquid::Template.parse(self.content).render(payload, info)
|
||||
rescue => e
|
||||
puts "Liquid Exception: #{e.message} in #{self.data["layout"]}"
|
||||
end
|
||||
|
||||
self.transform
|
||||
|
||||
# output keeps track of what will finally be written
|
||||
self.output = self.content
|
||||
|
||||
self.render_all_layouts(layouts, payload, info)
|
||||
end
|
||||
# recursively render layouts
|
||||
layout = layouts[self.data["layout"]]
|
||||
while layout
|
||||
payload = payload.deep_merge({"content" => self.output, "page" => layout.data})
|
||||
|
||||
# Write the generated page file to the destination directory.
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
#
|
||||
# Returns nothing.
|
||||
def write(dest)
|
||||
path = destination(dest)
|
||||
FileUtils.mkdir_p(File.dirname(path))
|
||||
File.open(path, 'w') do |f|
|
||||
f.write(self.output)
|
||||
begin
|
||||
self.output = Liquid::Template.parse(layout.content).render(payload, info)
|
||||
rescue => e
|
||||
puts "Liquid Exception: #{e.message} in #{self.data["layout"]}"
|
||||
end
|
||||
|
||||
layout = layouts[layout.data["layout"]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -24,7 +24,7 @@ class Hash
|
||||
# and then the plural key, and handling any nil entries.
|
||||
# +hash+ the hash to read from
|
||||
# +singular_key+ the singular key
|
||||
# +plural_key+ the plural key
|
||||
# +plural_key+ the singular key
|
||||
#
|
||||
# Returns an array
|
||||
def pluralized_array(singular_key, plural_key)
|
||||
@@ -50,19 +50,3 @@ class Date
|
||||
strftime("%Y-%m-%dT%H:%M:%S%Z")
|
||||
end if RUBY_VERSION < '1.9'
|
||||
end
|
||||
|
||||
module Enumerable
|
||||
# Returns true if path matches against any glob pattern.
|
||||
# Look for more detail about glob pattern in method File::fnmatch.
|
||||
def glob_include?(e)
|
||||
any? { |exp| File.fnmatch?(exp, e) }
|
||||
end
|
||||
end
|
||||
|
||||
if RUBY_VERSION < "1.9"
|
||||
class String
|
||||
def force_encoding(enc)
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
module Jekyll
|
||||
class Deprecator
|
||||
def self.process(args)
|
||||
no_subcommand(args)
|
||||
deprecation_message args, "--server", "The --server command has been replaced by the \
|
||||
'serve' subcommand."
|
||||
deprecation_message args, "--no-server", "To build Jekyll without launching a server, \
|
||||
use the 'build' subcommand."
|
||||
deprecation_message args, "--auto", "The switch '--auto' has been replaced with '--watch'."
|
||||
deprecation_message args, "--no-auto", "To disable auto-replication, simply leave off \
|
||||
the '--watch' switch."
|
||||
deprecation_message args, "--pygments", "The 'pygments' setting can only be set in \
|
||||
your config files."
|
||||
deprecation_message args, "--paginate", "The 'paginate' setting can only be set in your \
|
||||
config files."
|
||||
deprecation_message args, "--url", "The 'url' setting can only be set in your config files."
|
||||
end
|
||||
|
||||
def self.no_subcommand(args)
|
||||
if args.size > 0 && args.first =~ /^--/ && !%w[--help --version].include?(args.first)
|
||||
Jekyll::Logger.error "Deprecation:", "Jekyll now uses subcommands instead of just \
|
||||
switches. Run `jekyll help' to find out more."
|
||||
end
|
||||
end
|
||||
|
||||
def self.deprecation_message(args, deprecated_argument, message)
|
||||
if args.include?(deprecated_argument)
|
||||
Jekyll::Logger.error "Deprecation:", message
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,35 +0,0 @@
|
||||
module Jekyll
|
||||
|
||||
class Draft < Post
|
||||
|
||||
# Valid post name regex (no date)
|
||||
MATCHER = /^(.*)(\.[^.]+)$/
|
||||
|
||||
# Draft name validator. Draft filenames must be like:
|
||||
# my-awesome-post.textile
|
||||
#
|
||||
# Returns true if valid, false if not.
|
||||
def self.valid?(name)
|
||||
name =~ MATCHER
|
||||
end
|
||||
|
||||
# Get the full path to the directory containing the draft files
|
||||
def containing_dir(source, dir)
|
||||
File.join(source, dir, '_drafts')
|
||||
end
|
||||
|
||||
# Extract information from the post filename.
|
||||
#
|
||||
# name - The String filename of the post file.
|
||||
#
|
||||
# Returns nothing.
|
||||
def process(name)
|
||||
m, slug, ext = *name.match(MATCHER)
|
||||
self.date = File.mtime(File.join(@base, name))
|
||||
self.slug = slug
|
||||
self.ext = ext
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,4 +1,6 @@
|
||||
module Jekyll
|
||||
|
||||
class FatalException < StandardError
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,101 +1,28 @@
|
||||
require 'uri'
|
||||
|
||||
module Jekyll
|
||||
|
||||
module Filters
|
||||
# Convert a Textile string into HTML output.
|
||||
#
|
||||
# input - The Textile String to convert.
|
||||
#
|
||||
# Returns the HTML formatted String.
|
||||
def textilize(input)
|
||||
site = @context.registers[:site]
|
||||
converter = site.getConverterImpl(Jekyll::Converters::Textile)
|
||||
converter.convert(input)
|
||||
TextileConverter.new.convert(input)
|
||||
end
|
||||
|
||||
# Convert a Markdown string into HTML output.
|
||||
#
|
||||
# input - The Markdown String to convert.
|
||||
#
|
||||
# Returns the HTML formatted String.
|
||||
def markdownify(input)
|
||||
site = @context.registers[:site]
|
||||
converter = site.getConverterImpl(Jekyll::Converters::Markdown)
|
||||
converter.convert(input)
|
||||
end
|
||||
|
||||
# Format a date in short format e.g. "27 Jan 2011".
|
||||
#
|
||||
# date - the Time to format.
|
||||
#
|
||||
# Returns the formatting String.
|
||||
def date_to_string(date)
|
||||
time(date).strftime("%d %b %Y")
|
||||
date.strftime("%d %b %Y")
|
||||
end
|
||||
|
||||
# Format a date in long format e.g. "27 January 2011".
|
||||
#
|
||||
# date - The Time to format.
|
||||
#
|
||||
# Returns the formatted String.
|
||||
def date_to_long_string(date)
|
||||
time(date).strftime("%d %B %Y")
|
||||
date.strftime("%d %B %Y")
|
||||
end
|
||||
|
||||
# Format a date for use in XML.
|
||||
#
|
||||
# date - The Time to format.
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# date_to_xmlschema(Time.now)
|
||||
# # => "2011-04-24T20:34:46+08:00"
|
||||
#
|
||||
# Returns the formatted String.
|
||||
def date_to_xmlschema(date)
|
||||
time(date).xmlschema
|
||||
date.xmlschema
|
||||
end
|
||||
|
||||
# Format a date according to RFC-822
|
||||
#
|
||||
# date - The Time to format.
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# date_to_rfc822(Time.now)
|
||||
# # => "Sun, 24 Apr 2011 12:34:46 +0000"
|
||||
#
|
||||
# Returns the formatted String.
|
||||
def date_to_rfc822(date)
|
||||
time(date).rfc822
|
||||
end
|
||||
|
||||
# XML escape a string for use. Replaces any special characters with
|
||||
# appropriate HTML entity replacements.
|
||||
#
|
||||
# input - The String to escape.
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# xml_escape('foo "bar" <baz>')
|
||||
# # => "foo "bar" <baz>"
|
||||
#
|
||||
# Returns the escaped String.
|
||||
def xml_escape(input)
|
||||
CGI.escapeHTML(input)
|
||||
end
|
||||
|
||||
# CGI escape a string for use in a URL. Replaces any special characters
|
||||
# with appropriate %XX replacements.
|
||||
#
|
||||
# input - The String to escape.
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# cgi_escape('foo,bar;baz?')
|
||||
# # => "foo%2Cbar%3Bbaz%3F"
|
||||
#
|
||||
# Returns the escaped String.
|
||||
def cgi_escape(input)
|
||||
CGI::escape(input)
|
||||
end
|
||||
@@ -104,26 +31,10 @@ module Jekyll
|
||||
URI.escape(input)
|
||||
end
|
||||
|
||||
# Count the number of words in the input string.
|
||||
#
|
||||
# input - The String on which to operate.
|
||||
#
|
||||
# Returns the Integer word count.
|
||||
def number_of_words(input)
|
||||
input.split.length
|
||||
end
|
||||
|
||||
# Join an array of things into a string by separating with commes and the
|
||||
# word "and" for the last one.
|
||||
#
|
||||
# array - The Array of Strings to join.
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# array_to_sentence_string(["apples", "oranges", "grapes"])
|
||||
# # => "apples, oranges, and grapes"
|
||||
#
|
||||
# Returns the formatted String.
|
||||
def array_to_sentence_string(array)
|
||||
connector = "and"
|
||||
case array.length
|
||||
@@ -138,17 +49,5 @@ module Jekyll
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def time(input)
|
||||
case input
|
||||
when Time
|
||||
input
|
||||
when String
|
||||
Time.parse(input)
|
||||
else
|
||||
Jekyll::Logger.error "Invalid Date:", "'#{input}' is not a valid datetime."
|
||||
exit(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
module Jekyll
|
||||
|
||||
class Generator < Plugin
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,108 +1,57 @@
|
||||
module Jekyll
|
||||
module Generators
|
||||
class Pagination < Generator
|
||||
# This generator is safe from arbitrary code execution.
|
||||
safe true
|
||||
|
||||
# Generate paginated pages if necessary.
|
||||
#
|
||||
# site - The Site.
|
||||
#
|
||||
# Returns nothing.
|
||||
def generate(site)
|
||||
site.pages.dup.each do |page|
|
||||
paginate(site, page) if Pager.pagination_enabled?(site.config, page)
|
||||
end
|
||||
class Pagination < Generator
|
||||
safe true
|
||||
|
||||
def generate(site)
|
||||
site.pages.dup.each do |page|
|
||||
paginate(site, page) if Pager.pagination_enabled?(site.config, page.name)
|
||||
end
|
||||
|
||||
# Paginates the blog's posts. Renders the index.html file into paginated
|
||||
# directories, e.g.: page2/index.html, page3/index.html, etc and adds more
|
||||
# site-wide data.
|
||||
#
|
||||
# site - The Site.
|
||||
# page - The index.html Page that requires pagination.
|
||||
#
|
||||
# {"paginator" => { "page" => <Number>,
|
||||
# "per_page" => <Number>,
|
||||
# "posts" => [<Post>],
|
||||
# "total_posts" => <Number>,
|
||||
# "total_pages" => <Number>,
|
||||
# "previous_page" => <Number>,
|
||||
# "next_page" => <Number> }}
|
||||
def paginate(site, page)
|
||||
all_posts = site.site_payload['site']['posts']
|
||||
pages = Pager.calculate_pages(all_posts, site.config['paginate'].to_i)
|
||||
(1..pages).each do |num_page|
|
||||
pager = Pager.new(site.config, num_page, all_posts, pages)
|
||||
if num_page > 1
|
||||
newpage = Page.new(site, site.source, page.dir, page.name)
|
||||
newpage.pager = pager
|
||||
newpage.dir = File.join(page.dir, Pager.paginate_path(site.config, num_page))
|
||||
site.pages << newpage
|
||||
else
|
||||
page.pager = pager
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Paginates the blog's posts. Renders the index.html file into paginated
|
||||
# directories, ie: page2/index.html, page3/index.html, etc and adds more
|
||||
# site-wide data.
|
||||
# +page+ is the index.html Page that requires pagination
|
||||
#
|
||||
# {"paginator" => { "page" => <Number>,
|
||||
# "per_page" => <Number>,
|
||||
# "posts" => [<Post>],
|
||||
# "total_posts" => <Number>,
|
||||
# "total_pages" => <Number>,
|
||||
# "previous_page" => <Number>,
|
||||
# "next_page" => <Number> }}
|
||||
def paginate(site, page)
|
||||
all_posts = site.site_payload['site']['posts']
|
||||
pages = Pager.calculate_pages(all_posts, site.config['paginate'].to_i)
|
||||
(1..pages).each do |num_page|
|
||||
pager = Pager.new(site.config, num_page, all_posts, pages)
|
||||
if num_page > 1
|
||||
newpage = Page.new(site, site.source, page.dir, page.name)
|
||||
newpage.pager = pager
|
||||
newpage.dir = File.join(page.dir, "page#{num_page}")
|
||||
site.pages << newpage
|
||||
else
|
||||
page.pager = pager
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class Pager
|
||||
attr_reader :page, :per_page, :posts, :total_posts, :total_pages,
|
||||
:previous_page, :previous_page_path, :next_page, :next_page_path
|
||||
attr_reader :page, :per_page, :posts, :total_posts, :total_pages, :previous_page, :next_page
|
||||
|
||||
# Calculate the number of pages.
|
||||
#
|
||||
# all_posts - The Array of all Posts.
|
||||
# per_page - The Integer of entries per page.
|
||||
#
|
||||
# Returns the Integer number of pages.
|
||||
def self.calculate_pages(all_posts, per_page)
|
||||
(all_posts.size.to_f / per_page.to_i).ceil
|
||||
num_pages = all_posts.size / per_page.to_i
|
||||
num_pages = num_pages + 1 if all_posts.size % per_page.to_i != 0
|
||||
num_pages
|
||||
end
|
||||
|
||||
# Determine if pagination is enabled for a given file.
|
||||
#
|
||||
# config - The configuration Hash.
|
||||
# page - The Jekyll::Page with which to paginate
|
||||
#
|
||||
# Returns true if pagination is enabled, false otherwise.
|
||||
def self.pagination_enabled?(config, page)
|
||||
!config['paginate'].nil? &&
|
||||
page.name == 'index.html' &&
|
||||
subdirectories_identical(config['paginate_path'], page.dir)
|
||||
def self.pagination_enabled?(config, file)
|
||||
file == 'index.html' && !config['paginate'].nil?
|
||||
end
|
||||
|
||||
# Determine if the subdirectories of the two paths are the same relative to source
|
||||
#
|
||||
# paginate_path - the paginate_path configuration setting
|
||||
# page_dir - the directory of the Jekyll::Page
|
||||
#
|
||||
# Returns whether the subdirectories are the same relative to source
|
||||
def self.subdirectories_identical(paginate_path, page_dir)
|
||||
File.dirname(paginate_path).gsub(/\A\./, '') == page_dir.gsub(/\/\z/, '')
|
||||
end
|
||||
|
||||
# Static: Return the pagination path of the page
|
||||
#
|
||||
# site_config - the site config
|
||||
# num_page - the pagination page number
|
||||
#
|
||||
# Returns the pagination path as a string
|
||||
def self.paginate_path(site_config, num_page)
|
||||
return nil if num_page.nil? || num_page <= 1
|
||||
format = File.basename(site_config['paginate_path'])
|
||||
format.sub(':num', num_page.to_s)
|
||||
end
|
||||
|
||||
# Initialize a new Pager.
|
||||
#
|
||||
# config - The Hash configuration of the site.
|
||||
# page - The Integer page number.
|
||||
# all_posts - The Array of all the site's Posts.
|
||||
# num_pages - The Integer number of pages or nil if you'd like the number
|
||||
# of pages calculated.
|
||||
def initialize(config, page, all_posts, num_pages = nil)
|
||||
@page = page
|
||||
@per_page = config['paginate'].to_i
|
||||
@@ -118,14 +67,9 @@ module Jekyll
|
||||
@total_posts = all_posts.size
|
||||
@posts = all_posts[init..offset]
|
||||
@previous_page = @page != 1 ? @page - 1 : nil
|
||||
@previous_page_path = Pager.paginate_path(config, @previous_page)
|
||||
@next_page = @page != @total_pages ? @page + 1 : nil
|
||||
@next_page_path = Pager.paginate_path(config, @next_page)
|
||||
end
|
||||
|
||||
# Convert this Pager's data to a Hash suitable for use by Liquid.
|
||||
#
|
||||
# Returns the Hash representation of this Pager.
|
||||
def to_liquid
|
||||
{
|
||||
'page' => page,
|
||||
@@ -134,10 +78,10 @@ module Jekyll
|
||||
'total_posts' => total_posts,
|
||||
'total_pages' => total_pages,
|
||||
'previous_page' => previous_page,
|
||||
'previous_page_path' => previous_page_path,
|
||||
'next_page' => next_page,
|
||||
'next_page_path' => next_page_path
|
||||
'next_page' => next_page
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -1,24 +1,18 @@
|
||||
module Jekyll
|
||||
|
||||
class Layout
|
||||
include Convertible
|
||||
|
||||
# Gets the Site object.
|
||||
attr_reader :site
|
||||
|
||||
# Gets/Sets the extension of this layout.
|
||||
attr_accessor :site
|
||||
attr_accessor :ext
|
||||
|
||||
# Gets/Sets the Hash that holds the metadata for this layout.
|
||||
attr_accessor :data
|
||||
|
||||
# Gets/Sets the content of this layout.
|
||||
attr_accessor :content
|
||||
attr_accessor :data, :content
|
||||
|
||||
# Initialize a new Layout.
|
||||
# +site+ is the Site
|
||||
# +base+ is the String path to the <source>
|
||||
# +name+ is the String filename of the post file
|
||||
#
|
||||
# site - The Site.
|
||||
# base - The String path to the source.
|
||||
# name - The String filename of the post file.
|
||||
# Returns <Page>
|
||||
def initialize(site, base, name)
|
||||
@site = site
|
||||
@base = base
|
||||
@@ -30,13 +24,13 @@ module Jekyll
|
||||
self.read_yaml(base, name)
|
||||
end
|
||||
|
||||
# Extract information from the layout filename.
|
||||
# Extract information from the layout filename
|
||||
# +name+ is the String filename of the layout file
|
||||
#
|
||||
# name - The String filename of the layout file.
|
||||
#
|
||||
# Returns nothing.
|
||||
# Returns nothing
|
||||
def process(name)
|
||||
self.ext = File.extname(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,54 +0,0 @@
|
||||
require 'logger'
|
||||
|
||||
module Jekyll
|
||||
class Logger < Logger
|
||||
# Public: Print a jekyll message to stdout
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def self.info(topic, message)
|
||||
$stdout.puts message(topic, message)
|
||||
end
|
||||
|
||||
# Public: Print a jekyll message to stderr
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def self.warn(topic, message)
|
||||
$stderr.puts message(topic, message).yellow
|
||||
end
|
||||
|
||||
# Public: Print a jekyll error message to stderr
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns nothing
|
||||
def self.error(topic, message)
|
||||
$stderr.puts message(topic, message).red
|
||||
end
|
||||
|
||||
# Public: Build a Jekyll topic method
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
# message - the message detail
|
||||
#
|
||||
# Returns the formatted message
|
||||
def self.message(topic, message)
|
||||
formatted_topic(topic) + message.gsub(/\s+/, ' ')
|
||||
end
|
||||
|
||||
# Public: Format the topic
|
||||
#
|
||||
# topic - the topic of the message, e.g. "Configuration file", "Deprecation", etc.
|
||||
#
|
||||
# Returns the formatted topic statement
|
||||
def self.formatted_topic(topic)
|
||||
"#{topic} ".rjust(20)
|
||||
end
|
||||
end
|
||||
end
|
||||
26
lib/jekyll/migrators/csv.rb
Normal file
26
lib/jekyll/migrators/csv.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
module Jekyll
|
||||
module CSV
|
||||
#Reads a csv with title, permalink, body, published_at, and filter.
|
||||
#It creates a post file for each row in the csv
|
||||
def self.process(file = "posts.csv")
|
||||
FileUtils.mkdir_p "_posts"
|
||||
posts = 0
|
||||
FasterCSV.foreach(file) do |row|
|
||||
next if row[0] == "title"
|
||||
posts += 1
|
||||
name = row[3].split(" ")[0]+"-"+row[1]+(row[4] =~ /markdown/ ? ".markdown" : ".textile")
|
||||
File.open("_posts/#{name}", "w") do |f|
|
||||
f.puts <<-HEADER
|
||||
---
|
||||
layout: post
|
||||
title: #{row[0]}
|
||||
---
|
||||
|
||||
HEADER
|
||||
f.puts row[2]
|
||||
end
|
||||
end
|
||||
"Created #{posts} posts!"
|
||||
end
|
||||
end
|
||||
end
|
||||
86
lib/jekyll/migrators/drupal.rb
Normal file
86
lib/jekyll/migrators/drupal.rb
Normal file
@@ -0,0 +1,86 @@
|
||||
require 'rubygems'
|
||||
require 'sequel'
|
||||
require 'fileutils'
|
||||
require 'yaml'
|
||||
|
||||
# NOTE: This converter requires Sequel and the MySQL gems.
|
||||
# The MySQL gem can be difficult to install on OS X. Once you have MySQL
|
||||
# installed, running the following commands should work:
|
||||
# $ sudo gem install sequel
|
||||
# $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
|
||||
|
||||
module Jekyll
|
||||
module Drupal
|
||||
|
||||
# Reads a MySQL database via Sequel and creates a post file for each
|
||||
# post in wp_posts that has post_status = 'publish'.
|
||||
# This restriction is made because 'draft' posts are not guaranteed to
|
||||
# have valid dates.
|
||||
QUERY = "SELECT node.nid, node.title, node_revisions.body, node.created, node.status FROM node, node_revisions WHERE (node.type = 'blog' OR node.type = 'story') AND node.vid = node_revisions.vid"
|
||||
|
||||
def self.process(dbname, user, pass, host = 'localhost')
|
||||
db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
|
||||
|
||||
FileUtils.mkdir_p "_posts"
|
||||
FileUtils.mkdir_p "_drafts"
|
||||
|
||||
# Create the refresh layout
|
||||
# Change the refresh url if you customized your permalink config
|
||||
File.open("_layouts/refresh.html", "w") do |f|
|
||||
f.puts <<EOF
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="refresh" content="0;url={{ page.refresh_to_post_id }}.html" />
|
||||
</head>
|
||||
</html>
|
||||
EOF
|
||||
end
|
||||
|
||||
db[QUERY].each do |post|
|
||||
# Get required fields and construct Jekyll compatible name
|
||||
node_id = post[:nid]
|
||||
title = post[:title]
|
||||
content = post[:body]
|
||||
created = post[:created]
|
||||
time = Time.at(created)
|
||||
is_published = post[:status] == 1
|
||||
dir = is_published ? "_posts" : "_drafts"
|
||||
slug = title.strip.downcase.gsub(/(&|&)/, ' and ').gsub(/[\s\.\/\\]/, '-').gsub(/[^\w-]/, '').gsub(/[-_]{2,}/, '-').gsub(/^[-_]/, '').gsub(/[-_]$/, '')
|
||||
name = time.strftime("%Y-%m-%d-") + slug + '.md'
|
||||
|
||||
# Get the relevant fields as a hash, delete empty fields and convert
|
||||
# to YAML for the header
|
||||
data = {
|
||||
'layout' => 'post',
|
||||
'title' => title.to_s,
|
||||
'created' => created,
|
||||
}.delete_if { |k,v| v.nil? || v == ''}.to_yaml
|
||||
|
||||
# Write out the data and content to file
|
||||
File.open("#{dir}/#{name}", "w") do |f|
|
||||
f.puts data
|
||||
f.puts "---"
|
||||
f.puts content
|
||||
end
|
||||
|
||||
# Make a file to redirect from the old Drupal URL
|
||||
if is_published
|
||||
FileUtils.mkdir_p "node/#{node_id}"
|
||||
File.open("node/#{node_id}/index.md", "w") do |f|
|
||||
f.puts "---"
|
||||
f.puts "layout: refresh"
|
||||
f.puts "refresh_to_post_id: /#{time.strftime("%Y/%m/%d/") + slug}"
|
||||
f.puts "---"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: Make dirs & files for nodes of type 'page'
|
||||
# Make refresh pages for these as well
|
||||
|
||||
# TODO: Make refresh dirs & files according to entries in url_alias table
|
||||
end
|
||||
end
|
||||
end
|
||||
53
lib/jekyll/migrators/marley.rb
Normal file
53
lib/jekyll/migrators/marley.rb
Normal file
@@ -0,0 +1,53 @@
|
||||
require 'yaml'
|
||||
require 'fileutils'
|
||||
|
||||
module Jekyll
|
||||
module Marley
|
||||
|
||||
def self.regexp
|
||||
{ :id => /^\d{0,4}-{0,1}(.*)$/,
|
||||
:title => /^#\s*(.*)\s+$/,
|
||||
:title_with_date => /^#\s*(.*)\s+\(([0-9\/]+)\)$/,
|
||||
:published_on => /.*\s+\(([0-9\/]+)\)$/,
|
||||
:perex => /^([^\#\n]+\n)$/,
|
||||
:meta => /^\{\{\n(.*)\}\}\n$/mi # Multiline Regexp
|
||||
}
|
||||
end
|
||||
|
||||
def self.process(marley_data_dir)
|
||||
raise ArgumentError, "marley dir #{marley_data_dir} not found" unless File.directory?(marley_data_dir)
|
||||
|
||||
FileUtils.mkdir_p "_posts"
|
||||
|
||||
posts = 0
|
||||
Dir["#{marley_data_dir}/**/*.txt"].each do |f|
|
||||
next unless File.exists?(f)
|
||||
|
||||
#copied over from marley's app/lib/post.rb
|
||||
file_content = File.read(f)
|
||||
meta_content = file_content.slice!( self.regexp[:meta] )
|
||||
body = file_content.sub( self.regexp[:title], '').sub( self.regexp[:perex], '').strip
|
||||
|
||||
title = file_content.scan( self.regexp[:title] ).first.to_s.strip
|
||||
prerex = file_content.scan( self.regexp[:perex] ).first.to_s.strip
|
||||
published_on = DateTime.parse( post[:published_on] ) rescue File.mtime( File.dirname(f) )
|
||||
meta = ( meta_content ) ? YAML::load( meta_content.scan( self.regexp[:meta]).to_s ) : {}
|
||||
meta['title'] = title
|
||||
meta['layout'] = 'post'
|
||||
|
||||
formatted_date = published_on.strftime('%Y-%m-%d')
|
||||
post_name = File.dirname(f).split(%r{/}).last.gsub(/\A\d+-/, '')
|
||||
|
||||
name = "#{formatted_date}-#{post_name}"
|
||||
File.open("_posts/#{name}.markdown", "w") do |f|
|
||||
f.puts meta.to_yaml
|
||||
f.puts "---\n"
|
||||
f.puts "\n#{prerex}\n\n" if prerex
|
||||
f.puts body
|
||||
end
|
||||
posts += 1
|
||||
end
|
||||
"Created #{posts} posts!"
|
||||
end
|
||||
end
|
||||
end
|
||||
79
lib/jekyll/migrators/mephisto.rb
Normal file
79
lib/jekyll/migrators/mephisto.rb
Normal file
@@ -0,0 +1,79 @@
|
||||
# Quickly hacked together my Michael Ivey
|
||||
# Based on mt.rb by Nick Gerakines, open source and publically
|
||||
# available under the MIT license. Use this module at your own risk.
|
||||
|
||||
require 'rubygems'
|
||||
require 'sequel'
|
||||
require 'fastercsv'
|
||||
require 'fileutils'
|
||||
require File.join(File.dirname(__FILE__),"csv.rb")
|
||||
|
||||
# NOTE: This converter requires Sequel and the MySQL gems.
|
||||
# The MySQL gem can be difficult to install on OS X. Once you have MySQL
|
||||
# installed, running the following commands should work:
|
||||
# $ sudo gem install sequel
|
||||
# $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
|
||||
|
||||
module Jekyll
|
||||
module Mephisto
|
||||
#Accepts a hash with database config variables, exports mephisto posts into a csv
|
||||
#export PGPASSWORD if you must
|
||||
def self.postgres(c)
|
||||
sql = <<-SQL
|
||||
BEGIN;
|
||||
CREATE TEMP TABLE jekyll AS
|
||||
SELECT title, permalink, body, published_at, filter FROM contents
|
||||
WHERE user_id = 1 AND type = 'Article' ORDER BY published_at;
|
||||
COPY jekyll TO STDOUT WITH CSV HEADER;
|
||||
ROLLBACK;
|
||||
SQL
|
||||
command = %Q(psql -h #{c[:host] || "localhost"} -c "#{sql.strip}" #{c[:database]} #{c[:username]} -o #{c[:filename] || "posts.csv"})
|
||||
puts command
|
||||
`#{command}`
|
||||
CSV.process
|
||||
end
|
||||
|
||||
# This query will pull blog posts from all entries across all blogs. If
|
||||
# you've got unpublished, deleted or otherwise hidden posts please sift
|
||||
# through the created posts to make sure nothing is accidently published.
|
||||
|
||||
QUERY = "SELECT id, permalink, body, published_at, title FROM contents WHERE user_id = 1 AND type = 'Article' AND published_at IS NOT NULL ORDER BY published_at"
|
||||
|
||||
def self.process(dbname, user, pass, host = 'localhost')
|
||||
db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
|
||||
|
||||
FileUtils.mkdir_p "_posts"
|
||||
|
||||
db[QUERY].each do |post|
|
||||
title = post[:title]
|
||||
slug = post[:permalink]
|
||||
date = post[:published_at]
|
||||
content = post[:body]
|
||||
# more_content = ''
|
||||
|
||||
# Be sure to include the body and extended body.
|
||||
# if more_content != nil
|
||||
# content = content + " \n" + more_content
|
||||
# end
|
||||
|
||||
# Ideally, this script would determine the post format (markdown, html
|
||||
# , etc) and create files with proper extensions. At this point it
|
||||
# just assumes that markdown will be acceptable.
|
||||
name = [date.year, date.month, date.day, slug].join('-') + ".markdown"
|
||||
|
||||
data = {
|
||||
'layout' => 'post',
|
||||
'title' => title.to_s,
|
||||
'mt_id' => post[:entry_id],
|
||||
}.delete_if { |k,v| v.nil? || v == ''}.to_yaml
|
||||
|
||||
File.open("_posts/#{name}", "w") do |f|
|
||||
f.puts data
|
||||
f.puts "---"
|
||||
f.puts content
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
77
lib/jekyll/migrators/mt.rb
Normal file
77
lib/jekyll/migrators/mt.rb
Normal file
@@ -0,0 +1,77 @@
|
||||
# Created by Nick Gerakines, open source and publically available under the
|
||||
# MIT license. Use this module at your own risk.
|
||||
# I'm an Erlang/Perl/C++ guy so please forgive my dirty ruby.
|
||||
|
||||
require 'rubygems'
|
||||
require 'sequel'
|
||||
require 'fileutils'
|
||||
require 'yaml'
|
||||
|
||||
# NOTE: This converter requires Sequel and the MySQL gems.
|
||||
# The MySQL gem can be difficult to install on OS X. Once you have MySQL
|
||||
# installed, running the following commands should work:
|
||||
# $ sudo gem install sequel
|
||||
# $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
|
||||
|
||||
module Jekyll
|
||||
module MT
|
||||
# This query will pull blog posts from all entries across all blogs. If
|
||||
# you've got unpublished, deleted or otherwise hidden posts please sift
|
||||
# through the created posts to make sure nothing is accidently published.
|
||||
QUERY = "SELECT entry_id, entry_basename, entry_text, entry_text_more, entry_authored_on, entry_title, entry_convert_breaks FROM mt_entry"
|
||||
|
||||
def self.process(dbname, user, pass, host = 'localhost')
|
||||
db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
|
||||
|
||||
FileUtils.mkdir_p "_posts"
|
||||
|
||||
db[QUERY].each do |post|
|
||||
title = post[:entry_title]
|
||||
slug = post[:entry_basename].gsub(/_/, '-')
|
||||
date = post[:entry_authored_on]
|
||||
content = post[:entry_text]
|
||||
more_content = post[:entry_text_more]
|
||||
entry_convert_breaks = post[:entry_convert_breaks]
|
||||
|
||||
# Be sure to include the body and extended body.
|
||||
if more_content != nil
|
||||
content = content + " \n" + more_content
|
||||
end
|
||||
|
||||
# Ideally, this script would determine the post format (markdown, html
|
||||
# , etc) and create files with proper extensions. At this point it
|
||||
# just assumes that markdown will be acceptable.
|
||||
name = [date.year, date.month, date.day, slug].join('-') + '.' + self.suffix(entry_convert_breaks)
|
||||
|
||||
data = {
|
||||
'layout' => 'post',
|
||||
'title' => title.to_s,
|
||||
'mt_id' => post[:entry_id],
|
||||
'date' => date
|
||||
}.delete_if { |k,v| v.nil? || v == ''}.to_yaml
|
||||
|
||||
File.open("_posts/#{name}", "w") do |f|
|
||||
f.puts data
|
||||
f.puts "---"
|
||||
f.puts content
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.suffix(entry_type)
|
||||
if entry_type.nil? || entry_type.include?("markdown")
|
||||
# The markdown plugin I have saves this as "markdown_with_smarty_pants", so I just look for "markdown".
|
||||
"markdown"
|
||||
elsif entry_type.include?("textile")
|
||||
# This is saved as "textile_2" on my installation of MT 5.1.
|
||||
"textile"
|
||||
elsif entry_type == "0" || entry_type.include?("richtext")
|
||||
# richtext looks to me like it's saved as HTML, so I include it here.
|
||||
"html"
|
||||
else
|
||||
# Other values might need custom work.
|
||||
entry_type
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
73
lib/jekyll/migrators/posterous.rb
Normal file
73
lib/jekyll/migrators/posterous.rb
Normal file
@@ -0,0 +1,73 @@
|
||||
require 'rubygems'
|
||||
require 'jekyll'
|
||||
require 'fileutils'
|
||||
require 'net/http'
|
||||
require 'uri'
|
||||
require "json"
|
||||
|
||||
# ruby -r './lib/jekyll/migrators/posterous.rb' -e 'Jekyll::Posterous.process(email, pass, blog)'
|
||||
|
||||
module Jekyll
|
||||
module Posterous
|
||||
|
||||
def self.fetch(uri_str, limit = 10)
|
||||
# You should choose better exception.
|
||||
raise ArgumentError, 'Stuck in a redirect loop. Please double check your email and password' if limit == 0
|
||||
|
||||
response = nil
|
||||
Net::HTTP.start('posterous.com') {|http|
|
||||
req = Net::HTTP::Get.new(uri_str)
|
||||
req.basic_auth @email, @pass
|
||||
response = http.request(req)
|
||||
}
|
||||
|
||||
case response
|
||||
when Net::HTTPSuccess then response
|
||||
when Net::HTTPRedirection then fetch(response['location'], limit - 1)
|
||||
else response.error!
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def self.process(email, pass, blog = 'primary')
|
||||
@email, @pass = email, pass
|
||||
@api_token = JSON.parse(self.fetch("/api/2/auth/token").body)['api_token']
|
||||
FileUtils.mkdir_p "_posts"
|
||||
|
||||
posts = JSON.parse(self.fetch("/api/v2/users/me/sites/#{blog}/posts?api_token=#{@api_token}").body)
|
||||
page = 1
|
||||
|
||||
while posts.any?
|
||||
|
||||
posts.each do |post|
|
||||
title = post["title"]
|
||||
slug = title.gsub(/[^[:alnum:]]+/, '-').downcase
|
||||
date = Date.parse(post["display_date"])
|
||||
content = post["body_html"]
|
||||
published = !post["is_private"]
|
||||
name = "%02d-%02d-%02d-%s.html" % [date.year, date.month, date.day, slug]
|
||||
|
||||
# Get the relevant fields as a hash, delete empty fields and convert
|
||||
# to YAML for the header
|
||||
data = {
|
||||
'layout' => 'post',
|
||||
'title' => title.to_s,
|
||||
'published' => published
|
||||
}.delete_if { |k,v| v.nil? || v == ''}.to_yaml
|
||||
|
||||
# Write out the data and content to file
|
||||
File.open("_posts/#{name}", "w") do |f|
|
||||
f.puts data
|
||||
f.puts "---"
|
||||
f.puts content
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
page += 1
|
||||
posts = JSON.parse(self.fetch("/api/v2/users/me/sites/#{blog}/posts?api_token=#{@api_token}&page=#{page}").body)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
50
lib/jekyll/migrators/textpattern.rb
Normal file
50
lib/jekyll/migrators/textpattern.rb
Normal file
@@ -0,0 +1,50 @@
|
||||
require 'rubygems'
|
||||
require 'sequel'
|
||||
require 'fileutils'
|
||||
|
||||
# NOTE: This converter requires Sequel and the MySQL gems.
|
||||
# The MySQL gem can be difficult to install on OS X. Once you have MySQL
|
||||
# installed, running the following commands should work:
|
||||
# $ sudo gem install sequel
|
||||
# $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
|
||||
|
||||
module Jekyll
|
||||
module TextPattern
|
||||
# Reads a MySQL database via Sequel and creates a post file for each post.
|
||||
# The only posts selected are those with a status of 4 or 5, which means "live"
|
||||
# and "sticky" respectively.
|
||||
# Other statuses is 1 => draft, 2 => hidden and 3 => pending
|
||||
QUERY = "select Title, url_title, Posted, Body, Keywords from textpattern where Status = '4' or Status = '5'"
|
||||
|
||||
def self.process(dbname, user, pass, host = 'localhost')
|
||||
db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
|
||||
|
||||
FileUtils.mkdir_p "_posts"
|
||||
|
||||
db[QUERY].each do |post|
|
||||
# Get required fields and construct Jekyll compatible name
|
||||
title = post[:Title]
|
||||
slug = post[:url_title]
|
||||
date = post[:Posted]
|
||||
content = post[:Body]
|
||||
|
||||
name = [date.strftime("%Y-%m-%d"), slug].join('-') + ".textile"
|
||||
|
||||
# Get the relevant fields as a hash, delete empty fields and convert
|
||||
# to YAML for the header
|
||||
data = {
|
||||
'layout' => 'post',
|
||||
'title' => title.to_s,
|
||||
'tags' => post[:Keywords].split(',')
|
||||
}.delete_if { |k,v| v.nil? || v == ''}.to_yaml
|
||||
|
||||
# Write out the data and content to file
|
||||
File.open("_posts/#{name}", "w") do |f|
|
||||
f.puts data
|
||||
f.puts "---"
|
||||
f.puts content
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
49
lib/jekyll/migrators/typo.rb
Normal file
49
lib/jekyll/migrators/typo.rb
Normal file
@@ -0,0 +1,49 @@
|
||||
# Author: Toby DiPasquale <toby@cbcg.net>
|
||||
require 'fileutils'
|
||||
require 'rubygems'
|
||||
require 'sequel'
|
||||
|
||||
module Jekyll
|
||||
module Typo
|
||||
# this SQL *should* work for both MySQL and PostgreSQL, but I haven't
|
||||
# tested PostgreSQL yet (as of 2008-12-16)
|
||||
SQL = <<-EOS
|
||||
SELECT c.id id,
|
||||
c.title title,
|
||||
c.permalink slug,
|
||||
c.body body,
|
||||
c.published_at date,
|
||||
c.state state,
|
||||
COALESCE(tf.name, 'html') filter
|
||||
FROM contents c
|
||||
LEFT OUTER JOIN text_filters tf
|
||||
ON c.text_filter_id = tf.id
|
||||
EOS
|
||||
|
||||
def self.process dbname, user, pass, host='localhost'
|
||||
FileUtils.mkdir_p '_posts'
|
||||
db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
|
||||
db[SQL].each do |post|
|
||||
next unless post[:state] =~ /Published/
|
||||
|
||||
name = [ sprintf("%.04d", post[:date].year),
|
||||
sprintf("%.02d", post[:date].month),
|
||||
sprintf("%.02d", post[:date].day),
|
||||
post[:slug].strip ].join('-')
|
||||
# Can have more than one text filter in this field, but we just want
|
||||
# the first one for this
|
||||
name += '.' + post[:filter].split(' ')[0]
|
||||
|
||||
File.open("_posts/#{name}", 'w') do |f|
|
||||
f.puts({ 'layout' => 'post',
|
||||
'title' => post[:title].to_s,
|
||||
'typo_id' => post[:id]
|
||||
}.delete_if { |k, v| v.nil? || v == '' }.to_yaml)
|
||||
f.puts '---'
|
||||
f.puts post[:body].delete("\r")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end # module Typo
|
||||
end # module Jekyll
|
||||
56
lib/jekyll/migrators/wordpress.rb
Normal file
56
lib/jekyll/migrators/wordpress.rb
Normal file
@@ -0,0 +1,56 @@
|
||||
require 'rubygems'
|
||||
require 'sequel'
|
||||
require 'fileutils'
|
||||
require 'yaml'
|
||||
|
||||
# NOTE: This converter requires Sequel and the MySQL gems.
|
||||
# The MySQL gem can be difficult to install on OS X. Once you have MySQL
|
||||
# installed, running the following commands should work:
|
||||
# $ sudo gem install sequel
|
||||
# $ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
|
||||
|
||||
module Jekyll
|
||||
module WordPress
|
||||
|
||||
def self.process(dbname, user, pass, host = 'localhost', table_prefix = 'wp_')
|
||||
db = Sequel.mysql(dbname, :user => user, :password => pass, :host => host, :encoding => 'utf8')
|
||||
|
||||
FileUtils.mkdir_p "_posts"
|
||||
|
||||
# Reads a MySQL database via Sequel and creates a post file for each
|
||||
# post in wp_posts that has post_status = 'publish'.
|
||||
# This restriction is made because 'draft' posts are not guaranteed to
|
||||
# have valid dates.
|
||||
query = "select post_title, post_name, post_date, post_content, post_excerpt, ID, guid from #{table_prefix}posts where post_status = 'publish' and post_type = 'post'"
|
||||
|
||||
db[query].each do |post|
|
||||
# Get required fields and construct Jekyll compatible name
|
||||
title = post[:post_title]
|
||||
slug = post[:post_name]
|
||||
date = post[:post_date]
|
||||
content = post[:post_content]
|
||||
name = "%02d-%02d-%02d-%s.markdown" % [date.year, date.month, date.day,
|
||||
slug]
|
||||
|
||||
# Get the relevant fields as a hash, delete empty fields and convert
|
||||
# to YAML for the header
|
||||
data = {
|
||||
'layout' => 'post',
|
||||
'title' => title.to_s,
|
||||
'excerpt' => post[:post_excerpt].to_s,
|
||||
'wordpress_id' => post[:ID],
|
||||
'wordpress_url' => post[:guid],
|
||||
'date' => date
|
||||
}.delete_if { |k,v| v.nil? || v == ''}.to_yaml
|
||||
|
||||
# Write out the data and content to file
|
||||
File.open("_posts/#{name}", "w") do |f|
|
||||
f.puts data
|
||||
f.puts "---"
|
||||
f.puts content
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
45
lib/jekyll/migrators/wordpressdotcom.rb
Normal file
45
lib/jekyll/migrators/wordpressdotcom.rb
Normal file
@@ -0,0 +1,45 @@
|
||||
# coding: utf-8
|
||||
|
||||
require 'rubygems'
|
||||
require 'hpricot'
|
||||
require 'fileutils'
|
||||
require 'yaml'
|
||||
|
||||
module Jekyll
|
||||
|
||||
# This importer takes a wordpress.xml file,
|
||||
# which can be exported from your
|
||||
# wordpress.com blog (/wp-admin/export.php)
|
||||
module WordpressDotCom
|
||||
def self.process(filename = "wordpress.xml")
|
||||
FileUtils.mkdir_p "_posts"
|
||||
posts = 0
|
||||
|
||||
doc = Hpricot::XML(File.read(filename))
|
||||
|
||||
(doc/:channel/:item).each do |item|
|
||||
title = item.at(:title).inner_text.strip
|
||||
permalink_title = item.at('wp:post_name').inner_text
|
||||
date = Time.parse(item.at(:pubDate).inner_text)
|
||||
tags = (item/:category).map{|c| c.inner_text}.reject{|c| c == 'Uncategorized'}.uniq
|
||||
name = "#{date.strftime('%Y-%m-%d')}-#{permalink_title}.html"
|
||||
header = {
|
||||
'layout' => 'post',
|
||||
'title' => title,
|
||||
'tags' => tags
|
||||
}
|
||||
|
||||
File.open("_posts/#{name}", "w") do |f|
|
||||
f.puts header.to_yaml
|
||||
f.puts '---'
|
||||
f.puts item.at('content:encoded').inner_text
|
||||
end
|
||||
|
||||
posts += 1
|
||||
end
|
||||
|
||||
puts "Imported #{posts} posts"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,85 +0,0 @@
|
||||
# These are the same MIME types that GitHub Pages uses as of 17 Mar 2013.
|
||||
|
||||
text/html html htm shtml
|
||||
text/css css
|
||||
text/xml xml rss xsl
|
||||
image/gif gif
|
||||
image/jpeg jpeg jpg
|
||||
application/x-javascript js
|
||||
application/atom+xml atom
|
||||
|
||||
text/mathml mml
|
||||
text/plain txt
|
||||
text/vnd.sun.j2me.app-descriptor jad
|
||||
text/vnd.wap.wml wml
|
||||
text/x-component htc
|
||||
text/cache-manifest manifest appcache
|
||||
text/coffeescript coffee
|
||||
text/plain pde
|
||||
text/plain md markdown
|
||||
|
||||
image/png png
|
||||
image/svg+xml svg
|
||||
image/tiff tif tiff
|
||||
image/vnd.wap.wbmp wbmp
|
||||
image/x-icon ico
|
||||
image/x-jng jng
|
||||
image/x-ms-bmp bmp
|
||||
|
||||
application/json json
|
||||
application/java-archive jar ear
|
||||
application/mac-binhex40 hqx
|
||||
application/msword doc
|
||||
application/pdf pdf
|
||||
application/postscript ps eps ai
|
||||
application/rdf+xml rdf
|
||||
application/rtf rtf
|
||||
text/vcard vcf vcard
|
||||
application/vnd.apple.pkpass pkpass
|
||||
application/vnd.ms-excel xls
|
||||
application/vnd.ms-powerpoint ppt
|
||||
application/vnd.wap.wmlc wmlc
|
||||
application/xhtml+xml xhtml
|
||||
application/x-chrome-extension crx
|
||||
application/x-cocoa cco
|
||||
application/x-font-ttf ttf
|
||||
application/x-java-archive-diff jardiff
|
||||
application/x-java-jnlp-file jnlp
|
||||
application/x-makeself run
|
||||
application/x-ns-proxy-autoconfig pac
|
||||
application/x-perl pl pm
|
||||
application/x-pilot prc pdb
|
||||
application/x-rar-compressed rar
|
||||
application/x-redhat-package-manager rpm
|
||||
application/x-sea sea
|
||||
application/x-shockwave-flash swf
|
||||
application/x-stuffit sit
|
||||
application/x-tcl tcl tk
|
||||
application/x-web-app-manifest+json webapp
|
||||
application/x-x509-ca-cert der pem crt
|
||||
application/x-xpinstall xpi
|
||||
application/x-zip war
|
||||
application/zip zip
|
||||
|
||||
application/octet-stream bin exe dll
|
||||
application/octet-stream deb
|
||||
application/octet-stream dmg
|
||||
application/octet-stream eot
|
||||
application/octet-stream iso img
|
||||
application/octet-stream msi msp msm
|
||||
|
||||
audio/midi mid midi kar
|
||||
audio/mpeg mp3
|
||||
audio/x-realaudio ra
|
||||
audio/ogg ogg
|
||||
|
||||
video/3gpp 3gpp 3gp
|
||||
video/mpeg mpeg mpg
|
||||
video/quicktime mov
|
||||
video/x-flv flv
|
||||
video/x-mng mng
|
||||
video/x-ms-asf asx asf
|
||||
video/x-ms-wmv wmv
|
||||
video/x-msvideo avi
|
||||
video/ogg ogv
|
||||
video/webm webm
|
||||
@@ -1,18 +1,19 @@
|
||||
module Jekyll
|
||||
|
||||
class Page
|
||||
include Convertible
|
||||
|
||||
attr_writer :dir
|
||||
attr_accessor :site, :pager
|
||||
attr_accessor :name, :ext, :basename
|
||||
attr_accessor :name, :ext, :basename, :dir
|
||||
attr_accessor :data, :content, :output
|
||||
|
||||
# Initialize a new Page.
|
||||
# +site+ is the Site
|
||||
# +base+ is the String path to the <source>
|
||||
# +dir+ is the String path between <source> and the file
|
||||
# +name+ is the String filename of the file
|
||||
#
|
||||
# site - The Site object.
|
||||
# base - The String path to the source.
|
||||
# dir - The String path between the source and the file.
|
||||
# name - The String filename of the file.
|
||||
# Returns <Page>
|
||||
def initialize(site, base, dir, name)
|
||||
@site = site
|
||||
@base = base
|
||||
@@ -25,53 +26,41 @@ module Jekyll
|
||||
|
||||
# The generated directory into which the page will be placed
|
||||
# upon generation. This is derived from the permalink or, if
|
||||
# permalink is absent, we be '/'
|
||||
# permalink is absent, set to '/'
|
||||
#
|
||||
# Returns the String destination directory.
|
||||
# Returns <String>
|
||||
def dir
|
||||
url[-1, 1] == '/' ? url : File.dirname(url)
|
||||
end
|
||||
|
||||
# The full path and filename of the post. Defined in the YAML of the post
|
||||
# body.
|
||||
# The full path and filename of the post.
|
||||
# Defined in the YAML of the post body
|
||||
# (Optional)
|
||||
#
|
||||
# Returns the String permalink or nil if none has been set.
|
||||
# Returns <String>
|
||||
def permalink
|
||||
self.data && self.data['permalink']
|
||||
end
|
||||
|
||||
# The template of the permalink.
|
||||
#
|
||||
# Returns the template String.
|
||||
def template
|
||||
if self.site.permalink_style == :pretty
|
||||
if index? && html?
|
||||
"/:path/"
|
||||
elsif html?
|
||||
"/:path/:basename/"
|
||||
else
|
||||
"/:path/:basename:output_ext"
|
||||
end
|
||||
if self.site.permalink_style == :pretty && !index? && html?
|
||||
"/:basename/"
|
||||
else
|
||||
"/:path/:basename:output_ext"
|
||||
"/:basename:output_ext"
|
||||
end
|
||||
end
|
||||
|
||||
# The generated relative url of this page. e.g. /about.html.
|
||||
# The generated relative url of this page
|
||||
# e.g. /about.html
|
||||
#
|
||||
# Returns the String url.
|
||||
# Returns <String>
|
||||
def url
|
||||
return @url if @url
|
||||
|
||||
url = if permalink
|
||||
if site.config['relative_permalinks']
|
||||
File.join(@dir, permalink)
|
||||
else
|
||||
permalink
|
||||
end
|
||||
permalink
|
||||
else
|
||||
{
|
||||
"path" => @dir,
|
||||
"basename" => self.basename,
|
||||
"output_ext" => self.output_ext,
|
||||
}.inject(template) { |result, token|
|
||||
@@ -82,26 +71,23 @@ module Jekyll
|
||||
# sanitize url
|
||||
@url = url.split('/').reject{ |part| part =~ /^\.+$/ }.join('/')
|
||||
@url += "/" if url =~ /\/$/
|
||||
@url.gsub!(/\A([^\/])/, '/\1')
|
||||
@url
|
||||
end
|
||||
|
||||
# Extract information from the page filename.
|
||||
# Extract information from the page filename
|
||||
# +name+ is the String filename of the page file
|
||||
#
|
||||
# name - The String filename of the page file.
|
||||
#
|
||||
# Returns nothing.
|
||||
# Returns nothing
|
||||
def process(name)
|
||||
self.ext = File.extname(name)
|
||||
self.basename = name[0 .. -self.ext.length-1]
|
||||
end
|
||||
|
||||
# Add any necessary layouts to this post
|
||||
# +layouts+ is a Hash of {"name" => "layout"}
|
||||
# +site_payload+ is the site payload hash
|
||||
#
|
||||
# layouts - The Hash of {"name" => "layout"}.
|
||||
# site_payload - The site payload Hash.
|
||||
#
|
||||
# Returns nothing.
|
||||
# Returns nothing
|
||||
def render(layouts, site_payload)
|
||||
payload = {
|
||||
"page" => self.to_liquid,
|
||||
@@ -111,53 +97,47 @@ module Jekyll
|
||||
do_layout(payload, layouts)
|
||||
end
|
||||
|
||||
# Convert this Page's data to a Hash suitable for use by Liquid.
|
||||
#
|
||||
# Returns the Hash representation of this Page.
|
||||
def to_liquid
|
||||
self.data.deep_merge({
|
||||
"url" => self.url,
|
||||
"content" => self.content,
|
||||
"path" => self.data['path'] || path })
|
||||
"url" => File.join(@dir, self.url),
|
||||
"content" => self.content })
|
||||
end
|
||||
|
||||
# The path to the source file
|
||||
#
|
||||
# Returns the path to the source file
|
||||
def path
|
||||
File.join(@dir, @name).sub(/\A\//, '')
|
||||
end
|
||||
|
||||
|
||||
# Obtain destination path.
|
||||
# +dest+ is the String path to the destination dir
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
#
|
||||
# Returns the destination file path String.
|
||||
# Returns destination file path.
|
||||
def destination(dest)
|
||||
# The url needs to be unescaped in order to preserve the correct
|
||||
# filename.
|
||||
path = File.join(dest, CGI.unescape(self.url))
|
||||
# The url needs to be unescaped in order to preserve the correct filename
|
||||
path = File.join(dest, @dir, CGI.unescape(self.url))
|
||||
path = File.join(path, "index.html") if self.url =~ /\/$/
|
||||
path
|
||||
end
|
||||
|
||||
# Returns the object as a debug String.
|
||||
# Write the generated page file to the destination directory.
|
||||
# +dest+ is the String path to the destination dir
|
||||
#
|
||||
# Returns nothing
|
||||
def write(dest)
|
||||
path = destination(dest)
|
||||
FileUtils.mkdir_p(File.dirname(path))
|
||||
File.open(path, 'w') do |f|
|
||||
f.write(self.output)
|
||||
end
|
||||
end
|
||||
|
||||
def inspect
|
||||
"#<Jekyll:Page @name=#{self.name.inspect}>"
|
||||
end
|
||||
|
||||
# Returns the Boolean of whether this Page is HTML or not.
|
||||
def html?
|
||||
output_ext == '.html'
|
||||
end
|
||||
|
||||
# Returns the Boolean of whether this Page is an index file or not.
|
||||
def index?
|
||||
basename == 'index'
|
||||
end
|
||||
|
||||
def uses_relative_permalinks
|
||||
permalink && @dir != "" && site.config['relative_permalinks']
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
module Jekyll
|
||||
|
||||
class Plugin
|
||||
PRIORITIES = { :lowest => -100,
|
||||
:low => -10,
|
||||
@@ -33,7 +34,6 @@ module Jekyll
|
||||
#
|
||||
# Returns the Symbol priority.
|
||||
def self.priority(priority = nil)
|
||||
@priority ||= nil
|
||||
if priority && PRIORITIES.has_key?(priority)
|
||||
@priority = priority
|
||||
end
|
||||
@@ -72,4 +72,5 @@ module Jekyll
|
||||
# no-op for default
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
module Jekyll
|
||||
|
||||
class Post
|
||||
include Comparable
|
||||
include Convertible
|
||||
@@ -7,133 +8,57 @@ module Jekyll
|
||||
attr_accessor :lsi
|
||||
end
|
||||
|
||||
# Valid post name regex.
|
||||
MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)(\.[^.]+)$/
|
||||
|
||||
# Attributes for Liquid templates
|
||||
ATTRIBUTES_FOR_LIQUID = %w[
|
||||
title
|
||||
url
|
||||
date
|
||||
id
|
||||
categories
|
||||
next
|
||||
previous
|
||||
tags
|
||||
content
|
||||
excerpt
|
||||
path
|
||||
]
|
||||
|
||||
# Post name validator. Post filenames must be like:
|
||||
# 2008-11-05-my-awesome-post.textile
|
||||
# 2008-11-05-my-awesome-post.textile
|
||||
#
|
||||
# Returns true if valid, false if not.
|
||||
# Returns <Bool>
|
||||
def self.valid?(name)
|
||||
name =~ MATCHER
|
||||
end
|
||||
|
||||
attr_accessor :site
|
||||
attr_accessor :data, :extracted_excerpt, :content, :output, :ext
|
||||
attr_accessor :data, :content, :output, :ext
|
||||
attr_accessor :date, :slug, :published, :tags, :categories
|
||||
|
||||
attr_reader :name
|
||||
|
||||
# Initialize this Post instance.
|
||||
# +site+ is the Site
|
||||
# +base+ is the String path to the dir containing the post file
|
||||
# +name+ is the String filename of the post file
|
||||
# +categories+ is an Array of Strings for the categories for this post
|
||||
#
|
||||
# site - The Site.
|
||||
# base - The String path to the dir containing the post file.
|
||||
# name - The String filename of the post file.
|
||||
#
|
||||
# Returns the new Post.
|
||||
# Returns <Post>
|
||||
def initialize(site, source, dir, name)
|
||||
@site = site
|
||||
@dir = dir
|
||||
@base = self.containing_dir(source, dir)
|
||||
@base = File.join(source, dir, '_posts')
|
||||
@name = name
|
||||
|
||||
self.categories = dir.downcase.split('/').reject { |x| x.empty? }
|
||||
self.categories = dir.split('/').reject { |x| x.empty? }
|
||||
self.process(name)
|
||||
self.read_yaml(@base, name)
|
||||
|
||||
#If we've added a date and time to the yaml, use that instead of the filename date
|
||||
#Means we'll sort correctly.
|
||||
if self.data.has_key?('date')
|
||||
# ensure Time via to_s and reparse
|
||||
self.date = Time.parse(self.data["date"].to_s)
|
||||
end
|
||||
|
||||
self.published = self.published?
|
||||
|
||||
self.populate_categories
|
||||
self.populate_tags
|
||||
end
|
||||
|
||||
def published?
|
||||
if self.data.has_key?('published') && self.data['published'] == false
|
||||
false
|
||||
self.published = false
|
||||
else
|
||||
true
|
||||
self.published = true
|
||||
end
|
||||
end
|
||||
|
||||
def populate_categories
|
||||
self.tags = self.data.pluralized_array("tag", "tags")
|
||||
|
||||
if self.categories.empty?
|
||||
self.categories = self.data.pluralized_array('category', 'categories').map {|c| c.to_s.downcase}
|
||||
end
|
||||
self.categories.flatten!
|
||||
end
|
||||
|
||||
def populate_tags
|
||||
self.tags = self.data.pluralized_array("tag", "tags").flatten
|
||||
end
|
||||
|
||||
# Get the full path to the directory containing the post files
|
||||
def containing_dir(source, dir)
|
||||
return File.join(source, dir, '_posts')
|
||||
end
|
||||
|
||||
# Read the YAML frontmatter.
|
||||
#
|
||||
# base - The String path to the dir containing the file.
|
||||
# name - The String filename of the file.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_yaml(base, name)
|
||||
super(base, name)
|
||||
self.extracted_excerpt = self.extract_excerpt
|
||||
end
|
||||
|
||||
# The post excerpt. This is either a custom excerpt
|
||||
# set in YAML front matter or the result of extract_excerpt.
|
||||
#
|
||||
# Returns excerpt string.
|
||||
def excerpt
|
||||
if self.data.has_key? 'excerpt'
|
||||
self.data['excerpt']
|
||||
else
|
||||
self.extracted_excerpt
|
||||
self.categories = self.data.pluralized_array('category', 'categories')
|
||||
end
|
||||
end
|
||||
|
||||
# Public: the Post title, from the YAML Front-Matter or from the slug
|
||||
#
|
||||
# Returns the post title
|
||||
def title
|
||||
self.data["title"] || self.slug.split('-').select {|w| w.capitalize! || w }.join(' ')
|
||||
end
|
||||
|
||||
# Public: the path to the post relative to the site source,
|
||||
# from the YAML Front-Matter or from a combination of
|
||||
# the directory it's in, "_posts", and the name of the
|
||||
# post file
|
||||
#
|
||||
# Returns the path to the file relative to the site source
|
||||
def path
|
||||
self.data['path'] || File.join(@dir, '_posts', @name).sub(/\A\//, '')
|
||||
end
|
||||
|
||||
# Compares Post objects. First compares the Post date. If the dates are
|
||||
# equal, it compares the Post slugs.
|
||||
#
|
||||
# other - The other Post we are comparing to.
|
||||
# Spaceship is based on Post#date, slug
|
||||
#
|
||||
# Returns -1, 0, 1
|
||||
def <=>(other)
|
||||
@@ -144,11 +69,10 @@ module Jekyll
|
||||
return cmp
|
||||
end
|
||||
|
||||
# Extract information from the post filename.
|
||||
# Extract information from the post filename
|
||||
# +name+ is the String filename of the post file
|
||||
#
|
||||
# name - The String filename of the post file.
|
||||
#
|
||||
# Returns nothing.
|
||||
# Returns nothing
|
||||
def process(name)
|
||||
m, cats, date, slug, ext = *name.match(MATCHER)
|
||||
self.date = Time.parse(date)
|
||||
@@ -158,28 +82,21 @@ module Jekyll
|
||||
raise FatalException.new("Post #{name} does not have a valid date.")
|
||||
end
|
||||
|
||||
# Transform the contents and excerpt based on the content type.
|
||||
#
|
||||
# Returns nothing.
|
||||
def transform
|
||||
super
|
||||
self.extracted_excerpt = converter.convert(self.extracted_excerpt)
|
||||
end
|
||||
|
||||
# The generated directory into which the post will be placed
|
||||
# upon generation. This is derived from the permalink or, if
|
||||
# permalink is absent, set to the default date
|
||||
# e.g. "/2008/11/05/" if the permalink style is :date, otherwise nothing.
|
||||
# e.g. "/2008/11/05/" if the permalink style is :date, otherwise nothing
|
||||
#
|
||||
# Returns the String directory.
|
||||
# Returns <String>
|
||||
def dir
|
||||
File.dirname(url)
|
||||
end
|
||||
|
||||
# The full path and filename of the post. Defined in the YAML of the post
|
||||
# body (optional).
|
||||
# The full path and filename of the post.
|
||||
# Defined in the YAML of the post body
|
||||
# (Optional)
|
||||
#
|
||||
# Returns the String permalink.
|
||||
# Returns <String>
|
||||
def permalink
|
||||
self.data && self.data['permalink']
|
||||
end
|
||||
@@ -192,17 +109,15 @@ module Jekyll
|
||||
"/:categories/:title.html"
|
||||
when :date
|
||||
"/:categories/:year/:month/:day/:title.html"
|
||||
when :ordinal
|
||||
"/:categories/:year/:y_day/:title.html"
|
||||
else
|
||||
self.site.permalink_style.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# The generated relative url of this post.
|
||||
# The generated relative url of this post
|
||||
# e.g. /2008/11/05/my-awesome-post.html
|
||||
#
|
||||
# Returns the String URL.
|
||||
# Returns <String>
|
||||
def url
|
||||
return @url if @url
|
||||
|
||||
@@ -216,9 +131,7 @@ module Jekyll
|
||||
"title" => CGI.escape(slug),
|
||||
"i_day" => date.strftime("%d").to_i.to_s,
|
||||
"i_month" => date.strftime("%m").to_i.to_s,
|
||||
"categories" => categories.map { |c| URI.escape(c.to_s) }.join('/'),
|
||||
"short_month" => date.strftime("%b"),
|
||||
"y_day" => date.strftime("%j"),
|
||||
"categories" => categories.join('/'),
|
||||
"output_ext" => self.output_ext
|
||||
}.inject(template) { |result, token|
|
||||
result.gsub(/:#{Regexp.escape token.first}/, token.last)
|
||||
@@ -228,26 +141,31 @@ module Jekyll
|
||||
# sanitize url
|
||||
@url = url.split('/').reject{ |part| part =~ /^\.+$/ }.join('/')
|
||||
@url += "/" if url =~ /\/$/
|
||||
@url.gsub!(/\A([^\/])/, '/\1')
|
||||
@url
|
||||
end
|
||||
|
||||
# The UID for this post (useful in feeds).
|
||||
# The UID for this post (useful in feeds)
|
||||
# e.g. /2008/11/05/my-awesome-post
|
||||
#
|
||||
# Returns the String UID.
|
||||
# Returns <String>
|
||||
def id
|
||||
File.join(self.dir, self.slug)
|
||||
end
|
||||
|
||||
# Calculate related posts.
|
||||
#
|
||||
# Returns an Array of related Posts.
|
||||
# Returns [<Post>]
|
||||
def related_posts(posts)
|
||||
return [] unless posts.size > 1
|
||||
|
||||
if self.site.lsi
|
||||
build_index
|
||||
self.class.lsi ||= begin
|
||||
puts "Running the classifier... this could take a while."
|
||||
lsi = Classifier::LSI.new
|
||||
posts.each { |x| $stdout.print(".");$stdout.flush;lsi.add_item(x) }
|
||||
puts ""
|
||||
lsi
|
||||
end
|
||||
|
||||
related = self.class.lsi.find_related(self.content, 11)
|
||||
related - [self]
|
||||
@@ -256,25 +174,11 @@ module Jekyll
|
||||
end
|
||||
end
|
||||
|
||||
def build_index
|
||||
self.class.lsi ||= begin
|
||||
puts "Starting the classifier..."
|
||||
lsi = Classifier::LSI.new(:auto_rebuild => false)
|
||||
$stdout.print(" Populating LSI... "); $stdout.flush
|
||||
self.site.posts.each { |x| $stdout.print("."); $stdout.flush; lsi.add_item(x) }
|
||||
$stdout.print("\n Rebuilding LSI index... ")
|
||||
lsi.build_index
|
||||
puts ""
|
||||
lsi
|
||||
end
|
||||
end
|
||||
|
||||
# Add any necessary layouts to this post.
|
||||
# Add any necessary layouts to this post
|
||||
# +layouts+ is a Hash of {"name" => "layout"}
|
||||
# +site_payload+ is the site payload hash
|
||||
#
|
||||
# layouts - A Hash of {"name" => "layout"}.
|
||||
# site_payload - The site payload hash.
|
||||
#
|
||||
# Returns nothing.
|
||||
# Returns nothing
|
||||
def render(layouts, site_payload)
|
||||
# construct payload
|
||||
payload = {
|
||||
@@ -284,12 +188,11 @@ module Jekyll
|
||||
|
||||
do_layout(payload, layouts)
|
||||
end
|
||||
|
||||
|
||||
# Obtain destination path.
|
||||
# +dest+ is the String path to the destination dir
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
#
|
||||
# Returns destination file path String.
|
||||
# Returns destination file path.
|
||||
def destination(dest)
|
||||
# The url needs to be unescaped in order to preserve the correct filename
|
||||
path = File.join(dest, CGI.unescape(self.url))
|
||||
@@ -297,17 +200,34 @@ module Jekyll
|
||||
path
|
||||
end
|
||||
|
||||
# Convert this post into a Hash for use in Liquid templates.
|
||||
# Write the generated post file to the destination directory.
|
||||
# +dest+ is the String path to the destination dir
|
||||
#
|
||||
# Returns the representative Hash.
|
||||
def to_liquid
|
||||
further_data = Hash[ATTRIBUTES_FOR_LIQUID.map { |attribute|
|
||||
[attribute, send(attribute)]
|
||||
}]
|
||||
data.deep_merge(further_data)
|
||||
# Returns nothing
|
||||
def write(dest)
|
||||
path = destination(dest)
|
||||
FileUtils.mkdir_p(File.dirname(path))
|
||||
File.open(path, 'w') do |f|
|
||||
f.write(self.output)
|
||||
end
|
||||
end
|
||||
|
||||
# Convert this post into a Hash for use in Liquid templates.
|
||||
#
|
||||
# Returns <Hash>
|
||||
def to_liquid
|
||||
self.data.deep_merge({
|
||||
"title" => self.data["title"] || self.slug.split('-').select {|w| w.capitalize! || w }.join(' '),
|
||||
"url" => self.url,
|
||||
"date" => self.date,
|
||||
"id" => self.id,
|
||||
"categories" => self.categories,
|
||||
"next" => self.next,
|
||||
"previous" => self.previous,
|
||||
"tags" => self.tags,
|
||||
"content" => self.content })
|
||||
end
|
||||
|
||||
# Returns the shorthand String identifier of this Post.
|
||||
def inspect
|
||||
"<Post: #{self.id}>"
|
||||
end
|
||||
@@ -330,48 +250,6 @@ module Jekyll
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Internal: Extract excerpt from the content
|
||||
#
|
||||
# By default excerpt is your first paragraph of a post: everything before
|
||||
# the first two new lines:
|
||||
#
|
||||
# ---
|
||||
# title: Example
|
||||
# ---
|
||||
#
|
||||
# First paragraph with [link][1].
|
||||
#
|
||||
# Second paragraph.
|
||||
#
|
||||
# [1]: http://example.com/
|
||||
#
|
||||
# This is fairly good option for Markdown and Textile files. But might cause
|
||||
# problems for HTML posts (which is quite unusual for Jekyll). If default
|
||||
# excerpt delimiter is not good for you, you might want to set your own via
|
||||
# configuration option `excerpt_separator`. For example, following is a good
|
||||
# alternative for HTML posts:
|
||||
#
|
||||
# # file: _config.yml
|
||||
# excerpt_separator: "<!-- more -->"
|
||||
#
|
||||
# Notice that all markdown-style link references will be appended to the
|
||||
# excerpt. So the example post above will have this excerpt source:
|
||||
#
|
||||
# First paragraph with [link][1].
|
||||
#
|
||||
# [1]: http://example.com/
|
||||
#
|
||||
# Excerpts are rendered same time as content is rendered.
|
||||
#
|
||||
# Returns excerpt String
|
||||
def extract_excerpt
|
||||
separator = self.site.config['excerpt_separator']
|
||||
head, _, tail = self.content.partition(separator)
|
||||
|
||||
"" << head << "\n\n" << tail.scan(/^\[[^\]]+\]:.+$/).join("\n")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,54 +1,36 @@
|
||||
require 'set'
|
||||
|
||||
module Jekyll
|
||||
|
||||
class Site
|
||||
attr_accessor :config, :layouts, :posts, :pages, :static_files,
|
||||
:categories, :exclude, :include, :source, :dest, :lsi, :pygments,
|
||||
:permalink_style, :tags, :time, :future, :safe, :plugins, :limit_posts,
|
||||
:show_drafts, :keep_files, :baseurl
|
||||
:categories, :exclude, :source, :dest, :lsi, :pygments,
|
||||
:permalink_style, :tags, :time, :future, :safe, :plugins, :limit_posts
|
||||
|
||||
attr_accessor :converters, :generators
|
||||
|
||||
# Public: Initialize a new Site.
|
||||
# Initialize the site
|
||||
# +config+ is a Hash containing site configurations details
|
||||
#
|
||||
# config - A Hash containing site configuration details.
|
||||
# Returns <Site>
|
||||
def initialize(config)
|
||||
self.config = config.clone
|
||||
|
||||
self.safe = config['safe']
|
||||
self.source = File.expand_path(config['source'])
|
||||
self.dest = File.expand_path(config['destination'])
|
||||
self.plugins = plugins_path
|
||||
self.plugins = File.expand_path(config['plugins'])
|
||||
self.lsi = config['lsi']
|
||||
self.pygments = config['pygments']
|
||||
self.baseurl = config['baseurl']
|
||||
self.permalink_style = config['permalink'].to_sym
|
||||
self.exclude = config['exclude']
|
||||
self.include = config['include']
|
||||
self.exclude = config['exclude'] || []
|
||||
self.future = config['future']
|
||||
self.show_drafts = config['show_drafts']
|
||||
self.limit_posts = config['limit_posts']
|
||||
self.keep_files = config['keep_files']
|
||||
self.limit_posts = config['limit_posts'] || nil
|
||||
|
||||
self.reset
|
||||
self.setup
|
||||
end
|
||||
|
||||
# Public: Read, process, and write this Site to output.
|
||||
#
|
||||
# Returns nothing.
|
||||
def process
|
||||
self.reset
|
||||
self.read
|
||||
self.generate
|
||||
self.render
|
||||
self.cleanup
|
||||
self.write
|
||||
end
|
||||
|
||||
# Reset Site details.
|
||||
#
|
||||
# Returns nothing
|
||||
def reset
|
||||
self.time = if self.config['time']
|
||||
Time.parse(self.config['time'].to_s)
|
||||
@@ -62,62 +44,58 @@ module Jekyll
|
||||
self.categories = Hash.new { |hash, key| hash[key] = [] }
|
||||
self.tags = Hash.new { |hash, key| hash[key] = [] }
|
||||
|
||||
if self.limit_posts < 0
|
||||
raise ArgumentError, "limit_posts must be a non-negative number"
|
||||
end
|
||||
raise ArgumentError, "Limit posts must be nil or >= 1" if !self.limit_posts.nil? && self.limit_posts < 1
|
||||
end
|
||||
|
||||
# Load necessary libraries, plugins, converters, and generators.
|
||||
#
|
||||
# Returns nothing.
|
||||
def setup
|
||||
require 'classifier' if self.lsi
|
||||
|
||||
# Check that the destination dir isn't the source dir or a directory
|
||||
# parent to the source dir.
|
||||
if self.source =~ /^#{self.dest}/
|
||||
raise FatalException.new "Destination directory cannot be or contain the Source directory."
|
||||
end
|
||||
|
||||
# If safe mode is off, load in any Ruby files under the plugins
|
||||
# If safe mode is off, load in any ruby files under the plugins
|
||||
# directory.
|
||||
unless self.safe
|
||||
self.plugins.each do |plugins|
|
||||
Dir[File.join(plugins, "**/*.rb")].each do |f|
|
||||
require f
|
||||
end
|
||||
Dir[File.join(self.plugins, "**/*.rb")].each do |f|
|
||||
require f
|
||||
end
|
||||
end
|
||||
|
||||
self.converters = instantiate_subclasses(Jekyll::Converter)
|
||||
self.generators = instantiate_subclasses(Jekyll::Generator)
|
||||
end
|
||||
self.converters = Jekyll::Converter.subclasses.select do |c|
|
||||
!self.safe || c.safe
|
||||
end.map do |c|
|
||||
c.new(self.config)
|
||||
end
|
||||
|
||||
# Internal: Setup the plugin search path
|
||||
#
|
||||
# Returns an Array of plugin search paths
|
||||
def plugins_path
|
||||
if (config['plugins'] == Jekyll::Configuration::DEFAULTS['plugins'])
|
||||
[File.join(self.source, config['plugins'])]
|
||||
else
|
||||
Array(config['plugins']).map { |d| File.expand_path(d) }
|
||||
self.generators = Jekyll::Generator.subclasses.select do |c|
|
||||
!self.safe || c.safe
|
||||
end.map do |c|
|
||||
c.new(self.config)
|
||||
end
|
||||
end
|
||||
|
||||
# Read Site data from disk and load it into internal data structures.
|
||||
# Do the actual work of processing the site and generating the
|
||||
# real deal. 5 phases; reset, read, generate, render, write. This allows
|
||||
# rendering to have full site payload available.
|
||||
#
|
||||
# Returns nothing.
|
||||
# Returns nothing
|
||||
def process
|
||||
self.reset
|
||||
self.read
|
||||
self.generate
|
||||
self.render
|
||||
self.cleanup
|
||||
self.write
|
||||
end
|
||||
|
||||
def read
|
||||
self.read_layouts
|
||||
self.read_layouts # existing implementation did this at top level only so preserved that
|
||||
self.read_directories
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<layouts> and create a new Layout object
|
||||
# with each one.
|
||||
# Read all the files in <source>/<dir>/_layouts and create a new Layout
|
||||
# object with each one.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_layouts
|
||||
base = File.join(self.source, self.config['layouts'])
|
||||
# Returns nothing
|
||||
def read_layouts(dir = '')
|
||||
base = File.join(self.source, dir, "_layouts")
|
||||
return unless File.exists?(base)
|
||||
entries = []
|
||||
Dir.chdir(base) { entries = filter_entries(Dir['*.*']) }
|
||||
@@ -128,58 +106,14 @@ module Jekyll
|
||||
end
|
||||
end
|
||||
|
||||
# Recursively traverse directories to find posts, pages and static files
|
||||
# that will become part of the site according to the rules in
|
||||
# filter_entries.
|
||||
#
|
||||
# dir - The String relative path of the directory to read. Default: ''.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_directories(dir = '')
|
||||
base = File.join(self.source, dir)
|
||||
entries = Dir.chdir(base) { filter_entries(Dir.entries('.')) }
|
||||
|
||||
self.read_posts(dir)
|
||||
|
||||
if self.show_drafts
|
||||
self.read_drafts(dir)
|
||||
end
|
||||
|
||||
self.posts.sort!
|
||||
|
||||
# limit the posts if :limit_posts option is set
|
||||
if limit_posts > 0
|
||||
limit = self.posts.length < limit_posts ? self.posts.length : limit_posts
|
||||
self.posts = self.posts[-limit, limit]
|
||||
end
|
||||
|
||||
entries.each do |f|
|
||||
f_abs = File.join(base, f)
|
||||
f_rel = File.join(dir, f)
|
||||
if File.directory?(f_abs)
|
||||
next if self.dest.sub(/\/$/, '') == f_abs
|
||||
read_directories(f_rel)
|
||||
else
|
||||
first3 = File.open(f_abs) { |fd| fd.read(3) }
|
||||
if first3 == "---"
|
||||
# file appears to have a YAML header so process it as a page
|
||||
pages << Page.new(self, self.source, dir, f)
|
||||
else
|
||||
# otherwise treat it as a static file
|
||||
static_files << StaticFile.new(self, self.source, dir, f)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/_posts and create a new Post
|
||||
# object with each one.
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
#
|
||||
# Returns nothing.
|
||||
# Returns nothing
|
||||
def read_posts(dir)
|
||||
entries = get_entries(dir, '_posts')
|
||||
base = File.join(self.source, dir, '_posts')
|
||||
return unless File.exists?(base)
|
||||
entries = Dir.chdir(base) { filter_entries(Dir['**/*']) }
|
||||
|
||||
# first pass processes, but does not yet render post content
|
||||
entries.each do |f|
|
||||
@@ -187,72 +121,48 @@ module Jekyll
|
||||
post = Post.new(self, self.source, dir, f)
|
||||
|
||||
if post.published && (self.future || post.date <= self.time)
|
||||
aggregate_post_info(post)
|
||||
self.posts << post
|
||||
post.categories.each { |c| self.categories[c] << post }
|
||||
post.tags.each { |c| self.tags[c] << post }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.posts.sort!
|
||||
|
||||
# limit the posts if :limit_posts option is set
|
||||
self.posts = self.posts[-limit_posts, limit_posts] if limit_posts
|
||||
end
|
||||
|
||||
# Read all the files in <source>/<dir>/_drafts and create a new Post
|
||||
# object with each one.
|
||||
#
|
||||
# dir - The String relative path of the directory to read.
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_drafts(dir)
|
||||
entries = get_entries(dir, '_drafts')
|
||||
|
||||
# first pass processes, but does not yet render draft content
|
||||
entries.each do |f|
|
||||
if Draft.valid?(f)
|
||||
draft = Draft.new(self, self.source, dir, f)
|
||||
|
||||
aggregate_post_info(draft)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Run each of the Generators.
|
||||
#
|
||||
# Returns nothing.
|
||||
def generate
|
||||
self.generators.each do |generator|
|
||||
generator.generate(self)
|
||||
end
|
||||
end
|
||||
|
||||
# Render the site to the destination.
|
||||
#
|
||||
# Returns nothing.
|
||||
def render
|
||||
payload = site_payload
|
||||
self.posts.each do |post|
|
||||
post.render(self.layouts, payload)
|
||||
post.render(self.layouts, site_payload)
|
||||
end
|
||||
|
||||
self.pages.each do |page|
|
||||
relative_permalinks_deprecation_method if page.uses_relative_permalinks
|
||||
page.render(self.layouts, payload)
|
||||
page.render(self.layouts, site_payload)
|
||||
end
|
||||
|
||||
self.categories.values.map { |ps| ps.sort! { |a, b| b <=> a } }
|
||||
self.tags.values.map { |ps| ps.sort! { |a, b| b <=> a } }
|
||||
self.categories.values.map { |ps| ps.sort! { |a, b| b <=> a} }
|
||||
self.tags.values.map { |ps| ps.sort! { |a, b| b <=> a} }
|
||||
rescue Errno::ENOENT => e
|
||||
# ignore missing layout dir
|
||||
end
|
||||
|
||||
# Remove orphaned files and empty directories in destination.
|
||||
|
||||
# Remove orphaned files and empty directories in destination
|
||||
#
|
||||
# Returns nothing.
|
||||
# Returns nothing
|
||||
def cleanup
|
||||
# all files and directories in destination, including hidden ones
|
||||
dest_files = Set.new
|
||||
Dir.glob(File.join(self.dest, "**", "*"), File::FNM_DOTMATCH) do |file|
|
||||
if self.keep_files.length > 0
|
||||
dest_files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex
|
||||
else
|
||||
dest_files << file unless file =~ /\/\.{1,2}$/
|
||||
end
|
||||
dest_files << file unless file =~ /\/\.{1,2}$/
|
||||
end
|
||||
|
||||
# files to be written
|
||||
@@ -266,31 +176,20 @@ module Jekyll
|
||||
self.static_files.each do |sf|
|
||||
files << sf.destination(self.dest)
|
||||
end
|
||||
|
||||
|
||||
# adding files' parent directories
|
||||
dirs = Set.new
|
||||
files.each { |file| dirs << File.dirname(file) }
|
||||
files.merge(dirs)
|
||||
|
||||
|
||||
obsolete_files = dest_files - files
|
||||
|
||||
FileUtils.rm_rf(obsolete_files.to_a)
|
||||
end
|
||||
|
||||
# Private: creates a regular expression from the keep_files array
|
||||
# Write static files, pages and posts
|
||||
#
|
||||
# Examples
|
||||
# ['.git','.svn'] creates the following regex: /\/(\.git|\/.svn)/
|
||||
#
|
||||
# Returns the regular expression
|
||||
def keep_file_regex
|
||||
or_list = self.keep_files.join("|")
|
||||
pattern = "\/(#{or_list.gsub(".", "\.")})"
|
||||
Regexp.new pattern
|
||||
end
|
||||
|
||||
# Write static files, pages, and posts.
|
||||
#
|
||||
# Returns nothing.
|
||||
# Returns nothing
|
||||
def write
|
||||
self.posts.each do |post|
|
||||
post.write(self.dest)
|
||||
@@ -303,45 +202,59 @@ module Jekyll
|
||||
end
|
||||
end
|
||||
|
||||
# Construct a Hash of Posts indexed by the specified Post attribute.
|
||||
# Reads the directories and finds posts, pages and static files that will
|
||||
# become part of the valid site according to the rules in +filter_entries+.
|
||||
# The +dir+ String is a relative path used to call this method
|
||||
# recursively as it descends through directories
|
||||
#
|
||||
# post_attr - The String name of the Post attribute.
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# post_attr_hash('categories')
|
||||
# # => { 'tech' => [<Post A>, <Post B>],
|
||||
# # 'ruby' => [<Post B>] }
|
||||
#
|
||||
# Returns the Hash: { attr => posts } where
|
||||
# attr - One of the values for the requested attribute.
|
||||
# posts - The Array of Posts with the given attr value.
|
||||
def post_attr_hash(post_attr)
|
||||
# Build a hash map based on the specified post attribute ( post attr =>
|
||||
# array of posts ) then sort each array in reverse order.
|
||||
hash = Hash.new { |hsh, key| hsh[key] = Array.new }
|
||||
self.posts.each { |p| p.send(post_attr.to_sym).each { |t| hash[t] << p } }
|
||||
hash.values.map { |sortme| sortme.sort! { |a, b| b <=> a } }
|
||||
hash
|
||||
# Returns nothing
|
||||
def read_directories(dir = '')
|
||||
base = File.join(self.source, dir)
|
||||
entries = Dir.chdir(base){ filter_entries(Dir['*']) }
|
||||
|
||||
self.read_posts(dir)
|
||||
|
||||
entries.each do |f|
|
||||
f_abs = File.join(base, f)
|
||||
f_rel = File.join(dir, f)
|
||||
if File.directory?(f_abs)
|
||||
next if self.dest.sub(/\/$/, '') == f_abs
|
||||
read_directories(f_rel)
|
||||
elsif !File.symlink?(f_abs)
|
||||
first3 = File.open(f_abs) { |fd| fd.read(3) }
|
||||
if first3 == "---"
|
||||
# file appears to have a YAML header so process it as a page
|
||||
pages << Page.new(self, self.source, dir, f)
|
||||
else
|
||||
# otherwise treat it as a static file
|
||||
static_files << StaticFile.new(self, self.source, dir, f)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# The Hash payload containing site-wide data.
|
||||
# Constructs a hash map of Posts indexed by the specified Post attribute
|
||||
#
|
||||
# Returns the Hash: { "site" => data } where data is a Hash with keys:
|
||||
# "time" - The Time as specified in the configuration or the
|
||||
# current time if none was specified.
|
||||
# "posts" - The Array of Posts, sorted chronologically by post date
|
||||
# and then title.
|
||||
# "pages" - The Array of all Pages.
|
||||
# "html_pages" - The Array of HTML Pages.
|
||||
# "categories" - The Hash of category values and Posts.
|
||||
# See Site#post_attr_hash for type info.
|
||||
# "tags" - The Hash of tag values and Posts.
|
||||
# See Site#post_attr_hash for type info.
|
||||
# Returns {post_attr => [<Post>]}
|
||||
def post_attr_hash(post_attr)
|
||||
# Build a hash map based on the specified post attribute ( post attr => array of posts )
|
||||
# then sort each array in reverse order
|
||||
hash = Hash.new { |hash, key| hash[key] = Array.new }
|
||||
self.posts.each { |p| p.send(post_attr.to_sym).each { |t| hash[t] << p } }
|
||||
hash.values.map { |sortme| sortme.sort! { |a, b| b <=> a} }
|
||||
return hash
|
||||
end
|
||||
|
||||
# The Hash payload containing site-wide data
|
||||
#
|
||||
# Returns {"site" => {"time" => <Time>,
|
||||
# "posts" => [<Post>],
|
||||
# "pages" => [<Page>],
|
||||
# "categories" => [<Post>]}
|
||||
def site_payload
|
||||
{"site" => self.config.merge({
|
||||
"time" => self.time,
|
||||
"posts" => self.posts.sort { |a, b| b <=> a },
|
||||
"posts" => self.posts.sort { |a,b| b <=> a },
|
||||
"pages" => self.pages,
|
||||
"html_pages" => self.pages.reject { |page| !page.html? },
|
||||
"categories" => post_attr_hash('categories'),
|
||||
@@ -351,86 +264,17 @@ module Jekyll
|
||||
# Filter out any files/directories that are hidden or backup files (start
|
||||
# with "." or "#" or end with "~"), or contain site content (start with "_"),
|
||||
# or are excluded in the site configuration, unless they are web server
|
||||
# files such as '.htaccess'.
|
||||
#
|
||||
# entries - The Array of String file/directory entries to filter.
|
||||
#
|
||||
# Returns the Array of filtered entries.
|
||||
# files such as '.htaccess'
|
||||
def filter_entries(entries)
|
||||
entries.reject do |e|
|
||||
unless self.include.glob_include?(e)
|
||||
entries = entries.reject do |e|
|
||||
unless ['.htaccess'].include?(e)
|
||||
['.', '_', '#'].include?(e[0..0]) ||
|
||||
e[-1..-1] == '~' ||
|
||||
self.exclude.glob_include?(e) ||
|
||||
(File.symlink?(e) && self.safe)
|
||||
self.exclude.include?(e) ||
|
||||
File.symlink?(e)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Get the implementation class for the given Converter.
|
||||
#
|
||||
# klass - The Class of the Converter to fetch.
|
||||
#
|
||||
# Returns the Converter instance implementing the given Converter.
|
||||
def getConverterImpl(klass)
|
||||
matches = self.converters.select { |c| c.class == klass }
|
||||
if impl = matches.first
|
||||
impl
|
||||
else
|
||||
raise "Converter implementation not found for #{klass}"
|
||||
end
|
||||
end
|
||||
|
||||
# Create array of instances of the subclasses of the class or module
|
||||
# passed in as argument.
|
||||
#
|
||||
# klass - class or module containing the subclasses which should be
|
||||
# instantiated
|
||||
#
|
||||
# Returns array of instances of subclasses of parameter
|
||||
def instantiate_subclasses(klass)
|
||||
klass.subclasses.select do |c|
|
||||
!self.safe || c.safe
|
||||
end.sort.map do |c|
|
||||
c.new(self.config)
|
||||
end
|
||||
end
|
||||
|
||||
# Read the entries from a particular directory for processing
|
||||
#
|
||||
# dir - The String relative path of the directory to read
|
||||
# subfolder - The String directory to read
|
||||
#
|
||||
# Returns the list of entries to process
|
||||
def get_entries(dir, subfolder)
|
||||
base = File.join(self.source, dir, subfolder)
|
||||
return [] unless File.exists?(base)
|
||||
entries = Dir.chdir(base) { filter_entries(Dir['**/*']) }
|
||||
entries.delete_if { |e| File.directory?(File.join(base, e)) }
|
||||
end
|
||||
|
||||
# Aggregate post information
|
||||
#
|
||||
# post - The Post object to aggregate information for
|
||||
#
|
||||
# Returns nothing
|
||||
def aggregate_post_info(post)
|
||||
self.posts << post
|
||||
post.categories.each { |c| self.categories[c] << post }
|
||||
post.tags.each { |c| self.tags[c] << post }
|
||||
end
|
||||
|
||||
def relative_permalinks_deprecation_method
|
||||
if config['relative_permalinks'] && !@deprecated_relative_permalinks
|
||||
$stderr.puts # Places newline after "Generating..."
|
||||
Jekyll::Logger.warn "Deprecation:", "Starting in 1.1, permalinks for pages" +
|
||||
" in subfolders must be relative to the" +
|
||||
" site source directory, not the parent" +
|
||||
" directory. Check http://jekyllrb.com/docs/upgrading/"+
|
||||
" for more info."
|
||||
$stderr.print Jekyll::Logger.formatted_topic("") + "..." # for "done."
|
||||
@deprecated_relative_permalinks = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
module Jekyll
|
||||
|
||||
class StaticFile
|
||||
# The cache of last modification times [path] -> mtime.
|
||||
@@mtimes = Hash.new
|
||||
@@mtimes = Hash.new # the cache of last modification times [path] -> mtime
|
||||
|
||||
# Initialize a new StaticFile.
|
||||
# +site+ is the Site
|
||||
# +base+ is the String path to the <source>
|
||||
# +dir+ is the String path between <source> and the file
|
||||
# +name+ is the String filename of the file
|
||||
#
|
||||
# site - The Site.
|
||||
# base - The String path to the <source>.
|
||||
# dir - The String path between <source> and the file.
|
||||
# name - The String filename of the file.
|
||||
# Returns <StaticFile>
|
||||
def initialize(site, base, dir, name)
|
||||
@site = site
|
||||
@base = base
|
||||
@@ -16,21 +17,24 @@ module Jekyll
|
||||
@name = name
|
||||
end
|
||||
|
||||
# Obtains source file path.
|
||||
#
|
||||
# Returns source file path.
|
||||
def path
|
||||
File.join(@base, @dir, @name)
|
||||
end
|
||||
|
||||
# Obtain destination path.
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
# +dest+ is the String path to the destination dir
|
||||
#
|
||||
# Returns destination file path.
|
||||
def destination(dest)
|
||||
File.join(dest, @dir, @name)
|
||||
end
|
||||
|
||||
# Returns last modification time for this file.
|
||||
# Obtain mtime of the source path.
|
||||
#
|
||||
# Returns last modifiaction time for this file.
|
||||
def mtime
|
||||
File.stat(path).mtime.to_i
|
||||
end
|
||||
@@ -43,14 +47,13 @@ module Jekyll
|
||||
end
|
||||
|
||||
# Write the static file to the destination directory (if modified).
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
# +dest+ is the String path to the destination dir
|
||||
#
|
||||
# Returns false if the file was not modified since last time (no-op).
|
||||
def write(dest)
|
||||
dest_path = destination(dest)
|
||||
|
||||
return false if File.exist?(dest_path) and !modified?
|
||||
return false if File.exist? dest_path and !modified?
|
||||
@@mtimes[path] = mtime
|
||||
|
||||
FileUtils.mkdir_p(File.dirname(dest_path))
|
||||
@@ -64,7 +67,9 @@ module Jekyll
|
||||
# Returns nothing.
|
||||
def self.reset_cache
|
||||
@@mtimes = Hash.new
|
||||
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
# Gist Liquid Tag
|
||||
#
|
||||
# Example:
|
||||
# {% gist 1234567 %}
|
||||
# {% gist 1234567 file.rb %}
|
||||
|
||||
module Jekyll
|
||||
class GistTag < Liquid::Tag
|
||||
def render(context)
|
||||
if tag_contents = @markup.strip.match(/\A(\d+) ?(\S*)\Z/)
|
||||
gist_id, filename = tag_contents[1].strip, tag_contents[2].strip
|
||||
gist_script_tag(gist_id, filename)
|
||||
else
|
||||
"Error parsing gist id"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def gist_script_tag(gist_id, filename=nil)
|
||||
if filename.empty?
|
||||
"<script src=\"https://gist.github.com/#{gist_id}.js\"> </script>"
|
||||
else
|
||||
"<script src=\"https://gist.github.com/#{gist_id}.js?file=#{filename}\"> </script>"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('gist', Jekyll::GistTag)
|
||||
@@ -1,85 +1,73 @@
|
||||
module Jekyll
|
||||
module Tags
|
||||
class HighlightBlock < Liquid::Block
|
||||
include Liquid::StandardFilters
|
||||
|
||||
# The regular expression syntax checker. Start with the language specifier.
|
||||
# Follow that by zero or more space separated options that take one of two
|
||||
# forms:
|
||||
#
|
||||
# 1. name
|
||||
# 2. name=value
|
||||
SYNTAX = /^([a-zA-Z0-9.+#-]+)((\s+\w+(=\w+)?)*)$/
|
||||
class HighlightBlock < Liquid::Block
|
||||
include Liquid::StandardFilters
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
if markup.strip =~ SYNTAX
|
||||
@lang = $1
|
||||
@options = {}
|
||||
if defined?($2) && $2 != ''
|
||||
$2.split.each do |opt|
|
||||
key, value = opt.split('=')
|
||||
if value.nil?
|
||||
if key == 'linenos'
|
||||
value = 'inline'
|
||||
else
|
||||
value = true
|
||||
end
|
||||
# we need a language, but the linenos argument is optional.
|
||||
SYNTAX = /(\w+)\s?([\w\s=]+)*/
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
if markup =~ SYNTAX
|
||||
@lang = $1
|
||||
if defined? $2
|
||||
tmp_options = {}
|
||||
$2.split.each do |opt|
|
||||
key, value = opt.split('=')
|
||||
if value.nil?
|
||||
if key == 'linenos'
|
||||
value = 'inline'
|
||||
else
|
||||
value = true
|
||||
end
|
||||
@options[key] = value
|
||||
end
|
||||
tmp_options[key] = value
|
||||
end
|
||||
tmp_options = tmp_options.to_a.collect { |opt| opt.join('=') }
|
||||
# additional options to pass to Albino.
|
||||
@options = { 'O' => tmp_options.join(',') }
|
||||
else
|
||||
raise SyntaxError.new <<-eos
|
||||
Syntax Error in tag 'highlight' while parsing the following markup:
|
||||
|
||||
#{markup}
|
||||
|
||||
Valid syntax: highlight <lang> [linenos]
|
||||
eos
|
||||
@options = {}
|
||||
end
|
||||
else
|
||||
raise SyntaxError.new("Syntax Error in 'highlight' - Valid syntax: highlight <lang> [linenos]")
|
||||
end
|
||||
|
||||
def render(context)
|
||||
if context.registers[:site].pygments
|
||||
render_pygments(context, super)
|
||||
else
|
||||
render_codehighlighter(context, super)
|
||||
end
|
||||
end
|
||||
|
||||
def render_pygments(context, code)
|
||||
require 'pygments'
|
||||
|
||||
@options[:encoding] = 'utf-8'
|
||||
|
||||
output = add_code_tags(
|
||||
Pygments.highlight(code, :lexer => @lang, :options => @options),
|
||||
@lang
|
||||
)
|
||||
|
||||
output = context["pygments_prefix"] + output if context["pygments_prefix"]
|
||||
output = output + context["pygments_suffix"] if context["pygments_suffix"]
|
||||
output
|
||||
end
|
||||
|
||||
def render_codehighlighter(context, code)
|
||||
#The div is required because RDiscount blows ass
|
||||
<<-HTML
|
||||
<div>
|
||||
<pre><code class='#{@lang}'>#{h(code).strip}</code></pre>
|
||||
</div>
|
||||
HTML
|
||||
end
|
||||
|
||||
def add_code_tags(code, lang)
|
||||
# Add nested <code> tags to code blocks
|
||||
code = code.sub(/<pre>/,'<pre><code class="' + lang + '">')
|
||||
code = code.sub(/<\/pre>/,"</code></pre>")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def render(context)
|
||||
if context.registers[:site].pygments
|
||||
render_pygments(context, super.join)
|
||||
else
|
||||
render_codehighlighter(context, super.join)
|
||||
end
|
||||
end
|
||||
|
||||
def render_pygments(context, code)
|
||||
output = add_code_tags(Albino.new(code, @lang).to_s(@options), @lang)
|
||||
output = context["pygments_prefix"] + output if context["pygments_prefix"]
|
||||
output = output + context["pygments_suffix"] if context["pygments_suffix"]
|
||||
output
|
||||
end
|
||||
|
||||
def render_codehighlighter(context, code)
|
||||
#The div is required because RDiscount blows ass
|
||||
<<-HTML
|
||||
<div>
|
||||
<pre>
|
||||
<code class='#{@lang}'>#{h(code).strip}</code>
|
||||
</pre>
|
||||
</div>
|
||||
HTML
|
||||
end
|
||||
|
||||
def add_code_tags(code, lang)
|
||||
# Add nested <code> tags to code blocks
|
||||
code = code.sub(/<pre>/,'<pre><code class="' + lang + '">')
|
||||
code = code.sub(/<\/pre>/,"</code></pre>")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('highlight', Jekyll::Tags::HighlightBlock)
|
||||
Liquid::Template.register_tag('highlight', Jekyll::HighlightBlock)
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
module Jekyll
|
||||
module Tags
|
||||
class IncludeTag < Liquid::Tag
|
||||
def initialize(tag_name, file, tokens)
|
||||
super
|
||||
@file = file.strip
|
||||
|
||||
class IncludeTag < Liquid::Tag
|
||||
def initialize(tag_name, file, tokens)
|
||||
super
|
||||
@file = file.strip
|
||||
end
|
||||
|
||||
def render(context)
|
||||
includes_dir = File.join(context.registers[:site].source, '_includes')
|
||||
|
||||
if File.symlink?(includes_dir)
|
||||
return "Includes directory '#{includes_dir}' cannot be a symlink"
|
||||
end
|
||||
|
||||
def render(context)
|
||||
includes_dir = File.join(context.registers[:site].source, '_includes')
|
||||
if @file !~ /^[a-zA-Z0-9_\/\.-]+$/ || @file =~ /\.\// || @file =~ /\/\./
|
||||
return "Include file '#{@file}' contains invalid characters or sequences"
|
||||
end
|
||||
|
||||
if File.symlink?(includes_dir)
|
||||
return "Includes directory '#{includes_dir}' cannot be a symlink"
|
||||
end
|
||||
|
||||
if @file !~ /^[a-zA-Z0-9_\/\.-]+$/ || @file =~ /\.\// || @file =~ /\/\./
|
||||
return "Include file '#{@file}' contains invalid characters or sequences"
|
||||
end
|
||||
|
||||
Dir.chdir(includes_dir) do
|
||||
choices = Dir['**/*'].reject { |x| File.symlink?(x) }
|
||||
if choices.include?(@file)
|
||||
source = File.read(@file)
|
||||
partial = Liquid::Template.parse(source)
|
||||
context.stack do
|
||||
partial.render(context)
|
||||
end
|
||||
else
|
||||
"Included file '#{@file}' not found in _includes directory"
|
||||
Dir.chdir(includes_dir) do
|
||||
choices = Dir['**/*'].reject { |x| File.symlink?(x) }
|
||||
if choices.include?(@file)
|
||||
source = File.read(@file)
|
||||
partial = Liquid::Template.parse(source)
|
||||
context.stack do
|
||||
partial.render(context)
|
||||
end
|
||||
else
|
||||
"Included file '#{@file}' not found in _includes directory"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('include', Jekyll::Tags::IncludeTag)
|
||||
Liquid::Template.register_tag('include', Jekyll::IncludeTag)
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
module Jekyll
|
||||
module Tags
|
||||
class PostComparer
|
||||
MATCHER = /^(.+\/)*(\d+-\d+-\d+)-(.*)$/
|
||||
|
||||
attr_accessor :date, :slug
|
||||
|
||||
def initialize(name)
|
||||
all, path, date, slug = *name.sub(/^\//, "").match(MATCHER)
|
||||
@slug = path ? path + slug : slug
|
||||
@date = Time.parse(date)
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
slug == post_slug(other) &&
|
||||
date.year == other.date.year &&
|
||||
date.month == other.date.month &&
|
||||
date.day == other.date.day
|
||||
end
|
||||
|
||||
private
|
||||
# Construct the directory-aware post slug for a Jekyll::Post
|
||||
#
|
||||
# other - the Jekyll::Post
|
||||
#
|
||||
# Returns the post slug with the subdirectory (relative to _posts)
|
||||
def post_slug(other)
|
||||
path = other.name.split("/")[0...-1].join("/")
|
||||
if path.nil? || path == ""
|
||||
other.slug
|
||||
else
|
||||
path + '/' + other.slug
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class PostUrl < Liquid::Tag
|
||||
def initialize(tag_name, post, tokens)
|
||||
super
|
||||
@orig_post = post.strip
|
||||
@post = PostComparer.new(@orig_post)
|
||||
end
|
||||
|
||||
def render(context)
|
||||
site = context.registers[:site]
|
||||
|
||||
site.posts.each do |p|
|
||||
if @post == p
|
||||
return p.url
|
||||
end
|
||||
end
|
||||
|
||||
puts "ERROR: post_url: \"#{@orig_post}\" could not be found"
|
||||
|
||||
return "#"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('post_url', Jekyll::Tags::PostUrl)
|
||||
1
lib/site_template/.gitignore
vendored
1
lib/site_template/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
_site
|
||||
@@ -1,2 +0,0 @@
|
||||
name: Your New Jekyll Site
|
||||
pygments: true
|
||||
@@ -1,46 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<title>{{ page.title }}</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
<!-- syntax highlighting CSS -->
|
||||
<link rel="stylesheet" href="/css/syntax.css">
|
||||
|
||||
<!-- Custom CSS -->
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<div class="site">
|
||||
<div class="header">
|
||||
<h1 class="title"><a href="/">{{ site.name }}</a></h1>
|
||||
<a class="extra" href="/">home</a>
|
||||
</div>
|
||||
|
||||
{{ content }}
|
||||
|
||||
<div class="footer">
|
||||
<div class="contact">
|
||||
<p>
|
||||
Your Name<br />
|
||||
What You Are<br />
|
||||
your@email.com
|
||||
</p>
|
||||
</div>
|
||||
<div class="contact">
|
||||
<p>
|
||||
<a href="http://github.com/yourusername/">github.com/yourusername</a><br />
|
||||
<a href="http://twitter.com/yourusername/">twitter.com/yourusername</a><br />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- /container -->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
<h2>{{ page.title }}</h2>
|
||||
<p class="meta">{{ page.date | date_to_string }}</p>
|
||||
|
||||
<div id="post">
|
||||
{{ content }}
|
||||
</div>
|
||||
@@ -1,24 +0,0 @@
|
||||
---
|
||||
layout: post
|
||||
title: "Welcome to Jekyll!"
|
||||
date: <%= Time.now.strftime('%Y-%m-%d %H:%M:%S') %>
|
||||
categories: jekyll update
|
||||
---
|
||||
|
||||
You'll find this post in your `_posts` directory - edit this post and re-build (or run with the `-w` switch) to see your changes!
|
||||
To add new posts, simply add a file in the `_posts` directory that follows the convention: YYYY-MM-DD-name-of-post.ext.
|
||||
|
||||
Jekyll also offers powerful support for code snippets:
|
||||
|
||||
{% highlight ruby %}
|
||||
def print_hi(name)
|
||||
puts "Hi, #{name}"
|
||||
end
|
||||
print_hi('Tom')
|
||||
#=> prints 'Hi, Tom' to STDOUT.
|
||||
{% endhighlight %}
|
||||
|
||||
Check out the [Jekyll docs][jekyll] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll's GitHub repo][jekyll-gh].
|
||||
|
||||
[jekyll-gh]: https://github.com/mojombo/jekyll
|
||||
[jekyll]: http://jekyllrb.com
|
||||
@@ -1,165 +0,0 @@
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
/* Common
|
||||
/*
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Global Reset */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html, body { height: 100%; }
|
||||
|
||||
body {
|
||||
background-color: #FFF;
|
||||
font: 13.34px Helvetica, Arial, sans-serif;
|
||||
font-size: small;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-size: 100%; }
|
||||
|
||||
h1 { margin-bottom: 1em; }
|
||||
p { margin: 1em 0; }
|
||||
|
||||
a { color: #00a; }
|
||||
a:hover { color: #000; }
|
||||
a:visited { color: #a0a; }
|
||||
|
||||
table {
|
||||
font-size: inherit;
|
||||
font: 100%;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
/* Home
|
||||
/*
|
||||
/*****************************************************************************/
|
||||
ul.posts {
|
||||
list-style-type: none;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
ul.posts li {
|
||||
line-height: 1.75em;
|
||||
}
|
||||
|
||||
ul.posts span {
|
||||
color: #aaa;
|
||||
font-family: Monaco, "Courier New", monospace;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
/* Site
|
||||
/*
|
||||
/*****************************************************************************/
|
||||
|
||||
.site {
|
||||
font-size: 115%;
|
||||
text-align: justify;
|
||||
width: 42em;
|
||||
margin: 3em auto 2em;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.site .header a {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.site .header h1.title {
|
||||
display: inline-block;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.site .header h1.title a {
|
||||
color: #a00;
|
||||
}
|
||||
|
||||
.site .header h1.title a:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.site .header a.extra {
|
||||
color: #aaa;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.site .header a.extra:hover {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.site .meta {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.site .footer {
|
||||
font-size: 80%;
|
||||
color: #666;
|
||||
border-top: 4px solid #eee;
|
||||
margin-top: 2em;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.site .footer .contact {
|
||||
float: left;
|
||||
margin-right: 3em;
|
||||
}
|
||||
|
||||
.site .footer .contact a {
|
||||
color: #8085C1;
|
||||
}
|
||||
|
||||
.site .footer .rss {
|
||||
margin-top: 1.1em;
|
||||
margin-right: -.2em;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.site .footer .rss img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
/* Posts
|
||||
/*
|
||||
/*****************************************************************************/
|
||||
|
||||
/* standard */
|
||||
#post pre {
|
||||
border: 1px solid #ddd;
|
||||
background-color: #eef;
|
||||
padding: 0 .4em;
|
||||
}
|
||||
|
||||
#post ul, #post ol {
|
||||
margin-left: 1.35em;
|
||||
}
|
||||
|
||||
#post code {
|
||||
border: 1px solid #ddd;
|
||||
background-color: #eef;
|
||||
padding: 0 .2em;
|
||||
}
|
||||
|
||||
#post pre code {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* terminal */
|
||||
#post pre.terminal {
|
||||
border: 1px solid #000;
|
||||
background-color: #333;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
#post pre.terminal code {
|
||||
background-color: #333;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
.highlight { background: #ffffff; }
|
||||
.highlight .c { color: #999988; font-style: italic } /* Comment */
|
||||
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
|
||||
.highlight .k { font-weight: bold } /* Keyword */
|
||||
.highlight .o { font-weight: bold } /* Operator */
|
||||
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
|
||||
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
|
||||
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
|
||||
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
|
||||
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
|
||||
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
|
||||
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||
.highlight .gr { color: #aa0000 } /* Generic.Error */
|
||||
.highlight .gh { color: #999999 } /* Generic.Heading */
|
||||
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
|
||||
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
|
||||
.highlight .go { color: #888888 } /* Generic.Output */
|
||||
.highlight .gp { color: #555555 } /* Generic.Prompt */
|
||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
|
||||
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
|
||||
.highlight .kc { font-weight: bold } /* Keyword.Constant */
|
||||
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
|
||||
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
|
||||
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
|
||||
.highlight .m { color: #009999 } /* Literal.Number */
|
||||
.highlight .s { color: #d14 } /* Literal.String */
|
||||
.highlight .na { color: #008080 } /* Name.Attribute */
|
||||
.highlight .nb { color: #0086B3 } /* Name.Builtin */
|
||||
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
|
||||
.highlight .no { color: #008080 } /* Name.Constant */
|
||||
.highlight .ni { color: #800080 } /* Name.Entity */
|
||||
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
|
||||
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
|
||||
.highlight .nn { color: #555555 } /* Name.Namespace */
|
||||
.highlight .nt { color: #000080 } /* Name.Tag */
|
||||
.highlight .nv { color: #008080 } /* Name.Variable */
|
||||
.highlight .ow { font-weight: bold } /* Operator.Word */
|
||||
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.highlight .mf { color: #009999 } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
|
||||
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #d14 } /* Literal.String.Char */
|
||||
.highlight .sd { color: #d14 } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #d14 } /* Literal.String.Double */
|
||||
.highlight .se { color: #d14 } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #d14 } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #d14 } /* Literal.String.Other */
|
||||
.highlight .sr { color: #009926 } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #d14 } /* Literal.String.Single */
|
||||
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
|
||||
.highlight .vc { color: #008080 } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #008080 } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
|
||||
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
title: Your New Jekyll Site
|
||||
---
|
||||
|
||||
<div id="home">
|
||||
<h1>Blog Posts</h1>
|
||||
<ul class="posts">
|
||||
{% for post in site.posts %}
|
||||
<li><span>{{ post.date | date_to_string }}</span> » <a href="{{ post.url }}">{{ post.title }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
@@ -1,2 +0,0 @@
|
||||
#!/bin/sh
|
||||
bundle install
|
||||
4
site/.gitignore
vendored
4
site/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
_site/
|
||||
*.swp
|
||||
pkg/
|
||||
test/
|
||||
@@ -1 +0,0 @@
|
||||
jekyllrb.com
|
||||
@@ -1 +0,0 @@
|
||||
Jekyll's awesome website.
|
||||
@@ -1,3 +0,0 @@
|
||||
pygments: true
|
||||
relative_permalinks: false
|
||||
gauges_id: 503c5af6613f5d0f19000027
|
||||
@@ -1,32 +0,0 @@
|
||||
{% if site.gauges_id %}
|
||||
<!-- Gauges (http://gaug.es/) -->
|
||||
<script type="text/javascript">
|
||||
var _gauges = _gauges || [];
|
||||
(function() {
|
||||
var t = document.createElement('script');
|
||||
t.type = 'text/javascript';
|
||||
t.async = true;
|
||||
t.id = 'gauges-tracker';
|
||||
t.setAttribute('data-site-id', '{{ site.gauges_id }}');
|
||||
t.src = '//secure.gaug.es/track.js';
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(t, s);
|
||||
})();
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
{% if site.google_analytics_id %}
|
||||
<!-- Google Analytics (http://google.com/analytics) -->
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', '{{ site.google_analytics_id }}']);
|
||||
_gaq.push(['_setDomainName', '{{ site.url }}']); // Multiple sub-domains
|
||||
_gaq.push(['_setAllowLinker', true]); // Multiple TLDs
|
||||
_gaq.push(['_trackPageview']);
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
{% endif %}
|
||||
@@ -1,85 +0,0 @@
|
||||
<div class="unit one-fifth hide-on-mobiles">
|
||||
<aside>
|
||||
<h4>Getting Started</h4>
|
||||
<ul>
|
||||
<li class="{% if page.title == "Welcome" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/home">Welcome</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Installation" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/installation">Installation</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Basic Usage" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/usage">Basic Usage</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Directory structure" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/structure">Directory structure</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Configuration" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/configuration">Configuration</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h4>Your Content</h4>
|
||||
<ul>
|
||||
<li class="{% if page.title == "Front-matter" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/frontmatter">Front-matter</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Writing posts" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/posts">Writing posts</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Creating pages" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/pages">Creating pages</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Variables" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/variables">Variables</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Blog migrations" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/migrations">Blog migrations</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h4>Customization</h4>
|
||||
<ul>
|
||||
<li class="{% if page.title == "Templates" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/templates">Templates</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Permalinks" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/permalinks">Permalinks</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Pagination" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/pagination">Pagination</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Plugins" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/plugins">Plugins</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Extras" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/extras">Extras</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h4>Deployment</h4>
|
||||
<ul>
|
||||
<li class="{% if page.title == "GitHub Pages" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/github-pages">GitHub Pages</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Deployment methods" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/deployment-methods">Other methods</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h4>Miscellaneous</h4>
|
||||
<ul>
|
||||
<li class="{% if page.title == "Contributing" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/contributing">Contributing</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Troubleshooting" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/troubleshooting">Troubleshooting</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Sites using Jekyll" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/sites">Sites using Jekyll</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Resources" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/resources">Resources</a>
|
||||
</li>
|
||||
<li class="{% if page.title == "Upgrading" %}current{% endif %}">
|
||||
<a href="{{ site.url }}/docs/upgrading">Upgrading</a>
|
||||
</li>
|
||||
</ul>
|
||||
</aside>
|
||||
</div>
|
||||
@@ -1,36 +0,0 @@
|
||||
<div class="docs-nav-mobile unit whole show-on-mobiles">
|
||||
<select onchange="if (this.value) window.location.href=this.value">
|
||||
<option value="">Navigate the docs…</option>
|
||||
<optgroup label="Getting started">
|
||||
<option value="{{ site.url }}/docs/home">Welcome</option>
|
||||
<option value="{{ site.url }}/docs/installation">Installation</option>
|
||||
<option value="{{ site.url }}/docs/usage">Basic Usage</option>
|
||||
<option value="{{ site.url }}/docs/structure">Directory structure</option>
|
||||
<option value="{{ site.url }}/docs/configuration">Configuration</option>
|
||||
</optgroup>
|
||||
<optgroup label="Your Content">
|
||||
<option value="{{ site.url }}/docs/frontmatter">Front-matter</option>
|
||||
<option value="{{ site.url }}/docs/posts">Writing posts</option>
|
||||
<option value="{{ site.url }}/docs/pages">Creating pages</option>
|
||||
<option value="{{ site.url }}/docs/variables">Variables</option>
|
||||
<option value="{{ site.url }}/docs/migrations">Blog migrations</option>
|
||||
</optgroup>
|
||||
<optgroup label="Customization">
|
||||
<option value="{{ site.url }}/docs/templates">Templates</option>
|
||||
<option value="{{ site.url }}/docs/permalinks">Permalinks</option>
|
||||
<option value="{{ site.url }}/docs/pagination">Pagination</option>
|
||||
<option value="{{ site.url }}/docs/plugins">Plugins</option>
|
||||
<option value="{{ site.url }}/docs/extras">Extras</option>
|
||||
</optgroup>
|
||||
<optgroup label="Deployment">
|
||||
<option value="{{ site.url }}/docs/github-pages">GitHub Pages</option>
|
||||
<option value="{{ site.url }}/docs/deployment-methods">Other methods</option>
|
||||
</optgroup>
|
||||
<optgroup label="Miscellaneous">
|
||||
<option value="{{ site.url }}/docs/contributing">Contributing</option>
|
||||
<option value="{{ site.url }}/docs/troubleshooting">Troubleshooting</option>
|
||||
<option value="{{ site.url }}/docs/sites">Sites using Jekyll</option>
|
||||
<option value="{{ site.url }}/docs/resources">Resources</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
@@ -1,15 +0,0 @@
|
||||
<footer>
|
||||
<div class="grid">
|
||||
<div class="unit one-third center-on-mobiles">
|
||||
<p>By <a href="http://tom.preston-werner.com">Tom Preston-Werner</a>, <a href="http://quaran.to/">Nick Quaranto</a>, and many more <a href="https://github.com/mojombo/jekyll/graphs/contributors">awesome contributors</a>.</p>
|
||||
</div>
|
||||
<div class="unit two-thirds align-right center-on-mobiles">
|
||||
<p>
|
||||
Proudly hosted by
|
||||
<a href="https://github.com">
|
||||
<img src="{{ site.url }}/img/footer-logo.png" alt="GitHub • Social coding">
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -1,18 +0,0 @@
|
||||
<header>
|
||||
<nav class="mobile-nav show-on-mobiles">
|
||||
{% include primary-nav-items.html %}
|
||||
</nav>
|
||||
<div class="grid">
|
||||
<div class="unit one-third center-on-mobiles">
|
||||
<h1>
|
||||
<a href="{{ site.url }}/">
|
||||
<span>Jekyll</span>
|
||||
<img src="{{ site.url }}/img/logo-2x.png" width="249px" height="115px" alt="">
|
||||
</a>
|
||||
</h1>
|
||||
</div>
|
||||
<nav class="main-nav unit two-thirds hide-on-mobiles">
|
||||
{% include primary-nav-items.html %}
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
@@ -1,11 +0,0 @@
|
||||
<ul>
|
||||
<li class="{% if page.overview %}current{% endif %}">
|
||||
<a href="{{ site.url }}/">Overview</a>
|
||||
</li>
|
||||
<li class="{% unless page.overview %}current{% endunless %}">
|
||||
<a href="{{ site.url }}/docs/home">Doc<span class="show-on-mobiles">s</span><span class="hide-on-mobiles">umentation</span></a>
|
||||
</li>
|
||||
<li class="">
|
||||
<a href="https://github.com/mojombo/jekyll"><span class="hide-on-mobiles">View on </span>GitHub</a>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -1,22 +0,0 @@
|
||||
<div class="section-nav">
|
||||
<div class="left align-right">
|
||||
{% if page.prev_section != null %}
|
||||
<a href="{{ site.url }}/docs/{{ page.prev_section }}" class="prev">
|
||||
Back
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="prev disabled">Back</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="right align-left">
|
||||
{% if page.next_section != null %}
|
||||
<a href="{{ site.url }}/docs/{{ page.next_section }}" class="next">
|
||||
Next
|
||||
</a>
|
||||
{% else %}
|
||||
<span class="next disabled">Next</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{{ page.title }}</title>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link href='http://fonts.googleapis.com/css?family=Lato:100,300,400,700,900,100italic,300italic,400italic,700italic,900italic' rel='stylesheet' type='text/css'>
|
||||
<link href='http://fonts.googleapis.com/css?family=Arizonia' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" href="{{ site.url }}/css/normalize.css" />
|
||||
<link rel="stylesheet" href="{{ site.url }}/css/gridism.css" />
|
||||
<link rel="stylesheet" href="{{ site.url }}/css/style.css" />
|
||||
<link rel="stylesheet" href="{{ site.url }}/css/pygments.css" />
|
||||
<link rel="icon" type="image/x-icon" href="{{ site.url }}/favicon.png" />
|
||||
<script src="{{ site.url }}/js/modernizr-2.5.3.min.js"></script>
|
||||
</head>
|
||||
@@ -1,12 +0,0 @@
|
||||
{% include top.html %}
|
||||
|
||||
<body class="wrap">
|
||||
{% include header.html %}
|
||||
|
||||
{{ content }}
|
||||
|
||||
{% include footer.html %}
|
||||
{% include analytics.html %}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
layout: default
|
||||
---
|
||||
|
||||
<section class="docs">
|
||||
<div class="grid">
|
||||
|
||||
{% include docs_contents_mobile.html %}
|
||||
|
||||
<div class="unit four-fifths">
|
||||
<article>
|
||||
<h1>{{ page.title }}</h1>
|
||||
{{ content }}
|
||||
{% include section_nav.html %}
|
||||
</article>
|
||||
</div>
|
||||
|
||||
{% include docs_contents.html %}
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Gridism
|
||||
* A simple, responsive, and handy CSS grid by @cobyism
|
||||
* https://github.com/cobyism/gridism
|
||||
*/
|
||||
|
||||
/* Preserve some sanity */
|
||||
.grid,
|
||||
.unit {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Set up some rules to govern the grid */
|
||||
.grid {
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
.grid .unit {
|
||||
float: left;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
/* This ensures the outer gutters are equal to the (doubled) inner gutters. */
|
||||
.grid .unit:first-child { padding-left: 20px; }
|
||||
.grid .unit:last-child { padding-right: 20px; }
|
||||
|
||||
/* Nested grids already have padding though, so let’s nuke it */
|
||||
.unit .unit:first-child { padding-left: 0; }
|
||||
.unit .unit:last-child { padding-right: 0; }
|
||||
.unit .grid:first-child > .unit { padding-top: 0; }
|
||||
.unit .grid:last-child > .unit { padding-bottom: 0; }
|
||||
|
||||
/* Let people nuke the gutters/padding completely in a couple of ways */
|
||||
.no-gutters .unit,
|
||||
.unit.no-gutters {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* Wrapping at a maximum width is optional */
|
||||
.wrap .grid,
|
||||
.grid.wrap {
|
||||
max-width: 978px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Width classes also have shorthand versions numbered as fractions
|
||||
* For example: for a grid unit 1/3 (one third) of the parent width,
|
||||
* simply apply class="w-1-3" to the element. */
|
||||
.grid .whole, .grid .w-1-1 { width: 100%; }
|
||||
.grid .half, .grid .w-1-2 { width: 50%; }
|
||||
.grid .one-third, .grid .w-1-3 { width: 33.3332%; }
|
||||
.grid .two-thirds, .grid .w-2-3 { width: 66.6665%; }
|
||||
.grid .one-quarter, .grid .w-1-4 { width: 25%; }
|
||||
.grid .three-quarters, .grid .w-3-4 { width: 75%; }
|
||||
.grid .one-fifth, .grid .w-1-5 { width: 20%; }
|
||||
.grid .two-fifths, .grid .w-2-5 { width: 40%; }
|
||||
.grid .three-fifths, .grid .w-3-5 { width: 60%; }
|
||||
.grid .four-fifths, .grid .w-4-5 { width: 80%; }
|
||||
.grid .golden-small, .grid .w-g-s { width: 38.2716%; } /* Golden section: smaller piece */
|
||||
.grid .golden-large, .grid .w-g-l { width: 61.7283%; } /* Golden section: larger piece */
|
||||
|
||||
/* Utility classes */
|
||||
.align-center { text-align: center; }
|
||||
.align-left { text-align: left; }
|
||||
.align-right { text-align: right; }
|
||||
.pull-left { float: left; }
|
||||
.pull-right { float: right; }
|
||||
|
||||
.show-on-mobiles {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Responsive Stuff */
|
||||
@media screen and (max-width: 568px) {
|
||||
/* Stack anything that isn’t full-width on smaller screens */
|
||||
.grid .unit {
|
||||
width: 100% !important;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
.unit .grid .unit {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
/* Sometimes, you just want to be different on small screens */
|
||||
.center-on-mobiles {
|
||||
text-align: center !important;
|
||||
}
|
||||
.hide-on-mobiles {
|
||||
display: none !important;
|
||||
}
|
||||
.show-on-mobiles {
|
||||
display: block !important;
|
||||
}
|
||||
a .show-on-mobiles {
|
||||
display: inline !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Expand the wrap a bit further on larger screens */
|
||||
/*@media screen and (min-width: 1180px) {
|
||||
.wrap .grid {
|
||||
max-width: 1180px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}*/
|
||||
504
site/css/normalize.css
vendored
504
site/css/normalize.css
vendored
@@ -1,504 +0,0 @@
|
||||
/*! normalize.css 2012-03-11T12:53 UTC - http://github.com/necolas/normalize.css */
|
||||
|
||||
/* =============================================================================
|
||||
HTML5 display definitions
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Corrects block display not defined in IE6/7/8/9 & FF3
|
||||
*/
|
||||
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
nav,
|
||||
section,
|
||||
summary {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/*
|
||||
* Corrects inline-block display not defined in IE6/7/8/9 & FF3
|
||||
*/
|
||||
|
||||
audio,
|
||||
canvas,
|
||||
video {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevents modern browsers from displaying 'audio' without controls
|
||||
* Remove excess height in iOS5 devices
|
||||
*/
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4
|
||||
* Known issue: no IE6 support
|
||||
*/
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Base
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units
|
||||
* http://clagnut.com/blog/348/#c790
|
||||
* 2. Prevents iOS text size adjust after orientation change, without disabling user zoom
|
||||
* www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/
|
||||
*/
|
||||
|
||||
html {
|
||||
font-size: 100%; /* 1 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
-ms-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses font-family inconsistency between 'textarea' and other form elements.
|
||||
*/
|
||||
|
||||
html,
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses margins handled incorrectly in IE6/7
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Links
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Addresses outline displayed oddly in Chrome
|
||||
*/
|
||||
|
||||
a:focus {
|
||||
outline: thin dotted;
|
||||
}
|
||||
|
||||
/*
|
||||
* Improves readability when focused and also mouse hovered in all browsers
|
||||
* people.opera.com/patrickl/experiments/keyboard/test
|
||||
*/
|
||||
|
||||
a:hover,
|
||||
a:active {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Typography
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Addresses font sizes and margins set differently in IE6/7
|
||||
* Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5
|
||||
*/
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5em;
|
||||
margin: 0.83em 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.17em;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1em;
|
||||
margin: 1.33em 0;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 0.83em;
|
||||
margin: 1.67em 0;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 0.75em;
|
||||
margin: 2.33em 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling not present in IE7/8/9, S5, Chrome
|
||||
*/
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: 1px dotted;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses style set to 'bolder' in FF3+, S4/5, Chrome
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 1em 40px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling not present in S5, Chrome
|
||||
*/
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses styling not present in IE6/7/8/9
|
||||
*/
|
||||
|
||||
mark {
|
||||
background: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses margins set differently in IE6/7
|
||||
*/
|
||||
|
||||
p,
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Corrects font family set oddly in IE6, S4/5, Chrome
|
||||
* en.wikipedia.org/wiki/User:Davidgothberg/Test59
|
||||
*/
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: monospace, serif;
|
||||
_font-family: 'courier new', monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
/*
|
||||
* Improves readability of pre-formatted text in all browsers
|
||||
*/
|
||||
|
||||
pre {
|
||||
white-space: pre;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Addresses CSS quotes not supported in IE6/7
|
||||
* 2. Addresses quote property not supported in S4
|
||||
*/
|
||||
|
||||
/* 1 */
|
||||
|
||||
q {
|
||||
quotes: none;
|
||||
}
|
||||
|
||||
/* 2 */
|
||||
|
||||
q:before,
|
||||
q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prevents sub and sup affecting line-height in all browsers
|
||||
* gist.github.com/413930
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Lists
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Addresses margins set differently in IE6/7
|
||||
*/
|
||||
|
||||
dl,
|
||||
menu,
|
||||
ol,
|
||||
ul {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin: 0 0 0 40px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses paddings set differently in IE6/7
|
||||
*/
|
||||
|
||||
menu,
|
||||
ol,
|
||||
ul {
|
||||
padding: 0 0 0 40px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Corrects list images handled incorrectly in IE7
|
||||
*/
|
||||
|
||||
nav ul,
|
||||
nav ol {
|
||||
list-style: none;
|
||||
list-style-image: none;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Embedded content
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* 1. Removes border when inside 'a' element in IE6/7/8/9, FF3
|
||||
* 2. Improves image quality when scaled in IE7
|
||||
* code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/
|
||||
*/
|
||||
|
||||
img {
|
||||
border: 0; /* 1 */
|
||||
-ms-interpolation-mode: bicubic; /* 2 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Corrects overflow displayed oddly in IE9
|
||||
*/
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Figures
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Addresses margin not present in IE6/7/8/9, S5, O11
|
||||
*/
|
||||
|
||||
figure {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Forms
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Corrects margin displayed oddly in IE6/7
|
||||
*/
|
||||
|
||||
form {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Define consistent border, margin, and padding
|
||||
*/
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Corrects color not being inherited in IE6/7/8/9
|
||||
* 2. Corrects text not wrapping in FF3
|
||||
* 3. Corrects alignment displayed oddly in IE6/7
|
||||
*/
|
||||
|
||||
legend {
|
||||
border: 0; /* 1 */
|
||||
padding: 0;
|
||||
white-space: normal; /* 2 */
|
||||
*margin-left: -7px; /* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Corrects font size not being inherited in all browsers
|
||||
* 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome
|
||||
* 3. Improves appearance and consistency in all browsers
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
font-size: 100%; /* 1 */
|
||||
margin: 0; /* 2 */
|
||||
vertical-align: baseline; /* 3 */
|
||||
*vertical-align: middle; /* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet
|
||||
*/
|
||||
|
||||
button,
|
||||
input {
|
||||
line-height: normal; /* 1 */
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Improves usability and consistency of cursor style between image-type 'input' and others
|
||||
* 2. Corrects inability to style clickable 'input' types in iOS
|
||||
* 3. Removes inner spacing in IE7 without affecting normal text inputs
|
||||
* Known issue: inner spacing remains in IE6
|
||||
*/
|
||||
|
||||
button,
|
||||
input[type="button"],
|
||||
input[type="reset"],
|
||||
input[type="submit"] {
|
||||
cursor: pointer; /* 1 */
|
||||
-webkit-appearance: button; /* 2 */
|
||||
*overflow: visible; /* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Re-set default cursor for disabled elements
|
||||
*/
|
||||
|
||||
button[disabled],
|
||||
input[disabled] {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Addresses box sizing set to content-box in IE8/9
|
||||
* 2. Removes excess padding in IE8/9
|
||||
* 3. Removes excess padding in IE7
|
||||
Known issue: excess padding remains in IE6
|
||||
*/
|
||||
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
*height: 13px; /* 3 */
|
||||
*width: 13px; /* 3 */
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Addresses appearance set to searchfield in S5, Chrome
|
||||
* 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof)
|
||||
*/
|
||||
|
||||
input[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
-moz-box-sizing: content-box;
|
||||
-webkit-box-sizing: content-box; /* 2 */
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes inner padding and search cancel button in S5, Chrome on OS X
|
||||
*/
|
||||
|
||||
input[type="search"]::-webkit-search-decoration,
|
||||
input[type="search"]::-webkit-search-cancel-button {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes inner padding and border in FF3+
|
||||
* www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/
|
||||
*/
|
||||
|
||||
button::-moz-focus-inner,
|
||||
input::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. Removes default vertical scrollbar in IE6/7/8/9
|
||||
* 2. Improves readability and alignment in all browsers
|
||||
*/
|
||||
|
||||
textarea {
|
||||
overflow: auto; /* 1 */
|
||||
vertical-align: top; /* 2 */
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
Tables
|
||||
========================================================================== */
|
||||
|
||||
/*
|
||||
* Remove most spacing between table cells
|
||||
*/
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*.highlight { background: #333333; color: #ffffff}*/
|
||||
.highlight .hll { background-color: #ffffcc }
|
||||
.highlight .c { color: #87ceeb} /* Comment */
|
||||
.highlight .err { color: #ffffff} /* Error */
|
||||
.highlight .g { color: #ffffff} /* Generic */
|
||||
.highlight .k { color: #f0e68c} /* Keyword */
|
||||
.highlight .l { color: #ffffff} /* Literal */
|
||||
.highlight .n { color: #ffffff} /* Name */
|
||||
.highlight .o { color: #ffffff} /* Operator */
|
||||
.highlight .x { color: #ffffff} /* Other */
|
||||
.highlight .p { color: #ffffff} /* Punctuation */
|
||||
.highlight .cm { color: #87ceeb} /* Comment.Multiline */
|
||||
.highlight .cp { color: #cd5c5c} /* Comment.Preproc */
|
||||
.highlight .c1 { color: #87ceeb} /* Comment.Single */
|
||||
.highlight .cs { color: #87ceeb} /* Comment.Special */
|
||||
.highlight .gd { color: #0000c0; font-weight: bold; background-color: #008080 } /* Generic.Deleted */
|
||||
.highlight .ge { color: #c000c0; text-decoration: underline} /* Generic.Emph */
|
||||
.highlight .gr { color: #c0c0c0; font-weight: bold; background-color: #c00000 } /* Generic.Error */
|
||||
.highlight .gh { color: #cd5c5c} /* Generic.Heading */
|
||||
.highlight .gi { color: #ffffff; background-color: #0000c0 } /* Generic.Inserted */
|
||||
.highlight .go { color: #add8e6; font-weight: bold; background-color: #4d4d4d } /* Generic.Output */
|
||||
.highlight .gp { color: #ffffff} /* Generic.Prompt */
|
||||
.highlight .gs { color: #ffffff} /* Generic.Strong */
|
||||
.highlight .gu { color: #cd5c5c} /* Generic.Subheading */
|
||||
.highlight .gt { color: #c0c0c0; font-weight: bold; background-color: #c00000 } /* Generic.Traceback */
|
||||
.highlight .kc { color: #f0e68c} /* Keyword.Constant */
|
||||
.highlight .kd { color: #f0e68c} /* Keyword.Declaration */
|
||||
.highlight .kn { color: #f0e68c} /* Keyword.Namespace */
|
||||
.highlight .kp { color: #f0e68c} /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #f0e68c} /* Keyword.Reserved */
|
||||
.highlight .kt { color: #bdb76b} /* Keyword.Type */
|
||||
.highlight .ld { color: #ffffff} /* Literal.Date */
|
||||
.highlight .m { color: #ffffff} /* Literal.Number */
|
||||
.highlight .s { color: #ffffff} /* Literal.String */
|
||||
.highlight .na { color: #ffffff} /* Name.Attribute */
|
||||
.highlight .nb { color: #ffffff} /* Name.Builtin */
|
||||
.highlight .nc { color: #ffffff} /* Name.Class */
|
||||
.highlight .no { color: #ffa0a0} /* Name.Constant */
|
||||
.highlight .nd { color: #ffffff} /* Name.Decorator */
|
||||
.highlight .ni { color: #ffdead} /* Name.Entity */
|
||||
.highlight .ne { color: #ffffff} /* Name.Exception */
|
||||
.highlight .nf { color: #ffffff} /* Name.Function */
|
||||
.highlight .nl { color: #ffffff} /* Name.Label */
|
||||
.highlight .nn { color: #ffffff} /* Name.Namespace */
|
||||
.highlight .nx { color: #ffffff} /* Name.Other */
|
||||
.highlight .py { color: #ffffff} /* Name.Property */
|
||||
.highlight .nt { color: #f0e68c} /* Name.Tag */
|
||||
.highlight .nv { color: #98fb98} /* Name.Variable */
|
||||
.highlight .ow { color: #ffffff} /* Operator.Word */
|
||||
.highlight .w { color: #ffffff} /* Text.Whitespace */
|
||||
.highlight .mf { color: #ffffff} /* Literal.Number.Float */
|
||||
.highlight .mh { color: #ffffff} /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #ffffff} /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #ffffff} /* Literal.Number.Oct */
|
||||
.highlight .sb { color: #ffffff} /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #ffffff} /* Literal.String.Char */
|
||||
.highlight .sd { color: #ffffff} /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #ffffff} /* Literal.String.Double */
|
||||
.highlight .se { color: #ffffff} /* Literal.String.Escape */
|
||||
.highlight .sh { color: #ffffff} /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #ffffff} /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #ffffff} /* Literal.String.Other */
|
||||
.highlight .sr { color: #ffffff} /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #ffffff} /* Literal.String.Single */
|
||||
.highlight .ss { color: #ffffff} /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #ffffff} /* Name.Builtin.Pseudo */
|
||||
.highlight .vc { color: #98fb98} /* Name.Variable.Class */
|
||||
.highlight .vg { color: #98fb98} /* Name.Variable.Global */
|
||||
.highlight .vi { color: #98fb98} /* Name.Variable.Instance */
|
||||
.highlight .il { color: #ffffff} /* Literal.Number.Integer.Long */
|
||||
@@ -1,831 +0,0 @@
|
||||
/* Base */
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Lato, 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
font-size: 21px;
|
||||
font-weight: 300;
|
||||
color: #ddd;
|
||||
background: #333;
|
||||
border-top: 5px solid #fc0;
|
||||
box-shadow: inset 0 3px 30px rgba(0,0,0,.3);
|
||||
text-shadow: 0 1px 3px rgba(0,0,0,.5);
|
||||
}
|
||||
|
||||
.clear {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.clear:after {
|
||||
content: " ";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/* Sections */
|
||||
|
||||
body > header, body > section, body > footer {
|
||||
float: left;
|
||||
width: 100%;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
|
||||
body > header h1, body > header nav {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
body > header h1 span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
nav li {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.main-nav {
|
||||
margin-top: 52px;
|
||||
}
|
||||
|
||||
.main-nav li {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.main-nav li a {
|
||||
border-radius: 5px;
|
||||
font-weight: 800;
|
||||
font-size: 14px;
|
||||
padding: 0.5em 1em;
|
||||
text-shadow: none;
|
||||
text-transform: uppercase;
|
||||
transition: all .25s;
|
||||
-moz-transition: all .25s;
|
||||
-webkit-transition: all .25s;
|
||||
}
|
||||
|
||||
.main-nav li a:hover {
|
||||
background: #252525;
|
||||
box-shadow: inset 0 1px 3px rgba(0,0,0,.5), 0 1px 0 rgba(255,255,255,.1);
|
||||
text-shadow: 0 1px 3px rgba(0,0,0,.5);
|
||||
}
|
||||
|
||||
.main-nav li.current a {
|
||||
background: #fc0;
|
||||
color: #222;
|
||||
box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 1px 5px rgba(0,0,0,.5);
|
||||
text-shadow: 0 1px 0 rgba(255,255,255,.3);
|
||||
}
|
||||
|
||||
.mobile-nav ul {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
display: table;
|
||||
}
|
||||
|
||||
.mobile-nav a {
|
||||
float: left;
|
||||
width: 100%;
|
||||
background: #333;
|
||||
color: #fc0;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
font-weight: 800;
|
||||
padding: 5px 0;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.mobile-nav .current a {
|
||||
background: #fc0;
|
||||
color: #222;
|
||||
box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 1px 5px rgba(0,0,0,.5);
|
||||
text-shadow: 0 1px 0 rgba(255,255,255,.3);
|
||||
}
|
||||
|
||||
.mobile-nav li {
|
||||
display: table-cell;
|
||||
width: 33.3%;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px){
|
||||
.main-nav ul {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
@media (max-width: 720px){
|
||||
.main-nav .show-on-mobiles {
|
||||
display: inline;
|
||||
}
|
||||
.main-nav .hide-on-mobiles {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
|
||||
body > footer {
|
||||
background: #222;
|
||||
font-size: 16px;
|
||||
padding-bottom: 5px;
|
||||
color: #888;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
body > footer a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
body > footer .align-right p, body > footer img {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
body > footer img {
|
||||
position: relative;
|
||||
top: 8px;
|
||||
margin-left: 5px;
|
||||
width: 100px;
|
||||
height: 30px;
|
||||
opacity: .8;
|
||||
padding: 1px;
|
||||
-webkit-transition: opacity .2s;
|
||||
-moz-transition: opacity .2s;
|
||||
transition: opacity .2s;
|
||||
}
|
||||
|
||||
body > footer a:hover img {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@media (max-width: 568px){
|
||||
footer .one-third p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
footer .two-thirds p {
|
||||
margin-top: -20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Intro */
|
||||
|
||||
.intro .unit {
|
||||
padding: 10px 0 40px;
|
||||
}
|
||||
|
||||
.intro p {
|
||||
font-size: 1.75em;
|
||||
line-height: 1em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 569px){
|
||||
.intro p {
|
||||
font-size: 3.2em;
|
||||
}
|
||||
}
|
||||
|
||||
/* Quickstart */
|
||||
|
||||
.quickstart {
|
||||
background: #3F1F1F;
|
||||
color: #fff;
|
||||
margin: 60px 0;
|
||||
box-shadow: inset 0 3px 10px rgba(0,0,0,.4);
|
||||
}
|
||||
|
||||
.quickstart .content {
|
||||
padding: 0px 0;
|
||||
}
|
||||
|
||||
.quickstart h4 {
|
||||
font-size: 24px;
|
||||
line-height: 24px;
|
||||
margin-top: 20px;
|
||||
text-shadow: 0 1px 3px rgba(0,0,0,.8);
|
||||
}
|
||||
|
||||
.quickstart .code {
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
margin: 0 0 -30px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px){
|
||||
.quickstart .code {
|
||||
font-size: 18px;
|
||||
margin: -30px 0;
|
||||
float: right;
|
||||
}
|
||||
.quickstart h4 {
|
||||
margin: 50px 0 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code */
|
||||
|
||||
.quickstart .code {
|
||||
display: block;
|
||||
padding: 0;
|
||||
font-family: Menlo, Consolas, "Courier New", Courier, "Liberation Mono", monospace;
|
||||
line-height: 1.3em;
|
||||
}
|
||||
|
||||
.quickstart .code .title {
|
||||
display: block;
|
||||
text-align: center;
|
||||
margin: 0 20px;
|
||||
padding: 5px 0;
|
||||
border-radius: 5px 5px 0 0;
|
||||
box-shadow: 0 3px 10px rgba(0,0,0,.5);
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
color: #444;
|
||||
text-shadow: 0 1px 0 rgba(255,255,255,.5);
|
||||
background: #f7f7f7;
|
||||
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2Y3ZjdmNyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjclIiBzdG9wLWNvbG9yPSIjY2ZjZmNmIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2FhYWFhYSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=);
|
||||
background: -moz-linear-gradient(top, #f7f7f7 0%, #cfcfcf 7%, #aaaaaa 100%);
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f7f7f7), color-stop(7%,#cfcfcf), color-stop(100%,#aaaaaa));
|
||||
background: -webkit-linear-gradient(top, #f7f7f7 0%,#cfcfcf 7%,#aaaaaa 100%);
|
||||
background: -o-linear-gradient(top, #f7f7f7 0%,#cfcfcf 7%,#aaaaaa 100%);
|
||||
background: -ms-linear-gradient(top, #f7f7f7 0%,#cfcfcf 7%,#aaaaaa 100%);
|
||||
background: linear-gradient(top, #f7f7f7 0%,#cfcfcf 7%,#aaaaaa 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f7f7f7', endColorstr='#aaaaaa',GradientType=0 );
|
||||
border-bottom: 1px solid #111;
|
||||
}
|
||||
|
||||
.quickstart .code .shell {
|
||||
padding: 20px;
|
||||
text-shadow: none;
|
||||
margin: 0 20px;
|
||||
background: #3d3d3d;
|
||||
border-radius: 0 0 5px 5px;
|
||||
box-shadow: 0 5px 30px rgba(0,0,0,.3);
|
||||
}
|
||||
|
||||
.quickstart .code .line {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.quickstart .code .line span {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.quickstart .code .path {
|
||||
color: #87ceeb;
|
||||
}
|
||||
|
||||
.quickstart .code .prompt {
|
||||
color: #cd5c5c;
|
||||
}
|
||||
|
||||
.quickstart .code .command {
|
||||
color: #f0e68c;
|
||||
}
|
||||
|
||||
.quickstart .code .output {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
/* Free Hosting */
|
||||
|
||||
.free-hosting .pane {
|
||||
background: #444;
|
||||
border-radius: 10px;
|
||||
text-shadow: none;
|
||||
position: relative;
|
||||
padding: 0 20px 30px;
|
||||
}
|
||||
|
||||
.free-hosting img {
|
||||
margin: -30px 0 0;
|
||||
width: 180px;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.free-hosting h2 {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.free-hosting p,
|
||||
.free-hosting a {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.free-hosting p {
|
||||
margin: .75em 0;
|
||||
}
|
||||
|
||||
@media (min-width: 768px){
|
||||
.free-hosting img {
|
||||
float: left;
|
||||
margin: -20px -30px -30px -50px;
|
||||
width: 300px;
|
||||
height: 251px;
|
||||
}
|
||||
.free-hosting .pane-content {
|
||||
margin-top: 35px;
|
||||
padding-right: 30px;
|
||||
}
|
||||
.free-hosting p,
|
||||
.free-hosting a {
|
||||
font-size: 18px;
|
||||
}
|
||||
.free-hosting .pane:after {
|
||||
content: " ";
|
||||
float: right;
|
||||
background: url(../img/footer-arrow.png) top left no-repeat;
|
||||
width: 73px;
|
||||
height: 186px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -30px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Documentation */
|
||||
|
||||
.docs .content {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.docs article {
|
||||
background: #444;
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
margin: 0 10px;
|
||||
box-shadow: 0 3px 10px rgba(0,0,0,.1);
|
||||
min-height: 800px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 568px){
|
||||
.docs article {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px){
|
||||
.docs article {
|
||||
padding: 40px 40px 30px;
|
||||
font-size: 21px;
|
||||
}
|
||||
}
|
||||
|
||||
.docs aside {
|
||||
padding-top: 30px;
|
||||
}
|
||||
|
||||
.docs aside h4 {
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
padding: 0 0 10px 30px;
|
||||
margin-left: -30px;
|
||||
display: inline-block;
|
||||
border-bottom: 1px solid #c00;
|
||||
}
|
||||
|
||||
.docs aside ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.docs aside li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.docs aside li a {
|
||||
font-size: 16px;
|
||||
position: relative
|
||||
}
|
||||
|
||||
.docs aside li.current a:before {
|
||||
content: "";
|
||||
border-color: transparent transparent transparent #444;
|
||||
border-style: solid;
|
||||
border-width: 10px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -30px;
|
||||
}
|
||||
|
||||
.section-nav {
|
||||
text-align: center;
|
||||
padding-top: 40px;
|
||||
position: relative;
|
||||
background: url(../img/article-footer.png) top center no-repeat;
|
||||
margin: 40px -20px 10px;
|
||||
}
|
||||
|
||||
.section-nav > div {
|
||||
width: 49.5%;
|
||||
}
|
||||
|
||||
.section-nav a, .section-nav span {
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
text-transform: uppercase;
|
||||
font-weight: 700;
|
||||
padding: 8px 12px 10px;
|
||||
border-radius: 5px;
|
||||
/*border: 1px solid #333;*/
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,.3), inset 0 1px 1px rgba(255,255,255,.5);
|
||||
background: #777;
|
||||
}
|
||||
|
||||
.section-nav a:hover {
|
||||
color: #fff;
|
||||
background: #888;
|
||||
}
|
||||
|
||||
.section-nav .next, .section-nav .prev {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.section-nav .next:after, .section-nav .prev:before {
|
||||
font-size: 36px;
|
||||
color: #222;
|
||||
font-weight: 800;
|
||||
text-shadow: 0 1px 0 rgba(255,255,255,.4);
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
}
|
||||
|
||||
.section-nav .next:after {
|
||||
content: "›";
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.section-nav .prev:before {
|
||||
content: "‹";
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.section-nav .prev, .section-nav .prev:hover {
|
||||
/*float: left;*/
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.section-nav .next, .section-nav .next:hover {
|
||||
/*float: right;*/
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
.section-nav .disabled {
|
||||
opacity: .5;
|
||||
/*filter: alpha*/
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.docs-nav-mobile select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Code Highlighting */
|
||||
|
||||
|
||||
pre, code {
|
||||
white-space: pre;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: Menlo, Consolas, "Courier New", Courier, "Liberation Mono", monospace;
|
||||
font-size: 14px;
|
||||
padding: 0 .5em;
|
||||
line-height: 1.8em;
|
||||
}
|
||||
|
||||
@media (min-width: 768px){
|
||||
pre, code {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.highlight, p > pre, p > code, p > nobr > code, li > code {
|
||||
background: #333;
|
||||
color: #fff;
|
||||
border-radius: 5px;
|
||||
box-shadow: inset 0 1px 10px rgba(0,0,0,.3),
|
||||
0 1px 0 rgba(255,255,255,.1),
|
||||
0 -1px 0 rgba(0,0,0,.5);
|
||||
}
|
||||
|
||||
.highlight {
|
||||
padding: 10px 0;
|
||||
width: 100%;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
/* HTML Elements */
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #fc0;
|
||||
text-decoration: none;
|
||||
transition: all .25s;
|
||||
-moz-transition: all .25s;
|
||||
-webkit-transition: all .25s;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #f90;
|
||||
}
|
||||
|
||||
strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.left { float: left; }
|
||||
.right { float: right; }
|
||||
.align-right { text-align: right; }
|
||||
.align-left { text-align: left; }
|
||||
.align-center { text-align: center; }
|
||||
|
||||
/* Article HTML */
|
||||
|
||||
article h2,
|
||||
article h3,
|
||||
article h4,
|
||||
article h5,
|
||||
article h6 {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
article h4 {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
article ul li p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
article ul li, article ol li {
|
||||
line-height: 1.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
article ul li blockquote {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 2px solid #777;
|
||||
padding-left: 20px;
|
||||
font-style: italic;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
||||
/* Tables */
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
background: #555;
|
||||
margin: .5em 0;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,.3);
|
||||
}
|
||||
|
||||
thead {
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
color: #fff;
|
||||
background: #3a3a3a;
|
||||
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzNhM2EzYSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMxZTFlMWUiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
|
||||
background: -moz-linear-gradient(top, #3a3a3a 0%, #1e1e1e 100%);
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#3a3a3a), color-stop(100%,#1e1e1e));
|
||||
background: -webkit-linear-gradient(top, #3a3a3a 0%,#1e1e1e 100%);
|
||||
background: -o-linear-gradient(top, #3a3a3a 0%,#1e1e1e 100%);
|
||||
background: -ms-linear-gradient(top, #3a3a3a 0%,#1e1e1e 100%);
|
||||
background: linear-gradient(to bottom, #3a3a3a 0%,#1e1e1e 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3a3a3a', endColorstr='#1e1e1e',GradientType=0 );
|
||||
}
|
||||
|
||||
thead th {
|
||||
position: relative;
|
||||
box-shadow: inset 0 1px 0 rgba(255,255,255,.1);
|
||||
}
|
||||
|
||||
thead th:first-child {
|
||||
border-top-left-radius: 5px;
|
||||
}
|
||||
|
||||
thead th:last-child {
|
||||
border-top-right-radius: 5px;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: .5em .75em;
|
||||
}
|
||||
|
||||
td p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
th {
|
||||
text-transform: uppercase;
|
||||
font-size: 16px;
|
||||
padding: .5em .75em;
|
||||
text-shadow: 0 -1px 0 rgba(0,0,0,.9);
|
||||
color: #888;
|
||||
}
|
||||
|
||||
tbody td {
|
||||
border-top: 1px solid rgba(0,0,0,.1);
|
||||
box-shadow: inset 0 1px 0 rgba(255,255,255,.1);
|
||||
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwLjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIwIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=);
|
||||
background: -moz-linear-gradient(top, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 100%);
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,0.1)), color-stop(100%,rgba(255,255,255,0)));
|
||||
background: -webkit-linear-gradient(top, rgba(255,255,255,0.1) 0%,rgba(255,255,255,0) 100%);
|
||||
background: -o-linear-gradient(top, rgba(255,255,255,0.1) 0%,rgba(255,255,255,0) 100%);
|
||||
background: -ms-linear-gradient(top, rgba(255,255,255,0.1) 0%,rgba(255,255,255,0) 100%);
|
||||
background: linear-gradient(to bottom, rgba(255,255,255,0.1) 0%,rgba(255,255,255,0) 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#1affffff', endColorstr='#00ffffff',GradientType=0 );
|
||||
}
|
||||
|
||||
td p {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
td p code {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
code.option, th .option, code.filter, th .filter {
|
||||
color: #50B600;
|
||||
}
|
||||
|
||||
code.flag, th .flag, code.output, th .output {
|
||||
color: #049DCE;
|
||||
}
|
||||
|
||||
code.option, code.flag, code.filter, code.output {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
/* Note types */
|
||||
|
||||
.note {
|
||||
margin: 30px 0;
|
||||
margin-left: -30px;
|
||||
padding: 20px 20px 24px;
|
||||
padding-left: 50px;
|
||||
border-radius: 0 5px 5px 0;
|
||||
position: relative;
|
||||
box-shadow: 0 1px 5px rgba(0, 0, 0, .3), inset 0 1px 0 rgba(255,255,255,.2), inset 0 -1px 0 rgba(0,0,0,.3);
|
||||
background: #7e6d42;
|
||||
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzdlNmQ0MiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM1YzRlMzUiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
|
||||
background: -moz-linear-gradient(top, #7e6d42 0%, #5c4e35 100%);
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#7e6d42), color-stop(100%,#5c4e35));
|
||||
background: -webkit-linear-gradient(top, #7e6d42 0%,#5c4e35 100%);
|
||||
background: -o-linear-gradient(top, #7e6d42 0%,#5c4e35 100%);
|
||||
background: -ms-linear-gradient(top, #7e6d42 0%,#5c4e35 100%);
|
||||
background: linear-gradient(to bottom, #7e6d42 0%,#5c4e35 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#7e6d42', endColorstr='#5c4e35',GradientType=0 );
|
||||
}
|
||||
|
||||
@media (max-width: 568px){
|
||||
.note {
|
||||
margin-right: -30px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px){
|
||||
.note {
|
||||
margin-left: -50px;
|
||||
}
|
||||
}
|
||||
|
||||
.note:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
left: 0px;
|
||||
border-color: transparent #222 #222 transparent;
|
||||
border-style: solid;
|
||||
border-width: 5px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.note h5, .note p {
|
||||
margin: 0;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.note h5 {
|
||||
line-height: 1.5em;
|
||||
font-weight: 800;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.note p {
|
||||
font-weight: 400;
|
||||
font-size: .75em;
|
||||
}
|
||||
|
||||
.info {
|
||||
background: #0389aa;
|
||||
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAzODlhYSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDYxN2YiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
|
||||
background: -moz-linear-gradient(top, #0389aa 0%, #00617f 100%);
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#0389aa), color-stop(100%,#00617f));
|
||||
background: -webkit-linear-gradient(top, #0389aa 0%,#00617f 100%);
|
||||
background: -o-linear-gradient(top, #0389aa 0%,#00617f 100%);
|
||||
background: -ms-linear-gradient(top, #0389aa 0%,#00617f 100%);
|
||||
background: linear-gradient(to bottom, #0389aa 0%,#00617f 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0389aa', endColorstr='#00617f',GradientType=0 );
|
||||
}
|
||||
|
||||
.warning {
|
||||
background: #9e2812;
|
||||
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzllMjgxMiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiM2ZjBkMGQiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
|
||||
background: -moz-linear-gradient(top, #9e2812 0%, #6f0d0d 100%);
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#9e2812), color-stop(100%,#6f0d0d));
|
||||
background: -webkit-linear-gradient(top, #9e2812 0%,#6f0d0d 100%);
|
||||
background: -o-linear-gradient(top, #9e2812 0%,#6f0d0d 100%);
|
||||
background: -ms-linear-gradient(top, #9e2812 0%,#6f0d0d 100%);
|
||||
background: linear-gradient(to bottom, #9e2812 0%,#6f0d0d 100%);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9e2812', endColorstr='#6f0d0d',GradientType=0 );
|
||||
}
|
||||
|
||||
.info:before {
|
||||
border-color: transparent #00617f #00617f transparent;
|
||||
}
|
||||
|
||||
.warning:before {
|
||||
border-color: transparent #6f0d0d #6f0d0d transparent;
|
||||
}
|
||||
|
||||
.note:after {
|
||||
content: "★";
|
||||
color: #fc0;
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
left: 14px;
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 -1px 0 rgba(0,0,0,.5);
|
||||
}
|
||||
|
||||
.info:after {
|
||||
content: "ⓘ";
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: 15px;
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 -1px 0 rgba(0,0,0,.5);
|
||||
}
|
||||
|
||||
.warning:after {
|
||||
content: "‼";
|
||||
color: #fc0;
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: 15px;
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 -1px 0 rgba(0,0,0,.5);
|
||||
}
|
||||
|
||||
/* Responsive tables */
|
||||
|
||||
@media (max-width: 768px){
|
||||
.mobile-side-scroller {
|
||||
overflow-x: scroll;
|
||||
margin: 0 -40px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
}
|
||||
@@ -1,307 +0,0 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Configuration
|
||||
prev_section: structure
|
||||
next_section: frontmatter
|
||||
permalink: /docs/configuration/
|
||||
---
|
||||
|
||||
Jekyll allows you to concoct your sites in any way you can dream up, and it’s
|
||||
thanks to the powerful and flexible configuration options that this is possible.
|
||||
These options can either be specified in a `_config.yml` file placed in your
|
||||
site’s root directory, or can be specified as flags for the `jekyll` executable
|
||||
in the terminal.
|
||||
|
||||
## Configuration Settings
|
||||
|
||||
### Global Configuration
|
||||
|
||||
The table below lists the available settings for Jekyll, and the various <code
|
||||
class="option">options</code> (specified in the configuration file) and <code
|
||||
class="flag">flags</code> (specified on the command-line) that control them.
|
||||
|
||||
<div class="mobile-side-scroller">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th>
|
||||
<span class="option">Options</span> and <span class="flag">Flags</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class='setting'>
|
||||
<td>
|
||||
<p class='name'><strong>Site Source</strong></p>
|
||||
<p class='description'>Change the directory where Jekyll will read files</p>
|
||||
</td>
|
||||
<td class="align-center">
|
||||
<p><code class="option">source: DIR</code></p>
|
||||
<p><code class="flag">-s, --source DIR</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='setting'>
|
||||
<td>
|
||||
<p class='name'><strong>Site Destination</strong></p>
|
||||
<p class='description'>Change the directory where Jekyll will write files</p>
|
||||
</td>
|
||||
<td class="align-center">
|
||||
<p><code class="option">destination: DIR</code></p>
|
||||
<p><code class="flag">-d, --destination DIR</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='setting'>
|
||||
<td>
|
||||
<p class='name'><strong>Safe</strong></p>
|
||||
<p class='description'>Disable <a href="../plugins">custom plugins</a>.</p>
|
||||
</td>
|
||||
<td class="align-center">
|
||||
<p><code class="option">safe: BOOL</code></p>
|
||||
<p><code class="flag">--safe</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='setting'>
|
||||
<td>
|
||||
<p class='name'><strong>Exclude</strong></p>
|
||||
<p class="description">Exclude directories and/or files from the conversion</p>
|
||||
</td>
|
||||
<td class='align-center'>
|
||||
<p><code class="option">exclude: [DIR, FILE, ...]</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='setting'>
|
||||
<td>
|
||||
<p class='name'><strong>Include</strong></p>
|
||||
<p class="description">
|
||||
Force inclusion of directories and/or files in the conversion.
|
||||
<code>.htaccess</code> is a good example since dotfiles are excluded
|
||||
by default.
|
||||
</p>
|
||||
</td>
|
||||
<td class='align-center'>
|
||||
<p><code class="option">include: [DIR, FILE, ...]</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='setting'>
|
||||
<td>
|
||||
<p class='name'><strong>Time Zone</strong></p>
|
||||
<p class="description">
|
||||
Set the time zone for site generation. This sets the <code>TZ</code>
|
||||
environment variable, which Ruby uses to handle time and date
|
||||
creation and manipulation. Any entry from the
|
||||
<a href="http://en.wikipedia.org/wiki/Tz_database">IANA Time Zone
|
||||
Database</a> is valid, e.g. <code>America/New_York</code>. The default
|
||||
is the local time zone, as set by your operating system.
|
||||
</p>
|
||||
</td>
|
||||
<td class='align-center'>
|
||||
<p><code class="option">timezone: TIMEZONE</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
### Build Command Options
|
||||
|
||||
<div class="mobile-side-scroller">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th><span class="option">Options</span> and <span class="flag">Flags</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class='setting'>
|
||||
<td>
|
||||
<p class='name'><strong>Regeneration</strong></p>
|
||||
<p class='description'>Enable auto-regeneration of the site when files are modified.</p>
|
||||
</td>
|
||||
<td class="align-center">
|
||||
<p><code class="flag">-w, --watch</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='setting'>
|
||||
<td>
|
||||
<p class='name'><strong>Configuration</strong></p>
|
||||
<p class="description">Specify a config file. Overrides settings in <code>_config.yml</code></p>
|
||||
</td>
|
||||
<td class='align-center'>
|
||||
<p><code class="flag">--config FILE</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='setting'>
|
||||
<td>
|
||||
<p class='name'><strong>Drafts</strong></p>
|
||||
<p class="description">Process and render draft posts.</p>
|
||||
</td>
|
||||
<td class='align-center'>
|
||||
<p><code class="flag">--drafts</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='setting'>
|
||||
<td>
|
||||
<p class='name'><strong>Future</strong></p>
|
||||
<p class="description">Publish posts with a future date.</p>
|
||||
</td>
|
||||
<td class='align-center'>
|
||||
<p><code class="option">future: BOOL</code></p>
|
||||
<p><code class="flag">--future</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='setting'>
|
||||
<td>
|
||||
<p class='name'><strong>LSI</strong></p>
|
||||
<p class="description">Produce an index for related posts.</p>
|
||||
</td>
|
||||
<td class='align-center'>
|
||||
<p><code class="option">lsi: BOOL</code></p>
|
||||
<p><code class="flag">--lsi</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='setting'>
|
||||
<td>
|
||||
<p class='name'><strong>Limit Posts</strong></p>
|
||||
<p class="description">Limit the number of posts to parse and publish.</p>
|
||||
</td>
|
||||
<td class='align-center'>
|
||||
<p><code class="option">limit_posts: NUM</code></p>
|
||||
<p><code class="flag">--limit_posts NUM</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
### Serve Command Options
|
||||
|
||||
In addition to the options below, the `serve` sub-command can accept any of the options
|
||||
for the `build` sub-command, which are then applied to the site build which occurs right
|
||||
before your site is served.
|
||||
|
||||
<div class="mobile-side-scroller">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Setting</th>
|
||||
<th><span class="option">Options</span> and <span class="flag">Flags</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class='setting'>
|
||||
<td>
|
||||
<p class='name'><strong>Local Server Port</strong></p>
|
||||
<p class='description'>Listen on the given port.</p>
|
||||
</td>
|
||||
<td class="align-center">
|
||||
<p><code class="option">port: PORT</code></p>
|
||||
<p><code class="flag">--port PORT</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='setting'>
|
||||
<td>
|
||||
<p class='name'><strong>Local Server Hostname</strong></p>
|
||||
<p class='description'>Listen at the given hostname.</p>
|
||||
</td>
|
||||
<td class="align-center">
|
||||
<p><code class="option">host: HOSTNAME</code></p>
|
||||
<p><code class="flag">--host HOSTNAME</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class='setting'>
|
||||
<td>
|
||||
<p class='name'><strong>Base URL</strong></p>
|
||||
<p class='description'>Serve the website from the given base URL</p>
|
||||
</td>
|
||||
<td class="align-center">
|
||||
<p><code class="option">baseurl: URL</code></p>
|
||||
<p><code class="flag">--baseurl URL</code></p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="note warning">
|
||||
<h5>Do not use tabs in configuration files</h5>
|
||||
<p>
|
||||
This will either lead to parsing errors, or Jekyll will revert to the
|
||||
default settings. Use spaces instead.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
## Default Configuration
|
||||
|
||||
Jekyll runs with the following configuration options by default. Unless
|
||||
alternative settings for these options are explicitly specified in the
|
||||
configuration file or on the command-line, Jekyll will run using these options.
|
||||
|
||||
{% highlight yaml %}
|
||||
source: .
|
||||
destination: ./_site
|
||||
plugins: ./_plugins
|
||||
layouts: ./_layouts
|
||||
include: ['.htaccess']
|
||||
exclude: []
|
||||
keep_files: ['.git','.svn']
|
||||
timezone: nil
|
||||
|
||||
future: true
|
||||
show_drafts: nil
|
||||
limit_posts: 0
|
||||
pygments: true
|
||||
|
||||
relative_permalinks: true
|
||||
|
||||
permalink: date
|
||||
paginate_path: 'page:num'
|
||||
|
||||
markdown: maruku
|
||||
markdown_ext: markdown,mkd,mkdn,md
|
||||
textile_ext: textile
|
||||
|
||||
excerpt_separator: "\n\n"
|
||||
|
||||
safe: false
|
||||
watch: false # deprecated
|
||||
server: false # deprecated
|
||||
host: 0.0.0.0
|
||||
port: 4000
|
||||
baseurl: /
|
||||
url: http://localhost:4000
|
||||
lsi: false
|
||||
|
||||
maruku:
|
||||
use_tex: false
|
||||
use_divs: false
|
||||
png_engine: blahtex
|
||||
png_dir: images/latex
|
||||
png_url: /images/latex
|
||||
|
||||
rdiscount:
|
||||
extensions: []
|
||||
|
||||
redcarpet:
|
||||
extensions: []
|
||||
|
||||
kramdown:
|
||||
auto_ids: true
|
||||
footnote_nr: 1
|
||||
entity_output: as_char
|
||||
toc_levels: 1..6
|
||||
smart_quotes: lsquo,rsquo,ldquo,rdquo
|
||||
use_coderay: false
|
||||
|
||||
coderay:
|
||||
coderay_wrap: div
|
||||
coderay_line_numbers: inline
|
||||
coderay_line_numbers_start: 1
|
||||
coderay_tab_width: 4
|
||||
coderay_bold_every: 10
|
||||
coderay_css: style
|
||||
|
||||
redcloth:
|
||||
hard_breaks: true
|
||||
{% endhighlight %}
|
||||
@@ -1,104 +0,0 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Contributing
|
||||
prev_section: deployment-methods
|
||||
next_section: troubleshooting
|
||||
permalink: /docs/contributing/
|
||||
---
|
||||
|
||||
So you've got an awesome idea to throw into Jekyll. Great! Please keep the
|
||||
following in mind:
|
||||
|
||||
* If you're creating a small fix or patch to an existing feature, just a simple
|
||||
test will do. Please stay in the confines of the current test suite and use
|
||||
[Shoulda](http://github.com/thoughtbot/shoulda/tree/master) and
|
||||
[RR](http://github.com/btakita/rr/tree/master).
|
||||
* If it's a brand new feature, make sure to create a new
|
||||
[Cucumber](https://github.com/cucumber/cucumber/) feature and reuse steps
|
||||
where appropriate. Also, whipping up some documentation in your fork's `site`
|
||||
directory would be appreciated, and once merged it will also appear in
|
||||
the next update of the main site.
|
||||
* If your contribution adds or changes any Jekyll behavior, make sure to update
|
||||
the documentation. It lives in `site/_posts`. If the docs are missing
|
||||
information, please feel free to add it in. Great docs make a great project!
|
||||
* Please follow the [GitHub Ruby Styleguide](https://github.com/styleguide/ruby)
|
||||
when modifying Ruby code.
|
||||
|
||||
<div class="note warning">
|
||||
<h5>Contributions will not be accepted without tests</h5>
|
||||
<p>
|
||||
If you’re creating a small fix or patch to an existing feature, just
|
||||
a simple test will do.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
Test Dependencies
|
||||
-----------------
|
||||
|
||||
To run the test suite and build the gem you'll need to install Jekyll's
|
||||
dependencies. Jekyll uses Bundler, so a quick run of the `bundle` command and
|
||||
you're all set!
|
||||
|
||||
{% highlight bash %}
|
||||
$ bundle
|
||||
{% endhighlight %}
|
||||
|
||||
Before you start, run the tests and make sure that they pass (to confirm your
|
||||
environment is configured properly):
|
||||
|
||||
{% highlight bash %}
|
||||
$ rake test
|
||||
$ rake features
|
||||
{% endhighlight %}
|
||||
|
||||
Workflow
|
||||
--------
|
||||
|
||||
Here's the most direct way to get your work merged into the project:
|
||||
|
||||
* Fork the project.
|
||||
* Clone down your fork:
|
||||
|
||||
{% highlight bash %}
|
||||
git clone git://github.com/<username>/jekyll.git
|
||||
{% endhighlight %}
|
||||
|
||||
* Create a topic branch to contain your change:
|
||||
|
||||
{% highlight bash %}
|
||||
git checkout -b my_awesome_feature
|
||||
{% endhighlight %}
|
||||
|
||||
|
||||
* Hack away, add tests. Not necessarily in that order.
|
||||
* Make sure everything still passes by running `rake`.
|
||||
* If necessary, rebase your commits into logical chunks, without errors.
|
||||
* Push the branch up:
|
||||
|
||||
{% highlight bash %}
|
||||
git push origin my_awesome_feature
|
||||
{% endhighlight %}
|
||||
|
||||
* Create a pull request against mojombo/jekyll and describe what your change
|
||||
does and the why you think it should be merged.
|
||||
|
||||
Gotchas
|
||||
-------
|
||||
|
||||
* If you want to bump the gem version, please put that in a separate commit.
|
||||
This way, the maintainers can control when the gem gets released.
|
||||
* Try to keep your patch(es) based from the latest commit on mojombo/jekyll.
|
||||
The easier it is to apply your work, the less work the maintainers have to do,
|
||||
which is always a good thing.
|
||||
* Please don't tag your GitHub issue with \[fix\], \[feature\], etc. The maintainers
|
||||
actively read the issues and will label it once they come across it.
|
||||
|
||||
<div class="note">
|
||||
<h5>Let us know what could be better!</h5>
|
||||
<p>
|
||||
Both using and hacking on Jekyll should be fun, simple, and easy, so if for
|
||||
some reason you find it’s a pain, please <a
|
||||
href="https://github.com/mojombo/jekyll/issues/new">create an issue</a> on
|
||||
GitHub describing your experience so we can make it better.
|
||||
</p>
|
||||
</div>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user