mirror of
https://github.com/jekyll/jekyll.git
synced 2026-04-28 03:01:03 -04:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2db51e6464 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -13,4 +13,3 @@ site/_site/
|
||||
coverage
|
||||
.ruby-version
|
||||
.sass-cache
|
||||
tmp/stackprof-*
|
||||
|
||||
28
.travis.yml
28
.travis.yml
@@ -1,23 +1,15 @@
|
||||
language: ruby
|
||||
|
||||
cache: bundler
|
||||
|
||||
sudo: false
|
||||
|
||||
install:
|
||||
- script/rebund download
|
||||
- travis_retry bundle install --path vendor/bundle
|
||||
rvm:
|
||||
- 2.1
|
||||
- 2.0
|
||||
- 1.9.3
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- TEST_SUITE=test
|
||||
- TEST_SUITE=cucumber
|
||||
|
||||
before_script: bundle update
|
||||
|
||||
- 2.1
|
||||
- 2.0
|
||||
- 1.9.3
|
||||
script: script/cibuild
|
||||
|
||||
after_script:
|
||||
- script/rebund upload
|
||||
notifications:
|
||||
irc:
|
||||
on_success: change
|
||||
@@ -29,3 +21,7 @@ notifications:
|
||||
email:
|
||||
on_success: never
|
||||
on_failure: never
|
||||
env:
|
||||
global:
|
||||
- secure: bt5nglPTdsc0N5fB1dOJz2WbM81dGpDuVD8PnhEsxgUfoo6xavhU4+pNrUADlSUqQ1aJrdU+MKW4x+JZ2ZnJS8vOpNzRymuMZSbFaljK4pgFGiKFgBdMKxVikvoYcxKCjLAl7NJZ11W6hUw+JtJScClDZwrJJAQB6I7Isp/LsdM=
|
||||
- secure: Ym8nx7nbfGYGo47my92M+deJykaiMkdZdb615EO51liv/xy/0aQ919Jpfieugc9d3zVnm+zFGPbpv4YzRpsik6OlVBNa4lP+BnQ27ptf5YcLWD8Hksi7845WFLecXMoaTCoYer/TvYZsIWJb2nSDMH9qbfZhnd1YZKuvUpK0rEU=
|
||||
|
||||
5
Gemfile
5
Gemfile
@@ -1,7 +1,2 @@
|
||||
source 'https://rubygems.org'
|
||||
gemspec
|
||||
|
||||
if ENV['BENCHMARK']
|
||||
gem 'rbtrace'
|
||||
gem 'stackprof'
|
||||
end
|
||||
|
||||
280
History.markdown
280
History.markdown
@@ -2,247 +2,6 @@
|
||||
|
||||
### Major Enhancements
|
||||
|
||||
### Minor Enhancements
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
### Development Fixes
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
## 2.5.1 / 2014-11-08
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fix path sanitation bug related to Windows drive names (#3077)
|
||||
|
||||
### Development Fixes
|
||||
|
||||
* Add development time dependencies on minitest and test-unit to gemspec for cygwin (#3064)
|
||||
* Use Travis's built-in caching. (#3075)
|
||||
|
||||
## 2.5.0 / 2014-11-06
|
||||
|
||||
### Minor Enhancements
|
||||
|
||||
* Require gems in `:jekyll_plugins` Gemfile group unless `JEKYLL_NO_BUNDLER_REQUIRE` is specified in the environment. (#2865)
|
||||
* Centralize path sanitation in the `Site` object (#2882)
|
||||
* Allow placeholders in permalinks (#3031)
|
||||
* Allow users to specify the log level via `JEKYLL_LOG_LEVEL`. (#3067)
|
||||
* Fancy Indexing with WEBrick (#3018)
|
||||
* Allow Enumerables to be used with `where` filter. (#2986)
|
||||
* Meta descriptions in the site template now use `page.excerpt` if it's available (#2964)
|
||||
* Change indentation in `head.html` of site template to 2 spaces from 4 (#2973)
|
||||
* Use a `$content-width` variable instead of a fixed value in the site template CSS (#2972)
|
||||
* Strip newlines in site template `<meta>` description. (#2982)
|
||||
* Add link to atom feed in `head` of site template files (#2996)
|
||||
* Performance optimizations (#2994)
|
||||
* Use `Hash#each_key` instead of `Hash#keys.each` to speed up iteration
|
||||
over hash keys. (#3017)
|
||||
* Further minor performance enhancements. (#3022)
|
||||
* Add 'b' and 's' aliases for build and serve, respectively (#3065)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fix Rouge's RedCarpet plugin interface integration (#2951)
|
||||
* Remove `--watch` from the site template blog post since it defaults
|
||||
to watching in in 2.4.0 (#2922)
|
||||
* Fix code for media query mixin in site template (#2946)
|
||||
* Allow post URL's to have `.htm` extensions (#2925)
|
||||
* `Utils.slugify`: Don't create new objects when gsubbing (#2997)
|
||||
* The jsonify filter should deep-convert to Liquid when given an Array. (#3032)
|
||||
* Apply `jsonify` filter to Hashes deeply and effectively (#3063)
|
||||
* Use `127.0.0.1` as default host instead of `0.0.0.0` (#3053)
|
||||
* In the case that a Gemfile does not exist, ensure Jekyll doesn't fail on requiring the Gemfile group (#3066)
|
||||
|
||||
### Development Fixes
|
||||
|
||||
* Fix a typo in the doc block for `Jekyll::URL.escape_path` (#3052)
|
||||
* Add integration test for `jekyll new --blank` in TestUnit (#2913)
|
||||
* Add unit test for `jekyll new --force` logic (#2929)
|
||||
* Update outdated comment for `Convertible#transform` (#2957)
|
||||
* Add Hakiri badge to README. (#2953)
|
||||
* Add some simple benchmarking tools. (#2993)
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
* `NOKOGIRI_USE_SYSTEM_LIBRARIES=true` **decreases** installation time. (#3040)
|
||||
* Add FormKeep to resources as Jekyll form backend (#3010)
|
||||
* Fixing a mistake in the name of the new Liquid tag (#2969)
|
||||
* Update Font Awesome to v4.2.0. (#2898)
|
||||
* Fix link to #2895 in 2.4.0 release post. (#2899)
|
||||
* Add Big Footnotes for Kramdown plugin to list of third-party plugins (#2916)
|
||||
* Remove warning regarding GHP use of singular types for front matter defaults (#2919)
|
||||
* Fix quote character typo in site documentation for templates (#2917)
|
||||
* Point Liquid links to Liquid’s Github wiki (#2887)
|
||||
* Add HTTP Basic Auth (.htaccess) plugin to list of third-party plugins (#2931)
|
||||
* (Minor) Grammar & `_config.yml` filename fixes (#2911)
|
||||
* Added `mathml.rb` to the list of third-party plugins. (#2937)
|
||||
* Add `--force_polling` to the list of configuration options (#2943)
|
||||
* Escape unicode characters in site CSS (#2906)
|
||||
* Add note about using the github-pages gem via pages.github.com/versions.json (#2939)
|
||||
* Update usage documentation to reflect 2.4 auto-enabling of `--watch`. (#2954)
|
||||
* Add `--skip-initial-build` to configuration docs (#2949)
|
||||
* Fix a minor typo in Templates docs page (#2959)
|
||||
* Add a ditaa-ditaa plugin under Other section on the Plugins page (#2967)
|
||||
* Add `build/serve -V` option to configuration documentation (#2948)
|
||||
* Add 'Jekyll Twitter Plugin' to list of third-party plugins (#2979)
|
||||
* Docs: Update normalize.css to v3.0.2. (#2981)
|
||||
* Fix typo in Continuous Integration documentation (#2984)
|
||||
* Clarify behavior of `:categories` in permalinks (#3011)
|
||||
|
||||
## 2.4.0 / 2014-09-09
|
||||
|
||||
### Minor Enhancements
|
||||
|
||||
* Support a new `relative_include` tag (#2870)
|
||||
* Auto-enable watch on 'serve' (#2858)
|
||||
* Render Liquid in CoffeeScript files (#2830)
|
||||
* Array Liquid filters: `push`, `pop`, `unshift`, `shift` (#2895)
|
||||
* Add `:title` to collection URL template fillers (#2864)
|
||||
* Add support for CSV files in the `_data` directory (#2761)
|
||||
* Add the `name` variable to collection permalinks (#2799)
|
||||
* Add `inspect` liquid filter. (#2867)
|
||||
* Add a `slugify` Liquid filter (#2880)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use `Jekyll.sanitized_path` when adding static files to Collections (#2849)
|
||||
* Fix encoding of `main.scss` in site template (#2771)
|
||||
* Fix orientation bugs in default site template (#2862)
|
||||
|
||||
### Development Fixes
|
||||
|
||||
* Update simplecov gem to 0.9 (#2748)
|
||||
* Remove `docs/` dir (#2768)
|
||||
* add class `<< self` idiom to `New` command (#2817)
|
||||
* Allow Travis to 'parallelize' our tests (#2859)
|
||||
* Fix test for Liquid rendering in Sass (#2856)
|
||||
* Fixing "vertycal" typo in site template's `_base.scss` (#2889)
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
* Document the `name` variable for collection permalinks (#2829)
|
||||
* Adds info about installing jekyll in current dir (#2839)
|
||||
* Remove deprecated `jekyll-projectlist` plugin from list of third-party
|
||||
plugins (#2742)
|
||||
* Remove tag plugins that are built in to Jekyll (#2751)
|
||||
* Add `markdown-writer` package for Atom Editor to list of third-party
|
||||
plugins (#2763)
|
||||
* Fix typo in site documentation for collections (#2764)
|
||||
* Fix minor typo on plugins docs page (#2765)
|
||||
* Replace markdown with HTML in `sass_dir` note on assets page (#2791)
|
||||
* Fixed "bellow" typo in datafiles docs (#2879)
|
||||
* Fix code/markdown issue in documentation for variables (#2877)
|
||||
* Remove Good Include third-party plugin from plugins page (#2881)
|
||||
* Add some more docs on `include_relative` (#2884)
|
||||
|
||||
## 2.3.0 / 2014-08-10
|
||||
|
||||
### Minor Enhancements
|
||||
|
||||
* Allow Convertibles to be converted by >= 1 converters (#2704)
|
||||
* Allow Sass files to be rendered in Liquid, but never place them in layouts. (#2733)
|
||||
* Add `jekyll help` command (#2707)
|
||||
* Use `.scss` for `site_template` styles. (#2667)
|
||||
* Don't require the `scope` key in front matter defaults (#2659)
|
||||
* No longer set `permalink: pretty` in the `_config.yml` for the site template (#2680)
|
||||
* Rework site template to utilize Sass (#2687)
|
||||
* Notify the user when auto-regeneration is disabled. (#2696)
|
||||
* Allow partial variables in include tag filename argument (#2693)
|
||||
* Move instances of `Time.parse` into a Utils method (#2682)
|
||||
* Ignore subfolders in the `_posts` folder (#2705) REVERTS (#2633)
|
||||
* Front Matter default types should always be pluralized (#2732)
|
||||
* Read in static files into `collection.files` as `StaticFile`s (#2737)
|
||||
* Add `sassify` and `scssify` Liquid filters (#2739)
|
||||
* Replace `classifier` gem with `classifier-reborn` (#2721)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Use only the last extname when multiple converters exist (#2722)
|
||||
* Call `#to_liquid` before calling `#to_json` in jsonify filter (#2729)
|
||||
* Use non padded config in `strftime` to avoid parse string twice (#2673)
|
||||
* Replace deprecated Ruby methods with undeprecated ones (#2664)
|
||||
* Catch errors when parsing Post `date` front matter value & produce nice error message (#2649)
|
||||
* Allow static files in Collections (#2615)
|
||||
* Fixed typo in `Deprecator#gracefully_require` error message (#2694)
|
||||
* Remove preemptive loading of the 'classifier' gem. (#2697)
|
||||
* Use case-insensitive checking for the file extensions when loading config files (#2718)
|
||||
* When Reading Documents, Respect `encoding` Option (#2720)
|
||||
* Refactor based on jekyll-watch clean-up. (#2716)
|
||||
* `Document#to_s` should produce just the content of the document (#2731)
|
||||
|
||||
### Development Fixes
|
||||
|
||||
* Only include lib files in the gem (#2671)
|
||||
* Fix `git diff` command in `proof` script (#2672)
|
||||
* Make default rake task a multitask so tests run in parallel (#2735)
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
* Use Sass and a Docs Collection (#2651)
|
||||
* Add `latest_version.txt` file to the site (#2740)
|
||||
* Be more ambiguous about `page.content`. But more transparent. (#2522)
|
||||
* Streamlining front matter wording (instead of front-matter/frontmatter) (#2674)
|
||||
* Add note that source directory cannot be modified in GitHub Pages (#2669)
|
||||
* Fix links from #2669 to be actual HTML. Whoops. (#2679)
|
||||
* Add link to `jekyll-slim` in list of third-party plugins (#2689)
|
||||
* Add Barry Clark's Smashing Magazine tutorial to resources page (#2688)
|
||||
* Reorganize and update default configuration settings (#2456)
|
||||
* Fixing indentation in the configuration docs about Redcarpet exts (#2717)
|
||||
* Use `null` in YAML instead of `nil` in default config list (#2719)
|
||||
* Fix typo in Continuous Integration docs (#2708)
|
||||
|
||||
## 2.2.0 / 2014-07-29
|
||||
|
||||
### Minor Enhancements
|
||||
|
||||
* Throw a warning if the specified layout does not exist (#2620)
|
||||
* Whitelist Pygments options in safe mode (#2642)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Remove unnecessary `Jekyll::Tags::IncludeTag#blank?` method (#2625)
|
||||
* Categories in the path are ignored (#2633)
|
||||
|
||||
### Development Fixes
|
||||
|
||||
* Refactoring Errors & Requires of Third-Party stuff (#2591)
|
||||
* Add further tests for categories (#2584)
|
||||
* Proof site with html-proofer on change (#2605)
|
||||
* Fix up bug in #2605 which caused proofing the site not to function (#2608)
|
||||
* Use `bundle exec` in `script/proof` (#2610)
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
* Update Kramdown urls (#2588)
|
||||
* Add `Jekyll::AutolinkEmail` and `Jekyll::GitMetadata` to the list of
|
||||
third-party plugins (#2596)
|
||||
* Fix a bunch of broken links in the site (#2601)
|
||||
* Replace dead links with working links (#2611)
|
||||
* Add jekyll-hook to deployment methods (#2617)
|
||||
* Added kramdown-with-pygments plugin to the list of third-party plugins (#2623)
|
||||
* Update outdated "Extras" page and remove duplicate documentation (#2622)
|
||||
* Add co2 plugin to list of third-party plugins (#2639)
|
||||
* Attempt to clarify the way Sass imports happen (#2642)
|
||||
|
||||
## 2.1.1 / 2014-07-01
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Patch read vulnerabilities for data & confirm none for layouts (#2563)
|
||||
* Update Maruku dependency to allow use of the latest version (#2576)
|
||||
* Remove conditional assignment from document URL to prevent stale urls (#2575)
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
* Add vertical margin to `highlight` to separate code blocks (#2558)
|
||||
* Add `html_pages` to Variables docs (#2567)
|
||||
* Fixed broken link to Permalinks page (#2572)
|
||||
* Update link to Windows installation guide (#2578)
|
||||
|
||||
## 2.1.0 / 2014-06-28
|
||||
|
||||
### Minor Enhancements
|
||||
|
||||
* Bump to the latest Liquid version, 2.6.1 (#2495)
|
||||
@@ -263,13 +22,11 @@
|
||||
* Upgrade listen to `2.7.6 <= x < 3.0.0` (#2492)
|
||||
* Allow configuration of different Twitter and GitHub usernames in site template (#2485)
|
||||
* Bump Pygments to v0.6.0 (#2504)
|
||||
* Front matter defaults for documents in collections (#2419)
|
||||
* Front-matter defaults for documents in collections (#2419)
|
||||
* Include files with a url which ends in `/` in the `site.html_pages` list (#2524)
|
||||
* Make `highlight` tag use `language-` prefix in CSS class (#2511)
|
||||
* Lookup item property via `item#to_liquid` before `#data` or `#[]` in filters (#2493)
|
||||
* Skip initial build of site on serve with flag (#2477)
|
||||
* Add support for `hl_lines` in `highlight` tag (#2532)
|
||||
* Spike out `--watch` flag into a separate gem (#2550)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -281,7 +38,7 @@
|
||||
* Prevent code from overflowing container in site template (#2429)
|
||||
* Encode URLs in UTF-8 when escaping and unescaping (#2420)
|
||||
* No Layouts or Liquid for Asset Files (#2431)
|
||||
* Allow front matter defaults to set post categories (#2373)
|
||||
* Allow front-matter defaults to set post categories (#2373)
|
||||
* Fix command in subcommand deprecation warning (#2457)
|
||||
* Keep all parent directories of files/dirs in `keep_files` (#2458)
|
||||
* When using RedCarpet and Rouge without Rouge installed, fixed erroneous
|
||||
@@ -289,11 +46,6 @@
|
||||
* Ignore *all* directories and files that merit it on auto-generation (#2459)
|
||||
* Before copying file, explicitly remove the old one (#2535)
|
||||
* Merge file system categories with categories from YAML. (#2531)
|
||||
* Deep merge front matter defaults (#2490)
|
||||
* Ensure exclude and include arrays are arrays of strings (#2542)
|
||||
* Allow collections to have dots in their filenames (#2552)
|
||||
* Collections shouldn't try to read in directories as files (#2552)
|
||||
* Be quiet very quickly. (#2520)
|
||||
|
||||
### Development Fixes
|
||||
|
||||
@@ -301,7 +53,6 @@
|
||||
* Add test for sorting UTF-8 characters (#2384)
|
||||
* Use `https` for GitHub links in documentation (#2470)
|
||||
* Remove coverage reporting with Coveralls (#2494)
|
||||
* Fix a bit of missing TomDoc to `Jekyll::Commands::Build#build` (#2554)
|
||||
|
||||
### Site Enhancements
|
||||
|
||||
@@ -314,7 +65,7 @@
|
||||
* Prevent table from extending parent width in permalink style table (#2424)
|
||||
* Add collections to info about pagination support (#2389)
|
||||
* Add `jekyll_github_sample` plugin to list of third-party plugins (#2463)
|
||||
* Clarify documentation around front matter defaults and add details
|
||||
* Clarify documentation around front-matter defaults and add details
|
||||
about defaults for collections. (#2439)
|
||||
* Add Jekyll Project Version Tag to list of third-party plugins (#2468)
|
||||
* Use `https` for GitHub links across whole site (#2470)
|
||||
@@ -323,9 +74,6 @@
|
||||
* Add link to jekyll-compress-html to list of third-party plugins (#2514)
|
||||
* Add Piwigo Gallery to list of third-party plugins (#2526)
|
||||
* Set `show_drafts` to `false` in default configuration listing (#2536)
|
||||
* Provide an updated link for Windows installation instructions (#2544)
|
||||
* Remove `url` from configuration docs (#2547)
|
||||
* Documentation for Continuous Integration for your Jekyll Site (#2432)
|
||||
|
||||
## 2.0.3 / 2014-05-08
|
||||
|
||||
@@ -349,7 +97,7 @@
|
||||
* Update docs to reflect new `baseurl` default (#2341)
|
||||
* Add links to headers who have an ID. (#2342)
|
||||
* Use symbol instead of HTML number in `upgrading.md` (#2351)
|
||||
* Fix link to front matter defaults docs (#2353)
|
||||
* Fix link to frontmatter defaults docs (#2353)
|
||||
* Fix for `History.markdown` in order to fix history page in docs (#2363)
|
||||
|
||||
## 2.0.2 / 2014-05-07
|
||||
@@ -389,7 +137,7 @@
|
||||
* Expose `site.static_files` to Liquid (#2075)
|
||||
* Complete redesign of the template site generated by `jekyll new` (#2050)
|
||||
* Update Listen from 1.x to 2.x (#2097)
|
||||
* Front matter defaults (#2205)
|
||||
* Front-matter defaults (#2205)
|
||||
* Deprecate `relative_permalinks` configuration option (default to `false`) (#2307)
|
||||
* Exclude files based on prefix as well as `fnmatch?` (#2303)
|
||||
|
||||
@@ -434,7 +182,7 @@
|
||||
* Permit YAML blocks to end with three dots to better conform with the
|
||||
YAML spec (#2110)
|
||||
* Use `File.exist?` instead of deprecated `File.exists?` (#2214)
|
||||
* Require newline after start of YAML Front Matter header (#2211)
|
||||
* Require newline after start of YAML front-matter header (#2211)
|
||||
* Add the ability for pages to be marked as `published: false` (#1492)
|
||||
* Add `Jekyll::LiquidExtensions` with `.lookup_variable` method for easy
|
||||
looking up of variable values in a Liquid context. (#2253)
|
||||
@@ -1107,7 +855,7 @@
|
||||
* 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)
|
||||
* 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)
|
||||
@@ -1119,7 +867,7 @@
|
||||
* 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)
|
||||
* 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)
|
||||
@@ -1178,7 +926,7 @@
|
||||
* 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)
|
||||
* Ensure front-matter is at start of file (#562)
|
||||
|
||||
## 0.11.2 / 2011-12-27
|
||||
* Bug Fixes
|
||||
@@ -1299,7 +1047,7 @@
|
||||
## 0.5.6 / 2010-01-08
|
||||
* Bug Fixes
|
||||
* Require redcloth >= 4.2.1 in tests (#92)
|
||||
* Don't break on triple dashes in yaml front matter (#93)
|
||||
* Don't break on triple dashes in yaml frontmatter (#93)
|
||||
|
||||
### Minor Enhancements
|
||||
* Allow .mkd as markdown extension
|
||||
@@ -1334,9 +1082,9 @@
|
||||
* Configuration options set in config.yml are now available through the
|
||||
site payload (@vilcans)
|
||||
* Posts can now have an empty YAML front matter or none at all
|
||||
(@ bahuvrihi)
|
||||
(@bahuvrihi)
|
||||
* Bug Fixes
|
||||
* Fixing Ruby 1.9 issue that requires `#to_s` on the err object
|
||||
* Fixing Ruby 1.9 issue that requires to_s on the err object
|
||||
(@Chrononaut)
|
||||
* Fixes for pagination and ordering posts on the same day (@ujh)
|
||||
* Made pages respect permalinks style and permalinks in yml front matter
|
||||
@@ -1346,8 +1094,8 @@
|
||||
* Added trailing slash to pretty permalink style so Apache is happy
|
||||
(@eugenebolshakov)
|
||||
* Bad markdown processor in config fails sooner and with better message
|
||||
(@ gcnovus)
|
||||
* Allow CRLFs in yaml front matter (@juretta)
|
||||
(@gcnovus)
|
||||
* Allow CRLFs in yaml frontmatter (@juretta)
|
||||
* Added Date#xmlschema for Ruby versions < 1.9
|
||||
|
||||
## 0.5.1 / 2009-05-06
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
[](https://travis-ci.org/jekyll/jekyll)
|
||||
[](https://codeclimate.com/github/jekyll/jekyll)
|
||||
[](https://gemnasium.com/jekyll/jekyll)
|
||||
[](https://hakiri.io/github/jekyll/jekyll/master)
|
||||
|
||||
By Tom Preston-Werner, Nick Quaranto, Parker Moore, and many [awesome contributors](https://github.com/jekyll/jekyll/graphs/contributors)!
|
||||
By Tom Preston-Werner, Nick Quaranto, and many [awesome contributors](https://github.com/jekyll/jekyll/graphs/contributors)!
|
||||
|
||||
Jekyll is a simple, blog-aware, static site generator perfect for personal, project, or organization sites. Think of it like a file-based CMS, without all the complexity. Jekyll takes your content, renders Markdown and Liquid templates, and spits out a complete, static website ready to be served by Apache, Nginx or another web server. Jekyll is the engine behind [GitHub Pages](http://pages.github.com), which you can use to host sites right from your GitHub repositories.
|
||||
|
||||
|
||||
65
Rakefile
65
Rakefile
@@ -14,7 +14,7 @@ require 'jekyll/version'
|
||||
#############################################################################
|
||||
|
||||
def name
|
||||
@name ||= File.basename(Dir['*.gemspec'].first, ".*")
|
||||
@name ||= Dir['*.gemspec'].first.split('.').first
|
||||
end
|
||||
|
||||
def version
|
||||
@@ -53,32 +53,13 @@ def liquid_escape(markdown)
|
||||
markdown.gsub(/(`{[{%].+[}%]}`)/, "{% raw %}\\1{% endraw %}")
|
||||
end
|
||||
|
||||
def custom_release_header_anchors(markdown)
|
||||
header_regexp = /^(\d{1,2})\.(\d{1,2})\.(\d{1,2}) \/ \d{4}-\d{2}-\d{2}/
|
||||
section_regexp = /^### \w+ \w+$/
|
||||
markdown.split(/^##\s/).map do |release_notes|
|
||||
_, major, minor, patch = *release_notes.match(header_regexp)
|
||||
release_notes
|
||||
.gsub(header_regexp, "\\0\n{: #v\\1-\\2-\\3}")
|
||||
.gsub(section_regexp) { |section| "#{section}\n{: ##{sluffigy(section)}-v#{major}-#{minor}-#{patch}}" }
|
||||
end.join("\n## ")
|
||||
end
|
||||
|
||||
def sluffigy(header)
|
||||
header.gsub(/#/, '').strip.downcase.gsub(/\s+/, '-')
|
||||
end
|
||||
|
||||
def remove_head_from_history(markdown)
|
||||
index = markdown =~ /^##\s+\d+\.\d+\.\d+/
|
||||
markdown[index..-1]
|
||||
end
|
||||
|
||||
def converted_history(markdown)
|
||||
remove_head_from_history(
|
||||
custom_release_header_anchors(
|
||||
liquid_escape(
|
||||
linkify(
|
||||
normalize_bullets(markdown)))))
|
||||
remove_head_from_history(liquid_escape(linkify(normalize_bullets(markdown))))
|
||||
end
|
||||
|
||||
#############################################################################
|
||||
@@ -87,7 +68,7 @@ end
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
multitask :default => [:test, :features]
|
||||
task :default => [:test, :features]
|
||||
|
||||
require 'rake/testtask'
|
||||
Rake::TestTask.new(:test) do |test|
|
||||
@@ -134,7 +115,6 @@ namespace :site do
|
||||
desc "Generate and view the site locally"
|
||||
task :preview do
|
||||
require "launchy"
|
||||
require "jekyll"
|
||||
|
||||
# Yep, it's a hack! Wait a few seconds for the Jekyll site to generate and
|
||||
# then open it in a browser. Someday we can do better than this, I hope.
|
||||
@@ -146,36 +126,22 @@ namespace :site do
|
||||
|
||||
# Generate the site in server mode.
|
||||
puts "Running Jekyll..."
|
||||
options = {
|
||||
"source" => File.expand_path("site"),
|
||||
"destination" => File.expand_path("site/_site"),
|
||||
"watch" => true,
|
||||
"serving" => true
|
||||
}
|
||||
Jekyll::Commands::Build.process(options)
|
||||
Jekyll::Commands::Serve.process(options)
|
||||
end
|
||||
|
||||
desc "Generate the site"
|
||||
task :generate => [:history, :version_file] do
|
||||
require "jekyll"
|
||||
Jekyll::Commands::Build.process({
|
||||
"source" => File.expand_path("site"),
|
||||
"destination" => File.expand_path("site/_site")
|
||||
})
|
||||
Dir.chdir("site") do
|
||||
sh "#{File.expand_path('bin/jekyll', File.dirname(__FILE__))} serve --watch"
|
||||
end
|
||||
end
|
||||
|
||||
desc "Update normalize.css library to the latest version and minify"
|
||||
task :update_normalize_css do
|
||||
Dir.chdir("site/_sass") do
|
||||
Dir.chdir("site/_includes/css") do
|
||||
sh 'curl "http://necolas.github.io/normalize.css/latest/normalize.css" -o "normalize.scss"'
|
||||
sh 'sass "normalize.scss":"_normalize.scss" --style compressed'
|
||||
rm ['normalize.scss', Dir.glob('*.map')].flatten
|
||||
sh 'sass "normalize.scss":"normalize.css" --style compressed'
|
||||
sh 'rm "normalize.scss"'
|
||||
end
|
||||
end
|
||||
|
||||
desc "Commit the local site to the gh-pages branch and publish to GitHub Pages"
|
||||
task :publish => [:history, :version_file] do
|
||||
task :publish => [:history] do
|
||||
# Ensure the gh-pages dir exists so we can generate into it.
|
||||
puts "Checking for gh-pages dir..."
|
||||
unless File.exist?("./gh-pages")
|
||||
@@ -219,7 +185,7 @@ namespace :site do
|
||||
"permalink" => "/docs/history/",
|
||||
"prev_section" => "contributing"
|
||||
}
|
||||
Dir.chdir('site/_docs/') do
|
||||
Dir.chdir('site/docs/') do
|
||||
File.open("history.md", "w") do |file|
|
||||
file.write("#{front_matter.to_yaml}---\n\n")
|
||||
file.write(converted_history(history_file))
|
||||
@@ -230,11 +196,6 @@ namespace :site do
|
||||
end
|
||||
end
|
||||
|
||||
desc "Write the site latest_version.txt file"
|
||||
task :version_file do
|
||||
File.open('site/latest_version.txt', 'wb') { |f| f.write(version) }
|
||||
end
|
||||
|
||||
namespace :releases do
|
||||
desc "Create new release post"
|
||||
task :new, :version do |t, args|
|
||||
@@ -267,20 +228,18 @@ end
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
desc "Release #{name} v#{version}"
|
||||
task :release => :build do
|
||||
unless `git branch` =~ /^\* master$/
|
||||
puts "You must be on the master branch to release!"
|
||||
exit!
|
||||
end
|
||||
sh "git commit --allow-empty -m 'Release :gem: #{version}'"
|
||||
sh "git commit --allow-empty -m 'Release #{version}'"
|
||||
sh "git tag v#{version}"
|
||||
sh "git push origin master"
|
||||
sh "git push origin v#{version}"
|
||||
sh "gem push pkg/#{name}-#{version}.gem"
|
||||
end
|
||||
|
||||
desc "Build #{name} v#{version} into pkg/"
|
||||
task :build do
|
||||
mkdir_p "pkg"
|
||||
sh "gem build #{gemspec_file}"
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
require 'benchmark/ips'
|
||||
|
||||
enum = (0..50).to_a
|
||||
nested = enum.map { |i| [i] }
|
||||
|
||||
def do_thing(blah)
|
||||
blah * 1
|
||||
end
|
||||
|
||||
Benchmark.ips do |x|
|
||||
x.report('.map.flatten with nested arrays') { nested.map { |i| do_thing(i) }.flatten(1) }
|
||||
x.report('.flat_map with nested arrays') { nested.flat_map { |i| do_thing(i) } }
|
||||
|
||||
x.report('.map.flatten with no nested arrays') { enum.map { |i| do_thing(i) }.flatten(1) }
|
||||
x.report('.flat_map with no nested arrays') { enum.flat_map { |i| do_thing(i) } }
|
||||
end
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
require 'benchmark/ips'
|
||||
|
||||
h = {:bar => 'uco'}
|
||||
|
||||
Benchmark.ips do |x|
|
||||
x.report('fetch with no block') { h.fetch(:bar, (0..9).to_a) }
|
||||
x.report('fetch with a block') { h.fetch(:bar) { (0..9).to_a } }
|
||||
x.report('brackets with an ||') { h[:bar] || (0..9).to_a }
|
||||
end
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require_relative '../lib/jekyll'
|
||||
require 'benchmark/ips'
|
||||
|
||||
base_directory = Dir.pwd
|
||||
|
||||
Benchmark.ips do |x|
|
||||
#
|
||||
# Does not include the base_directory
|
||||
#
|
||||
x.report('with no questionable path') do
|
||||
Jekyll.sanitized_path(base_directory, '')
|
||||
end
|
||||
x.report('with a single-part questionable path') do
|
||||
Jekyll.sanitized_path(base_directory, 'thingy')
|
||||
end
|
||||
x.report('with a multi-part questionable path') do
|
||||
Jekyll.sanitized_path(base_directory, 'thingy/in/my/soup')
|
||||
end
|
||||
x.report('with a single-part traversal path') do
|
||||
Jekyll.sanitized_path(base_directory, '../thingy')
|
||||
end
|
||||
x.report('with a multi-part traversal path') do
|
||||
Jekyll.sanitized_path(base_directory, '../thingy/in/my/../../soup')
|
||||
end
|
||||
|
||||
#
|
||||
# Including the base_directory
|
||||
#
|
||||
x.report('with the exact same paths') do
|
||||
Jekyll.sanitized_path(base_directory, base_directory)
|
||||
end
|
||||
x.report('with a single-part absolute path including the base_directory') do
|
||||
Jekyll.sanitized_path(base_directory, File.join(base_directory, 'thingy'))
|
||||
end
|
||||
x.report('with a multi-part absolute path including the base_directory') do
|
||||
Jekyll.sanitized_path(base_directory, File.join(base_directory, 'thingy/in/my/soup'))
|
||||
end
|
||||
x.report('with a single-part traversal path including the base_directory') do
|
||||
Jekyll.sanitized_path(base_directory, File.join(base_directory, 'thingy/..'))
|
||||
end
|
||||
x.report('with a multi-part traversal path including the base_directory') do
|
||||
Jekyll.sanitized_path(base_directory, File.join('thingy/in/my/../../soup'))
|
||||
end
|
||||
end
|
||||
@@ -1,14 +0,0 @@
|
||||
require 'benchmark/ips'
|
||||
|
||||
def fast
|
||||
yield
|
||||
end
|
||||
|
||||
def slow(&block)
|
||||
block.call
|
||||
end
|
||||
|
||||
Benchmark.ips do |x|
|
||||
x.report('yield') { fast { (0..9).to_a } }
|
||||
x.report('block.call') { slow { (0..9).to_a } }
|
||||
end
|
||||
@@ -1,11 +0,0 @@
|
||||
require 'benchmark/ips'
|
||||
|
||||
Benchmark.ips do |x|
|
||||
x.report('parallel assignment') do
|
||||
a, b = 1, 2
|
||||
end
|
||||
x.report('multi-line assignment') do
|
||||
a = 1
|
||||
b = 2
|
||||
end
|
||||
end
|
||||
@@ -1,8 +0,0 @@
|
||||
require 'benchmark/ips'
|
||||
|
||||
url = "http://jekyllrb.com"
|
||||
|
||||
Benchmark.ips do |x|
|
||||
x.report('+=') { url += '/' }
|
||||
x.report('<<') { url << '/' }
|
||||
end
|
||||
@@ -1,13 +0,0 @@
|
||||
require 'benchmark/ips'
|
||||
|
||||
def str
|
||||
'http://baruco.org/2014/some-talk-with-some-amount-of-value'
|
||||
end
|
||||
|
||||
Benchmark.ips do |x|
|
||||
x.report('#tr') { str.tr('some', 'a') }
|
||||
x.report('#gsub') { str.gsub('some', 'a') }
|
||||
x.report('#gsub!') { str.gsub!('some', 'a') }
|
||||
x.report('#sub') { str.sub('some', 'a') }
|
||||
x.report('#sub!') { str.sub!('some', 'a') }
|
||||
end
|
||||
@@ -1,6 +0,0 @@
|
||||
require 'benchmark/ips'
|
||||
|
||||
Benchmark.ips do |x|
|
||||
x.report('block') { (1..100).map { |i| i.to_s } }
|
||||
x.report('&:to_s') { (1..100).map(&:to_s) }
|
||||
end
|
||||
@@ -13,8 +13,6 @@ require 'mercenary'
|
||||
end
|
||||
end
|
||||
|
||||
Jekyll::PluginManager.require_from_bundler
|
||||
|
||||
Jekyll::Deprecator.process(ARGV)
|
||||
|
||||
Mercenary.program(:jekyll) do |p|
|
||||
|
||||
3
cucumber.yml
Normal file
3
cucumber.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
default: --format pretty
|
||||
travis: --format progress
|
||||
html_report: --format progress --format html --out=features_report.html
|
||||
93
docs/jp/CONTRIBUTING.jp.markdown
Normal file
93
docs/jp/CONTRIBUTING.jp.markdown
Normal file
@@ -0,0 +1,93 @@
|
||||
コントリビュート
|
||||
==========
|
||||
|
||||
あなたは Jekyll に投じるすばらしいアイディアを持っています。
|
||||
すばらしいことです!次の事柄を心に留めてください。
|
||||
|
||||
* **テストなしではコントリビュートはできません。**
|
||||
* もし、既存の機能への小さな修正やパッチを作成したなら、シンプルなテストを行います。
|
||||
現在のテストスイートの範囲にとどまり、そして
|
||||
[Shoulda](https://github.com/thoughtbot/shoulda/tree/master) や
|
||||
[RR](https://github.com/btakita/rr/tree/master) を使用してください。
|
||||
* もし、それが新しい機能の場合は、必ず新しい
|
||||
[Cucumber](https://github.com/cucumber/cucumber/) の機能を作成し、
|
||||
必要に応じて手順を再利用します。
|
||||
また、あなたがフォークした `site` に
|
||||
急ぎいくつかのドキュメントを用意し、一度マージを行い
|
||||
メイン `site` の jekyllrb.com に転送していただければ幸いです。
|
||||
* あなたのコントリビュートによって Jekyll の振る舞いが変わった場合、ドキュメントを更新すべきです。
|
||||
それは `site/docs` にあります。
|
||||
もし、 docs に情報の誤りがあった場合、遠慮なく追加してください。
|
||||
すばらしいドキュメントはすばらしいプロジェクトを作ります!
|
||||
* Ruby のコードを変更するときは、 [GitHub Ruby Styleguide](https://github.com/styleguide/ruby)
|
||||
に従ってください。
|
||||
* **小さなプルリクエスト** に最善を尽くしてください。
|
||||
簡単に提案された変更はレビューされ、マージされる可能性が高いです。
|
||||
* プルリクエストを送信するとき、プルリクエストのボディを賢明に使用してください。
|
||||
変更されたかどうかの記述、変更の背後にある動機、 [完了したかどうかのタスクリスト](http://git.io/gfm-tasks)
|
||||
もレビュー時間を早めます。
|
||||
|
||||
テストの依存関係
|
||||
-----------------
|
||||
|
||||
テストスイートの実行や gem のビルドのために、
|
||||
Jekyll の依存ツールをインストールする必要があります。
|
||||
Jekyll は Bundler を使用しており、 `bundle` コマンドを実行すると全ての設定が迅速に行われます!
|
||||
|
||||
$ bundle
|
||||
|
||||
はじめる前に、テストを実行し、必ずテストが通ることを
|
||||
確認してください(あなたの環境が適切に設定されているかを確認するために):
|
||||
|
||||
$ bundle exec rake test
|
||||
$ bundle exec rake features
|
||||
|
||||
ワークフロー
|
||||
--------
|
||||
|
||||
これは、あなたの作業がプロジェクトにマージされるもっとも直接的な方法です:
|
||||
|
||||
* プロジェクトをフォークします。
|
||||
* あなたのフォークプロジェクトをクローンします ( `git clone git@github.com:<username>/jekyll.git` )。
|
||||
* トピックブランチを作成し、あなたの変更を含んでください ( `git checkout -b my_awesome_feature` )。
|
||||
* ハックし、テストを追加します。必ずしもこの順番でなくてかまいません
|
||||
* `rake` を実行し、テストが必ず全て通ることを確認してください
|
||||
* 必要に応じて、エラーがないようにコミットを論理的な塊にリベースしてください
|
||||
* ブランチをプッシュしてください ( `git push origin my_awesome_feature` ).
|
||||
* jekyll/jekyll プロジェクトの master ブランチに対してプルリクエストを作成し、
|
||||
あなたの変更内容と、なぜそれをマージすべきかを記述してください
|
||||
|
||||
ドキュメントの更新
|
||||
----------------------
|
||||
|
||||
私たちは Jekyll のドキュメントについて最善を尽くしたいです。
|
||||
私たちはドキュメントをオープンソース化しました、そして
|
||||
あなたが Jekyll に欠けているものを見つけた場合、私たちはプルリクエストを歓迎しています。
|
||||
|
||||
あなたは、 GitHub.com 上の Jekyll リポジトリの [site]({{ site.repository }}/tree/master/site) で
|
||||
jekyllrb.comのドキュメントを見つけることができます。
|
||||
|
||||
全てのドキュメントのプルリクエストは `master` に向けられる必要があります。
|
||||
他のブランチに向けたプルリクエストは受け入れられません。
|
||||
|
||||
GitHub の [Jekyll wiki](https://github.com/jekyll/jekyll/wiki) は、
|
||||
自由に更新することができるように、プルリクエストなしで
|
||||
全ての GitHub ユーザがアクセス権を持つことができます。
|
||||
|
||||
落とし穴
|
||||
-------
|
||||
|
||||
* もし、 gem のバージョンがかちあった場合、コミットを分けてください。
|
||||
この方法だと、メンテナが gem をリリースするときに制御できます。
|
||||
* jekyll/jekyll の最新コミットに基づいて(複数の)パッチを維持してください。
|
||||
それは適用するためのあなたの仕事で、メンテナがしなければならないことを少なくするのは
|
||||
とてもよいことです。
|
||||
* あなたの GitHub issue で [fix], [feature] などのタグをつけないでください。
|
||||
メンテナは積極的に issue を読み、彼らが問題に出くわしたらラベルをつけるでしょう。
|
||||
|
||||
最後に…
|
||||
----------
|
||||
|
||||
ありがとう! Jekyll のハックは楽しいものでなければなりません。
|
||||
もし、あなたがこのハードを理解するための何かを発見した場合、知らせてください。
|
||||
我々のプロセスやドキュメントを改善することができます!
|
||||
68
docs/jp/README.jp.markdown
Normal file
68
docs/jp/README.jp.markdown
Normal file
@@ -0,0 +1,68 @@
|
||||
# [Jekyll](http://jekyllrb.com/)
|
||||
|
||||
[](http://badge.fury.io/rb/jekyll)
|
||||
|
||||
[](https://travis-ci.org/jekyll/jekyll)
|
||||
[](https://codeclimate.com/github/jekyll/jekyll)
|
||||
[](https://gemnasium.com/jekyll/jekyll)
|
||||
|
||||
Tom Preston-Werner, Nick Quaranto や多くの[素晴らしいコントリビュータ](https://github.com/jekyll/jekyll/graphs/contributors)によって作成されています!
|
||||
|
||||
Jekyll は個人プロジェクトや組織のサイトに最適な、シンプルで、ブログを意識した静的サイトジェネレータです。
|
||||
複雑さを排除したファイルベースのCMSのようなものと考えてください。
|
||||
Jekyll はコンテンツを受け取り、 Markdown や Liquid テンプレート をレンダリングし、
|
||||
Apache や Nginx やその他の Web サーバに提供する準備ができた静的な Web サイトを完全に出力してくれます。
|
||||
Jekyll は [GitHub Pages](http://pages.github.com) の背後にあるエンジンなので、
|
||||
あなたの GitHub リポジトリからサイトをホストするために使用する事ができます。
|
||||
|
||||
## 原理
|
||||
|
||||
Jekyll あなたがするように伝えたことをします ― それ以上でもそれ以下でもありません。
|
||||
それは、大胆な仮定によってユーザの裏をかこうとせず、
|
||||
また、不必要な複雑さや設定をユーザに負担しません。
|
||||
簡単に言えば、 Jekyll はあなたの道を開け、
|
||||
真に重要なもの: コンテンツに集中することができます。
|
||||
|
||||
## 開始方法
|
||||
|
||||
* gem を[インストール](http://jekyllrb.com/docs/installation/)します
|
||||
* [使用方法](http://jekyllrb.com/docs/usage/) と [設定方法](http://jekyllrb.com/docs/configuration/) を読みます
|
||||
* 既存の [Jekyll で作られたサイト](https://wiki.github.com/jekyll/jekyll/sites) をチラッと見ます
|
||||
* Fork し、あなたの変更を [コントリビュート](http://jekyllrb.com/docs/contributing/) します
|
||||
* 質問があったら? irc.freenode.net の `#jekyll` チャンネルをチェックしてください
|
||||
|
||||
## より深く
|
||||
|
||||
* 以前のシステムからの[移行](http://jekyllrb.com/docs/migrations/)
|
||||
* [YAML Front Matter](http://jekyllrb.com/docs/frontmatter/) がどのように働くかを学ぶ
|
||||
* [変数](http://jekyllrb.com/docs/variables/)を使ってサイトに情報を表示する
|
||||
* posts が生成される時の[パーマリンク](http://jekyllrb.com/docs/permalinks/)をカスタマイズ
|
||||
* 人生を容易にするために、組み込みの [Liquid 拡張](http://jekyllrb.com/docs/templates/)を使用する
|
||||
* あなたのサイト固有のコンテンツを生成するために、カスタム[プラグイン](http://jekyllrb.com/docs/plugins/)を使用する
|
||||
|
||||
## 実行時の依存関係
|
||||
|
||||
* Commander: コマンドラインインターフェース構築 (Ruby)
|
||||
* Colorator: コマンドライン出力に色付け (Ruby)
|
||||
* Classifier: posts の関連を生成 (Ruby)
|
||||
* Directory Watcher: サイトの自動再生成 (Ruby)
|
||||
* Kramdown: デフォルトの Markdown エンジン (Ruby)
|
||||
* Liquid: テンプレートシステム (Ruby)
|
||||
* Pygments.rb: シンタックスハイライト (Ruby/Python)
|
||||
* RedCarpet: Markdown エンジン (Ruby)
|
||||
* Safe YAML: セキュリティのために構築された YAML パーサ (Ruby)
|
||||
|
||||
## 開発時の依存関係
|
||||
|
||||
* Launchy: クロスプラットフォーム ファイルランチャ (Ruby)
|
||||
* Maruku: Markdown スーパーセット インタプリタ (Ruby)
|
||||
* RDiscount: Discount Markdown プロセッサ (Ruby)
|
||||
* RedCloth: Textile サポート (Ruby)
|
||||
* RedGreen: よりよいテスト出力 (Ruby)
|
||||
* RR: モック (Ruby)
|
||||
* Shoulda: テストフレームワーク (Ruby)
|
||||
* SimpleCov: カバレッジフレームワーク (Ruby)
|
||||
|
||||
## ライセンス
|
||||
|
||||
[ライセンス](https://github.com/jekyll/jekyll/blob/master/LICENSE)を見てください。
|
||||
@@ -45,20 +45,6 @@ Feature: Data
|
||||
And I should see "Jack" in "_site/index.html"
|
||||
And I should see "Leon" in "_site/index.html"
|
||||
|
||||
Scenario: autoload *.csv files in _data directory
|
||||
Given I have a _data directory
|
||||
And I have a "_data/members.csv" file with content:
|
||||
"""
|
||||
name,age
|
||||
Jack,28
|
||||
Leon,34
|
||||
"""
|
||||
And I have an "index.html" page that contains "{% for member in site.data.members %}{{member.name}}{% endfor %}"
|
||||
When I run jekyll build
|
||||
Then the "_site/index.html" file should exist
|
||||
And I should see "Jack" in "_site/index.html"
|
||||
And I should see "Leon" in "_site/index.html"
|
||||
|
||||
Scenario: autoload *.yml files in _data directory with space in file name
|
||||
Given I have a _data directory
|
||||
And I have a "_data/team members.yml" file with content:
|
||||
|
||||
@@ -83,8 +83,6 @@ Feature: frontmatter defaults
|
||||
And I have a "index.html" file that contains "nothing"
|
||||
And I have a "_slides/slide1.html" file with content:
|
||||
"""
|
||||
---
|
||||
---
|
||||
Value: {{ page.myval }}
|
||||
"""
|
||||
And I have a "_config.yml" file with content:
|
||||
@@ -130,9 +128,3 @@ Feature: frontmatter defaults
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Value: Override" in "_site/slides/slide2.html"
|
||||
|
||||
Scenario: Deep merge frontmatter defaults
|
||||
Given I have an "index.html" page with fruit "{orange: 1}" that contains "Fruits: {{ page.fruit.orange | plus: page.fruit.apple }}"
|
||||
And I have a configuration file with "defaults" set to "[{scope: {path: ""}, values: {fruit: {apple: 2}}}]"
|
||||
When I run jekyll build
|
||||
Then I should see "Fruits: 3" in "_site/index.html"
|
||||
|
||||
@@ -66,14 +66,3 @@ Feature: Include tags
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "one included" in "_site/index.html"
|
||||
|
||||
Scenario: Include a file with partial variables
|
||||
Given I have an _includes directory
|
||||
And I have an "_includes/one.html" file that contains "one included"
|
||||
And I have a configuration file with:
|
||||
| key | value |
|
||||
| include_file | one |
|
||||
And I have an "index.html" page that contains "{% include {{ site.include_file }}.html %}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "one included" in "_site/index.html"
|
||||
|
||||
@@ -45,7 +45,7 @@ Feature: Markdown
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "My awesome code" in "_site/index.html"
|
||||
And I should see "<pre><code>My awesome code</code></pre>" in "_site/index.html"
|
||||
And I should see "<pre><code>\nMy awesome code\n</code></pre>" in "_site/index.html"
|
||||
|
||||
Scenario: Maruku fenced codeblocks
|
||||
Given I have a configuration file with "markdown" set to "maruku"
|
||||
@@ -64,4 +64,4 @@ Feature: Markdown
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "My awesome string" in "_site/index.html"
|
||||
And I should see "<pre class="ruby"><code class="ruby">puts "My awesome string"</code></pre>" in "_site/index.html"
|
||||
And I should see "<pre class="ruby"><code class="ruby">\nputs "My awesome string"\n</code></pre>" in "_site/index.html"
|
||||
|
||||
@@ -83,13 +83,3 @@ Feature: Fancy permalinks
|
||||
Then the _site directory should exist
|
||||
And the _site/custom/posts directory should exist
|
||||
And I should see "bla bla" in "_site/custom/posts/some.html"
|
||||
|
||||
Scenario: Use per-post ending in .htm
|
||||
Given I have a _posts directory
|
||||
And I have the following post:
|
||||
| title | date | permalink | content |
|
||||
| Some post | 2013-04-14 | /custom/posts/some.htm | bla bla |
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And the _site/custom/posts directory should exist
|
||||
And I should see "bla bla" in "_site/custom/posts/some.htm"
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
Feature: Configuring and using plugins
|
||||
As a hacker
|
||||
I want to specify my own plugins that can modify Jekyll's behaviour
|
||||
|
||||
Scenario: Add a gem-based plugin
|
||||
Given I have an "index.html" file that contains "Whatever"
|
||||
And I have a configuration file with "gems" set to "[jekyll_test_plugin]"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Whatever" in "_site/index.html"
|
||||
And I should see "this is a test" in "_site/test.txt"
|
||||
|
||||
Scenario: Add an empty whitelist to restrict all gems
|
||||
Given I have an "index.html" file that contains "Whatever"
|
||||
And I have a configuration file with:
|
||||
| key | value |
|
||||
| gems | [jekyll_test_plugin] |
|
||||
| whitelist | [] |
|
||||
When I run jekyll build --safe
|
||||
Then the _site directory should exist
|
||||
And I should see "Whatever" in "_site/index.html"
|
||||
And the "_site/test.txt" file should not exist
|
||||
|
||||
Scenario: Add a whitelist to restrict some gems but allow others
|
||||
Given I have an "index.html" file that contains "Whatever"
|
||||
And I have a configuration file with:
|
||||
| key | value |
|
||||
| gems | [jekyll_test_plugin, jekyll_test_plugin_malicious] |
|
||||
| whitelist | [jekyll_test_plugin] |
|
||||
When I run jekyll build --safe
|
||||
Then the _site directory should exist
|
||||
And I should see "Whatever" in "_site/index.html"
|
||||
And the "_site/test.txt" file should exist
|
||||
And I should see "this is a test" in "_site/test.txt"
|
||||
@@ -70,41 +70,17 @@ 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 category is in a folder and has category in YAML
|
||||
Given I have a movies directory
|
||||
And I have a movies/_posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post in "movies":
|
||||
| title | date | layout | category | content |
|
||||
| Star Wars | 2009-03-27 | simple | film | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post category: {{ page.categories }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post category: movies" in "_site/movies/film/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when category is in a folder and has categories in YAML
|
||||
Given I have a movies directory
|
||||
And I have a movies/_posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post in "movies":
|
||||
| title | date | layout | categories | content |
|
||||
| Star Wars | 2009-03-27 | simple | [film, scifi] | Luke, I am your father. |
|
||||
| title | date | layout | categories | content |
|
||||
| Star Wars | 2009-03-27 | simple | [film] | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post category: {{ page.categories }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post category: movies" in "_site/movies/film/scifi/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when category is in a folder and duplicated category is in YAML
|
||||
Given I have a movies directory
|
||||
And I have a movies/_posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post in "movies":
|
||||
| title | date | layout | category | content |
|
||||
| Star Wars | 2009-03-27 | simple | movies | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post category: {{ page.categories }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post category: movies" in "_site/movies/2009/03/27/star-wars.html"
|
||||
And I should see "Post category: movies" in "_site/movies/film/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.tags variable
|
||||
Given I have a _posts directory
|
||||
@@ -165,23 +141,12 @@ 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
|
||||
Scenario: Use post.categories variable when category is in YAML
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | categories | content |
|
||||
| Star Wars | 2009-03-27 | simple | ['scifi', 'movies'] | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post categories: {{ page.categories | array_to_sentence_string }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "Post categories: scifi and movies" in "_site/scifi/movies/2009/03/27/star-wars.html"
|
||||
|
||||
Scenario: Use post.categories variable when categories are in YAML and are duplicated
|
||||
Given I have a _posts directory
|
||||
And I have a _layouts directory
|
||||
And I have the following post:
|
||||
| title | date | layout | categories | content |
|
||||
| Star Wars | 2009-03-27 | simple | ['movies', 'movies'] | Luke, I am your father. |
|
||||
| title | date | layout | category | content |
|
||||
| Star Wars | 2009-03-27 | simple | movies | Luke, I am your father. |
|
||||
And I have a simple layout that contains "Post category: {{ page.categories }}"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
|
||||
@@ -21,15 +21,14 @@ Feature: Rendering
|
||||
And I should not see "Ahoy, indeed!" in "_site/index.css"
|
||||
And I should not see "Ahoy, indeed!" in "_site/index.js"
|
||||
|
||||
Scenario: Render liquid in Sass
|
||||
Scenario: Don't render liquid in Sass
|
||||
Given I have an "index.scss" page that contains ".foo-bar { color:{{site.color}}; }"
|
||||
And I have a configuration file with "color" set to "red"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see ".foo-bar {\n color: red; }" in "_site/index.css"
|
||||
Then the _site directory should not exist
|
||||
And I should see "Invalid CSS after" in the build output
|
||||
|
||||
Scenario: Render liquid in CoffeeScript
|
||||
Given I have an "index.coffee" page with animal "cicada" that contains "hey='for {{page.animal}}'"
|
||||
Scenario: Don't render liquid in CoffeeScript
|
||||
Given I have an "index.coffee" page that contains "hey='for {{site.animal}}'"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "hey = 'for cicada';" in "_site/index.js"
|
||||
And I should see "hey = 'for {{site.animal}}';" in "_site/index.js"
|
||||
|
||||
@@ -243,10 +243,33 @@ 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: arbitrary file reads via layouts
|
||||
Given I have an "index.html" page with layout "page" that contains "FOO"
|
||||
And I have a "_config.yml" file that contains "layouts: '../../../../../../../../../../../../../../usr/include'"
|
||||
Scenario: Add a gem-based plugin
|
||||
Given I have an "index.html" file that contains "Whatever"
|
||||
And I have a configuration file with "gems" set to "[jekyll_test_plugin]"
|
||||
When I run jekyll build
|
||||
Then the _site directory should exist
|
||||
And I should see "FOO" in "_site/index.html"
|
||||
And I should not see " " in "_site/index.html"
|
||||
And I should see "Whatever" in "_site/index.html"
|
||||
And I should see "this is a test" in "_site/test.txt"
|
||||
|
||||
Scenario: Add an empty whitelist to restrict all gems
|
||||
Given I have an "index.html" file that contains "Whatever"
|
||||
And I have a configuration file with:
|
||||
| key | value |
|
||||
| gems | [jekyll_test_plugin] |
|
||||
| whitelist | [] |
|
||||
When I run jekyll build --safe
|
||||
Then the _site directory should exist
|
||||
And I should see "Whatever" in "_site/index.html"
|
||||
And the "_site/test.txt" file should not exist
|
||||
|
||||
Scenario: Add a whitelist to restrict some gems but allow others
|
||||
Given I have an "index.html" file that contains "Whatever"
|
||||
And I have a configuration file with:
|
||||
| key | value |
|
||||
| gems | [jekyll_test_plugin, jekyll_test_plugin_malicious] |
|
||||
| whitelist | [jekyll_test_plugin] |
|
||||
When I run jekyll build --safe
|
||||
Then the _site directory should exist
|
||||
And I should see "Whatever" in "_site/index.html"
|
||||
And the "_site/test.txt" file should exist
|
||||
And I should see "this is a test" in "_site/test.txt"
|
||||
|
||||
@@ -22,8 +22,8 @@ Before do
|
||||
end
|
||||
|
||||
After do
|
||||
FileUtils.rm_rf(TEST_DIR) if File.exist?(TEST_DIR)
|
||||
FileUtils.rm(JEKYLL_COMMAND_OUTPUT_FILE) if File.exist?(JEKYLL_COMMAND_OUTPUT_FILE)
|
||||
FileUtils.rm_rf(TEST_DIR) if File.exists?(TEST_DIR)
|
||||
FileUtils.rm(JEKYLL_COMMAND_OUTPUT_FILE) if File.exists?(JEKYLL_COMMAND_OUTPUT_FILE)
|
||||
end
|
||||
|
||||
World(Test::Unit::Assertions)
|
||||
@@ -146,13 +146,6 @@ When /^I run jekyll(.*)$/ do |args|
|
||||
end
|
||||
end
|
||||
|
||||
When /^I run bundle(.*)$/ do |args|
|
||||
status = run_bundle(args)
|
||||
if args.include?("--verbose") || ENV['DEBUG']
|
||||
puts jekyll_run_output
|
||||
end
|
||||
end
|
||||
|
||||
When /^I change "(.*)" to contain "(.*)"$/ do |file, text|
|
||||
File.open(file, 'a') do |f|
|
||||
f.write(text)
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
require 'fileutils'
|
||||
require 'posix-spawn'
|
||||
require 'rr'
|
||||
require 'test/unit'
|
||||
require 'time'
|
||||
|
||||
JEKYLL_SOURCE_DIR = File.dirname(File.dirname(File.dirname(__FILE__)))
|
||||
TEST_DIR = File.expand_path(File.join('..', '..', 'tmp', 'jekyll'), File.dirname(__FILE__))
|
||||
JEKYLL_PATH = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'jekyll'))
|
||||
JEKYLL_PATH = File.join(File.dirname(__FILE__), '..', '..', 'bin', 'jekyll')
|
||||
JEKYLL_COMMAND_OUTPUT_FILE = File.join(File.dirname(TEST_DIR), 'jekyll_output.txt')
|
||||
|
||||
def source_dir(*files)
|
||||
@@ -18,20 +17,11 @@ def jekyll_output_file
|
||||
end
|
||||
|
||||
def jekyll_run_output
|
||||
File.read(jekyll_output_file) if File.file?(jekyll_output_file)
|
||||
end
|
||||
|
||||
def run_bundle(args)
|
||||
child = run_in_shell('bundle', *args.strip.split(' '))
|
||||
File.read(jekyll_output_file)
|
||||
end
|
||||
|
||||
def run_jekyll(args)
|
||||
child = run_in_shell(JEKYLL_PATH, *args.strip.split(' '), "--trace")
|
||||
child.status.exitstatus == 0
|
||||
end
|
||||
|
||||
def run_in_shell(*args)
|
||||
POSIX::Spawn::Child.new *args, :out => [JEKYLL_COMMAND_OUTPUT_FILE, "w"]
|
||||
system "#{JEKYLL_PATH} #{args} --trace > #{jekyll_output_file} 2>&1"
|
||||
end
|
||||
|
||||
def slug(title)
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
require 'fileutils'
|
||||
require 'colorator'
|
||||
require 'cucumber/formatter/console'
|
||||
require 'cucumber/formatter/io'
|
||||
require 'gherkin/formatter/escaping'
|
||||
|
||||
module Features
|
||||
module Support
|
||||
# The formatter used for <tt>--format pretty</tt> (the default formatter).
|
||||
#
|
||||
# This formatter prints features to plain text - exactly how they were parsed,
|
||||
# just prettier. That means with proper indentation and alignment of table columns.
|
||||
#
|
||||
# If the output is STDOUT (and not a file), there are bright colours to watch too.
|
||||
#
|
||||
class Overview
|
||||
include FileUtils
|
||||
include Cucumber::Formatter::Console
|
||||
include Cucumber::Formatter::Io
|
||||
include Gherkin::Formatter::Escaping
|
||||
attr_writer :indent
|
||||
attr_reader :runtime
|
||||
|
||||
def initialize(runtime, path_or_io, options)
|
||||
@runtime, @io, @options = runtime, ensure_io(path_or_io, "pretty"), options
|
||||
@exceptions = []
|
||||
@indent = 0
|
||||
@prefixes = options[:prefixes] || {}
|
||||
@delayed_messages = []
|
||||
end
|
||||
|
||||
def before_features(features)
|
||||
print_profile_information
|
||||
end
|
||||
|
||||
def after_features(features)
|
||||
@io.puts
|
||||
print_summary(features)
|
||||
end
|
||||
|
||||
def before_feature(feature)
|
||||
@exceptions = []
|
||||
@indent = 0
|
||||
end
|
||||
|
||||
def comment_line(comment_line)
|
||||
end
|
||||
|
||||
def after_tags(tags)
|
||||
end
|
||||
|
||||
def tag_name(tag_name)
|
||||
end
|
||||
|
||||
def before_feature_element(feature_element)
|
||||
@indent = 2
|
||||
@scenario_indent = 2
|
||||
end
|
||||
|
||||
def after_feature_element(feature_element)
|
||||
end
|
||||
|
||||
def before_background(background)
|
||||
@indent = 2
|
||||
@scenario_indent = 2
|
||||
@in_background = true
|
||||
end
|
||||
|
||||
def after_background(background)
|
||||
@in_background = nil
|
||||
end
|
||||
|
||||
def background_name(keyword, name, file_colon_line, source_indent)
|
||||
print_feature_element_name(keyword, name, file_colon_line, source_indent)
|
||||
end
|
||||
|
||||
def scenario_name(keyword, name, file_colon_line, source_indent)
|
||||
print_feature_element_name(keyword, name, file_colon_line, source_indent)
|
||||
end
|
||||
|
||||
def before_step(step)
|
||||
@current_step = step
|
||||
end
|
||||
|
||||
def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line)
|
||||
@hide_this_step = false
|
||||
if exception
|
||||
if @exceptions.include?(exception)
|
||||
@hide_this_step = true
|
||||
return
|
||||
end
|
||||
@exceptions << exception
|
||||
end
|
||||
if status != :failed && @in_background ^ background
|
||||
@hide_this_step = true
|
||||
return
|
||||
end
|
||||
@status = status
|
||||
end
|
||||
|
||||
CHARS = {
|
||||
:failed => "x".red,
|
||||
:pending => "?".yellow,
|
||||
:undefined => "x".red,
|
||||
:passed => ".".green,
|
||||
:skipped => "-".blue
|
||||
}
|
||||
|
||||
def step_name(keyword, step_match, status, source_indent, background, file_colon_line)
|
||||
@io.print CHARS[status]
|
||||
end
|
||||
|
||||
def exception(exception, status)
|
||||
return if @hide_this_step
|
||||
@io.puts
|
||||
print_exception(exception, status, @indent)
|
||||
@io.flush
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def print_feature_element_name(keyword, name, file_colon_line, source_indent)
|
||||
@io.puts
|
||||
names = name.empty? ? [name] : name.split("\n")
|
||||
line = " #{keyword}: #{names[0]}"
|
||||
if @options[:source]
|
||||
line_comment = "#{file_colon_line}"
|
||||
@io.print(line_comment)
|
||||
end
|
||||
@io.print(line)
|
||||
@io.print " "
|
||||
@io.flush
|
||||
end
|
||||
|
||||
def cell_prefix(status)
|
||||
@prefixes[status]
|
||||
end
|
||||
|
||||
def print_summary(features)
|
||||
@io.puts
|
||||
print_stats(features, @options)
|
||||
print_snippets(@options)
|
||||
print_passing_wip(@options)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -20,31 +20,28 @@ Gem::Specification.new do |s|
|
||||
s.email = 'tom@mojombo.com'
|
||||
s.homepage = 'https://github.com/jekyll/jekyll'
|
||||
|
||||
all_files = `git ls-files -z`.split("\x0")
|
||||
s.files = all_files.grep(%r{^(bin|lib)/})
|
||||
s.executables = all_files.grep(%r{^bin/}) { |f| File.basename(f) }
|
||||
s.files = `git ls-files`.split($/)
|
||||
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
||||
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
||||
s.require_paths = ["lib"]
|
||||
|
||||
s.rdoc_options = ["--charset=UTF-8"]
|
||||
s.extra_rdoc_files = %w[README.markdown LICENSE]
|
||||
|
||||
s.add_runtime_dependency('liquid', "~> 2.6.1")
|
||||
s.add_runtime_dependency('kramdown', "~> 1.3")
|
||||
s.add_runtime_dependency('liquid', "~> 2.6.1")
|
||||
s.add_runtime_dependency('classifier', "~> 1.3")
|
||||
s.add_runtime_dependency('listen', [">= 2.7.6", "< 3.0.0"])
|
||||
s.add_runtime_dependency('kramdown', "~> 1.3")
|
||||
s.add_runtime_dependency('pygments.rb', "~> 0.6.0")
|
||||
s.add_runtime_dependency('mercenary', "~> 0.3.3")
|
||||
s.add_runtime_dependency('safe_yaml', "~> 1.0")
|
||||
s.add_runtime_dependency('colorator', "~> 0.1")
|
||||
|
||||
# Before 3.0 drops, phase the following gems out as dev dependencies
|
||||
# and gracefully handle their absence.
|
||||
s.add_runtime_dependency('pygments.rb', "~> 0.6.0")
|
||||
s.add_runtime_dependency('redcarpet', "~> 3.1")
|
||||
s.add_runtime_dependency('toml', '~> 0.1.0')
|
||||
s.add_runtime_dependency('jekyll-paginate', '~> 1.0')
|
||||
s.add_runtime_dependency('jekyll-gist', '~> 1.0')
|
||||
s.add_runtime_dependency('jekyll-coffeescript', '~> 1.0')
|
||||
s.add_runtime_dependency('jekyll-sass-converter', '~> 1.0')
|
||||
s.add_runtime_dependency('jekyll-watch', '~> 1.1')
|
||||
s.add_runtime_dependency('classifier-reborn', "~> 2.0")
|
||||
|
||||
s.add_development_dependency('rake', "~> 10.1")
|
||||
s.add_development_dependency('rdoc', "~> 3.11")
|
||||
@@ -53,16 +50,14 @@ Gem::Specification.new do |s|
|
||||
s.add_development_dependency('rr', "~> 1.1")
|
||||
s.add_development_dependency('cucumber', "1.3.11")
|
||||
s.add_development_dependency('RedCloth', "~> 4.2")
|
||||
s.add_development_dependency('maruku', "~> 0.7.0")
|
||||
s.add_development_dependency('maruku', "0.7.0")
|
||||
s.add_development_dependency('rdiscount', "~> 1.6")
|
||||
s.add_development_dependency('launchy', "~> 2.3")
|
||||
s.add_development_dependency('simplecov', "~> 0.9")
|
||||
s.add_development_dependency('simplecov', "~> 0.7")
|
||||
s.add_development_dependency('simplecov-gem-adapter', "~> 1.0.1")
|
||||
s.add_development_dependency('mime-types', "~> 1.5")
|
||||
s.add_development_dependency('activesupport', '~> 3.2.13')
|
||||
s.add_development_dependency('jekyll_test_plugin')
|
||||
s.add_development_dependency('jekyll_test_plugin_malicious')
|
||||
s.add_development_dependency('rouge', '~> 1.7')
|
||||
s.add_development_dependency('minitest') if RUBY_PLATFORM =~ /cygwin/
|
||||
s.add_development_dependency('test-unit') if RUBY_PLATFORM =~ /cygwin/
|
||||
s.add_development_dependency('rouge', '~> 1.3')
|
||||
end
|
||||
|
||||
244
lib/jekyll.rb
244
lib/jekyll.rb
@@ -18,143 +18,53 @@ require 'rubygems'
|
||||
# stdlib
|
||||
require 'fileutils'
|
||||
require 'time'
|
||||
require 'safe_yaml/load'
|
||||
require 'English'
|
||||
require 'pathname'
|
||||
require 'logger'
|
||||
|
||||
# 3rd party
|
||||
require 'safe_yaml/load'
|
||||
require 'liquid'
|
||||
require 'kramdown'
|
||||
require 'colorator'
|
||||
require 'toml'
|
||||
|
||||
SafeYAML::OPTIONS[:suppress_warnings] = true
|
||||
# internal requires
|
||||
require 'jekyll/version'
|
||||
require 'jekyll/utils'
|
||||
require 'jekyll/hooks'
|
||||
require 'jekyll/log_adapter'
|
||||
require 'jekyll/stevenson'
|
||||
require 'jekyll/deprecator'
|
||||
require 'jekyll/configuration'
|
||||
require 'jekyll/document'
|
||||
require 'jekyll/collection'
|
||||
require 'jekyll/plugin_manager'
|
||||
require 'jekyll/frontmatter_defaults'
|
||||
require 'jekyll/site'
|
||||
require 'jekyll/convertible'
|
||||
require 'jekyll/url'
|
||||
require 'jekyll/layout'
|
||||
require 'jekyll/page'
|
||||
require 'jekyll/post'
|
||||
require 'jekyll/excerpt'
|
||||
require 'jekyll/draft'
|
||||
require 'jekyll/filters'
|
||||
require 'jekyll/static_file'
|
||||
require 'jekyll/errors'
|
||||
require 'jekyll/related_posts'
|
||||
require 'jekyll/cleaner'
|
||||
require 'jekyll/entry_filter'
|
||||
require 'jekyll/layout_reader'
|
||||
require 'jekyll/publisher'
|
||||
require 'jekyll/renderer'
|
||||
|
||||
module Jekyll
|
||||
|
||||
# internal requires
|
||||
autoload :Cleaner, 'jekyll/cleaner'
|
||||
autoload :Collection, 'jekyll/collection'
|
||||
autoload :Configuration, 'jekyll/configuration'
|
||||
autoload :Convertible, 'jekyll/convertible'
|
||||
autoload :Deprecator, 'jekyll/deprecator'
|
||||
autoload :Document, 'jekyll/document'
|
||||
autoload :Draft, 'jekyll/draft'
|
||||
autoload :EntryFilter, 'jekyll/entry_filter'
|
||||
autoload :Errors, 'jekyll/errors'
|
||||
autoload :Excerpt, 'jekyll/excerpt'
|
||||
autoload :Filters, 'jekyll/filters'
|
||||
autoload :FrontmatterDefaults, 'jekyll/frontmatter_defaults'
|
||||
autoload :Layout, 'jekyll/layout'
|
||||
autoload :LayoutReader, 'jekyll/layout_reader'
|
||||
autoload :LogAdapter, 'jekyll/log_adapter'
|
||||
autoload :Page, 'jekyll/page'
|
||||
autoload :PluginManager, 'jekyll/plugin_manager'
|
||||
autoload :Post, 'jekyll/post'
|
||||
autoload :Publisher, 'jekyll/publisher'
|
||||
autoload :RelatedPosts, 'jekyll/related_posts'
|
||||
autoload :Renderer, 'jekyll/renderer'
|
||||
autoload :Site, 'jekyll/site'
|
||||
autoload :StaticFile, 'jekyll/static_file'
|
||||
autoload :Stevenson, 'jekyll/stevenson'
|
||||
autoload :URL, 'jekyll/url'
|
||||
autoload :Utils, 'jekyll/utils'
|
||||
autoload :VERSION, 'jekyll/version'
|
||||
|
||||
# extensions
|
||||
require 'jekyll/plugin'
|
||||
require 'jekyll/converter'
|
||||
require 'jekyll/generator'
|
||||
require 'jekyll/command'
|
||||
require 'jekyll/liquid_extensions'
|
||||
|
||||
class << self
|
||||
# Public: Tells you which Jekyll environment you are building in so you can skip tasks
|
||||
# if you need to. This is useful when doing expensive compression tasks on css and
|
||||
# images and allows you to skip that when working in development.
|
||||
|
||||
def env
|
||||
ENV["JEKYLL_ENV"] || "development"
|
||||
end
|
||||
|
||||
# Public: Generate a Jekyll configuration Hash by merging the default
|
||||
# options with anything in _config.yml, and adding the given options on top.
|
||||
#
|
||||
# override - A Hash of config directives that override any options in both
|
||||
# the defaults and the config file. See Jekyll::Configuration::DEFAULTS for a
|
||||
# list of option names and their defaults.
|
||||
#
|
||||
# Returns the final configuration Hash.
|
||||
def configuration(override = Hash.new)
|
||||
config = Configuration[Configuration::DEFAULTS]
|
||||
override = Configuration[override].stringify_keys
|
||||
unless override.delete('skip_config_files')
|
||||
config = config.read_config_files(config.config_files(override))
|
||||
end
|
||||
|
||||
# Merge DEFAULTS < _config.yml < override
|
||||
config = Utils.deep_merge_hashes(config, override).stringify_keys
|
||||
set_timezone(config['timezone']) if config['timezone']
|
||||
|
||||
config
|
||||
end
|
||||
|
||||
# Public: Set the TZ environment variable to use the timezone specified
|
||||
#
|
||||
# timezone - the IANA Time Zone
|
||||
#
|
||||
# Returns nothing
|
||||
def set_timezone(timezone)
|
||||
ENV['TZ'] = timezone
|
||||
end
|
||||
|
||||
# Public: Fetch the logger instance for this Jekyll process.
|
||||
#
|
||||
# Returns the LogAdapter instance.
|
||||
def logger
|
||||
@logger ||= LogAdapter.new(Stevenson.new, (ENV["JEKYLL_LOG_LEVEL"] || :info).to_sym)
|
||||
end
|
||||
|
||||
# Public: Set the log writer.
|
||||
# New log writer must respond to the same methods
|
||||
# as Ruby's interal Logger.
|
||||
#
|
||||
# writer - the new Logger-compatible log transport
|
||||
#
|
||||
# Returns the new logger.
|
||||
def logger=(writer)
|
||||
@logger = LogAdapter.new(writer)
|
||||
end
|
||||
|
||||
# Public: An array of sites
|
||||
#
|
||||
# Returns the Jekyll sites created.
|
||||
def sites
|
||||
@sites ||= []
|
||||
end
|
||||
|
||||
# Public: Ensures the questionable path is prefixed with the base directory
|
||||
# and prepends the questionable path with the base directory if false.
|
||||
#
|
||||
# base_directory - the directory with which to prefix the questionable path
|
||||
# questionable_path - the path we're unsure about, and want prefixed
|
||||
#
|
||||
# Returns the sanitized path.
|
||||
def sanitized_path(base_directory, questionable_path)
|
||||
return base_directory if base_directory.eql?(questionable_path)
|
||||
|
||||
clean_path = File.expand_path(questionable_path, "/")
|
||||
clean_path = clean_path.sub(/^\A\w\:\//, '/')
|
||||
|
||||
unless clean_path.start_with?(base_directory.sub(/^\A\w\:\//, '/'))
|
||||
File.join(base_directory, clean_path)
|
||||
else
|
||||
clean_path
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
# extensions
|
||||
require 'jekyll/plugin'
|
||||
require 'jekyll/converter'
|
||||
require 'jekyll/generator'
|
||||
require 'jekyll/command'
|
||||
require 'jekyll/liquid_extensions'
|
||||
|
||||
require_all 'jekyll/commands'
|
||||
require_all 'jekyll/converters'
|
||||
@@ -162,11 +72,75 @@ require_all 'jekyll/converters/markdown'
|
||||
require_all 'jekyll/generators'
|
||||
require_all 'jekyll/tags'
|
||||
|
||||
# Eventually remove these for 3.0 as non-core
|
||||
Jekyll::Deprecator.gracefully_require(%w[
|
||||
toml
|
||||
jekyll-paginate
|
||||
jekyll-gist
|
||||
jekyll-coffeescript
|
||||
jekyll-sass-converter
|
||||
])
|
||||
# plugins
|
||||
require 'jekyll-coffeescript'
|
||||
require 'jekyll-sass-converter'
|
||||
require 'jekyll-paginate'
|
||||
require 'jekyll-gist'
|
||||
|
||||
SafeYAML::OPTIONS[:suppress_warnings] = true
|
||||
|
||||
module Jekyll
|
||||
|
||||
# Public: Tells you which Jekyll environment you are building in so you can skip tasks
|
||||
# if you need to. This is useful when doing expensive compression tasks on css and
|
||||
# images and allows you to skip that when working in development.
|
||||
|
||||
def self.env
|
||||
ENV["JEKYLL_ENV"] || "development"
|
||||
end
|
||||
|
||||
# Public: Generate a Jekyll configuration Hash by merging the default
|
||||
# options with anything in _config.yml, and adding the given options on top.
|
||||
#
|
||||
# override - A Hash of config directives that override any options in both
|
||||
# the defaults and the config file. See Jekyll::Configuration::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))
|
||||
|
||||
# Merge DEFAULTS < _config.yml < override
|
||||
config = Utils.deep_merge_hashes(config, override).stringify_keys
|
||||
set_timezone(config['timezone']) if config['timezone']
|
||||
|
||||
config
|
||||
end
|
||||
|
||||
# Static: Set the TZ environment variable to use the timezone specified
|
||||
#
|
||||
# timezone - the IANA Time Zone
|
||||
#
|
||||
# Returns nothing
|
||||
def self.set_timezone(timezone)
|
||||
ENV['TZ'] = timezone
|
||||
end
|
||||
|
||||
def self.logger
|
||||
@logger ||= LogAdapter.new(Stevenson.new)
|
||||
end
|
||||
|
||||
def self.logger=(writer)
|
||||
@logger = LogAdapter.new(writer)
|
||||
end
|
||||
|
||||
# Public: File system root
|
||||
#
|
||||
# Returns the root of the filesystem as a Pathname
|
||||
def self.fs_root
|
||||
@fs_root ||= "/"
|
||||
end
|
||||
|
||||
def self.sanitized_path(base_directory, questionable_path)
|
||||
clean_path = File.expand_path(questionable_path, fs_root)
|
||||
clean_path.gsub!(/\A\w\:\//, '/')
|
||||
unless clean_path.start_with?(base_directory)
|
||||
File.join(base_directory, clean_path)
|
||||
else
|
||||
clean_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -29,7 +29,7 @@ module Jekyll
|
||||
# Returns a Set with the file paths
|
||||
def existing_files
|
||||
files = Set.new
|
||||
Dir.glob(site.in_dest_dir("**", "*"), File::FNM_DOTMATCH) do |file|
|
||||
Dir.glob(File.join(site.dest, "**", "*"), File::FNM_DOTMATCH) do |file|
|
||||
files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex || keep_dirs.include?(file)
|
||||
end
|
||||
files
|
||||
@@ -76,7 +76,7 @@ module Jekyll
|
||||
#
|
||||
# Returns a Set with the directory paths
|
||||
def keep_dirs
|
||||
site.keep_files.map { |file| parent_dirs(site.in_dest_dir(file)) }.flatten.to_set
|
||||
site.keep_files.map{|file| parent_dirs(File.join(site.dest, file))}.flatten.to_set
|
||||
end
|
||||
|
||||
# Private: Creates a regular expression from the config's keep_files array
|
||||
|
||||
@@ -22,29 +22,14 @@ module Jekyll
|
||||
@docs ||= []
|
||||
end
|
||||
|
||||
# Fetch the static files in this collection.
|
||||
# Defaults to an empty array if no static files have been read in.
|
||||
#
|
||||
# Returns an array of Jekyll::StaticFile objects.
|
||||
def files
|
||||
@files ||= []
|
||||
end
|
||||
|
||||
# Read the allowed documents into the collection's array of docs.
|
||||
#
|
||||
# Returns the sorted array of docs.
|
||||
def read
|
||||
filtered_entries.each do |file_path|
|
||||
full_path = collection_dir(file_path)
|
||||
next if File.directory?(full_path)
|
||||
if Utils.has_yaml_header? full_path
|
||||
doc = Jekyll::Document.new(full_path, { site: site, collection: self })
|
||||
doc.read
|
||||
docs << doc
|
||||
else
|
||||
relative_dir = Jekyll.sanitized_path(relative_directory, File.dirname(file_path)).chomp("/.")
|
||||
files << StaticFile.new(site, site.source, relative_dir, File.basename(full_path), self)
|
||||
end
|
||||
doc = Jekyll::Document.new(Jekyll.sanitized_path(directory, file_path), { site: site, collection: self })
|
||||
doc.read
|
||||
docs << doc
|
||||
end
|
||||
docs.sort!
|
||||
end
|
||||
@@ -55,10 +40,9 @@ module Jekyll
|
||||
# relative to the collection's directory
|
||||
def entries
|
||||
return Array.new unless exists?
|
||||
@entries ||=
|
||||
Dir.glob(collection_dir("**", "*.*")).map do |entry|
|
||||
entry["#{collection_dir}/"] = ''; entry
|
||||
end
|
||||
Dir.glob(File.join(directory, "**", "*.*")).map do |entry|
|
||||
entry[File.join(directory, "")] = ''; entry
|
||||
end
|
||||
end
|
||||
|
||||
# Filtered version of the entries in this collection.
|
||||
@@ -67,13 +51,9 @@ module Jekyll
|
||||
# Returns a list of filtered entry paths.
|
||||
def filtered_entries
|
||||
return Array.new unless exists?
|
||||
@filtered_entries ||=
|
||||
Dir.chdir(directory) do
|
||||
entry_filter.filter(entries).reject do |f|
|
||||
path = collection_dir(f)
|
||||
File.directory?(path) || (File.symlink?(f) && site.safe)
|
||||
end
|
||||
end
|
||||
Dir.chdir(directory) do
|
||||
entry_filter.filter(entries)
|
||||
end
|
||||
end
|
||||
|
||||
# The directory for this Collection, relative to the site source.
|
||||
@@ -81,28 +61,15 @@ module Jekyll
|
||||
# Returns a String containing the directory name where the collection
|
||||
# is stored on the filesystem.
|
||||
def relative_directory
|
||||
@relative_directory ||= "_#{label}"
|
||||
"_#{label}"
|
||||
end
|
||||
|
||||
# The full path to the directory containing the collection.
|
||||
# The full path to the directory containing the
|
||||
#
|
||||
# Returns a String containing th directory name where the collection
|
||||
# is stored on the filesystem.
|
||||
def directory
|
||||
@directory ||= site.in_source_dir(relative_directory)
|
||||
end
|
||||
|
||||
# The full path to the directory containing the collection, with
|
||||
# optional subpaths.
|
||||
#
|
||||
# *files - (optional) any other path pieces relative to the
|
||||
# directory to append to the path
|
||||
#
|
||||
# Returns a String containing th directory name where the collection
|
||||
# is stored on the filesystem.
|
||||
def collection_dir(*files)
|
||||
return directory if files.empty?
|
||||
site.in_source_dir(relative_directory, *files)
|
||||
Jekyll.sanitized_path(site.source, relative_directory)
|
||||
end
|
||||
|
||||
# Checks whether the directory "exists" for this collection.
|
||||
@@ -138,7 +105,7 @@ module Jekyll
|
||||
#
|
||||
# Returns a sanitized version of the label.
|
||||
def sanitize_label(label)
|
||||
label.gsub(/[^a-z0-9_\-\.]/i, '')
|
||||
label.gsub(/[^a-z0-9_\-]/i, '')
|
||||
end
|
||||
|
||||
# Produce a representation of this Collection for use in Liquid.
|
||||
@@ -151,7 +118,6 @@ module Jekyll
|
||||
metadata.merge({
|
||||
"label" => label,
|
||||
"docs" => docs,
|
||||
"files" => files,
|
||||
"directory" => directory,
|
||||
"output" => write?,
|
||||
"relative_directory" => relative_directory
|
||||
|
||||
@@ -19,6 +19,31 @@ module Jekyll
|
||||
super(base)
|
||||
end
|
||||
|
||||
# Paths to ignore for the watch option
|
||||
#
|
||||
# options - A Hash of options passed to the command
|
||||
#
|
||||
# Returns a list of relative paths from source that should be ignored
|
||||
def ignore_paths(options)
|
||||
source = options['source']
|
||||
destination = options['destination']
|
||||
config_files = Configuration[options].config_files(options)
|
||||
paths = config_files + Array(destination)
|
||||
ignored = []
|
||||
|
||||
source_abs = Pathname.new(source).expand_path
|
||||
paths.each do |p|
|
||||
path_abs = Pathname.new(p).expand_path
|
||||
begin
|
||||
rel_path = path_abs.relative_path_from(source_abs).to_s
|
||||
ignored << Regexp.new(Regexp.escape(rel_path)) unless rel_path.start_with?('../')
|
||||
rescue ArgumentError
|
||||
# Could not find a relative path
|
||||
end
|
||||
end
|
||||
ignored
|
||||
end
|
||||
|
||||
# Run Site#process and catch errors
|
||||
#
|
||||
# site - the Jekyll::Site object
|
||||
@@ -26,7 +51,7 @@ module Jekyll
|
||||
# Returns nothing
|
||||
def process_site(site)
|
||||
site.process
|
||||
rescue Jekyll::Errors::FatalException => e
|
||||
rescue Jekyll::FatalException => e
|
||||
Jekyll.logger.error "ERROR:", "YOUR SITE COULD NOT BE BUILT:"
|
||||
Jekyll.logger.error "", "------------------------------------"
|
||||
Jekyll.logger.error "", e.message
|
||||
@@ -51,7 +76,7 @@ module Jekyll
|
||||
c.option 'config', '--config CONFIG_FILE[,CONFIG_FILE2,...]', Array, 'Custom configuration file'
|
||||
c.option 'future', '--future', 'Publishes posts with a future date'
|
||||
c.option 'limit_posts', '--limit_posts MAX_POSTS', Integer, 'Limits the number of posts to parse and publish'
|
||||
c.option 'watch', '-w', '--[no-]watch', 'Watch for changes and rebuild'
|
||||
c.option 'watch', '-w', '--watch', 'Watch for changes and rebuild'
|
||||
c.option 'force_polling', '--force_polling', 'Force watch to use polling'
|
||||
c.option 'lsi', '--lsi', 'Use LSI for improved related posts'
|
||||
c.option 'show_drafts', '-D', '--drafts', 'Render posts in the _drafts folder'
|
||||
|
||||
@@ -9,7 +9,6 @@ module Jekyll
|
||||
prog.command(:build) do |c|
|
||||
c.syntax 'build [options]'
|
||||
c.description 'Build your site'
|
||||
c.alias :b
|
||||
|
||||
add_build_options(c)
|
||||
|
||||
@@ -33,18 +32,13 @@ module Jekyll
|
||||
else
|
||||
build(site, options)
|
||||
end
|
||||
|
||||
if options.fetch('watch', false)
|
||||
watch(site, options)
|
||||
else
|
||||
Jekyll.logger.info "Auto-regeneration:", "disabled. Use --watch to enable."
|
||||
end
|
||||
watch(site, options) if options['watch']
|
||||
end
|
||||
|
||||
# Build your Jekyll site.
|
||||
#
|
||||
# site - the Jekyll::Site instance to build
|
||||
# options - A Hash of options passed to the command
|
||||
# options - the
|
||||
#
|
||||
# Returns nothing.
|
||||
def build(site, options)
|
||||
@@ -64,8 +58,38 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def watch(site, options)
|
||||
Deprecator.gracefully_require 'jekyll-watch'
|
||||
Jekyll::Watcher.watch(options)
|
||||
require 'listen'
|
||||
|
||||
listener = Listen.to(
|
||||
options['source'],
|
||||
:ignore => ignore_paths(options),
|
||||
:force_polling => options['force_polling']
|
||||
) do |modified, added, removed|
|
||||
t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
|
||||
n = modified.length + added.length + removed.length
|
||||
print Jekyll.logger.formatted_topic("Regenerating:") + "#{n} files at #{t} "
|
||||
begin
|
||||
process_site(site)
|
||||
puts "...done."
|
||||
rescue => e
|
||||
puts "...error:"
|
||||
Jekyll.logger.warn "Error:", e.message
|
||||
Jekyll.logger.warn "Error:", "Run jekyll build --trace for more information."
|
||||
end
|
||||
end
|
||||
listener.start
|
||||
|
||||
Jekyll.logger.info "Auto-regeneration:", "enabled for '#{source}'"
|
||||
|
||||
unless options['serving']
|
||||
trap("INT") do
|
||||
listener.stop
|
||||
puts " Halting auto-regeneration."
|
||||
exit 0
|
||||
end
|
||||
|
||||
loop { sleep 1000 }
|
||||
end
|
||||
end
|
||||
|
||||
end # end of class << self
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
module Jekyll
|
||||
module Commands
|
||||
class Help < Command
|
||||
class << self
|
||||
|
||||
def init_with_program(prog)
|
||||
prog.command(:help) do |c|
|
||||
c.syntax 'help [subcommand]'
|
||||
c.description 'Show the help message, optionally for a given subcommand.'
|
||||
|
||||
c.action do |args, _|
|
||||
cmd = (args.first || "").to_sym
|
||||
if args.empty?
|
||||
puts prog
|
||||
elsif prog.has_command? cmd
|
||||
puts prog.commands[cmd]
|
||||
else
|
||||
invalid_command(prog, cmd)
|
||||
abort
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def invalid_command(prog, cmd)
|
||||
Jekyll.logger.error "Error:", "Hmm... we don't know what the '#{cmd}' command is."
|
||||
Jekyll.logger.info "Valid commands:", prog.commands.keys.join(", ")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3,80 +3,78 @@ require 'erb'
|
||||
module Jekyll
|
||||
module Commands
|
||||
class New < Command
|
||||
class << self
|
||||
def init_with_program(prog)
|
||||
prog.command(:new) do |c|
|
||||
c.syntax 'new PATH'
|
||||
c.description 'Creates a new Jekyll site scaffold in PATH'
|
||||
def self.init_with_program(prog)
|
||||
prog.command(:new) do |c|
|
||||
c.syntax 'new PATH'
|
||||
c.description 'Creates a new Jekyll site scaffold in PATH'
|
||||
|
||||
c.option 'force', '--force', 'Force creation even if PATH already exists'
|
||||
c.option 'blank', '--blank', 'Creates scaffolding but with empty files'
|
||||
|
||||
c.action do |args, options|
|
||||
Jekyll::Commands::New.process(args, options)
|
||||
end
|
||||
c.option 'force', '--force', 'Force creation even if PATH already exists'
|
||||
c.option 'blank', '--blank', 'Creates scaffolding but with empty files'
|
||||
|
||||
c.action do |args, options|
|
||||
Jekyll::Commands::New.process(args, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.process(args, options = {})
|
||||
raise ArgumentError.new('You must specify a path.') if args.empty?
|
||||
|
||||
new_blog_path = File.expand_path(args.join(" "), Dir.pwd)
|
||||
FileUtils.mkdir_p new_blog_path
|
||||
if preserve_source_location?(new_blog_path, options)
|
||||
Jekyll.logger.abort_with "Conflict:", "#{new_blog_path} exists and is not empty."
|
||||
end
|
||||
|
||||
if options["blank"]
|
||||
create_blank_site new_blog_path
|
||||
else
|
||||
create_sample_files new_blog_path
|
||||
|
||||
File.open(File.expand_path(initialized_post_name, new_blog_path), "w") do |f|
|
||||
f.write(scaffold_post_content)
|
||||
end
|
||||
end
|
||||
|
||||
def process(args, options = {})
|
||||
raise ArgumentError.new('You must specify a path.') if args.empty?
|
||||
Jekyll.logger.info "New jekyll site installed in #{new_blog_path}."
|
||||
end
|
||||
|
||||
new_blog_path = File.expand_path(args.join(" "), Dir.pwd)
|
||||
FileUtils.mkdir_p new_blog_path
|
||||
if preserve_source_location?(new_blog_path, options)
|
||||
Jekyll.logger.abort_with "Conflict:", "#{new_blog_path} exists and is not empty."
|
||||
end
|
||||
|
||||
if options["blank"]
|
||||
create_blank_site new_blog_path
|
||||
else
|
||||
create_sample_files new_blog_path
|
||||
|
||||
File.open(File.expand_path(initialized_post_name, new_blog_path), "w") do |f|
|
||||
f.write(scaffold_post_content)
|
||||
end
|
||||
end
|
||||
|
||||
Jekyll.logger.info "New jekyll site installed in #{new_blog_path}."
|
||||
def self.create_blank_site(path)
|
||||
Dir.chdir(path) do
|
||||
FileUtils.mkdir(%w(_layouts _posts _drafts))
|
||||
FileUtils.touch("index.html")
|
||||
end
|
||||
end
|
||||
|
||||
def create_blank_site(path)
|
||||
Dir.chdir(path) do
|
||||
FileUtils.mkdir(%w(_layouts _posts _drafts))
|
||||
FileUtils.touch("index.html")
|
||||
end
|
||||
end
|
||||
def self.scaffold_post_content
|
||||
ERB.new(File.read(File.expand_path(scaffold_path, site_template))).result
|
||||
end
|
||||
|
||||
def scaffold_post_content
|
||||
ERB.new(File.read(File.expand_path(scaffold_path, site_template))).result
|
||||
end
|
||||
# Internal: Gets the filename of the sample post to be created
|
||||
#
|
||||
# Returns the filename of the sample post, as a String
|
||||
def self.initialized_post_name
|
||||
"_posts/#{Time.now.strftime('%Y-%m-%d')}-welcome-to-jekyll.markdown"
|
||||
end
|
||||
|
||||
# Internal: Gets the filename of the sample post to be created
|
||||
#
|
||||
# Returns the filename of the sample post, as a String
|
||||
def initialized_post_name
|
||||
"_posts/#{Time.now.strftime('%Y-%m-%d')}-welcome-to-jekyll.markdown"
|
||||
end
|
||||
private
|
||||
|
||||
private
|
||||
def self.preserve_source_location?(path, options)
|
||||
!options["force"] && !Dir["#{path}/**/*"].empty?
|
||||
end
|
||||
|
||||
def preserve_source_location?(path, options)
|
||||
!options["force"] && !Dir["#{path}/**/*"].empty?
|
||||
end
|
||||
def self.create_sample_files(path)
|
||||
FileUtils.cp_r site_template + '/.', path
|
||||
FileUtils.rm File.expand_path(scaffold_path, path)
|
||||
end
|
||||
|
||||
def 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 site_template
|
||||
File.expand_path("../../site_template", File.dirname(__FILE__))
|
||||
end
|
||||
|
||||
def scaffold_path
|
||||
"_posts/0000-00-00-welcome-to-jekyll.markdown.erb"
|
||||
end
|
||||
end
|
||||
def self.scaffold_path
|
||||
"_posts/0000-00-00-welcome-to-jekyll.markdown.erb"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,7 +10,6 @@ module Jekyll
|
||||
c.syntax 'serve [options]'
|
||||
c.description 'Serve your site locally'
|
||||
c.alias :server
|
||||
c.alias :s
|
||||
|
||||
add_build_options(c)
|
||||
|
||||
@@ -21,8 +20,7 @@ module Jekyll
|
||||
c.option 'skip_initial_build', '--skip-initial-build', 'Skips the initial site build which occurs before the server is started.'
|
||||
|
||||
c.action do |args, options|
|
||||
options["serving"] = true
|
||||
options["watch"] = true unless options.key?("watch")
|
||||
options["serving"] ||= true
|
||||
Jekyll::Commands::Build.process(options)
|
||||
Jekyll::Commands::Serve.process(options)
|
||||
end
|
||||
@@ -76,20 +74,16 @@ module Jekyll
|
||||
|
||||
def webrick_options(config)
|
||||
opts = {
|
||||
:BindAddress => config['host'],
|
||||
:DirectoryIndex => %w(index.html index.htm index.cgi index.rhtml index.xml),
|
||||
:DocumentRoot => config['destination'],
|
||||
:DoNotReverseLookup => true,
|
||||
:MimeTypes => mime_types,
|
||||
:Port => config['port'],
|
||||
:StartCallback => start_callback(config['detach'])
|
||||
:BindAddress => config['host'],
|
||||
:MimeTypes => mime_types,
|
||||
:DoNotReverseLookup => true,
|
||||
:StartCallback => start_callback(config['detach']),
|
||||
:DirectoryIndex => %w(index.html index.htm index.cgi index.rhtml index.xml)
|
||||
}
|
||||
|
||||
if config['verbose']
|
||||
opts.merge!({
|
||||
:Logger => WEBrick::Log.new($stdout, WEBrick::Log::DEBUG)
|
||||
})
|
||||
else
|
||||
if !config['verbose']
|
||||
opts.merge!({
|
||||
:AccessLog => [],
|
||||
:Logger => WEBrick::Log.new([], WEBrick::Log::WARN)
|
||||
@@ -123,10 +117,9 @@ module Jekyll
|
||||
|
||||
# recreate NondisclosureName under utf-8 circumstance
|
||||
def file_handler_options
|
||||
WEBrick::Config::FileHandler.merge({
|
||||
:FancyIndexing => true,
|
||||
:NondisclosureName => ['.ht*','~*']
|
||||
})
|
||||
fh_option = WEBrick::Config::FileHandler
|
||||
fh_option[:NondisclosureName] = ['.ht*','~*']
|
||||
fh_option
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -6,55 +6,46 @@ module Jekyll
|
||||
# Default options. Overridden by values in _config.yml.
|
||||
# Strings rather than symbols are used for compatibility with YAML.
|
||||
DEFAULTS = {
|
||||
# Where things are
|
||||
'source' => Dir.pwd,
|
||||
'destination' => File.join(Dir.pwd, '_site'),
|
||||
'plugins' => '_plugins',
|
||||
'layouts' => '_layouts',
|
||||
'data_source' => '_data',
|
||||
'keep_files' => ['.git','.svn'],
|
||||
'gems' => [],
|
||||
'collections' => nil,
|
||||
|
||||
# Handling Reading
|
||||
'safe' => false,
|
||||
'include' => ['.htaccess'],
|
||||
'exclude' => [],
|
||||
'keep_files' => ['.git','.svn'],
|
||||
'encoding' => 'utf-8',
|
||||
'markdown_ext' => 'markdown,mkdown,mkdn,mkd,md',
|
||||
'textile_ext' => 'textile',
|
||||
'timezone' => nil, # use the local timezone
|
||||
|
||||
# Filtering Content
|
||||
'encoding' => 'utf-8', # always use utf-8 encoding. NEVER FORGET
|
||||
|
||||
'safe' => false,
|
||||
'detach' => false, # default to not detaching the server
|
||||
'show_drafts' => nil,
|
||||
'limit_posts' => 0,
|
||||
'lsi' => false,
|
||||
'future' => true, # remove and make true just default
|
||||
'unpublished' => false,
|
||||
|
||||
# Plugins
|
||||
'whitelist' => [],
|
||||
'gems' => [],
|
||||
|
||||
# Conversion
|
||||
'markdown' => 'kramdown',
|
||||
'highlighter' => 'pygments',
|
||||
'lsi' => false,
|
||||
'excerpt_separator' => "\n\n",
|
||||
|
||||
# Serving
|
||||
'detach' => false, # default to not detaching the server
|
||||
'port' => '4000',
|
||||
'host' => '127.0.0.1',
|
||||
'baseurl' => '',
|
||||
|
||||
# Backwards-compatibility options
|
||||
'relative_permalinks' => false,
|
||||
|
||||
# Output Configuration
|
||||
'markdown' => 'kramdown',
|
||||
'highlighter' => 'pygments',
|
||||
'permalink' => 'date',
|
||||
'baseurl' => '',
|
||||
'include' => ['.htaccess'],
|
||||
'exclude' => [],
|
||||
'paginate_path' => '/page:num',
|
||||
'timezone' => nil, # use the local timezone
|
||||
|
||||
'quiet' => false,
|
||||
'defaults' => [],
|
||||
'markdown_ext' => 'markdown,mkdown,mkdn,mkd,md',
|
||||
'textile_ext' => 'textile',
|
||||
|
||||
'port' => '4000',
|
||||
'host' => '0.0.0.0',
|
||||
|
||||
'excerpt_separator' => "\n\n",
|
||||
|
||||
'defaults' => [],
|
||||
|
||||
'maruku' => {
|
||||
'use_tex' => false,
|
||||
@@ -112,15 +103,11 @@ module Jekyll
|
||||
override['source'] || self['source'] || DEFAULTS['source']
|
||||
end
|
||||
|
||||
def quiet?(override = {})
|
||||
override['quiet'] || self['quiet'] || DEFAULTS['quiet']
|
||||
end
|
||||
|
||||
def safe_load_file(filename)
|
||||
case File.extname(filename)
|
||||
when /\.toml/i
|
||||
when '.toml'
|
||||
TOML.load_file(filename)
|
||||
when /\.ya?ml/i
|
||||
when /\.y(a)?ml/
|
||||
SafeYAML.load_file(filename)
|
||||
else
|
||||
raise ArgumentError, "No parser for '#{filename}' is available. Use a .toml or .y(a)ml file instead."
|
||||
@@ -133,9 +120,6 @@ module Jekyll
|
||||
#
|
||||
# Returns an Array of config files
|
||||
def config_files(override)
|
||||
# Be quiet quickly.
|
||||
Jekyll.logger.log_level = :error if quiet?(override)
|
||||
|
||||
# Get configuration from <source>/_config.yml or <source>/<config_file>
|
||||
config_files = override.delete('config')
|
||||
if config_files.to_s.empty?
|
||||
@@ -208,31 +192,31 @@ module Jekyll
|
||||
def backwards_compatibilize
|
||||
config = clone
|
||||
# Provide backwards-compatibility
|
||||
if config.key?('auto') || config.key?('watch')
|
||||
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"+
|
||||
" --[no-]watch/-w command-line option instead."
|
||||
" --watch/-w command-line option instead."
|
||||
config.delete('auto')
|
||||
config.delete('watch')
|
||||
end
|
||||
|
||||
if config.key? 'server'
|
||||
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.key? 'server_port'
|
||||
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.key?('port')
|
||||
config['port'] = config['server_port'] unless config.has_key?('port')
|
||||
config.delete('server_port')
|
||||
end
|
||||
|
||||
if config.key? 'pygments'
|
||||
if config.has_key? 'pygments'
|
||||
Jekyll.logger.warn "Deprecation:", "The 'pygments' configuration option" +
|
||||
" has been renamed to 'highlighter'. Please update your" +
|
||||
" config file accordingly. The allowed values are 'rouge', " +
|
||||
@@ -250,7 +234,6 @@ module Jekyll
|
||||
" as a list of comma-separated values."
|
||||
config[option] = csv_to_array(config[option])
|
||||
end
|
||||
config[option].map!(&:to_s)
|
||||
end
|
||||
|
||||
if config.fetch('markdown', 'kramdown').to_s.downcase.eql?("maruku")
|
||||
@@ -264,7 +247,7 @@ module Jekyll
|
||||
def fix_common_issues
|
||||
config = clone
|
||||
|
||||
if config.key?('paginate') && (!config['paginate'].is_a?(Integer) || config['paginate'] < 1)
|
||||
if config.has_key?('paginate') && (!config['paginate'].is_a?(Integer) || config['paginate'] < 1)
|
||||
Jekyll.logger.warn "Config Warning:", "The `paginate` key must be a" +
|
||||
" positive integer or nil. It's currently set to '#{config['paginate'].inspect}'."
|
||||
config['paginate'] = nil
|
||||
|
||||
@@ -11,50 +11,25 @@ module Jekyll
|
||||
@parser =
|
||||
case @config['markdown'].downcase
|
||||
when 'redcarpet' then RedcarpetParser.new(@config)
|
||||
when 'kramdown' then KramdownParser.new(@config)
|
||||
when 'kramdown' then KramdownParser.new(@config)
|
||||
when 'rdiscount' then RDiscountParser.new(@config)
|
||||
when 'maruku' then MarukuParser.new(@config)
|
||||
when 'maruku' then MarukuParser.new(@config)
|
||||
else
|
||||
# So they can't try some tricky bullshit or go down the ancestor chain, I hope.
|
||||
if allowed_custom_class?(@config['markdown'])
|
||||
self.class.const_get(@config['markdown']).new(@config)
|
||||
else
|
||||
Jekyll.logger.error "Invalid Markdown Processor:", "#{@config['markdown']}"
|
||||
Jekyll.logger.error "", "Valid options are [ #{valid_processors.join(" | ")} ]"
|
||||
raise Errors::FatalException, "Invalid Markdown Processor: #{@config['markdown']}"
|
||||
Jekyll.logger.error "", "Valid options are [ maruku | rdiscount | kramdown | redcarpet ]"
|
||||
raise FatalException, "Invalid Markdown Processor: #{@config['markdown']}"
|
||||
end
|
||||
end
|
||||
@setup = true
|
||||
end
|
||||
|
||||
def valid_processors
|
||||
%w[
|
||||
maruku
|
||||
rdiscount
|
||||
kramdown
|
||||
redcarpet
|
||||
] + third_party_processors
|
||||
end
|
||||
|
||||
def third_party_processors
|
||||
self.class.constants - %w[
|
||||
KramdownParser
|
||||
MarukuParser
|
||||
RDiscountParser
|
||||
RedcarpetParser
|
||||
PRIORITIES
|
||||
].map(&:to_sym)
|
||||
end
|
||||
|
||||
def extname_matches_regexp
|
||||
@extname_matches_regexp ||= Regexp.new(
|
||||
'(' + @config['markdown_ext'].gsub(',','|') +')$',
|
||||
Regexp::IGNORECASE
|
||||
)
|
||||
end
|
||||
|
||||
def matches(ext)
|
||||
ext =~ extname_matches_regexp
|
||||
rgx = '^\.(' + @config['markdown_ext'].gsub(',','|') +')$'
|
||||
ext =~ Regexp.new(rgx, Regexp::IGNORECASE)
|
||||
end
|
||||
|
||||
def output_ext(ext)
|
||||
|
||||
@@ -8,7 +8,7 @@ module Jekyll
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Markdown. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install kramdown'
|
||||
raise Errors::FatalException.new("Missing dependency: kramdown")
|
||||
raise FatalException.new("Missing dependency: kramdown")
|
||||
end
|
||||
|
||||
def convert(content)
|
||||
@@ -16,7 +16,7 @@ module Jekyll
|
||||
if @config['kramdown']['use_coderay']
|
||||
%w[wrap line_numbers line_numbers_start tab_width bold_every css default_lang].each do |opt|
|
||||
key = "coderay_#{opt}"
|
||||
@config['kramdown'][key] = @config['kramdown']['coderay'][key] unless @config['kramdown'].key?(key)
|
||||
@config['kramdown'][key] = @config['kramdown']['coderay'][key] unless @config['kramdown'].has_key?(key)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ module Jekyll
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Markdown. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install maruku'
|
||||
raise Errors::FatalException.new("Missing dependency: maruku")
|
||||
raise FatalException.new("Missing dependency: maruku")
|
||||
end
|
||||
|
||||
def load_divs_library
|
||||
|
||||
@@ -3,9 +3,13 @@ module Jekyll
|
||||
class Markdown
|
||||
class RDiscountParser
|
||||
def initialize(config)
|
||||
Jekyll::Deprecator.gracefully_require "rdiscount"
|
||||
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)
|
||||
|
||||
@@ -14,7 +14,7 @@ module Jekyll
|
||||
module WithPygments
|
||||
include CommonMethods
|
||||
def block_code(code, lang)
|
||||
Jekyll::Deprecator.gracefully_require("pygments")
|
||||
require 'pygments'
|
||||
lang = lang && lang.split.first || "text"
|
||||
add_code_tags(
|
||||
Pygments.highlight(code, :lexer => lang, :options => { :encoding => 'utf-8' }),
|
||||
@@ -48,47 +48,52 @@ module Jekyll
|
||||
end
|
||||
|
||||
protected
|
||||
def rouge_formatter(lexer)
|
||||
Rouge::Formatters::HTML.new(:wrap => false)
|
||||
def rouge_formatter(opts = {})
|
||||
Rouge::Formatters::HTML.new(opts.merge(wrap: false))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def initialize(config)
|
||||
Deprecator.gracefully_require("redcarpet")
|
||||
require 'redcarpet'
|
||||
@config = config
|
||||
@redcarpet_extensions = {}
|
||||
@config['redcarpet']['extensions'].each { |e| @redcarpet_extensions[e.to_sym] = true }
|
||||
|
||||
@renderer ||= class_with_proper_highlighter(@config['highlighter'])
|
||||
end
|
||||
@renderer ||= case @config['highlighter']
|
||||
when 'pygments'
|
||||
Class.new(Redcarpet::Render::HTML) do
|
||||
include WithPygments
|
||||
end
|
||||
when 'rouge'
|
||||
Class.new(Redcarpet::Render::HTML) do
|
||||
begin
|
||||
require 'rouge'
|
||||
require 'rouge/plugins/redcarpet'
|
||||
rescue LoadError => e
|
||||
Jekyll.logger.error "You are missing the 'rouge' gem. Please run:"
|
||||
Jekyll.logger.error " $ [sudo] gem install rouge"
|
||||
Jekyll.logger.error "Or add 'rouge' to your Gemfile."
|
||||
raise FatalException.new("Missing dependency: rouge")
|
||||
end
|
||||
|
||||
def class_with_proper_highlighter(highlighter)
|
||||
case highlighter
|
||||
when "pygments"
|
||||
Class.new(Redcarpet::Render::HTML) do
|
||||
include WithPygments
|
||||
end
|
||||
when "rouge"
|
||||
Class.new(Redcarpet::Render::HTML) do
|
||||
Jekyll::Deprecator.gracefully_require(%w[
|
||||
rouge
|
||||
rouge/plugins/redcarpet
|
||||
])
|
||||
if Rouge.version < '1.3.0'
|
||||
abort "Please install Rouge 1.3.0 or greater and try running Jekyll again."
|
||||
end
|
||||
|
||||
if Rouge.version < '1.3.0'
|
||||
abort "Please install Rouge 1.3.0 or greater and try running Jekyll again."
|
||||
end
|
||||
|
||||
include Rouge::Plugins::Redcarpet
|
||||
include CommonMethods
|
||||
include WithRouge
|
||||
end
|
||||
else
|
||||
Class.new(Redcarpet::Render::HTML) do
|
||||
include WithoutHighlighting
|
||||
end
|
||||
end
|
||||
include Rouge::Plugins::Redcarpet
|
||||
include CommonMethods
|
||||
include WithRouge
|
||||
end
|
||||
else
|
||||
Class.new(Redcarpet::Render::HTML) do
|
||||
include WithoutHighlighting
|
||||
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)
|
||||
|
||||
@@ -13,18 +13,12 @@ module Jekyll
|
||||
rescue LoadError
|
||||
STDERR.puts 'You are missing a library required for Textile. Please run:'
|
||||
STDERR.puts ' $ [sudo] gem install RedCloth'
|
||||
raise Errors::FatalException.new("Missing dependency: RedCloth")
|
||||
end
|
||||
|
||||
def extname_matches_regexp
|
||||
@extname_matches_regexp ||= Regexp.new(
|
||||
'(' + @config['textile_ext'].gsub(',','|') +')$',
|
||||
Regexp::IGNORECASE
|
||||
)
|
||||
raise FatalException.new("Missing dependency: RedCloth")
|
||||
end
|
||||
|
||||
def matches(ext)
|
||||
ext =~ extname_matches_regexp
|
||||
rgx = '(' + @config['textile_ext'].gsub(',','|') +')'
|
||||
ext =~ Regexp.new(rgx, Regexp::IGNORECASE)
|
||||
end
|
||||
|
||||
def output_ext(ext)
|
||||
@@ -38,7 +32,7 @@ module Jekyll
|
||||
return RedCloth.new(content).to_html if @config['redcloth'].nil?
|
||||
|
||||
# List of attributes defined on RedCloth
|
||||
# (from https://github.com/jgarber/redcloth/blob/master/lib/redcloth/textile_doc.rb)
|
||||
# (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']
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ module Jekyll
|
||||
|
||||
# Whether the file is published or not, as indicated in YAML front-matter
|
||||
def published?
|
||||
!(data.key?('published') && data['published'] == false)
|
||||
!(data.has_key?('published') && data['published'] == false)
|
||||
end
|
||||
|
||||
# Returns merged option hash for File.read of self.site (if exists)
|
||||
@@ -43,7 +43,7 @@ module Jekyll
|
||||
# Returns nothing.
|
||||
def read_yaml(base, name, opts = {})
|
||||
begin
|
||||
self.content = File.read(site.in_source_dir(base, name),
|
||||
self.content = File.read(File.join(base, name),
|
||||
merged_file_read_opts(opts))
|
||||
if content =~ /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m
|
||||
self.content = $POSTMATCH
|
||||
@@ -60,17 +60,13 @@ module Jekyll
|
||||
|
||||
# Transform the contents based on the content type.
|
||||
#
|
||||
# Returns the transformed contents.
|
||||
# Returns nothing.
|
||||
def transform
|
||||
converters.reduce(content) do |output, converter|
|
||||
begin
|
||||
converter.convert output
|
||||
rescue => e
|
||||
Jekyll.logger.error "Conversion error:", "#{converter.class} encountered an error converting '#{path}'."
|
||||
Jekyll.logger.error("Conversion error:", e.to_s)
|
||||
raise e
|
||||
end
|
||||
end
|
||||
self.content = converter.convert(content)
|
||||
rescue => e
|
||||
Jekyll.logger.error "Conversion error:", "There was an error converting" +
|
||||
" '#{path}'."
|
||||
raise e
|
||||
end
|
||||
|
||||
# Determine the extension depending on content_type.
|
||||
@@ -78,21 +74,15 @@ module Jekyll
|
||||
# Returns the String extension for the output file.
|
||||
# e.g. ".html" for an HTML output file.
|
||||
def output_ext
|
||||
if converters.all? { |c| c.is_a?(Jekyll::Converters::Identity) }
|
||||
ext
|
||||
else
|
||||
converters.map { |c|
|
||||
c.output_ext(ext) unless c.is_a?(Jekyll::Converters::Identity)
|
||||
}.compact.last
|
||||
end
|
||||
converter.output_ext(ext)
|
||||
end
|
||||
|
||||
# Determine which converter to use based on this convertible's
|
||||
# extension.
|
||||
#
|
||||
# Returns the Converter instance.
|
||||
def converters
|
||||
@converters ||= site.converters.select { |c| c.matches(ext) }.sort
|
||||
def converter
|
||||
@converter ||= site.converters.find { |c| c.matches(ext) }
|
||||
end
|
||||
|
||||
# Render Liquid in the content
|
||||
@@ -129,12 +119,12 @@ module Jekyll
|
||||
#
|
||||
# Returns the type of self.
|
||||
def type
|
||||
if is_a?(Draft)
|
||||
:drafts
|
||||
elsif is_a?(Post)
|
||||
:posts
|
||||
if is_a?(Post)
|
||||
:post
|
||||
elsif is_a?(Page)
|
||||
:pages
|
||||
:page
|
||||
elsif is_a?(Draft)
|
||||
:draft
|
||||
end
|
||||
end
|
||||
|
||||
@@ -144,46 +134,25 @@ module Jekyll
|
||||
# Returns true if the extname belongs to the set of extensions
|
||||
# that asset files use.
|
||||
def asset_file?
|
||||
sass_file? || coffeescript_file?
|
||||
end
|
||||
|
||||
# Determine whether the document is a Sass file.
|
||||
#
|
||||
# Returns true if extname == .sass or .scss, false otherwise.
|
||||
def sass_file?
|
||||
%w[.sass .scss].include?(ext)
|
||||
end
|
||||
|
||||
# Determine whether the document is a CoffeeScript file.
|
||||
#
|
||||
# Returns true if extname == .coffee, false otherwise.
|
||||
def coffeescript_file?
|
||||
'.coffee'.eql?(ext)
|
||||
%w[.sass .scss .coffee].include?(ext)
|
||||
end
|
||||
|
||||
# Determine whether the file should be rendered with Liquid.
|
||||
#
|
||||
# Always returns true.
|
||||
# Returns false if the document is either an asset file or a yaml file,
|
||||
# true otherwise.
|
||||
def render_with_liquid?
|
||||
true
|
||||
!asset_file?
|
||||
end
|
||||
|
||||
# Determine whether the file should be placed into layouts.
|
||||
#
|
||||
# Returns false if the document is an asset file.
|
||||
# Returns false if the document is either an asset file or a yaml file,
|
||||
# true otherwise.
|
||||
def place_in_layout?
|
||||
!asset_file?
|
||||
end
|
||||
|
||||
# Checks if the layout specified in the document actually exists
|
||||
#
|
||||
# layout - the layout to check
|
||||
#
|
||||
# Returns true if the layout is invalid, false if otherwise
|
||||
def invalid_layout?(layout)
|
||||
!data["layout"].nil? && layout.nil? && !(self.is_a? Jekyll::Excerpt)
|
||||
end
|
||||
|
||||
# Recursively render layouts
|
||||
#
|
||||
# layouts - a list of the layouts
|
||||
@@ -194,9 +163,6 @@ module Jekyll
|
||||
def render_all_layouts(layouts, payload, info)
|
||||
# recursively render layouts
|
||||
layout = layouts[data["layout"]]
|
||||
|
||||
Jekyll.logger.warn("Build Warning:", "Layout '#{data["layout"]}' requested in #{path} does not exist.") if invalid_layout? layout
|
||||
|
||||
used = Set.new([layout])
|
||||
|
||||
while layout
|
||||
@@ -227,11 +193,11 @@ module Jekyll
|
||||
info = { :filters => [Jekyll::Filters], :registers => { :site => site, :page => payload['page'] } }
|
||||
|
||||
# render and transform content (this becomes the final content of the object)
|
||||
payload["highlighter_prefix"] = converters.first.highlighter_prefix
|
||||
payload["highlighter_suffix"] = converters.first.highlighter_suffix
|
||||
payload["highlighter_prefix"] = converter.highlighter_prefix
|
||||
payload["highlighter_suffix"] = converter.highlighter_suffix
|
||||
|
||||
self.content = render_liquid(content, payload, info) if render_with_liquid?
|
||||
self.content = transform
|
||||
transform
|
||||
|
||||
# output keeps track of what will finally be written
|
||||
self.output = content
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
module Jekyll
|
||||
module Deprecator
|
||||
extend self
|
||||
|
||||
def process(args)
|
||||
class Deprecator
|
||||
def self.process(args)
|
||||
no_subcommand(args)
|
||||
arg_is_present? args, "--server", "The --server command has been replaced by the \
|
||||
'serve' subcommand."
|
||||
@@ -18,44 +16,21 @@ module Jekyll
|
||||
arg_is_present? args, "--url", "The 'url' setting can only be set in your config files."
|
||||
end
|
||||
|
||||
def no_subcommand(args)
|
||||
def self.no_subcommand(args)
|
||||
if args.size > 0 && args.first =~ /^--/ && !%w[--help --version].include?(args.first)
|
||||
deprecation_message "Jekyll now uses subcommands instead of just \
|
||||
Jekyll.logger.error "Deprecation:", "Jekyll now uses subcommands instead of just \
|
||||
switches. Run `jekyll --help' to find out more."
|
||||
end
|
||||
end
|
||||
|
||||
def arg_is_present?(args, deprecated_argument, message)
|
||||
def self.arg_is_present?(args, deprecated_argument, message)
|
||||
if args.include?(deprecated_argument)
|
||||
deprecation_message(message)
|
||||
end
|
||||
end
|
||||
|
||||
def deprecation_message(message)
|
||||
def self.deprecation_message(message)
|
||||
Jekyll.logger.error "Deprecation:", message
|
||||
end
|
||||
|
||||
def defaults_deprecate_type(old, current)
|
||||
Jekyll.logger.warn "Defaults:", "The '#{old}' type has become '#{current}'."
|
||||
Jekyll.logger.warn "Defaults:", "Please update your front-matter defaults to use 'type: #{current}'."
|
||||
end
|
||||
|
||||
def gracefully_require(gem_name)
|
||||
Array(gem_name).each do |name|
|
||||
begin
|
||||
require name
|
||||
rescue LoadError => e
|
||||
Jekyll.logger.error "Dependency Error:", <<-MSG
|
||||
Yikes! It looks like you don't have #{name} or one of its dependencies installed.
|
||||
In order to use Jekyll as currently configured, you'll need to install this gem.
|
||||
|
||||
The full error message from Ruby is: '#{e.message}'
|
||||
|
||||
If you run into trouble, you can find helpful resources at http://jekyllrb.com/help/!
|
||||
MSG
|
||||
raise Errors::MissingDependencyException.new(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
module Jekyll
|
||||
class Document
|
||||
include Comparable
|
||||
|
||||
attr_reader :path, :site, :extname
|
||||
attr_reader :path, :site
|
||||
attr_accessor :content, :collection, :output
|
||||
|
||||
# Create a new Document.
|
||||
@@ -16,9 +14,7 @@ module Jekyll
|
||||
def initialize(path, relations)
|
||||
@site = relations[:site]
|
||||
@path = path
|
||||
@extname = File.extname(path)
|
||||
@collection = relations[:collection]
|
||||
@has_yaml_header = nil
|
||||
end
|
||||
|
||||
# Fetch the Document's data.
|
||||
@@ -34,21 +30,23 @@ module Jekyll
|
||||
# Returns a String path which represents the relative path
|
||||
# from the site source to this document
|
||||
def relative_path
|
||||
@relative_path ||= Pathname.new(path).relative_path_from(Pathname.new(site.source)).to_s
|
||||
end
|
||||
|
||||
# The base filename of the document, without the file extname.
|
||||
#
|
||||
# Returns the basename without the file extname.
|
||||
def basename_without_ext
|
||||
@basename_without_ext ||= File.basename(path, '.*')
|
||||
Pathname.new(path).relative_path_from(Pathname.new(site.source)).to_s
|
||||
end
|
||||
|
||||
# The base filename of the document.
|
||||
#
|
||||
# suffix - (optional) the suffix to be removed from the end of the filename
|
||||
#
|
||||
# Returns the base filename of the document.
|
||||
def basename
|
||||
@basename ||= File.basename(path)
|
||||
def basename(suffix = "")
|
||||
File.basename(path, suffix)
|
||||
end
|
||||
|
||||
# The extension name of the document.
|
||||
#
|
||||
# Returns the extension name of the document.
|
||||
def extname
|
||||
File.extname(path)
|
||||
end
|
||||
|
||||
# Produces a "cleaned" relative path.
|
||||
@@ -63,8 +61,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the cleaned relative path of the document.
|
||||
def cleaned_relative_path
|
||||
@cleaned_relative_path ||=
|
||||
relative_path[0 .. -extname.length - 1].sub(collection.relative_directory, "")
|
||||
relative_path[0 .. -extname.length - 1].sub(collection.relative_directory, "")
|
||||
end
|
||||
|
||||
# Determine whether the document is a YAML file.
|
||||
@@ -80,21 +77,7 @@ module Jekyll
|
||||
# Returns true if the extname belongs to the set of extensions
|
||||
# that asset files use.
|
||||
def asset_file?
|
||||
sass_file? || coffeescript_file?
|
||||
end
|
||||
|
||||
# Determine whether the document is a Sass file.
|
||||
#
|
||||
# Returns true if extname == .sass or .scss, false otherwise.
|
||||
def sass_file?
|
||||
%w[.sass .scss].include?(extname)
|
||||
end
|
||||
|
||||
# Determine whether the document is a CoffeeScript file.
|
||||
#
|
||||
# Returns true if extname == .coffee, false otherwise.
|
||||
def coffeescript_file?
|
||||
'.coffee'.eql?(extname)
|
||||
%w[.sass .scss .coffee].include?(extname)
|
||||
end
|
||||
|
||||
# Determine whether the file should be rendered with Liquid.
|
||||
@@ -102,7 +85,7 @@ module Jekyll
|
||||
# Returns false if the document is either an asset file or a yaml file,
|
||||
# true otherwise.
|
||||
def render_with_liquid?
|
||||
!(coffeescript_file? || yaml_file?)
|
||||
!(asset_file? || yaml_file?)
|
||||
end
|
||||
|
||||
# Determine whether the file should be placed into layouts.
|
||||
@@ -128,9 +111,7 @@ module Jekyll
|
||||
{
|
||||
collection: collection.label,
|
||||
path: cleaned_relative_path,
|
||||
output_ext: Jekyll::Renderer.new(site, self).output_ext,
|
||||
name: Utils.slugify(basename_without_ext),
|
||||
title: Utils.slugify(data['title']) || Utils.slugify(basename_without_ext)
|
||||
output_ext: Jekyll::Renderer.new(site, self).output_ext
|
||||
}
|
||||
end
|
||||
|
||||
@@ -146,7 +127,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the computed URL for the document.
|
||||
def url
|
||||
@url = URL.new({
|
||||
@url ||= URL.new({
|
||||
template: url_template,
|
||||
placeholders: url_placeholders,
|
||||
permalink: permalink
|
||||
@@ -159,8 +140,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the full path to the output file of this document.
|
||||
def destination(base_directory)
|
||||
dest = site.in_dest_dir(base_directory)
|
||||
path = site.in_dest_dir(dest, url)
|
||||
path = Jekyll.sanitized_path(base_directory, url)
|
||||
path = File.join(path, "index.html") if url =~ /\/$/
|
||||
path
|
||||
end
|
||||
@@ -192,7 +172,7 @@ module Jekyll
|
||||
#
|
||||
# Returns true if the 'published' key is specified in the YAML front-matter and not `false`.
|
||||
def published?
|
||||
!(data.key?('published') && data['published'] == false)
|
||||
!(data.has_key?('published') && data['published'] == false)
|
||||
end
|
||||
|
||||
# Read in the file and assign the content and data based on the file contents.
|
||||
@@ -255,7 +235,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the content of the document
|
||||
def to_s
|
||||
content || ''
|
||||
output || content
|
||||
end
|
||||
|
||||
# Compare this document against another document.
|
||||
|
||||
@@ -14,8 +14,8 @@ module Jekyll
|
||||
end
|
||||
|
||||
# Get the full path to the directory containing the draft files
|
||||
def containing_dir(dir)
|
||||
site.in_source_dir(dir, '_drafts')
|
||||
def containing_dir(source, dir)
|
||||
File.join(source, dir, '_drafts')
|
||||
end
|
||||
|
||||
# The path to the draft source file, relative to the site source
|
||||
|
||||
@@ -47,7 +47,7 @@ module Jekyll
|
||||
|
||||
def excluded?(entry)
|
||||
excluded = glob_include?(site.exclude, relative_to_source(entry))
|
||||
Jekyll.logger.debug "EntryFilter:", "excluded?(#{relative_to_source(entry)}) ==> #{excluded}"
|
||||
Jekyll.logger.debug "excluded?(#{relative_to_source(entry)}) ==> #{excluded}"
|
||||
excluded
|
||||
end
|
||||
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
module Jekyll
|
||||
module Errors
|
||||
class FatalException < RuntimeError
|
||||
end
|
||||
|
||||
class MissingDependencyException < FatalException
|
||||
end
|
||||
class FatalException < StandardError
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
require 'jekyll/convertible'
|
||||
require 'forwardable'
|
||||
|
||||
module Jekyll
|
||||
@@ -106,7 +107,7 @@ module Jekyll
|
||||
# Returns excerpt String
|
||||
def extract_excerpt(post_content)
|
||||
separator = site.config['excerpt_separator']
|
||||
head, _, tail = post_content.to_s.partition(separator)
|
||||
head, _, tail = post_content.partition(separator)
|
||||
|
||||
"" << head << "\n\n" << tail.scan(/^\[[^\]]+\]:.+$/).join("\n")
|
||||
end
|
||||
|
||||
@@ -25,39 +25,6 @@ module Jekyll
|
||||
converter.convert(input)
|
||||
end
|
||||
|
||||
# Convert a Sass string into CSS output.
|
||||
#
|
||||
# input - The Sass String to convert.
|
||||
#
|
||||
# Returns the CSS formatted String.
|
||||
def sassify(input)
|
||||
site = @context.registers[:site]
|
||||
converter = site.getConverterImpl(Jekyll::Converters::Sass)
|
||||
converter.convert(input)
|
||||
end
|
||||
|
||||
# Convert a Scss string into CSS output.
|
||||
#
|
||||
# input - The Scss String to convert.
|
||||
#
|
||||
# Returns the CSS formatted String.
|
||||
def scssify(input)
|
||||
site = @context.registers[:site]
|
||||
converter = site.getConverterImpl(Jekyll::Converters::Scss)
|
||||
converter.convert(input)
|
||||
end
|
||||
|
||||
# Slugify a filename or title.
|
||||
#
|
||||
# input - The filename or title to slugify.
|
||||
#
|
||||
# Returns the given filename or title as a lowercase String, with every
|
||||
# sequence of spaces and non-alphanumeric characters replaced with a
|
||||
# hyphen.
|
||||
def slugify(input)
|
||||
Utils.slugify(input)
|
||||
end
|
||||
|
||||
# Format a date in short format e.g. "27 Jan 2011".
|
||||
#
|
||||
# date - the Time to format.
|
||||
@@ -188,7 +155,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the converted json string
|
||||
def jsonify(input)
|
||||
as_liquid(input).to_json
|
||||
input.to_json
|
||||
end
|
||||
|
||||
# Group an array of items by a property
|
||||
@@ -214,13 +181,12 @@ module Jekyll
|
||||
# Filter an array of objects
|
||||
#
|
||||
# input - the object array
|
||||
# property - property within each object to filter by
|
||||
# key - key within each object to filter by
|
||||
# value - desired value
|
||||
#
|
||||
# Returns the filtered array of objects
|
||||
def where(input, property, value)
|
||||
return input unless input.is_a?(Enumerable)
|
||||
input = input.values if input.is_a?(Hash)
|
||||
return input unless input.is_a?(Array)
|
||||
input.select { |object| item_property(object, property) == value }
|
||||
end
|
||||
|
||||
@@ -260,43 +226,6 @@ module Jekyll
|
||||
end
|
||||
end
|
||||
|
||||
def pop(array, input = 1)
|
||||
return array unless array.is_a?(Array)
|
||||
new_ary = array.dup
|
||||
new_ary.pop(input.to_i || 1)
|
||||
new_ary
|
||||
end
|
||||
|
||||
def push(array, input)
|
||||
return array unless array.is_a?(Array)
|
||||
new_ary = array.dup
|
||||
new_ary.push(input)
|
||||
new_ary
|
||||
end
|
||||
|
||||
def shift(array, input = 1)
|
||||
return array unless array.is_a?(Array)
|
||||
new_ary = array.dup
|
||||
new_ary.shift(input.to_i || 1)
|
||||
new_ary
|
||||
end
|
||||
|
||||
def unshift(array, input)
|
||||
return array unless array.is_a?(Array)
|
||||
new_ary = array.dup
|
||||
new_ary.unshift(input)
|
||||
new_ary
|
||||
end
|
||||
|
||||
# Convert an object into its String representation for debugging
|
||||
#
|
||||
# input - The Object to be converted
|
||||
#
|
||||
# Returns a String representation of the object.
|
||||
def inspect(input)
|
||||
CGI.escapeHTML(input.inspect)
|
||||
end
|
||||
|
||||
private
|
||||
def time(input)
|
||||
case input
|
||||
@@ -325,18 +254,5 @@ module Jekyll
|
||||
item[property.to_s]
|
||||
end
|
||||
end
|
||||
|
||||
def as_liquid(item)
|
||||
case item
|
||||
when String, Numeric, nil
|
||||
item.to_liquid
|
||||
when Hash
|
||||
Hash[item.map { |k, v| [as_liquid(k), as_liquid(v)] }]
|
||||
when Array
|
||||
item.map{ |i| as_liquid(i) }
|
||||
else
|
||||
item.respond_to?(:to_liquid) ? as_liquid(item.to_liquid) : item
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,180 +1,148 @@
|
||||
module Jekyll
|
||||
# This class handles custom defaults for YAML frontmatter settings.
|
||||
# These are set in _config.yml and apply both to internal use (e.g. layout)
|
||||
# and the data available to liquid.
|
||||
#
|
||||
# It is exposed via the frontmatter_defaults method on the site class.
|
||||
class FrontmatterDefaults
|
||||
# Initializes a new instance.
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
def update_deprecated_types(set)
|
||||
return set unless set.key?('scope') && set['scope'].key?('type')
|
||||
|
||||
set['scope']['type'] = case set['scope']['type']
|
||||
when 'page'
|
||||
Deprecator.defaults_deprecate_type('page', 'pages')
|
||||
'pages'
|
||||
when 'post'
|
||||
Deprecator.defaults_deprecate_type('post', 'posts')
|
||||
'posts'
|
||||
when 'draft'
|
||||
Deprecator.defaults_deprecate_type('draft', 'drafts')
|
||||
'drafts'
|
||||
else
|
||||
set['scope']['type']
|
||||
class Configuration
|
||||
# This class handles custom defaults for YAML frontmatter settings.
|
||||
# These are set in _config.yml and apply both to internal use (e.g. layout)
|
||||
# and the data available to liquid.
|
||||
#
|
||||
# It is exposed via the frontmatter_defaults method on the site class.
|
||||
class FrontmatterDefaults
|
||||
# Initializes a new instance.
|
||||
def initialize(site)
|
||||
@site = site
|
||||
end
|
||||
|
||||
set
|
||||
end
|
||||
# Finds a default value for a given setting, filtered by path and type
|
||||
#
|
||||
# path - the path (relative to the source) of the page, post or :draft the default is used in
|
||||
# type - a symbol indicating whether a :page, a :post or a :draft calls this method
|
||||
#
|
||||
# Returns the default value or nil if none was found
|
||||
def find(path, type, setting)
|
||||
value = nil
|
||||
old_scope = nil
|
||||
|
||||
# Finds a default value for a given setting, filtered by path and type
|
||||
#
|
||||
# path - the path (relative to the source) of the page, post or :draft the default is used in
|
||||
# type - a symbol indicating whether a :page, a :post or a :draft calls this method
|
||||
#
|
||||
# Returns the default value or nil if none was found
|
||||
def find(path, type, setting)
|
||||
value = nil
|
||||
old_scope = nil
|
||||
matching_sets(path, type).each do |set|
|
||||
if set['values'].has_key?(setting) && has_precedence?(old_scope, set['scope'])
|
||||
value = set['values'][setting]
|
||||
old_scope = set['scope']
|
||||
end
|
||||
end
|
||||
value
|
||||
end
|
||||
|
||||
matching_sets(path, type).each do |set|
|
||||
if set['values'].key?(setting) && has_precedence?(old_scope, set['scope'])
|
||||
value = set['values'][setting]
|
||||
old_scope = set['scope']
|
||||
# Collects a hash with all default values for a page or post
|
||||
#
|
||||
# path - the relative path of the page or post
|
||||
# type - a symbol indicating the type (:post, :page or :draft)
|
||||
#
|
||||
# Returns a hash with all default values (an empty hash if there are none)
|
||||
def all(path, type)
|
||||
defaults = {}
|
||||
old_scope = nil
|
||||
matching_sets(path, type).each do |set|
|
||||
if has_precedence?(old_scope, set['scope'])
|
||||
defaults.merge! set['values']
|
||||
old_scope = set['scope']
|
||||
else
|
||||
defaults = set['values'].merge(defaults)
|
||||
end
|
||||
end
|
||||
defaults
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Checks if a given default setting scope matches the given path and type
|
||||
#
|
||||
# scope - the hash indicating the scope, as defined in _config.yml
|
||||
# path - the path to check for
|
||||
# type - the type (:post, :page or :draft) to check for
|
||||
#
|
||||
# Returns true if the scope applies to the given path and type
|
||||
def applies?(scope, path, type)
|
||||
applies_path?(scope, path) && applies_type?(scope, type)
|
||||
end
|
||||
|
||||
def applies_path?(scope, path)
|
||||
return true if scope['path'].empty?
|
||||
|
||||
scope_path = Pathname.new(scope['path'])
|
||||
Pathname.new(sanitize_path(path)).ascend do |path|
|
||||
if path == scope_path
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
value
|
||||
end
|
||||
|
||||
# Collects a hash with all default values for a page or post
|
||||
#
|
||||
# path - the relative path of the page or post
|
||||
# type - a symbol indicating the type (:post, :page or :draft)
|
||||
#
|
||||
# Returns a hash with all default values (an empty hash if there are none)
|
||||
def all(path, type)
|
||||
defaults = {}
|
||||
old_scope = nil
|
||||
matching_sets(path, type).each do |set|
|
||||
if has_precedence?(old_scope, set['scope'])
|
||||
defaults = Utils.deep_merge_hashes(defaults, set['values'])
|
||||
old_scope = set['scope']
|
||||
def applies_type?(scope, type)
|
||||
!scope.has_key?('type') || scope['type'] == type.to_s
|
||||
end
|
||||
|
||||
# Checks if a given set of default values is valid
|
||||
#
|
||||
# set - the default value hash, as defined in _config.yml
|
||||
#
|
||||
# Returns true if the set is valid and can be used in this class
|
||||
def valid?(set)
|
||||
set.is_a?(Hash) && set['scope'].is_a?(Hash) && set['scope']['path'].is_a?(String) && set['values'].is_a?(Hash)
|
||||
end
|
||||
|
||||
# Determines if a new scope has precedence over an old one
|
||||
#
|
||||
# old_scope - the old scope hash, or nil if there's none
|
||||
# new_scope - the new scope hash
|
||||
#
|
||||
# Returns true if the new scope has precedence over the older
|
||||
def has_precedence?(old_scope, new_scope)
|
||||
return true if old_scope.nil?
|
||||
|
||||
new_path = sanitize_path(new_scope['path'])
|
||||
old_path = sanitize_path(old_scope['path'])
|
||||
|
||||
if new_path.length != old_path.length
|
||||
new_path.length >= old_path.length
|
||||
elsif new_scope.has_key? 'type'
|
||||
true
|
||||
else
|
||||
defaults = Utils.deep_merge_hashes(set['values'], defaults)
|
||||
!old_scope.has_key? 'type'
|
||||
end
|
||||
end
|
||||
defaults
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Checks if a given default setting scope matches the given path and type
|
||||
#
|
||||
# scope - the hash indicating the scope, as defined in _config.yml
|
||||
# path - the path to check for
|
||||
# type - the type (:post, :page or :draft) to check for
|
||||
#
|
||||
# Returns true if the scope applies to the given path and type
|
||||
def applies?(scope, path, type)
|
||||
applies_path?(scope, path) && applies_type?(scope, type)
|
||||
end
|
||||
|
||||
def applies_path?(scope, path)
|
||||
return true if !scope.has_key?('path') || scope['path'].empty?
|
||||
|
||||
scope_path = Pathname.new(scope['path'])
|
||||
Pathname.new(sanitize_path(path)).ascend do |path|
|
||||
if path == scope_path
|
||||
return true
|
||||
# Collects a list of sets that match the given path and type
|
||||
#
|
||||
# Returns an array of hashes
|
||||
def matching_sets(path, type)
|
||||
valid_sets.select do |set|
|
||||
applies?(set['scope'], path, type)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Determines whether the scope applies to type.
|
||||
# The scope applies to the type if:
|
||||
# 1. no 'type' is specified
|
||||
# 2. the 'type' in the scope is the same as the type asked about
|
||||
#
|
||||
# scope - the Hash defaults set being asked about application
|
||||
# type - the type of the document being processed / asked about
|
||||
# its defaults.
|
||||
#
|
||||
# Returns true if either of the above conditions are satisfied,
|
||||
# otherwise returns false
|
||||
def applies_type?(scope, type)
|
||||
!scope.key?('type') || scope['type'].eql?(type.to_s)
|
||||
end
|
||||
# Returns a list of valid sets
|
||||
#
|
||||
# This is not cached to allow plugins to modify the configuration
|
||||
# and have their changes take effect
|
||||
#
|
||||
# Returns an array of hashes
|
||||
def valid_sets
|
||||
sets = @site.config['defaults']
|
||||
return [] unless sets.is_a?(Array)
|
||||
|
||||
# Checks if a given set of default values is valid
|
||||
#
|
||||
# set - the default value hash, as defined in _config.yml
|
||||
#
|
||||
# Returns true if the set is valid and can be used in this class
|
||||
def valid?(set)
|
||||
set.is_a?(Hash) && set['values'].is_a?(Hash)
|
||||
end
|
||||
|
||||
# Determines if a new scope has precedence over an old one
|
||||
#
|
||||
# old_scope - the old scope hash, or nil if there's none
|
||||
# new_scope - the new scope hash
|
||||
#
|
||||
# Returns true if the new scope has precedence over the older
|
||||
def has_precedence?(old_scope, new_scope)
|
||||
return true if old_scope.nil?
|
||||
|
||||
new_path = sanitize_path(new_scope['path'])
|
||||
old_path = sanitize_path(old_scope['path'])
|
||||
|
||||
if new_path.length != old_path.length
|
||||
new_path.length >= old_path.length
|
||||
elsif new_scope.key? 'type'
|
||||
true
|
||||
else
|
||||
!old_scope.key? 'type'
|
||||
sets.select do |set|
|
||||
unless valid?(set)
|
||||
Jekyll.logger.warn "Default:", "An invalid default set was found"
|
||||
end
|
||||
valid?(set)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Collects a list of sets that match the given path and type
|
||||
#
|
||||
# Returns an array of hashes
|
||||
def matching_sets(path, type)
|
||||
valid_sets.select do |set|
|
||||
!set.has_key?('scope') || applies?(set['scope'], path, type)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a list of valid sets
|
||||
#
|
||||
# This is not cached to allow plugins to modify the configuration
|
||||
# and have their changes take effect
|
||||
#
|
||||
# Returns an array of hashes
|
||||
def valid_sets
|
||||
sets = @site.config['defaults']
|
||||
return [] unless sets.is_a?(Array)
|
||||
|
||||
sets.map do |set|
|
||||
if valid?(set)
|
||||
update_deprecated_types(set)
|
||||
# Sanitizes the given path by removing a leading and addding a trailing slash
|
||||
def sanitize_path(path)
|
||||
if path.nil? || path.empty?
|
||||
""
|
||||
else
|
||||
Jekyll.logger.warn "Defaults:", "An invalid front-matter default set was found:"
|
||||
Jekyll.logger.warn "#{set}"
|
||||
nil
|
||||
path.gsub(/\A\//, '').gsub(/([^\/])\z/, '\1/')
|
||||
end
|
||||
end.compact
|
||||
end
|
||||
|
||||
# Sanitizes the given path by removing a leading and addding a trailing slash
|
||||
def sanitize_path(path)
|
||||
if path.nil? || path.empty?
|
||||
""
|
||||
else
|
||||
path.gsub(/\A\//, '').gsub(/([^\/])\z/, '\1/')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
62
lib/jekyll/hooks.rb
Normal file
62
lib/jekyll/hooks.rb
Normal file
@@ -0,0 +1,62 @@
|
||||
module Jekyll
|
||||
module Hooks
|
||||
|
||||
class HookCollection
|
||||
include Enumerable
|
||||
|
||||
def each(&block)
|
||||
if block.nil?
|
||||
hook_methods
|
||||
else
|
||||
hook_methods.each &block
|
||||
end
|
||||
end
|
||||
|
||||
def hook_methods
|
||||
@hook_methods ||= Array.new
|
||||
end
|
||||
|
||||
def add_hook(proc)
|
||||
hook_methods << proc
|
||||
end
|
||||
|
||||
def exec(*args)
|
||||
if args.empty?
|
||||
hook_methods.each { |hook| hook.call }
|
||||
else
|
||||
hook_methods.each do |hook|
|
||||
args.each { |arg| hook.call(arg) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
%w[
|
||||
post_reset
|
||||
pre_read
|
||||
post_read
|
||||
pre_generate
|
||||
post_generate
|
||||
pre_render
|
||||
post_render
|
||||
pre_cleanup
|
||||
post_cleanup
|
||||
pre_write
|
||||
post_write
|
||||
].each do |method|
|
||||
declaration = <<-METH
|
||||
def #{method}(method_name, *args)
|
||||
cr = caller
|
||||
((@hooks ||= Hash.new).fetch(method_name.to_s, HookCollection.new)).add_hook -> { cr.send(method_name.to_sym, args) }
|
||||
end
|
||||
def #{method}_exec(*args)
|
||||
((@hooks ||= Hash.new).fetch(method_name.to_s, HookCollection.new)).exec(*args)
|
||||
end
|
||||
METH
|
||||
puts declaration
|
||||
class_eval declaration
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -38,12 +38,12 @@ module Jekyll
|
||||
end
|
||||
|
||||
def layout_directory_inside_source
|
||||
site.in_source_dir(site.config['layouts'])
|
||||
Jekyll.sanitized_path(site.source, site.config['layouts'])
|
||||
end
|
||||
|
||||
def layout_directory_in_cwd
|
||||
dir = Jekyll.sanitized_path(Dir.pwd, site.config['layouts'])
|
||||
if File.directory?(dir) && !site.safe
|
||||
if File.directory?(dir)
|
||||
dir
|
||||
else
|
||||
nil
|
||||
|
||||
@@ -126,7 +126,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the path to the source file
|
||||
def path
|
||||
data.fetch('path') { relative_path.sub(/\A\//, '') }
|
||||
data.fetch('path', relative_path.sub(/\A\//, ''))
|
||||
end
|
||||
|
||||
# The path to the page source file, relative to the site source
|
||||
@@ -140,7 +140,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the destination file path String.
|
||||
def destination(dest)
|
||||
path = site.in_dest_dir(dest, URL.unescape_path(url))
|
||||
path = Jekyll.sanitized_path(dest, URL.unescape_path(url))
|
||||
path = File.join(path, "index.html") if url =~ /\/$/
|
||||
path
|
||||
end
|
||||
|
||||
@@ -27,7 +27,7 @@ module Jekyll
|
||||
# Returns the Symbol priority.
|
||||
def self.priority(priority = nil)
|
||||
@priority ||= nil
|
||||
if priority && PRIORITIES.key?(priority)
|
||||
if priority && PRIORITIES.has_key?(priority)
|
||||
@priority = priority
|
||||
end
|
||||
@priority || :normal
|
||||
@@ -56,15 +56,6 @@ module Jekyll
|
||||
PRIORITIES[other.priority] <=> PRIORITIES[self.priority]
|
||||
end
|
||||
|
||||
# Spaceship is priority [higher -> lower]
|
||||
#
|
||||
# other - The class to be compared.
|
||||
#
|
||||
# Returns -1, 0, 1.
|
||||
def <=>(other)
|
||||
self.class <=> other.class
|
||||
end
|
||||
|
||||
# Initialize a new plugin. This should be overridden by the subclass.
|
||||
#
|
||||
# config - The Hash of configuration options.
|
||||
|
||||
@@ -17,7 +17,6 @@ module Jekyll
|
||||
def conscientious_require
|
||||
require_plugin_files
|
||||
require_gems
|
||||
self.class.require_from_bundler
|
||||
end
|
||||
|
||||
# Require each of the gem plugins specified.
|
||||
@@ -26,26 +25,11 @@ module Jekyll
|
||||
def require_gems
|
||||
site.gems.each do |gem|
|
||||
if plugin_allowed?(gem)
|
||||
Jekyll.logger.debug("PluginManager:", "Requiring #{gem}")
|
||||
require gem
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.require_from_bundler
|
||||
if ENV["JEKYLL_NO_BUNDLER_REQUIRE"]
|
||||
false
|
||||
else
|
||||
require "bundler"
|
||||
required_gems = Bundler.require(:jekyll_plugins)
|
||||
Jekyll.logger.debug("PluginManager:", "Required #{required_gems.map(&:name).join(', ')}")
|
||||
ENV["JEKYLL_NO_BUNDLER_REQUIRE"] = "true"
|
||||
true
|
||||
end
|
||||
rescue LoadError, Bundler::GemfileNotFound
|
||||
false
|
||||
end
|
||||
|
||||
# Check whether a gem plugin is allowed to be used during this build.
|
||||
#
|
||||
# gem_name - the name of the gem
|
||||
@@ -82,7 +66,7 @@ module Jekyll
|
||||
# Returns an Array of plugin search paths
|
||||
def plugins_path
|
||||
if (site.config['plugins'] == Jekyll::Configuration::DEFAULTS['plugins'])
|
||||
[site.in_source_dir(site.config['plugins'])]
|
||||
[Jekyll.sanitized_path(site.source, site.config['plugins'])]
|
||||
else
|
||||
Array(site.config['plugins']).map { |d| File.expand_path(d) }
|
||||
end
|
||||
|
||||
@@ -49,7 +49,7 @@ module Jekyll
|
||||
def initialize(site, source, dir, name)
|
||||
@site = site
|
||||
@dir = dir
|
||||
@base = containing_dir(dir)
|
||||
@base = containing_dir(source, dir)
|
||||
@name = name
|
||||
|
||||
self.categories = dir.downcase.split('/').reject { |x| x.empty? }
|
||||
@@ -60,8 +60,8 @@ module Jekyll
|
||||
site.frontmatter_defaults.find(File.join(dir, name), type, key)
|
||||
end
|
||||
|
||||
if data.key?('date')
|
||||
self.date = Utils.parse_date(data["date"].to_s, "Post '#{relative_path}' does not have a valid date in the YAML front matter.")
|
||||
if data.has_key?('date')
|
||||
self.date = Time.parse(data["date"].to_s)
|
||||
end
|
||||
|
||||
populate_categories
|
||||
@@ -69,7 +69,7 @@ module Jekyll
|
||||
end
|
||||
|
||||
def published?
|
||||
if data.key?('published') && data['published'] == false
|
||||
if data.has_key?('published') && data['published'] == false
|
||||
false
|
||||
else
|
||||
true
|
||||
@@ -78,9 +78,8 @@ module Jekyll
|
||||
|
||||
def populate_categories
|
||||
categories_from_data = Utils.pluralized_array_from_hash(data, 'category', 'categories')
|
||||
self.categories = (
|
||||
Array(categories) + categories_from_data
|
||||
).map {|c| c.to_s.downcase}.flatten.uniq
|
||||
self.categories = (Array(categories) + categories_from_data).map {|c| c.to_s.downcase}
|
||||
categories.flatten!
|
||||
end
|
||||
|
||||
def populate_tags
|
||||
@@ -88,8 +87,8 @@ module Jekyll
|
||||
end
|
||||
|
||||
# Get the full path to the directory containing the post files
|
||||
def containing_dir(dir)
|
||||
site.in_source_dir(dir, '_posts')
|
||||
def containing_dir(source, dir)
|
||||
return File.join(source, dir, '_posts')
|
||||
end
|
||||
|
||||
# Read the YAML frontmatter.
|
||||
@@ -108,14 +107,14 @@ module Jekyll
|
||||
#
|
||||
# Returns excerpt string.
|
||||
def excerpt
|
||||
data.fetch('excerpt') { extracted_excerpt.to_s }
|
||||
data.fetch('excerpt', extracted_excerpt.to_s)
|
||||
end
|
||||
|
||||
# Public: the Post title, from the YAML Front-Matter or from the slug
|
||||
#
|
||||
# Returns the post title
|
||||
def title
|
||||
data.fetch('title') { titleized_slug }
|
||||
data.fetch("title", titleized_slug)
|
||||
end
|
||||
|
||||
# Turns the post slug into a suitable title
|
||||
@@ -130,7 +129,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the path to the file relative to the site source
|
||||
def path
|
||||
data.fetch('path') { relative_path.sub(/\A\//, '') }
|
||||
data.fetch('path', relative_path.sub(/\A\//, ''))
|
||||
end
|
||||
|
||||
# The path to the post source file, relative to the site source
|
||||
@@ -159,9 +158,14 @@ module Jekyll
|
||||
# Returns nothing.
|
||||
def process(name)
|
||||
m, cats, date, slug, ext = *name.match(MATCHER)
|
||||
self.date = Utils.parse_date(date, "Post '#{relative_path}' does not have a valid date in the filename.")
|
||||
self.date = Time.parse(date)
|
||||
self.slug = slug
|
||||
self.ext = ext
|
||||
rescue ArgumentError
|
||||
path = File.join(@dir || "", name)
|
||||
msg = "Post '#{path}' does not have a valid date.\n"
|
||||
msg << "Fix the date, or exclude the file or directory from being processed"
|
||||
raise FatalException.new(msg)
|
||||
end
|
||||
|
||||
# The generated directory into which the post will be placed
|
||||
@@ -216,8 +220,8 @@ module Jekyll
|
||||
:month => date.strftime("%m"),
|
||||
:day => date.strftime("%d"),
|
||||
:title => slug,
|
||||
:i_day => date.strftime("%-d"),
|
||||
:i_month => date.strftime("%-m"),
|
||||
:i_day => date.strftime("%d").to_i.to_s,
|
||||
:i_month => date.strftime("%m").to_i.to_s,
|
||||
:categories => (categories || []).map { |c| c.to_s }.join('/'),
|
||||
:short_month => date.strftime("%b"),
|
||||
:short_year => date.strftime("%y"),
|
||||
@@ -268,8 +272,8 @@ module Jekyll
|
||||
# Returns destination file path String.
|
||||
def destination(dest)
|
||||
# The url needs to be unescaped in order to preserve the correct filename
|
||||
path = site.in_dest_dir(dest, URL.unescape_path(url))
|
||||
path = File.join(path, "index.html") if path[/\.html?$/].nil?
|
||||
path = Jekyll.sanitized_path(dest, URL.unescape_path(url))
|
||||
path = File.join(path, "index.html") if path[/\.html$/].nil?
|
||||
path
|
||||
end
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ module Jekyll
|
||||
def initialize(post)
|
||||
@post = post
|
||||
@site = post.site
|
||||
require 'classifier-reborn' if site.lsi
|
||||
require 'classifier' if site.lsi
|
||||
end
|
||||
|
||||
def build
|
||||
@@ -27,7 +27,7 @@ module Jekyll
|
||||
|
||||
def build_index
|
||||
self.class.lsi ||= begin
|
||||
lsi = ClassifierReborn::LSI.new(:auto_rebuild => false)
|
||||
lsi = Classifier::LSI.new(:auto_rebuild => false)
|
||||
display("Populating LSI...")
|
||||
|
||||
site.posts.each do |x|
|
||||
@@ -46,7 +46,8 @@ module Jekyll
|
||||
end
|
||||
|
||||
def most_recent_posts
|
||||
@most_recent_posts ||= (site.posts.reverse - [post]).first(10)
|
||||
recent_posts = site.posts.reverse - [post]
|
||||
recent_posts.first(10)
|
||||
end
|
||||
|
||||
def display(output)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
module Jekyll
|
||||
class Renderer
|
||||
|
||||
@@ -49,17 +47,14 @@ module Jekyll
|
||||
output = render_liquid(output, payload, info)
|
||||
end
|
||||
|
||||
output = convert(output)
|
||||
document.content = output
|
||||
|
||||
if document.place_in_layout?
|
||||
place_in_layouts(
|
||||
output,
|
||||
convert(output),
|
||||
payload,
|
||||
info
|
||||
)
|
||||
else
|
||||
output
|
||||
convert(output)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -97,15 +92,6 @@ module Jekyll
|
||||
raise e
|
||||
end
|
||||
|
||||
# Checks if the layout specified in the document actually exists
|
||||
#
|
||||
# layout - the layout to check
|
||||
#
|
||||
# Returns true if the layout is invalid, false if otherwise
|
||||
def invalid_layout?(layout)
|
||||
!document.data["layout"].nil? && layout.nil?
|
||||
end
|
||||
|
||||
# Render layouts and place given content inside.
|
||||
#
|
||||
# content - the content to be placed in the layout
|
||||
@@ -115,9 +101,6 @@ module Jekyll
|
||||
def place_in_layouts(content, payload, info)
|
||||
output = content.dup
|
||||
layout = site.layouts[document.data["layout"]]
|
||||
|
||||
Jekyll.logger.warn("Build Warning:", "Layout '#{document.data["layout"]}' requested in #{document.relative_path} does not exist.") if invalid_layout? layout
|
||||
|
||||
used = Set.new([layout])
|
||||
|
||||
while layout
|
||||
|
||||
@@ -1,31 +1,29 @@
|
||||
# encoding: UTF-8
|
||||
require 'csv'
|
||||
|
||||
module Jekyll
|
||||
class Site
|
||||
attr_reader :source, :dest, :config
|
||||
attr_accessor :layouts, :posts, :pages, :static_files,
|
||||
:exclude, :include, :lsi, :highlighter, :permalink_style,
|
||||
:time, :future, :unpublished, :safe, :plugins, :limit_posts,
|
||||
:show_drafts, :keep_files, :baseurl, :data, :file_read_opts,
|
||||
:gems, :plugin_manager
|
||||
attr_accessor :config, :layouts, :posts, :pages, :static_files,
|
||||
:exclude, :include, :source, :dest, :lsi, :highlighter,
|
||||
:permalink_style, :time, :future, :unpublished, :safe, :plugins, :limit_posts,
|
||||
:show_drafts, :keep_files, :baseurl, :data, :file_read_opts, :gems,
|
||||
:plugin_manager
|
||||
|
||||
attr_accessor :converters, :generators
|
||||
|
||||
include Jekyll::Hooks
|
||||
|
||||
# Public: Initialize a new Site.
|
||||
#
|
||||
# config - A Hash containing site configuration details.
|
||||
def initialize(config)
|
||||
@config = config.clone
|
||||
self.config = config.clone
|
||||
|
||||
%w[safe lsi highlighter baseurl exclude include future unpublished
|
||||
show_drafts limit_posts keep_files gems].each do |opt|
|
||||
self.send("#{opt}=", config[opt])
|
||||
end
|
||||
|
||||
# Source and destination may not be changed after the site has been created.
|
||||
@source = File.expand_path(config['source']).freeze
|
||||
@dest = File.expand_path(config['destination']).freeze
|
||||
self.source = File.expand_path(config['source'])
|
||||
self.dest = File.expand_path(config['destination'])
|
||||
self.permalink_style = config['permalink'].to_sym
|
||||
|
||||
self.plugin_manager = Jekyll::PluginManager.new(self)
|
||||
self.plugins = plugin_manager.plugins_path
|
||||
@@ -33,10 +31,6 @@ module Jekyll
|
||||
self.file_read_opts = {}
|
||||
self.file_read_opts[:encoding] = config['encoding'] if config['encoding']
|
||||
|
||||
self.permalink_style = config['permalink'].to_sym
|
||||
|
||||
Jekyll.sites << self
|
||||
|
||||
reset
|
||||
setup
|
||||
end
|
||||
@@ -57,7 +51,7 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing
|
||||
def reset
|
||||
self.time = (config['time'] ? Utils.parse_date(config['time'].to_s, "Invalid time in _config.yml.") : Time.now)
|
||||
self.time = (config['time'] ? Time.parse(config['time'].to_s) : Time.now)
|
||||
self.layouts = {}
|
||||
self.posts = []
|
||||
self.pages = []
|
||||
@@ -88,35 +82,11 @@ module Jekyll
|
||||
dest_pathname = Pathname.new(dest)
|
||||
Pathname.new(source).ascend do |path|
|
||||
if path == dest_pathname
|
||||
raise Errors::FatalException.new "Destination directory cannot be or contain the Source directory."
|
||||
raise FatalException.new "Destination directory cannot be or contain the Source directory."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Prefix a given path with the source directory.
|
||||
#
|
||||
# paths - (optional) path elements to a file or directory within the
|
||||
# source directory
|
||||
#
|
||||
# Returns a path which is prefixed with the source directory.
|
||||
def in_source_dir(*paths)
|
||||
paths.reduce(source) do |base, path|
|
||||
Jekyll.sanitized_path(base, path)
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Prefix a given path with the destination directory.
|
||||
#
|
||||
# paths - (optional) path elements to a file or directory within the
|
||||
# destination directory
|
||||
#
|
||||
# Returns a path which is prefixed with the destination directory.
|
||||
def in_dest_dir(*paths)
|
||||
paths.reduce(dest) do |base, path|
|
||||
Jekyll.sanitized_path(base, path)
|
||||
end
|
||||
end
|
||||
|
||||
# The list of collections and their corresponding Jekyll::Collection instances.
|
||||
# If config['collections'] is set, a new instance is created for each item in the collection.
|
||||
# If config['collections'] is not set, a new hash is returned.
|
||||
@@ -161,7 +131,7 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing.
|
||||
def read_directories(dir = '')
|
||||
base = in_source_dir(dir)
|
||||
base = File.join(source, dir)
|
||||
entries = Dir.chdir(base) { filter_entries(Dir.entries('.'), base) }
|
||||
|
||||
read_posts(dir)
|
||||
@@ -170,11 +140,11 @@ module Jekyll
|
||||
limit_posts! if limit_posts > 0 # limit the posts if :limit_posts option is set
|
||||
|
||||
entries.each do |f|
|
||||
f_abs = in_source_dir(base, f)
|
||||
f_abs = File.join(base, f)
|
||||
if File.directory?(f_abs)
|
||||
f_rel = File.join(dir, f)
|
||||
read_directories(f_rel) unless dest.sub(/\/$/, '') == f_abs
|
||||
elsif Utils.has_yaml_header?(f_abs)
|
||||
elsif has_yaml_header?(f_abs)
|
||||
page = Page.new(self, source, dir, f)
|
||||
pages << page if publisher.publish?(page)
|
||||
else
|
||||
@@ -227,7 +197,7 @@ module Jekyll
|
||||
#
|
||||
# Returns nothing
|
||||
def read_data(dir)
|
||||
base = in_source_dir(dir)
|
||||
base = File.join(source, dir)
|
||||
read_data_to(base, self.data)
|
||||
end
|
||||
|
||||
@@ -242,23 +212,18 @@ module Jekyll
|
||||
return unless File.directory?(dir) && (!safe || !File.symlink?(dir))
|
||||
|
||||
entries = Dir.chdir(dir) do
|
||||
Dir['*.{yaml,yml,json,csv}'] + Dir['*'].select { |fn| File.directory?(fn) }
|
||||
Dir['*.{yaml,yml,json}'] + Dir['*'].select { |fn| File.directory?(fn) }
|
||||
end
|
||||
|
||||
entries.each do |entry|
|
||||
path = in_source_dir(dir, entry)
|
||||
path = File.join(dir, entry)
|
||||
next if File.symlink?(path) && safe
|
||||
|
||||
key = sanitize_filename(File.basename(entry, '.*'))
|
||||
if File.directory?(path)
|
||||
read_data_to(path, data[key] = {})
|
||||
else
|
||||
case File.extname(path).downcase
|
||||
when '.csv'
|
||||
data[key] = CSV.read(path, :headers => true).map(&:to_hash)
|
||||
else
|
||||
data[key] = SafeYAML.load_file(path)
|
||||
end
|
||||
data[key] = SafeYAML.load_file(path)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -436,10 +401,10 @@ module Jekyll
|
||||
#
|
||||
# Returns the list of entries to process
|
||||
def get_entries(dir, subfolder)
|
||||
base = in_source_dir(dir, subfolder)
|
||||
base = File.join(source, dir, subfolder)
|
||||
return [] unless File.exist?(base)
|
||||
entries = Dir.chdir(base) { filter_entries(Dir['**/*'], base) }
|
||||
entries.delete_if { |e| File.directory?(in_source_dir(base, e)) }
|
||||
entries.delete_if { |e| File.directory?(File.join(base, e)) }
|
||||
end
|
||||
|
||||
# Aggregate post information
|
||||
@@ -467,7 +432,7 @@ module Jekyll
|
||||
|
||||
def documents
|
||||
collections.reduce(Set.new) do |docs, (_, collection)|
|
||||
docs + collection.docs + collection.files
|
||||
docs.merge(collection.docs)
|
||||
end.to_a
|
||||
end
|
||||
|
||||
@@ -480,7 +445,7 @@ module Jekyll
|
||||
end
|
||||
|
||||
def frontmatter_defaults
|
||||
@frontmatter_defaults ||= FrontmatterDefaults.new(self)
|
||||
@frontmatter_defaults ||= Configuration::FrontmatterDefaults.new(self)
|
||||
end
|
||||
|
||||
private
|
||||
@@ -489,6 +454,10 @@ module Jekyll
|
||||
pages.any? { |page| page.uses_relative_permalinks }
|
||||
end
|
||||
|
||||
def has_yaml_header?(file)
|
||||
!!(File.open(file, 'rb') { |f| f.read(5) } =~ /\A---\r?\n/)
|
||||
end
|
||||
|
||||
def limit_posts!
|
||||
limit = posts.length < limit_posts ? posts.length : limit_posts
|
||||
self.posts = posts[-limit, limit]
|
||||
|
||||
@@ -9,12 +9,11 @@ module Jekyll
|
||||
# base - The String path to the <source>.
|
||||
# dir - The String path between <source> and the file.
|
||||
# name - The String filename of the file.
|
||||
def initialize(site, base, dir, name, collection = nil)
|
||||
def initialize(site, base, dir, name)
|
||||
@site = site
|
||||
@base = base
|
||||
@dir = dir
|
||||
@name = name
|
||||
@collection = collection
|
||||
end
|
||||
|
||||
# Returns source file path.
|
||||
@@ -24,11 +23,7 @@ module Jekyll
|
||||
|
||||
# Returns the source file path relative to the site source
|
||||
def relative_path
|
||||
@relative_path ||= File.join(*[@dir, @name].compact)
|
||||
end
|
||||
|
||||
def extname
|
||||
File.extname(path)
|
||||
@relative_path ||= path.sub(/\A#{@site.source}/, '')
|
||||
end
|
||||
|
||||
# Obtain destination path.
|
||||
@@ -37,15 +32,7 @@ module Jekyll
|
||||
#
|
||||
# Returns destination file path.
|
||||
def destination(dest)
|
||||
@site.in_dest_dir(*[dest, destination_rel_dir, @name].compact)
|
||||
end
|
||||
|
||||
def destination_rel_dir
|
||||
if @collection
|
||||
@dir.gsub(/\A_/, '')
|
||||
else
|
||||
@dir
|
||||
end
|
||||
File.join(*[dest, @dir, @name].compact)
|
||||
end
|
||||
|
||||
# Returns last modification time for this file.
|
||||
@@ -60,13 +47,6 @@ module Jekyll
|
||||
@@mtimes[path] != mtime
|
||||
end
|
||||
|
||||
# Whether to write the file to the filesystem
|
||||
#
|
||||
# Returns true.
|
||||
def write?
|
||||
true
|
||||
end
|
||||
|
||||
# Write the static file to the destination directory (if modified).
|
||||
#
|
||||
# dest - The String path to the destination dir.
|
||||
@@ -95,7 +75,7 @@ module Jekyll
|
||||
|
||||
def to_liquid
|
||||
{
|
||||
"path" => File.join("", relative_path),
|
||||
"path" => relative_path,
|
||||
"modified_time" => mtime.to_s,
|
||||
"extname" => File.extname(relative_path)
|
||||
}
|
||||
|
||||
@@ -4,11 +4,9 @@ module Jekyll
|
||||
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 three
|
||||
# forms: name, name=value, or name="<quoted list>"
|
||||
#
|
||||
# <quoted list> is a space-separated list of numbers
|
||||
SYNTAX = /^([a-zA-Z0-9.+#-]+)((\s+\w+(=(\w+|"([0-9]+\s)*[0-9]+"))?)*)$/
|
||||
# Follow that by zero or more space separated options that take one of two
|
||||
# forms: name or name=value
|
||||
SYNTAX = /^([a-zA-Z0-9.+#-]+)((\s+\w+(=\w+)?)*)$/
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
@@ -16,14 +14,8 @@ module Jekyll
|
||||
@lang = $1.downcase
|
||||
@options = {}
|
||||
if defined?($2) && $2 != ''
|
||||
# Split along 3 possible forms -- key="<quoted list>", key=value, or key
|
||||
$2.scan(/(?:\w="[^"]*"|\w=\w|\w)+/) do |opt|
|
||||
$2.split.each do |opt|
|
||||
key, value = opt.split('=')
|
||||
# If a quoted list, convert to array
|
||||
if value && value.include?("\"")
|
||||
value.gsub!(/"/, "")
|
||||
value = value.split
|
||||
end
|
||||
@options[key.to_sym] = value || true
|
||||
end
|
||||
end
|
||||
@@ -44,11 +36,9 @@ eos
|
||||
suffix = context["highlighter_suffix"] || ""
|
||||
code = super.to_s.strip
|
||||
|
||||
is_safe = !!context.registers[:site].safe
|
||||
|
||||
output = case context.registers[:site].highlighter
|
||||
when 'pygments'
|
||||
render_pygments(code, is_safe)
|
||||
render_pygments(code)
|
||||
when 'rouge'
|
||||
render_rouge(code)
|
||||
else
|
||||
@@ -59,30 +49,11 @@ eos
|
||||
prefix + rendered_output + suffix
|
||||
end
|
||||
|
||||
def sanitized_opts(opts, is_safe)
|
||||
if is_safe
|
||||
Hash[[
|
||||
[:startinline, opts.fetch(:startinline, nil)],
|
||||
[:hl_linenos, opts.fetch(:hl_linenos, nil)],
|
||||
[:linenos, opts.fetch(:linenos, nil)],
|
||||
[:encoding, opts.fetch(:encoding, 'utf-8')],
|
||||
[:cssclass, opts.fetch(:cssclass, nil)]
|
||||
].reject {|f| f.last.nil? }]
|
||||
else
|
||||
opts
|
||||
end
|
||||
end
|
||||
|
||||
def render_pygments(code, is_safe)
|
||||
def render_pygments(code)
|
||||
require 'pygments'
|
||||
|
||||
@options[:encoding] = 'utf-8'
|
||||
|
||||
highlighted_code = Pygments.highlight(
|
||||
code,
|
||||
:lexer => @lang,
|
||||
:options => sanitized_opts(@options, is_safe)
|
||||
)
|
||||
highlighted_code = Pygments.highlight(code, :lexer => @lang, :options => @options)
|
||||
|
||||
if highlighted_code.nil?
|
||||
Jekyll.logger.error "There was an error highlighting your code:"
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
module Jekyll
|
||||
module Tags
|
||||
class IncludeTagError < StandardError
|
||||
@@ -13,14 +11,15 @@ module Jekyll
|
||||
|
||||
class IncludeTag < Liquid::Tag
|
||||
|
||||
attr_reader :includes_dir
|
||||
SYNTAX_EXAMPLE = "{% include file.ext param='value' param2='value' %}"
|
||||
|
||||
VALID_SYNTAX = /([\w-]+)\s*=\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))/
|
||||
VARIABLE_SYNTAX = /(?<variable>[^{]*\{\{\s*(?<name>[\w\-\.]+)\s*(\|.*)?\}\}[^\s}]*)(?<params>.*)/
|
||||
VARIABLE_SYNTAX = /(?<variable>\{\{\s*(?<name>[\w\-\.]+)\s*(\|.*)?\}\})(?<params>.*)/
|
||||
|
||||
INCLUDES_DIR = '_includes'
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
@includes_dir = tag_includes_dir
|
||||
matched = markup.strip.match(VARIABLE_SYNTAX)
|
||||
if matched
|
||||
@file = matched['variable'].strip
|
||||
@@ -29,11 +28,6 @@ module Jekyll
|
||||
@file, @params = markup.strip.split(' ', 2);
|
||||
end
|
||||
validate_params if @params
|
||||
@tag_name = tag_name
|
||||
end
|
||||
|
||||
def syntax_example
|
||||
"{% #{@tag_name} file.ext param='value' param2='value' %}"
|
||||
end
|
||||
|
||||
def parse_params(context)
|
||||
@@ -65,7 +59,7 @@ Invalid syntax for include tag. File contains invalid characters or sequences:
|
||||
|
||||
Valid syntax:
|
||||
|
||||
#{syntax_example}
|
||||
#{SYNTAX_EXAMPLE}
|
||||
|
||||
eos
|
||||
end
|
||||
@@ -81,7 +75,7 @@ Invalid syntax for include tag:
|
||||
|
||||
Valid syntax:
|
||||
|
||||
#{syntax_example}
|
||||
#{SYNTAX_EXAMPLE}
|
||||
|
||||
eos
|
||||
end
|
||||
@@ -100,12 +94,8 @@ eos
|
||||
end
|
||||
end
|
||||
|
||||
def tag_includes_dir
|
||||
'_includes'
|
||||
end
|
||||
|
||||
def render(context)
|
||||
dir = resolved_includes_dir(context)
|
||||
dir = File.join(File.realpath(context.registers[:site].source), INCLUDES_DIR)
|
||||
|
||||
file = render_variable(context) || @file
|
||||
validate_file_name(file)
|
||||
@@ -121,14 +111,10 @@ eos
|
||||
partial.render!(context)
|
||||
end
|
||||
rescue => e
|
||||
raise IncludeTagError.new e.message, File.join(@includes_dir, @file)
|
||||
raise IncludeTagError.new e.message, File.join(INCLUDES_DIR, @file)
|
||||
end
|
||||
end
|
||||
|
||||
def resolved_includes_dir(context)
|
||||
File.join(File.realpath(context.registers[:site].source), @includes_dir)
|
||||
end
|
||||
|
||||
def validate_path(path, dir, safe)
|
||||
if safe && !realpath_prefixed_with?(path, dir)
|
||||
raise IOError.new "The included file '#{path}' should exist and should not be a symlink"
|
||||
@@ -138,34 +124,23 @@ eos
|
||||
end
|
||||
|
||||
def path_relative_to_source(dir, path)
|
||||
File.join(@includes_dir, path.sub(Regexp.new("^#{dir}"), ""))
|
||||
File.join(INCLUDES_DIR, path.sub(Regexp.new("^#{dir}"), ""))
|
||||
end
|
||||
|
||||
def realpath_prefixed_with?(path, dir)
|
||||
File.exist?(path) && File.realpath(path).start_with?(dir)
|
||||
end
|
||||
|
||||
def blank?
|
||||
false
|
||||
end
|
||||
|
||||
# This method allows to modify the file content by inheriting from the class.
|
||||
def source(file, context)
|
||||
File.read(file, file_read_opts(context))
|
||||
end
|
||||
end
|
||||
|
||||
class IncludeRelativeTag < IncludeTag
|
||||
def tag_includes_dir
|
||||
'.'
|
||||
end
|
||||
|
||||
def page_path(context)
|
||||
context.registers[:page].nil? ? includes_dir : File.dirname(context.registers[:page]["path"])
|
||||
end
|
||||
|
||||
def resolved_includes_dir(context)
|
||||
context.registers[:site].in_source_dir(page_path(context))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Liquid::Template.register_tag('include', Jekyll::Tags::IncludeTag)
|
||||
Liquid::Template.register_tag('include_relative', Jekyll::Tags::IncludeRelativeTag)
|
||||
|
||||
@@ -7,9 +7,9 @@ module Jekyll
|
||||
|
||||
def initialize(name)
|
||||
all, path, date, slug = *name.sub(/^\//, "").match(MATCHER)
|
||||
raise ArgumentError.new("'#{name}' does not contain valid date and/or title.") unless all
|
||||
raise ArgumentError.new("'#{name}' does not contain valid date and/or title") unless all
|
||||
@slug = path ? path + slug : slug
|
||||
@date = Utils.parse_date(date, "'#{name}' does not contain valid date.")
|
||||
@date = Time.parse(date)
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
|
||||
@@ -37,46 +37,33 @@ module Jekyll
|
||||
#
|
||||
# Returns the String URL
|
||||
def to_s
|
||||
sanitize_url(generated_permalink || generated_url)
|
||||
end
|
||||
|
||||
# Generates a URL from the permalink
|
||||
#
|
||||
# Returns the _unsanitized String URL
|
||||
def generated_permalink
|
||||
(@generated_permlink ||= generate_url(@permalink)) if @permalink
|
||||
end
|
||||
|
||||
# Generates a URL from the template
|
||||
#
|
||||
# Returns the _unsanitized String URL
|
||||
def generated_url
|
||||
@generated_url ||= generate_url(@template)
|
||||
sanitize_url(@permalink || generate_url)
|
||||
end
|
||||
|
||||
# Internal: Generate the URL by replacing all placeholders with their
|
||||
# respective values in the given template
|
||||
# respective values
|
||||
#
|
||||
# Returns the _unsanitizied_ String URL
|
||||
def generate_url(template)
|
||||
@placeholders.inject(template) do |result, token|
|
||||
break result if result.index(':').nil?
|
||||
def generate_url
|
||||
@placeholders.inject(@template) do |result, token|
|
||||
result.gsub(/:#{token.first}/, self.class.escape_path(token.last))
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a sanitized String URL
|
||||
def sanitize_url(in_url)
|
||||
url = in_url \
|
||||
# Remove all double slashes
|
||||
.gsub(/\/\//, '/') \
|
||||
# Remove every URL segment that consists solely of dots
|
||||
.split('/').reject{ |part| part =~ /^\.+$/ }.join('/') \
|
||||
# Always add a leading slash
|
||||
.gsub(/\A([^\/])/, '/\1')
|
||||
|
||||
# Remove all double slashes
|
||||
url = in_url.gsub(/\/\//, "/")
|
||||
|
||||
# Remove every URL segment that consists solely of dots
|
||||
url = url.split('/').reject{ |part| part =~ /^\.+$/ }.join('/')
|
||||
|
||||
# Append a trailing slash to the URL if the unsanitized URL had one
|
||||
url << "/" if in_url[-1].eql?('/')
|
||||
url += "/" if in_url =~ /\/$/
|
||||
|
||||
# Always add a leading slash
|
||||
url.gsub!(/\A([^\/])/, '/\1')
|
||||
|
||||
url
|
||||
end
|
||||
@@ -92,7 +79,7 @@ module Jekyll
|
||||
#
|
||||
# Returns the escaped path.
|
||||
def self.escape_path(path)
|
||||
# Because URI.escape doesn't escape '?', '[' and ']' by default,
|
||||
# Because URI.escape doesn't escape '?', '[' and ']' by defaut,
|
||||
# specify unsafe string (except unreserved, sub-delims, ":", "@" and "/").
|
||||
#
|
||||
# URI path segment is defined in RFC 3986 as follows:
|
||||
|
||||
@@ -1,125 +1,87 @@
|
||||
module Jekyll
|
||||
module Utils
|
||||
extend self
|
||||
class << self
|
||||
|
||||
# Merges a master hash with another hash, recursively.
|
||||
#
|
||||
# master_hash - the "parent" hash whose values will be overridden
|
||||
# other_hash - the other hash whose values will be persisted after the merge
|
||||
#
|
||||
# This code was lovingly stolen from some random gem:
|
||||
# http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
|
||||
#
|
||||
# Thanks to whoever made it.
|
||||
def deep_merge_hashes(master_hash, other_hash)
|
||||
target = master_hash.dup
|
||||
# Merges a master hash with another hash, recursively.
|
||||
#
|
||||
# master_hash - the "parent" hash whose values will be overridden
|
||||
# other_hash - the other hash whose values will be persisted after the merge
|
||||
#
|
||||
# This code was lovingly stolen from some random gem:
|
||||
# http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
|
||||
#
|
||||
# Thanks to whoever made it.
|
||||
def deep_merge_hashes(master_hash, other_hash)
|
||||
target = master_hash.dup
|
||||
|
||||
other_hash.each_key do |key|
|
||||
if other_hash[key].is_a? Hash and target[key].is_a? Hash
|
||||
target[key] = Utils.deep_merge_hashes(target[key], other_hash[key])
|
||||
next
|
||||
other_hash.keys.each do |key|
|
||||
if other_hash[key].is_a? Hash and target[key].is_a? Hash
|
||||
target[key] = Utils.deep_merge_hashes(target[key], other_hash[key])
|
||||
next
|
||||
end
|
||||
|
||||
target[key] = other_hash[key]
|
||||
end
|
||||
|
||||
target[key] = other_hash[key]
|
||||
target
|
||||
end
|
||||
|
||||
target
|
||||
end
|
||||
|
||||
# Read array from the supplied hash favouring the singular key
|
||||
# and then the plural key, and handling any nil entries.
|
||||
#
|
||||
# hash - the hash to read from
|
||||
# singular_key - the singular key
|
||||
# plural_key - the plural key
|
||||
#
|
||||
# Returns an array
|
||||
def pluralized_array_from_hash(hash, singular_key, plural_key)
|
||||
[].tap do |array|
|
||||
array << (value_from_singular_key(hash, singular_key) || value_from_plural_key(hash, plural_key))
|
||||
end.flatten.compact
|
||||
end
|
||||
|
||||
def value_from_singular_key(hash, key)
|
||||
hash[key] if (hash.key?(key) || (hash.default_proc && hash[key]))
|
||||
end
|
||||
|
||||
def value_from_plural_key(hash, key)
|
||||
if hash.key?(key) || (hash.default_proc && hash[key])
|
||||
val = hash[key]
|
||||
case val
|
||||
when String
|
||||
val.split
|
||||
when Array
|
||||
val.compact
|
||||
# Read array from the supplied hash favouring the singular key
|
||||
# and then the plural key, and handling any nil entries.
|
||||
#
|
||||
# hash - the hash to read from
|
||||
# singular_key - the singular key
|
||||
# plural_key - the plural key
|
||||
#
|
||||
# Returns an array
|
||||
def pluralized_array_from_hash(hash, singular_key, plural_key)
|
||||
[].tap do |array|
|
||||
array << (value_from_singular_key(hash, singular_key) || value_from_plural_key(hash, plural_key))
|
||||
end.flatten.compact
|
||||
end
|
||||
|
||||
def value_from_singular_key(hash, key)
|
||||
hash[key] if (hash.has_key?(key) || (hash.default_proc && hash[key]))
|
||||
end
|
||||
|
||||
def value_from_plural_key(hash, key)
|
||||
if hash.has_key?(key) || (hash.default_proc && hash[key])
|
||||
val = hash[key]
|
||||
case val
|
||||
when String
|
||||
val.split
|
||||
when Array
|
||||
val.compact
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def transform_keys(hash)
|
||||
result = {}
|
||||
hash.each_key do |key|
|
||||
result[yield(key)] = hash[key]
|
||||
def transform_keys(hash)
|
||||
result = {}
|
||||
hash.each_key do |key|
|
||||
result[yield(key)] = hash[key]
|
||||
end
|
||||
result
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
# Apply #to_sym to all keys in the hash
|
||||
#
|
||||
# hash - the hash to which to apply this transformation
|
||||
#
|
||||
# Returns a new hash with symbolized keys
|
||||
def symbolize_hash_keys(hash)
|
||||
transform_keys(hash) { |key| key.to_sym rescue key }
|
||||
end
|
||||
|
||||
# Apply #to_s to all keys in the Hash
|
||||
#
|
||||
# hash - the hash to which to apply this transformation
|
||||
#
|
||||
# Returns a new hash with stringified keys
|
||||
def stringify_hash_keys(hash)
|
||||
transform_keys(hash) { |key| key.to_s rescue key }
|
||||
end
|
||||
|
||||
# Parse a date/time and throw an error if invalid
|
||||
#
|
||||
# input - the date/time to parse
|
||||
# msg - (optional) the error message to show the user
|
||||
#
|
||||
# Returns the parsed date if successful, throws a FatalException
|
||||
# if not
|
||||
def parse_date(input, msg = "Input could not be parsed.")
|
||||
Time.parse(input)
|
||||
rescue ArgumentError
|
||||
raise Errors::FatalException.new("Invalid date '#{input}': " + msg)
|
||||
end
|
||||
|
||||
# Determines whether a given file has
|
||||
#
|
||||
# Returns true if the YAML front matter is present.
|
||||
def has_yaml_header?(file)
|
||||
!!(File.open(file, 'rb') { |f| f.read(5) } =~ /\A---\r?\n/)
|
||||
end
|
||||
|
||||
# Slugify a filename or title.
|
||||
#
|
||||
# name - the filename or title to slugify
|
||||
#
|
||||
# Returns the given filename or title in lowercase, with every
|
||||
# sequence of spaces and non-alphanumeric characters replaced with a
|
||||
# hyphen.
|
||||
def slugify(string)
|
||||
unless string.nil?
|
||||
string \
|
||||
# Replace each non-alphanumeric character sequence with a hyphen
|
||||
.gsub(/[^a-z0-9]+/i, '-') \
|
||||
# Remove leading/trailing hyphen
|
||||
.gsub(/^\-|\-$/i, '') \
|
||||
# Downcase it
|
||||
.downcase
|
||||
# Apply #to_sym to all keys in the hash
|
||||
#
|
||||
# hash - the hash to which to apply this transformation
|
||||
#
|
||||
# Returns a new hash with symbolized keys
|
||||
def symbolize_hash_keys(hash)
|
||||
transform_keys(hash) { |key| key.to_sym rescue key }
|
||||
end
|
||||
end
|
||||
|
||||
# Apply #to_s to all keys in the Hash
|
||||
#
|
||||
# hash - the hash to which to apply this transformation
|
||||
#
|
||||
# Returns a new hash with stringified keys
|
||||
def stringify_hash_keys(hash)
|
||||
transform_keys(hash) { |key| key.to_s rescue key }
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
module Jekyll
|
||||
VERSION = '2.5.1'
|
||||
VERSION = '2.0.3'
|
||||
end
|
||||
|
||||
3
lib/site_template/.gitignore
vendored
3
lib/site_template/.gitignore
vendored
@@ -1,2 +1 @@
|
||||
_site
|
||||
.sass-cache
|
||||
_site
|
||||
@@ -1,14 +1,12 @@
|
||||
# Site settings
|
||||
title: Your awesome title
|
||||
email: your-email@domain.com
|
||||
description: > # this means to ignore newlines until "baseurl:"
|
||||
Write an awesome description for your new site here. You can edit this
|
||||
line in _config.yml. It will appear in your document head meta (for
|
||||
Google search results) and in your feed.xml site description.
|
||||
baseurl: "" # the subpath of your site, e.g. /blog/
|
||||
url: "http://yourdomain.com" # the base hostname & protocol for your site
|
||||
description: "Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description."
|
||||
baseurl: ""
|
||||
url: "http://yourdomain.com"
|
||||
twitter_username: jekyllrb
|
||||
github_username: jekyll
|
||||
|
||||
# Build settings
|
||||
markdown: kramdown
|
||||
permalink: pretty
|
||||
|
||||
@@ -1,53 +1,59 @@
|
||||
<footer class="site-footer">
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="wrap">
|
||||
|
||||
<h2 class="footer-heading">{{ site.title }}</h2>
|
||||
|
||||
<div class="footer-col-wrapper">
|
||||
<div class="footer-col footer-col-1">
|
||||
<ul class="contact-list">
|
||||
<li>{{ site.title }}</li>
|
||||
<li><a href="mailto:{{ site.email }}">{{ site.email }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer-col-1 column">
|
||||
<ul>
|
||||
<li>{{ site.title }}</li>
|
||||
<li><a href="mailto:{{ site.email }}">{{ site.email }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="footer-col footer-col-2">
|
||||
<ul class="social-media-list">
|
||||
{% if site.github_username %}
|
||||
<li>
|
||||
<a href="https://github.com/{{ site.github_username }}">
|
||||
<span class="icon icon--github">
|
||||
<svg viewBox="0 0 16 16">
|
||||
<path fill="#828282" d="M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761 c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32 c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472 c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037 C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65 c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261 c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082 c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129 c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z"/>
|
||||
</svg>
|
||||
</span>
|
||||
<div class="footer-col-2 column">
|
||||
<ul>
|
||||
{% if site.github_username %}<li>
|
||||
<a href="https://github.com/{{ site.github_username }}">
|
||||
<span class="icon github">
|
||||
<svg version="1.1" class="github-icon-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#C2C2C2" d="M7.999,0.431c-4.285,0-7.76,3.474-7.76,7.761
|
||||
c0,3.428,2.223,6.337,5.307,7.363c0.388,0.071,0.53-0.168,0.53-0.374c0-0.184-0.007-0.672-0.01-1.32
|
||||
c-2.159,0.469-2.614-1.04-2.614-1.04c-0.353-0.896-0.862-1.135-0.862-1.135c-0.705-0.481,0.053-0.472,0.053-0.472
|
||||
c0.779,0.055,1.189,0.8,1.189,0.8c0.692,1.186,1.816,0.843,2.258,0.645c0.071-0.502,0.271-0.843,0.493-1.037
|
||||
C4.86,11.425,3.049,10.76,3.049,7.786c0-0.847,0.302-1.54,0.799-2.082C3.768,5.507,3.501,4.718,3.924,3.65
|
||||
c0,0,0.652-0.209,2.134,0.796C6.677,4.273,7.34,4.187,8,4.184c0.659,0.003,1.323,0.089,1.943,0.261
|
||||
c1.482-1.004,2.132-0.796,2.132-0.796c0.423,1.068,0.157,1.857,0.077,2.054c0.497,0.542,0.798,1.235,0.798,2.082
|
||||
c0,2.981-1.814,3.637-3.543,3.829c0.279,0.24,0.527,0.713,0.527,1.437c0,1.037-0.01,1.874-0.01,2.129
|
||||
c0,0.208,0.14,0.449,0.534,0.373c3.081-1.028,5.302-3.935,5.302-7.362C15.76,3.906,12.285,0.431,7.999,0.431z"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="username">{{ site.github_username }}</span>
|
||||
</a>
|
||||
</li>{% endif %}
|
||||
{% if site.twitter_username %}<li>
|
||||
<a href="https://twitter.com/{{ site.twitter_username }}">
|
||||
<span class="icon twitter">
|
||||
<svg version="1.1" class="twitter-icon-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<path fill="#C2C2C2" d="M15.969,3.058c-0.586,0.26-1.217,0.436-1.878,0.515c0.675-0.405,1.194-1.045,1.438-1.809
|
||||
c-0.632,0.375-1.332,0.647-2.076,0.793c-0.596-0.636-1.446-1.033-2.387-1.033c-1.806,0-3.27,1.464-3.27,3.27
|
||||
c0,0.256,0.029,0.506,0.085,0.745C5.163,5.404,2.753,4.102,1.14,2.124C0.859,2.607,0.698,3.168,0.698,3.767
|
||||
c0,1.134,0.577,2.135,1.455,2.722C1.616,6.472,1.112,6.325,0.671,6.08c0,0.014,0,0.027,0,0.041c0,1.584,1.127,2.906,2.623,3.206
|
||||
C3.02,9.402,2.731,9.442,2.433,9.442c-0.211,0-0.416-0.021-0.615-0.059c0.416,1.299,1.624,2.245,3.055,2.271
|
||||
c-1.119,0.877-2.529,1.4-4.061,1.4c-0.264,0-0.524-0.015-0.78-0.046c1.447,0.928,3.166,1.469,5.013,1.469
|
||||
c6.015,0,9.304-4.983,9.304-9.304c0-0.142-0.003-0.283-0.009-0.423C14.976,4.29,15.531,3.714,15.969,3.058z"/>
|
||||
</svg>
|
||||
</span>
|
||||
<span class="username">{{ site.twitter_username }}</span>
|
||||
</a>
|
||||
</li>{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<span class="username">{{ site.github_username }}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if site.twitter_username %}
|
||||
<li>
|
||||
<a href="https://twitter.com/{{ site.twitter_username }}">
|
||||
<span class="icon icon--twitter">
|
||||
<svg viewBox="0 0 16 16">
|
||||
<path fill="#828282" d="M15.969,3.058c-0.586,0.26-1.217,0.436-1.878,0.515c0.675-0.405,1.194-1.045,1.438-1.809
|
||||
c-0.632,0.375-1.332,0.647-2.076,0.793c-0.596-0.636-1.446-1.033-2.387-1.033c-1.806,0-3.27,1.464-3.27,3.27 c0,0.256,0.029,0.506,0.085,0.745C5.163,5.404,2.753,4.102,1.14,2.124C0.859,2.607,0.698,3.168,0.698,3.767 c0,1.134,0.577,2.135,1.455,2.722C1.616,6.472,1.112,6.325,0.671,6.08c0,0.014,0,0.027,0,0.041c0,1.584,1.127,2.906,2.623,3.206 C3.02,9.402,2.731,9.442,2.433,9.442c-0.211,0-0.416-0.021-0.615-0.059c0.416,1.299,1.624,2.245,3.055,2.271 c-1.119,0.877-2.529,1.4-4.061,1.4c-0.264,0-0.524-0.015-0.78-0.046c1.447,0.928,3.166,1.469,5.013,1.469 c6.015,0,9.304-4.983,9.304-9.304c0-0.142-0.003-0.283-0.009-0.423C14.976,4.29,15.531,3.714,15.969,3.058z"/>
|
||||
</svg>
|
||||
</span>
|
||||
|
||||
<span class="username">{{ site.twitter_username }}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="footer-col footer-col-3">
|
||||
<p class="text">{{ site.description }}</p>
|
||||
</div>
|
||||
<div class="footer-col-3 column">
|
||||
<p class="text">{{ site.description }}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width initial-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>{% if page.title %}{{ page.title }}{% else %}{{ site.title }}{% endif %}</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<meta name="description" content="{{ site.description }}">
|
||||
<link rel="canonical" href="{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}">
|
||||
|
||||
<title>{% if page.title %}{{ page.title }}{% else %}{{ site.title }}{% endif %}</title>
|
||||
<meta name="description" content="{% if page.excerpt %}{{ page.excerpt | strip_html | strip_newlines | truncate: 160 }}{% else %}{{ site.description }}{% endif %}">
|
||||
<!-- Custom CSS -->
|
||||
<link rel="stylesheet" href="{{ "/css/main.css" | prepend: site.baseurl }}">
|
||||
|
||||
<link rel="stylesheet" href="{{ "/css/main.css" | prepend: site.baseurl }}">
|
||||
<link rel="canonical" href="{{ page.url | replace:'index.html','' | prepend: site.baseurl | prepend: site.url }}">
|
||||
<link rel="alternate" type="application/atom+xml" title="{{ site.title }}" href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" />
|
||||
</head>
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
<header class="site-header">
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="wrap">
|
||||
|
||||
<a class="site-title" href="{{ site.baseurl }}/">{{ site.title }}</a>
|
||||
|
||||
<nav class="site-nav">
|
||||
<a href="#" class="menu-icon">
|
||||
<svg viewBox="0 0 18 15">
|
||||
<path fill="#424242" d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.031C17.335,0,18,0.665,18,1.484L18,1.484z"/>
|
||||
<path fill="#424242" d="M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0c0-0.82,0.665-1.484,1.484-1.484 h15.031C17.335,6.031,18,6.696,18,7.516L18,7.516z"/>
|
||||
<path fill="#424242" d="M18,13.516C18,14.335,17.335,15,16.516,15H1.484C0.665,15,0,14.335,0,13.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.031C17.335,12.031,18,12.696,18,13.516L18,13.516z"/>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 18 15" enable-background="new 0 0 18 15" xml:space="preserve">
|
||||
<path fill="#505050" d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0
|
||||
h15.031C17.335,0,18,0.665,18,1.484L18,1.484z"/>
|
||||
<path fill="#505050" d="M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0c0-0.82,0.665-1.484,1.484-1.484
|
||||
h15.031C17.335,6.031,18,6.696,18,7.516L18,7.516z"/>
|
||||
<path fill="#505050" d="M18,13.516C18,14.335,17.335,15,16.516,15H1.484C0.665,15,0,14.335,0,13.516l0,0
|
||||
c0-0.82,0.665-1.484,1.484-1.484h15.031C17.335,12.031,18,12.696,18,13.516L18,13.516z"/>
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<div class="trigger">
|
||||
{% for page in site.pages %}
|
||||
{% if page.title %}
|
||||
<a class="page-link" href="{{ page.url | prepend: site.baseurl }}">{{ page.title }}</a>
|
||||
{% endif %}
|
||||
{% if page.title %}<a class="page-link" href="{{ page.url | prepend: site.baseurl }}">{{ page.title }}</a>{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@@ -3,18 +3,17 @@
|
||||
|
||||
{% include head.html %}
|
||||
|
||||
<body>
|
||||
<body>
|
||||
|
||||
{% include header.html %}
|
||||
|
||||
<div class="page-content">
|
||||
<div class="wrapper">
|
||||
{{ content }}
|
||||
<div class="wrap">
|
||||
{{ content }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include footer.html %}
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</body>
|
||||
</html>
|
||||
@@ -4,11 +4,11 @@ layout: default
|
||||
<div class="post">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">{{ page.title }}</h1>
|
||||
<h1>{{ page.title }}</h1>
|
||||
</header>
|
||||
|
||||
<article class="post-content">
|
||||
{{ content }}
|
||||
{{ content }}
|
||||
</article>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -4,12 +4,12 @@ layout: default
|
||||
<div class="post">
|
||||
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">{{ page.title }}</h1>
|
||||
<p class="post-meta">{{ page.date | date: "%b %-d, %Y" }}{% if page.author %} • {{ page.author }}{% endif %}{% if page.meta %} • {{ page.meta }}{% endif %}</p>
|
||||
<h1>{{ page.title }}</h1>
|
||||
<p class="meta">{{ page.date | date: "%b %-d, %Y" }}{% if page.author %} • {{ page.author }}{% endif %}{% if page.meta %} • {{ page.meta }}{% endif %}</p>
|
||||
</header>
|
||||
|
||||
<article class="post-content">
|
||||
{{ content }}
|
||||
{{ content }}
|
||||
</article>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -4,9 +4,9 @@ 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. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.
|
||||
|
||||
To add new posts, simply add a file in the `_posts` directory that follows the convention `YYYY-MM-DD-name-of-post.ext` and includes the necessary front matter. Take a look at the source for this post to get an idea about how it works.
|
||||
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:
|
||||
|
||||
@@ -18,8 +18,7 @@ print_hi('Tom')
|
||||
#=> prints 'Hi, Tom' to STDOUT.
|
||||
{% endhighlight %}
|
||||
|
||||
Check out the [Jekyll docs][jekyll] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll’s dedicated Help repository][jekyll-help].
|
||||
Check out the [Jekyll docs][jekyll] 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]: http://jekyllrb.com
|
||||
[jekyll-gh]: https://github.com/jekyll/jekyll
|
||||
[jekyll-help]: https://github.com/jekyll/jekyll-help
|
||||
[jekyll-gh]: https://github.com/jekyll/jekyll
|
||||
[jekyll]: http://jekyllrb.com
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
/**
|
||||
* Reset some basic elements
|
||||
*/
|
||||
body, h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre, hr,
|
||||
dl, dd, ol, ul, figure {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Basic styling
|
||||
*/
|
||||
body {
|
||||
font-family: $base-font-family;
|
||||
font-size: $base-font-size;
|
||||
line-height: $base-line-height;
|
||||
font-weight: 300;
|
||||
color: $text-color;
|
||||
background-color: $background-color;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set `margin-bottom` to maintain vertical rhythm
|
||||
*/
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
p, blockquote, pre,
|
||||
ul, ol, dl, figure,
|
||||
%vertical-rhythm {
|
||||
margin-bottom: $spacing-unit / 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Images
|
||||
*/
|
||||
img {
|
||||
max-width: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Figures
|
||||
*/
|
||||
figure > img {
|
||||
display: block;
|
||||
}
|
||||
|
||||
figcaption {
|
||||
font-size: $small-font-size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Lists
|
||||
*/
|
||||
ul, ol {
|
||||
margin-left: $spacing-unit;
|
||||
}
|
||||
|
||||
li {
|
||||
> ul,
|
||||
> ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Headings
|
||||
*/
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Links
|
||||
*/
|
||||
a {
|
||||
color: $brand-color;
|
||||
text-decoration: none;
|
||||
|
||||
&:visited {
|
||||
color: darken($brand-color, 15%);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: $text-color;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Blockquotes
|
||||
*/
|
||||
blockquote {
|
||||
color: $grey-color;
|
||||
border-left: 4px solid $grey-color-light;
|
||||
padding-left: $spacing-unit / 2;
|
||||
font-size: 18px;
|
||||
letter-spacing: -1px;
|
||||
font-style: italic;
|
||||
|
||||
> :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Code formatting
|
||||
*/
|
||||
pre,
|
||||
code {
|
||||
font-size: 15px;
|
||||
border: 1px solid $grey-color-light;
|
||||
border-radius: 3px;
|
||||
background-color: #eef;
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 1px 5px;
|
||||
}
|
||||
|
||||
pre {
|
||||
padding: 8px 12px;
|
||||
overflow-x: scroll;
|
||||
|
||||
> code {
|
||||
border: 0;
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper
|
||||
*/
|
||||
.wrapper {
|
||||
max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit} * 2));
|
||||
max-width: calc(#{$content-width} - (#{$spacing-unit} * 2));
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
padding-right: $spacing-unit;
|
||||
padding-left: $spacing-unit;
|
||||
@extend %clearfix;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
max-width: -webkit-calc(#{$content-width} - (#{$spacing-unit}));
|
||||
max-width: calc(#{$content-width} - (#{$spacing-unit}));
|
||||
padding-right: $spacing-unit / 2;
|
||||
padding-left: $spacing-unit / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Clearfix
|
||||
*/
|
||||
%clearfix {
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Icons
|
||||
*/
|
||||
.icon {
|
||||
|
||||
> svg {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: middle;
|
||||
|
||||
path {
|
||||
fill: $grey-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,236 +0,0 @@
|
||||
/**
|
||||
* Site header
|
||||
*/
|
||||
.site-header {
|
||||
border-top: 5px solid $grey-color-dark;
|
||||
border-bottom: 1px solid $grey-color-light;
|
||||
min-height: 56px;
|
||||
|
||||
// Positioning context for the mobile navigation icon
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.site-title {
|
||||
font-size: 26px;
|
||||
line-height: 56px;
|
||||
letter-spacing: -1px;
|
||||
margin-bottom: 0;
|
||||
float: left;
|
||||
|
||||
&,
|
||||
&:visited {
|
||||
color: $grey-color-dark;
|
||||
}
|
||||
}
|
||||
|
||||
.site-nav {
|
||||
float: right;
|
||||
line-height: 56px;
|
||||
|
||||
.menu-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
color: $text-color;
|
||||
line-height: $base-line-height;
|
||||
|
||||
// Gaps between nav items, but not on the first one
|
||||
&:not(:first-child) {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-query($on-palm) {
|
||||
position: absolute;
|
||||
top: 9px;
|
||||
right: 30px;
|
||||
background-color: $background-color;
|
||||
border: 1px solid $grey-color-light;
|
||||
border-radius: 5px;
|
||||
text-align: right;
|
||||
|
||||
.menu-icon {
|
||||
display: block;
|
||||
float: right;
|
||||
width: 36px;
|
||||
height: 26px;
|
||||
line-height: 0;
|
||||
padding-top: 10px;
|
||||
text-align: center;
|
||||
|
||||
> svg {
|
||||
width: 18px;
|
||||
height: 15px;
|
||||
|
||||
path {
|
||||
fill: $grey-color-dark;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.trigger {
|
||||
clear: both;
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover .trigger {
|
||||
display: block;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.page-link {
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Site footer
|
||||
*/
|
||||
.site-footer {
|
||||
border-top: 1px solid $grey-color-light;
|
||||
padding: $spacing-unit 0;
|
||||
}
|
||||
|
||||
.footer-heading {
|
||||
font-size: 18px;
|
||||
margin-bottom: $spacing-unit / 2;
|
||||
}
|
||||
|
||||
.contact-list,
|
||||
.social-media-list {
|
||||
list-style: none;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.footer-col-wrapper {
|
||||
font-size: 15px;
|
||||
color: $grey-color;
|
||||
margin-left: -$spacing-unit / 2;
|
||||
@extend %clearfix;
|
||||
}
|
||||
|
||||
.footer-col {
|
||||
float: left;
|
||||
margin-bottom: $spacing-unit / 2;
|
||||
padding-left: $spacing-unit / 2;
|
||||
}
|
||||
|
||||
.footer-col-1 {
|
||||
width: -webkit-calc(35% - (#{$spacing-unit} / 2));
|
||||
width: calc(35% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
.footer-col-2 {
|
||||
width: -webkit-calc(20% - (#{$spacing-unit} / 2));
|
||||
width: calc(20% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
.footer-col-3 {
|
||||
width: -webkit-calc(45% - (#{$spacing-unit} / 2));
|
||||
width: calc(45% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
.footer-col-1,
|
||||
.footer-col-2 {
|
||||
width: -webkit-calc(50% - (#{$spacing-unit} / 2));
|
||||
width: calc(50% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
|
||||
.footer-col-3 {
|
||||
width: -webkit-calc(100% - (#{$spacing-unit} / 2));
|
||||
width: calc(100% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
}
|
||||
|
||||
@include media-query($on-palm) {
|
||||
.footer-col {
|
||||
float: none;
|
||||
width: -webkit-calc(100% - (#{$spacing-unit} / 2));
|
||||
width: calc(100% - (#{$spacing-unit} / 2));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Page content
|
||||
*/
|
||||
.page-content {
|
||||
padding: $spacing-unit 0;
|
||||
}
|
||||
|
||||
.page-heading {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.post-list {
|
||||
margin-left: 0;
|
||||
list-style: none;
|
||||
|
||||
> li {
|
||||
margin-bottom: $spacing-unit;
|
||||
}
|
||||
}
|
||||
|
||||
.post-meta {
|
||||
font-size: $small-font-size;
|
||||
color: $grey-color;
|
||||
}
|
||||
|
||||
.post-link {
|
||||
display: block;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Posts
|
||||
*/
|
||||
.post-header {
|
||||
margin-bottom: $spacing-unit;
|
||||
}
|
||||
|
||||
.post-title {
|
||||
font-size: 42px;
|
||||
letter-spacing: -1px;
|
||||
line-height: 1;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.post-content {
|
||||
margin-bottom: $spacing-unit;
|
||||
|
||||
h2 {
|
||||
font-size: 32px;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 26px;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 20px;
|
||||
|
||||
@include media-query($on-laptop) {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/**
|
||||
* Syntax highlighting styles
|
||||
*/
|
||||
.highlight {
|
||||
background: #fff;
|
||||
@extend %vertical-rhythm;
|
||||
|
||||
.c { color: #998; font-style: italic } // Comment
|
||||
.err { color: #a61717; background-color: #e3d2d2 } // Error
|
||||
.k { font-weight: bold } // Keyword
|
||||
.o { font-weight: bold } // Operator
|
||||
.cm { color: #998; font-style: italic } // Comment.Multiline
|
||||
.cp { color: #999; font-weight: bold } // Comment.Preproc
|
||||
.c1 { color: #998; font-style: italic } // Comment.Single
|
||||
.cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special
|
||||
.gd { color: #000; background-color: #fdd } // Generic.Deleted
|
||||
.gd .x { color: #000; background-color: #faa } // Generic.Deleted.Specific
|
||||
.ge { font-style: italic } // Generic.Emph
|
||||
.gr { color: #a00 } // Generic.Error
|
||||
.gh { color: #999 } // Generic.Heading
|
||||
.gi { color: #000; background-color: #dfd } // Generic.Inserted
|
||||
.gi .x { color: #000; background-color: #afa } // Generic.Inserted.Specific
|
||||
.go { color: #888 } // Generic.Output
|
||||
.gp { color: #555 } // Generic.Prompt
|
||||
.gs { font-weight: bold } // Generic.Strong
|
||||
.gu { color: #aaa } // Generic.Subheading
|
||||
.gt { color: #a00 } // Generic.Traceback
|
||||
.kc { font-weight: bold } // Keyword.Constant
|
||||
.kd { font-weight: bold } // Keyword.Declaration
|
||||
.kp { font-weight: bold } // Keyword.Pseudo
|
||||
.kr { font-weight: bold } // Keyword.Reserved
|
||||
.kt { color: #458; font-weight: bold } // Keyword.Type
|
||||
.m { color: #099 } // Literal.Number
|
||||
.s { color: #d14 } // Literal.String
|
||||
.na { color: #008080 } // Name.Attribute
|
||||
.nb { color: #0086B3 } // Name.Builtin
|
||||
.nc { color: #458; font-weight: bold } // Name.Class
|
||||
.no { color: #008080 } // Name.Constant
|
||||
.ni { color: #800080 } // Name.Entity
|
||||
.ne { color: #900; font-weight: bold } // Name.Exception
|
||||
.nf { color: #900; font-weight: bold } // Name.Function
|
||||
.nn { color: #555 } // Name.Namespace
|
||||
.nt { color: #000080 } // Name.Tag
|
||||
.nv { color: #008080 } // Name.Variable
|
||||
.ow { font-weight: bold } // Operator.Word
|
||||
.w { color: #bbb } // Text.Whitespace
|
||||
.mf { color: #099 } // Literal.Number.Float
|
||||
.mh { color: #099 } // Literal.Number.Hex
|
||||
.mi { color: #099 } // Literal.Number.Integer
|
||||
.mo { color: #099 } // Literal.Number.Oct
|
||||
.sb { color: #d14 } // Literal.String.Backtick
|
||||
.sc { color: #d14 } // Literal.String.Char
|
||||
.sd { color: #d14 } // Literal.String.Doc
|
||||
.s2 { color: #d14 } // Literal.String.Double
|
||||
.se { color: #d14 } // Literal.String.Escape
|
||||
.sh { color: #d14 } // Literal.String.Heredoc
|
||||
.si { color: #d14 } // Literal.String.Interpol
|
||||
.sx { color: #d14 } // Literal.String.Other
|
||||
.sr { color: #009926 } // Literal.String.Regex
|
||||
.s1 { color: #d14 } // Literal.String.Single
|
||||
.ss { color: #990073 } // Literal.String.Symbol
|
||||
.bp { color: #999 } // Name.Builtin.Pseudo
|
||||
.vc { color: #008080 } // Name.Variable.Class
|
||||
.vg { color: #008080 } // Name.Variable.Global
|
||||
.vi { color: #008080 } // Name.Variable.Instance
|
||||
.il { color: #099 } // Literal.Number.Integer.Long
|
||||
}
|
||||
410
lib/site_template/css/main.css
Normal file
410
lib/site_template/css/main.css
Normal file
@@ -0,0 +1,410 @@
|
||||
/* Base */
|
||||
/* ----------------------------------------------------------*/
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html, body { height: 100%; }
|
||||
|
||||
body {
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.5;
|
||||
font-weight: 300;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 { font-size: 100%; font-weight: 400; }
|
||||
|
||||
a { color: #2a7ae2; text-decoration: none; }
|
||||
a:hover { color: #000; text-decoration: underline; }
|
||||
a:visited { color: #205caa; }
|
||||
|
||||
/* Utility */
|
||||
|
||||
.wrap:before,
|
||||
.wrap:after { content:""; display:table; }
|
||||
.wrap:after { clear: both; }
|
||||
.wrap {
|
||||
max-width: 800px;
|
||||
padding: 0 30px;
|
||||
margin: 0 auto;
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
|
||||
/* Layout Styles */
|
||||
/* ----------------------------------------------------------*/
|
||||
|
||||
/* Site header */
|
||||
|
||||
.site-header {
|
||||
border-top: 5px solid #333;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
min-height: 56px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.site-title,
|
||||
.site-title:hover,
|
||||
.site-title:visited {
|
||||
display: block;
|
||||
color: #333;
|
||||
font-size: 26px;
|
||||
letter-spacing: -1px;
|
||||
float: left;
|
||||
line-height: 56px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.site-nav {
|
||||
float: right;
|
||||
line-height: 56px;
|
||||
}
|
||||
|
||||
.site-nav .menu-icon { display: none; }
|
||||
|
||||
.site-nav .page-link {
|
||||
margin-left: 20px;
|
||||
color: #727272;
|
||||
letter-spacing: -.5px;
|
||||
}
|
||||
|
||||
/* Site footer */
|
||||
|
||||
.site-footer {
|
||||
border-top: 1px solid #e8e8e8;
|
||||
padding: 30px 0;
|
||||
}
|
||||
|
||||
.footer-heading {
|
||||
font-size: 18px;
|
||||
font-weight: 300;
|
||||
letter-spacing: -.5px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.site-footer .column { float: left; margin-bottom: 15px; }
|
||||
|
||||
.footer-col-1 {
|
||||
width: 270px; /*fallback*/
|
||||
width: -webkit-calc(35% - 10px);
|
||||
width: -moz-calc(35% - 10px);
|
||||
width: -o-calc(35% - 10px);
|
||||
width: calc(35% - 10px);
|
||||
margin-right: 10px
|
||||
}
|
||||
.footer-col-2 {
|
||||
width: 175px; /*fallback*/
|
||||
width: -webkit-calc(23.125% - 10px);
|
||||
width: -moz-calc(23.125% - 10px);
|
||||
width: -o-calc(23.125% - 10px);
|
||||
width: calc(23.125% - 10px);
|
||||
margin-right: 10px
|
||||
}
|
||||
.footer-col-3 {
|
||||
width: 335px; /*fallback*/
|
||||
width: -webkit-calc(41.875%);
|
||||
width: -moz-calc(41.875%);
|
||||
width: -o-calc(41.875%);
|
||||
width: calc(41.875%);
|
||||
}
|
||||
|
||||
.site-footer ul { list-style: none; }
|
||||
|
||||
.site-footer li,
|
||||
.site-footer p {
|
||||
font-size: 15px;
|
||||
letter-spacing: -.3px;
|
||||
color: #828282;
|
||||
}
|
||||
|
||||
.github-icon-svg,
|
||||
.twitter-icon-svg {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: relative;
|
||||
top: 3px;
|
||||
}
|
||||
|
||||
|
||||
/* Page Content styles */
|
||||
/* ----------------------------------------------------------*/
|
||||
|
||||
.page-content {
|
||||
padding: 30px 0;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
|
||||
/* Home styles */
|
||||
/* ----------------------------------------------------------*/
|
||||
|
||||
.home h1 { margin-bottom: 25px; }
|
||||
|
||||
.posts { list-style-type: none; }
|
||||
|
||||
.posts li { margin-bottom: 30px; }
|
||||
|
||||
.posts .post-link {
|
||||
font-size: 24px;
|
||||
letter-spacing: -1px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.posts .post-date {
|
||||
display: block;
|
||||
font-size: 15px;
|
||||
color: #818181;
|
||||
}
|
||||
|
||||
|
||||
/* Post styles */
|
||||
/* ----------------------------------------------------------*/
|
||||
|
||||
.post-header { margin: 10px 0 30px; }
|
||||
|
||||
.post-header h1 {
|
||||
font-size: 42px;
|
||||
letter-spacing: -1.75px;
|
||||
line-height: 1;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.post-header .meta {
|
||||
font-size: 15px;
|
||||
color: #818181;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.post-content { margin: 0 0 30px; }
|
||||
|
||||
.post-content > * { margin: 20px 0; }
|
||||
|
||||
|
||||
.post-content h1,
|
||||
.post-content h2,
|
||||
.post-content h3,
|
||||
.post-content h4,
|
||||
.post-content h5,
|
||||
.post-content h6 {
|
||||
line-height: 1;
|
||||
font-weight: 300;
|
||||
margin: 40px 0 20px;
|
||||
}
|
||||
|
||||
.post-content h2 {
|
||||
font-size: 32px;
|
||||
letter-spacing: -1.25px;
|
||||
}
|
||||
|
||||
.post-content h3 {
|
||||
font-size: 26px;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
|
||||
.post-content h4 {
|
||||
font-size: 20px;
|
||||
letter-spacing: -1px;
|
||||
}
|
||||
|
||||
.post-content blockquote {
|
||||
border-left: 4px solid #e8e8e8;
|
||||
padding-left: 20px;
|
||||
font-size: 18px;
|
||||
opacity: .6;
|
||||
letter-spacing: -1px;
|
||||
font-style: italic;
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
.post-content ul,
|
||||
.post-content ol { padding-left: 20px; }
|
||||
|
||||
.post pre,
|
||||
.post code {
|
||||
border: 1px solid #d5d5e9;
|
||||
background-color: #eef;
|
||||
padding: 8px 12px;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
font-size: 15px;
|
||||
overflow:scroll;
|
||||
}
|
||||
|
||||
.post code { padding: 1px 5px; }
|
||||
|
||||
.post ul,
|
||||
.post ol { margin-left: 1.35em; }
|
||||
|
||||
.post pre code {
|
||||
border: 0;
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
/* terminal */
|
||||
.post pre.terminal {
|
||||
border: 1px solid #000;
|
||||
background-color: #333;
|
||||
color: #FFF;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.post pre.terminal code { background-color: #333; }
|
||||
|
||||
/* Syntax highlighting styles */
|
||||
/* ----------------------------------------------------------*/
|
||||
|
||||
.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 */
|
||||
|
||||
|
||||
/* media queries */
|
||||
/* ----------------------------------------------------------*/
|
||||
|
||||
|
||||
@media screen and (max-width: 750px) {
|
||||
|
||||
.footer-col-1 { width: 50%; }
|
||||
|
||||
.footer-col-2 {
|
||||
width: 45%; /*fallback*/
|
||||
width: -webkit-calc(50% - 10px);
|
||||
width: -moz-calc(50% - 10px);
|
||||
width: -o-calc(50% - 10px);
|
||||
width: calc(50% - 10px);
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.site-footer .column.footer-col-3 {
|
||||
width: auto;
|
||||
float: none;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
|
||||
.wrap { padding: 0 12px; }
|
||||
|
||||
.site-nav {
|
||||
position: fixed;
|
||||
z-index: 10;
|
||||
top: 14px; right: 8px;
|
||||
background-color: white;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #e8e8e8;
|
||||
}
|
||||
|
||||
.site-nav .menu-icon {
|
||||
display: block;
|
||||
font-size: 24px;
|
||||
color: #505050;
|
||||
float: right;
|
||||
width: 36px;
|
||||
text-align: center;
|
||||
line-height: 36px;
|
||||
}
|
||||
|
||||
.site-nav .menu-icon svg { width: 18px; height: 16px; }
|
||||
|
||||
.site-nav .trigger {
|
||||
clear: both;
|
||||
margin-bottom: 5px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.site-nav:hover .trigger { display: block; }
|
||||
|
||||
.site-nav .page-link {
|
||||
display: block;
|
||||
text-align: right;
|
||||
line-height: 1.25;
|
||||
padding: 5px 10px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.post-header h1 { font-size: 36px; }
|
||||
.post-content h2 { font-size: 28px; }
|
||||
.post-content h3 { font-size: 22px; }
|
||||
.post-content h4 { font-size: 18px; }
|
||||
.post-content blockquote { padding-left: 10px; }
|
||||
.post-content ul,
|
||||
.post-content ol { padding-left: 10px; }
|
||||
|
||||
.site-footer .column {
|
||||
float: none;
|
||||
clear: both;
|
||||
width: auto;
|
||||
margin: 0 0 15px; }
|
||||
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
---
|
||||
# Only the main Sass file needs front matter (the dashes are enough)
|
||||
---
|
||||
@charset "utf-8";
|
||||
|
||||
|
||||
|
||||
// Our variables
|
||||
$base-font-family: Helvetica, Arial, sans-serif;
|
||||
$base-font-size: 16px;
|
||||
$small-font-size: $base-font-size * 0.875;
|
||||
$base-line-height: 1.5;
|
||||
|
||||
$spacing-unit: 30px;
|
||||
|
||||
$text-color: #111;
|
||||
$background-color: #fdfdfd;
|
||||
$brand-color: #2a7ae2;
|
||||
|
||||
$grey-color: #828282;
|
||||
$grey-color-light: lighten($grey-color, 40%);
|
||||
$grey-color-dark: darken($grey-color, 25%);
|
||||
|
||||
// Width of the content area
|
||||
$content-width: 800px;
|
||||
|
||||
$on-palm: 600px;
|
||||
$on-laptop: 800px;
|
||||
|
||||
|
||||
|
||||
// Using media queries with like this:
|
||||
// @include media-query($on-palm) {
|
||||
// .wrapper {
|
||||
// padding-right: $spacing-unit / 2;
|
||||
// padding-left: $spacing-unit / 2;
|
||||
// }
|
||||
// }
|
||||
@mixin media-query($device) {
|
||||
@media screen and (max-width: $device) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Import partials from `sass_dir` (defaults to `_sass`)
|
||||
@import
|
||||
"base",
|
||||
"layout",
|
||||
"syntax-highlighting"
|
||||
;
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
layout: null
|
||||
layout: none
|
||||
---
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
@@ -7,7 +7,7 @@ layout: null
|
||||
<title>{{ site.title | xml_escape }}</title>
|
||||
<description>{{ site.description | xml_escape }}</description>
|
||||
<link>{{ site.url }}{{ site.baseurl }}/</link>
|
||||
<atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml"/>
|
||||
<atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self" type="application/rss+xml" />
|
||||
<pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
|
||||
<lastBuildDate>{{ site.time | date_to_rfc822 }}</lastBuildDate>
|
||||
<generator>Jekyll v{{ jekyll.version }}</generator>
|
||||
|
||||
@@ -4,16 +4,13 @@ layout: default
|
||||
|
||||
<div class="home">
|
||||
|
||||
<h1 class="page-heading">Posts</h1>
|
||||
<h1>Posts</h1>
|
||||
|
||||
<ul class="post-list">
|
||||
<ul class="posts">
|
||||
{% for post in site.posts %}
|
||||
<li>
|
||||
<span class="post-meta">{{ post.date | date: "%b %-d, %Y" }}</span>
|
||||
|
||||
<h2>
|
||||
<a class="post-link" href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a>
|
||||
</h2>
|
||||
<span class="post-date">{{ post.date | date: "%b %-d, %Y" }}</span>
|
||||
<a class="post-link" href="{{ post.url | prepend: site.baseurl }}">{{ post.title }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
#! /bin/bash
|
||||
|
||||
script/branding
|
||||
|
||||
set -e
|
||||
|
||||
if test -z "$TEST_SUITE"; then
|
||||
script/test
|
||||
script/cucumber
|
||||
else
|
||||
script/$TEST_SUITE
|
||||
fi
|
||||
bundle exec rake
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
time bundle exec cucumber \
|
||||
-f Features::Support::Overview \
|
||||
"$@"
|
||||
24
script/proof
24
script/proof
@@ -1,24 +0,0 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# Usage:
|
||||
# script/proof
|
||||
|
||||
set -e
|
||||
|
||||
if [[ "$1" != "-f" ]]; then
|
||||
git diff --name-only ..master | grep '^site/' || {
|
||||
echo "No site files changed. We'll skip proofing. Run with -f to force."
|
||||
exit 0
|
||||
}
|
||||
fi
|
||||
|
||||
echo "Some site files have been changed! Proofing..."
|
||||
|
||||
command -v htmlproof || {
|
||||
echo "Installing HTML::Proofer!"
|
||||
gem install html-proofer -- --use-system-libraries
|
||||
}
|
||||
|
||||
bundle exec jekyll build -s site -d _site --trace
|
||||
printf "\e[0;36mProofing begins now!\e[0m\n"
|
||||
htmlproof ./_site
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
export BENCHMARK=true
|
||||
command -v stackprof > /dev/null || script/bootstrap
|
||||
|
||||
TEST_SCRIPT="Jekyll::Commands::Build.process({'source' => 'site'})"
|
||||
PROF_OUTPUT_FILE=tmp/stackprof-$(date +%Y%m%d).dump
|
||||
|
||||
test -f "$PROF_OUTPUT_FILE" || {
|
||||
bundle exec ruby -r./lib/jekyll -rstackprof \
|
||||
-e "StackProf.run(mode: :cpu, out: '${PROF_OUTPUT_FILE}') { ${TEST_SCRIPT} }"
|
||||
}
|
||||
|
||||
bundle exec stackprof $PROF_OUTPUT_FILE $@
|
||||
17
script/test
17
script/test
@@ -1,20 +1,11 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# Usage:
|
||||
# script/test
|
||||
# script/test <test_file>
|
||||
|
||||
set -x
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
TEST_FILES="./test/test_*.rb"
|
||||
TEST_FILES="test/test*.rb"
|
||||
else
|
||||
TEST_FILES="$@"
|
||||
fi
|
||||
|
||||
RAKE_LIB_DIR=$(ruby -e "puts Gem::Specification.find_by_name('rake').gem_dir + '/lib'")
|
||||
|
||||
set -x
|
||||
|
||||
time bundle exec ruby -I"lib:test" \
|
||||
-I"${RAKE_LIB_DIR}" \
|
||||
"${RAKE_LIB_DIR}/rake/rake_test_loader.rb" \
|
||||
$TEST_FILES
|
||||
/usr/bin/env bundle exec ruby -I"lib:test" -r rake -r rake/rake_test_loader ${TEST_FILES}
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
markdown: kramdown
|
||||
highlighter: pygments
|
||||
relative_permalinks: false
|
||||
gauges_id: 503c5af6613f5d0f19000027
|
||||
permalink: /news/:year/:month/:day/:title/
|
||||
excerpt_separator: noifniof3nioaniof3nioafafinoafnoif
|
||||
|
||||
gauges_id: 503c5af6613f5d0f19000027
|
||||
google_analytics_id: UA-50755011-1
|
||||
|
||||
repository: https://github.com/jekyll/jekyll
|
||||
help_url: https://github.com/jekyll/jekyll-help
|
||||
|
||||
collections:
|
||||
docs:
|
||||
output: true
|
||||
google_analytics_id: UA-50755011-1
|
||||
timezone: America/Los_Angeles
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
docs:
|
||||
- github-pages
|
||||
- deployment-methods
|
||||
- continuous-integration
|
||||
|
||||
- title: Miscellaneous
|
||||
docs:
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Assets
|
||||
prev_section: datafiles
|
||||
next_section: migrations
|
||||
permalink: /docs/assets/
|
||||
---
|
||||
|
||||
Jekyll provides built-in support for Sass and CoffeeScript. In order to use
|
||||
them, create a file with the proper extension name (one of `.sass`, `.scss`,
|
||||
or `.coffee`) and start the file with two lines of triple dashes, like this:
|
||||
|
||||
{% highlight sass %}
|
||||
---
|
||||
---
|
||||
|
||||
// start content
|
||||
.my-definition
|
||||
font-size: 1.2em
|
||||
{% endhighlight %}
|
||||
|
||||
Jekyll treats these files the same as a regular page, in that the output file
|
||||
will be placed in the same directory that it came from. For instance, if you
|
||||
have a file named `css/styles.scss` in your site's source folder, Jekyll
|
||||
will process it and put it in your site's destination folder under
|
||||
`css/styles.css`.
|
||||
|
||||
<div class="note info">
|
||||
<h5>Jekyll processes all Liquid filters and tags in asset files</h5>
|
||||
<p>If you are using <a href="http://mustache.github.io">Mustache</a>
|
||||
or another JavaScript templating language that conflicts with
|
||||
the <a href="/docs/templates/">Liquid template syntax</a>, you
|
||||
will need to place <code>{% raw %}</code> and
|
||||
<code>{% endraw %}</code> tags around your code.</p>
|
||||
</div>
|
||||
|
||||
## Sass/SCSS
|
||||
|
||||
Jekyll allows you to customize your Sass conversion in certain ways.
|
||||
|
||||
Place all your partials in your `sass_dir`, which defaults to
|
||||
`<source>/_sass`. Place your main SCSS or Sass files in the place you want
|
||||
them to be in the output file, such as `<source>/css`. For an example, take
|
||||
a look at [this example site using Sass support in Jekyll][example-sass].
|
||||
|
||||
If you are using Sass `@import` statements, you'll need to ensure that your
|
||||
`sass_dir` is set to the base directory that contains your Sass files. You
|
||||
can do that thusly:
|
||||
|
||||
{% highlight yaml %}
|
||||
sass:
|
||||
sass_dir: _sass
|
||||
{% endhighlight %}
|
||||
|
||||
The Sass converter will default the `sass_dir` configuration option to
|
||||
`_sass`.
|
||||
|
||||
[example-sass]: https://github.com/jekyll/jekyll-sass-converter/tree/master/example
|
||||
|
||||
<div class="note info">
|
||||
<h5>The <code>sass_dir</code> is only used by Sass</h5>
|
||||
<p>
|
||||
|
||||
Note that the <code>sass_dir</code> becomes the load path for Sass imports,
|
||||
nothing more. This means that Jekyll does not know about these files
|
||||
directly, so any files here should not contain the YAML Front Matter as
|
||||
described above nor will they be transformed as described above. This
|
||||
folder should only contain imports.
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
You may also specify the output style with the `style` option in your
|
||||
`_config.yml` file:
|
||||
|
||||
{% highlight yaml %}
|
||||
sass:
|
||||
style: :compressed
|
||||
{% endhighlight %}
|
||||
|
||||
These are passed to Sass, so any output style options Sass supports are valid
|
||||
here, too.
|
||||
@@ -1,177 +0,0 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Continuous Integration
|
||||
prev_section: deployment-methods
|
||||
next_section: troubleshooting
|
||||
permalink: /docs/continuous-integration/
|
||||
---
|
||||
|
||||
You can easily test your website build against one or more versions of Ruby.
|
||||
The following guide will show you how to set up a free build environment on
|
||||
[Travis][0], with [GitHub][1] integration for pull requests. Paid
|
||||
alternatives exist for private repositories.
|
||||
|
||||
[0]: https://travis-ci.org/
|
||||
[1]: https://github.com/
|
||||
|
||||
## 1. Enabling Travis and GitHub
|
||||
|
||||
Enabling Travis builds for your GitHub repository is pretty simple:
|
||||
|
||||
1. Go to your profile on travis-ci.org: https://travis-ci.org/profile/username
|
||||
2. Find the repository for which you're interested in enabling builds.
|
||||
3. Click the slider on the right so it says "ON" and is a dark grey.
|
||||
4. Optionally configure the build by clicking on the wrench icon. Further
|
||||
configuration happens in your `.travis.yml` file. More details on that
|
||||
below.
|
||||
|
||||
## 2. The Test Script
|
||||
|
||||
The simplest test script simply runs `jekyll build` and ensures that Jekyll
|
||||
doesn't fail to build the site. It doesn't check the resulting site, but it
|
||||
does ensure things are built properly.
|
||||
|
||||
When testing Jekyll output, there is no better tool than [html-proofer][2].
|
||||
This tool checks your resulting site to ensure all links and images exist.
|
||||
Utilize it either with the convenient `htmlproof` command-line executable,
|
||||
or write a Ruby script which utilizes the gem.
|
||||
|
||||
### The HTML Proofer Executable
|
||||
|
||||
{% highlight bash %}
|
||||
#!/usr/bin/env bash
|
||||
set -e # halt script on error
|
||||
|
||||
bundle exec jekyll build
|
||||
bundle exec htmlproof ./_site
|
||||
{% endhighlight %}
|
||||
|
||||
Some options can be specified via command-line switches. Check out the
|
||||
`html-proofer` README for more information about these switches, or run
|
||||
`htmlproof --help` locally.
|
||||
|
||||
### The HTML Proofer Library
|
||||
|
||||
You can also invoke `html-proofer` in Ruby scripts (e.g. in a Rakefile):
|
||||
|
||||
{% highlight ruby %}
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'html/proofer'
|
||||
HTML::Proofer.new("./_site").run
|
||||
{% endhighlight %}
|
||||
|
||||
Options are given as a second argument to `.new`, and are encoded in a
|
||||
symbol-keyed Ruby Hash. More information about the configuration options,
|
||||
check out `html-proofer`'s README file.
|
||||
|
||||
[2]: https://github.com/gjtorikian/html-proofer
|
||||
|
||||
## 3. Configuring Your Travis Builds
|
||||
|
||||
This file is used to configure your Travis builds. Because Jekyll is built
|
||||
with Ruby and requires RubyGems to install, we use the Ruby language build
|
||||
environment. Below is a sample `.travis.yml` file, and what follows that is
|
||||
an explanation of each line.
|
||||
|
||||
{% highlight yaml %}
|
||||
language: ruby
|
||||
rvm:
|
||||
- 2.1
|
||||
script: ./script/cibuild
|
||||
|
||||
# branch whitelist
|
||||
branches:
|
||||
only:
|
||||
- gh-pages # test the gh-pages branch
|
||||
- /pages-(.*)/ # test every branch which starts with "pages-"
|
||||
|
||||
env:
|
||||
global:
|
||||
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true # speeds up installation of html-proofer
|
||||
{% endhighlight %}
|
||||
|
||||
Ok, now for an explanation of each line:
|
||||
|
||||
{% highlight yaml %}
|
||||
language: ruby
|
||||
{% endhighlight %}
|
||||
|
||||
This line tells Travis to use a Ruby build container. It gives your script
|
||||
access to Bundler, RubyGems, and a Ruby runtime.
|
||||
|
||||
{% highlight yaml %}
|
||||
rvm:
|
||||
- 2.1
|
||||
{% endhighlight %}
|
||||
|
||||
RVM is a popular Ruby Version Manager (like rbenv, chruby, etc). This
|
||||
directive tells Travis the Ruby version to use when running your test
|
||||
script.
|
||||
|
||||
{% highlight yaml %}
|
||||
script: ./script/cibuild
|
||||
{% endhighlight %}
|
||||
|
||||
Travis allows you to run any arbitrary shell script to test your site. One
|
||||
convention is to put all scripts for your project in the `script`
|
||||
directory, and to call your test script `cibuild`. This line is completely
|
||||
customizable. If your script won't change much, you can write your test
|
||||
incantation here directly:
|
||||
|
||||
{% highlight yaml %}
|
||||
script: jekyll build && htmlproof ./_site
|
||||
{% endhighlight %}
|
||||
|
||||
The `script` directive can be absolutely any valid shell command.
|
||||
|
||||
{% highlight yaml %}
|
||||
# branch whitelist
|
||||
branches:
|
||||
only:
|
||||
- gh-pages # test the gh-pages branch
|
||||
- /pages-(.*)/ # test every branch which starts with "pages-"
|
||||
{% endhighlight %}
|
||||
|
||||
You want to ensure the Travis builds for your site are being run only on
|
||||
the branch or branches which contain your site. One means of ensuring this
|
||||
isolation is including a branch whitelist in your Travis configuration
|
||||
file. By specifying the `gh-pages` branch, you will ensure the associated
|
||||
test script (discussed above) is only executed on site branches. If you use
|
||||
a pull request flow for proposing changes, you may wish to enforce a
|
||||
convention for your builds such that all branches containing edits are
|
||||
prefixed, exemplified above with the `/pages-(.*)/` regular expression.
|
||||
|
||||
The `branches` directive is completely optional.
|
||||
|
||||
{% highlight yaml %}
|
||||
env:
|
||||
global:
|
||||
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true # speeds up installation of html-proofer
|
||||
{% endhighlight %}
|
||||
|
||||
Using `html-proofer`? You'll want this environment variable. Nokogiri, used
|
||||
to parse HTML files in your compiled site, comes bundled with libraries
|
||||
which it must compile each time it is installed. Luckily, you can
|
||||
dramatically decrease the install time of Nokogiri by setting the
|
||||
environment variable `NOKOGIRI_USE_SYSTEM_LIBRARIES` to `true`.
|
||||
|
||||
## 4. Gotchas
|
||||
|
||||
### Exclude `vendor`
|
||||
|
||||
Travis bundles all gems in the `vendor` directory on its build servers,
|
||||
which Jekyll will mistakenly read and explode on. To avoid this, exclude
|
||||
`vendor` in your `_config.yml`:
|
||||
|
||||
{% highlight yaml %}
|
||||
exclude: [vendor]
|
||||
{% endhighlight %}
|
||||
|
||||
### Questions?
|
||||
|
||||
This entire guide is open-source. Go ahead and [edit it][3] if you have a
|
||||
fix or [ask for help][4] if you run into trouble and need some help.
|
||||
|
||||
[3]: https://github.com/jekyll/jekyll/edit/master/site/_docs/continuous-integration.md
|
||||
[4]: https://github.com/jekyll/jekyll-help#how-do-i-ask-a-question
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
layout: docs
|
||||
title: Extras
|
||||
prev_section: plugins
|
||||
next_section: github-pages
|
||||
permalink: /docs/extras/
|
||||
---
|
||||
|
||||
There are a number of (optional) extra features that Jekyll supports that you
|
||||
may want to install, depending on how you plan to use Jekyll.
|
||||
|
||||
## Math Support
|
||||
|
||||
Kramdown comes with optional support for LaTeX to PNG rendering via [MathJax](http://www.mathjax.org/) within math blocks. See the Kramdown documentation on [math blocks](http://kramdown.gettalong.org/syntax.html#math-blocks) and [math support](http://kramdown.gettalong.org/converter/html.html#math-support) for more details.
|
||||
|
||||
## Alternative Markdown Processors
|
||||
|
||||
See the Markdown section on the [configuration page](/docs/configuration/#markdown-options) for instructions on how to use and configure alternative Markdown processors, as well as how to create [custom processors](/docs/configuration/#custom-markdown-processors).
|
||||
@@ -1,19 +1,20 @@
|
||||
/*!
|
||||
* Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome
|
||||
* Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
|
||||
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
|
||||
*/
|
||||
@font-face {
|
||||
font-family: 'FontAwesome';
|
||||
src: url('../fonts/fontawesome-webfont.eot?v=4.2.0');
|
||||
src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');
|
||||
src: url('../fonts/fontawesome-webfont.eot?v=4.1.0');
|
||||
src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
.fa {
|
||||
display: inline-block;
|
||||
font: normal normal normal 14px/1 FontAwesome;
|
||||
font-size: inherit;
|
||||
text-rendering: auto;
|
||||
font-family: FontAwesome;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
@@ -29,10 +30,10 @@
|
||||
left: 0.5em;
|
||||
opacity: 0;
|
||||
font-size: 0.8em;
|
||||
|
||||
-webkit-transition: opacity 0.2s ease-in-out 0.1s;
|
||||
-moz-transition: opacity 0.2s ease-in-out 0.1s;
|
||||
-o-transition: opacity 0.2s ease-in-out 0.1s;
|
||||
transition: opacity 0.2s ease-in-out 0.1s;
|
||||
-ms-transition: opacity 0.2s ease-in-out 0.1s;
|
||||
}
|
||||
h2:hover .header-link,
|
||||
h3:hover .header-link,
|
||||
1
site/_includes/css/normalize.css
vendored
Normal file
1
site/_includes/css/normalize.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user