├── .editorconfig ├── .eslintrc.json ├── .gitattributes ├── .github └── contributing.md ├── .gitignore ├── .travis.yml ├── .verb.md ├── LICENSE ├── README.md ├── changelog.md ├── custom.scss ├── examples ├── build.js └── ctor.js ├── index.js ├── lib ├── plugins.js └── utils.js ├── package.json └── test ├── fixtures ├── 404.html ├── Gemfile ├── LICENSE.md ├── README.md ├── _config.yml ├── _includes │ └── head.html ├── _layouts │ ├── default.html │ ├── page.html │ └── post.html ├── _posts │ ├── 2016-01-01-whats-jekyll.md │ ├── 2016-01-02-example-content.md │ └── 2016-01-03-introduction.md ├── _sass │ ├── _base.scss │ ├── _code.scss │ ├── _layout.scss │ ├── _masthead.scss │ ├── _message.scss │ ├── _pagination.scss │ ├── _posts.scss │ ├── _syntax.scss │ ├── _type.scss │ └── _variables.scss ├── about.md ├── atom.xml ├── css │ ├── cayman.css │ └── normalize.css ├── index.html ├── jekyll-cayman-theme.gemspec ├── public │ ├── apple-touch-icon-precomposed.png │ └── favicon.ico └── styles.scss └── test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org/ 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [{**/{actual,fixtures,expected,templates}/**,*.md}] 13 | trim_trailing_whitespace = false 14 | insert_final_newline = false 15 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": false, 4 | "es6": true, 5 | "node": true, 6 | "mocha": true 7 | }, 8 | 9 | "globals": { 10 | "document": false, 11 | "navigator": false, 12 | "window": false 13 | }, 14 | 15 | "rules": { 16 | "accessor-pairs": 2, 17 | "arrow-spacing": [2, { "before": true, "after": true }], 18 | "block-spacing": [2, "always"], 19 | "brace-style": [2, "1tbs", { "allowSingleLine": true }], 20 | "comma-dangle": [2, "never"], 21 | "comma-spacing": [2, { "before": false, "after": true }], 22 | "comma-style": [2, "last"], 23 | "constructor-super": 2, 24 | "curly": [2, "multi-line"], 25 | "dot-location": [2, "property"], 26 | "eol-last": 2, 27 | "eqeqeq": [2, "allow-null"], 28 | "generator-star-spacing": [2, { "before": true, "after": true }], 29 | "handle-callback-err": [2, "^(err|error)$" ], 30 | "indent": [2, 2, { "SwitchCase": 1 }], 31 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }], 32 | "keyword-spacing": [2, { "before": true, "after": true }], 33 | "new-cap": [2, { "newIsCap": true, "capIsNew": false }], 34 | "new-parens": 2, 35 | "no-array-constructor": 2, 36 | "no-caller": 2, 37 | "no-class-assign": 2, 38 | "no-cond-assign": 2, 39 | "no-const-assign": 2, 40 | "no-control-regex": 2, 41 | "no-debugger": 2, 42 | "no-delete-var": 2, 43 | "no-dupe-args": 2, 44 | "no-dupe-class-members": 2, 45 | "no-dupe-keys": 2, 46 | "no-duplicate-case": 2, 47 | "no-empty-character-class": 2, 48 | "no-eval": 2, 49 | "no-ex-assign": 2, 50 | "no-extend-native": 2, 51 | "no-extra-bind": 2, 52 | "no-extra-boolean-cast": 2, 53 | "no-extra-parens": [2, "functions"], 54 | "no-fallthrough": 2, 55 | "no-floating-decimal": 2, 56 | "no-func-assign": 2, 57 | "no-implied-eval": 2, 58 | "no-inner-declarations": [2, "functions"], 59 | "no-invalid-regexp": 2, 60 | "no-irregular-whitespace": 2, 61 | "no-iterator": 2, 62 | "no-label-var": 2, 63 | "no-labels": 2, 64 | "no-lone-blocks": 2, 65 | "no-mixed-spaces-and-tabs": 2, 66 | "no-multi-spaces": 2, 67 | "no-multi-str": 2, 68 | "no-multiple-empty-lines": [2, { "max": 1 }], 69 | "no-native-reassign": 0, 70 | "no-negated-in-lhs": 2, 71 | "no-new": 2, 72 | "no-new-func": 2, 73 | "no-new-object": 2, 74 | "no-new-require": 2, 75 | "no-new-wrappers": 2, 76 | "no-obj-calls": 2, 77 | "no-octal": 2, 78 | "no-octal-escape": 2, 79 | "no-proto": 0, 80 | "no-redeclare": 2, 81 | "no-regex-spaces": 2, 82 | "no-return-assign": 2, 83 | "no-self-compare": 2, 84 | "no-sequences": 2, 85 | "no-shadow-restricted-names": 2, 86 | "no-spaced-func": 2, 87 | "no-sparse-arrays": 2, 88 | "no-this-before-super": 2, 89 | "no-throw-literal": 2, 90 | "no-trailing-spaces": 0, 91 | "no-undef": 2, 92 | "no-undef-init": 2, 93 | "no-unexpected-multiline": 2, 94 | "no-unneeded-ternary": [2, { "defaultAssignment": false }], 95 | "no-unreachable": 2, 96 | "no-unused-vars": [2, { "vars": "all", "args": "none" }], 97 | "no-useless-call": 0, 98 | "no-with": 2, 99 | "one-var": [0, { "initialized": "never" }], 100 | "operator-linebreak": [0, "after", { "overrides": { "?": "before", ":": "before" } }], 101 | "padded-blocks": [0, "never"], 102 | "quotes": [2, "single", "avoid-escape"], 103 | "radix": 2, 104 | "semi": [2, "always"], 105 | "semi-spacing": [2, { "before": false, "after": true }], 106 | "space-before-blocks": [2, "always"], 107 | "space-before-function-paren": [2, "never"], 108 | "space-in-parens": [2, "never"], 109 | "space-infix-ops": 2, 110 | "space-unary-ops": [2, { "words": true, "nonwords": false }], 111 | "spaced-comment": [0, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }], 112 | "use-isnan": 2, 113 | "valid-typeof": 2, 114 | "wrap-iife": [2, "any"], 115 | "yoda": [2, "never"] 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Enforce Unix newlines 2 | * text eol=lf 3 | 4 | # binaries 5 | *.ai binary 6 | *.psd binary 7 | *.jpg binary 8 | *.gif binary 9 | *.png binary 10 | *.jpeg binary 11 | -------------------------------------------------------------------------------- /.github/contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to hekyll 2 | 3 | First and foremost, thank you! We appreciate that you want to contribute to hekyll, your time is valuable, and your contributions mean a lot to us. 4 | 5 | **What does "contributing" mean?** 6 | 7 | Creating an issue is the simplest form of contributing to a project. But there are many ways to contribute, including the following: 8 | 9 | - Updating or correcting documentation 10 | - Feature requests 11 | - Bug reports 12 | 13 | If you'd like to learn more about contributing in general, the [Guide to Idiomatic Contributing](https://github.com/jonschlinkert/idiomatic-contributing) has a lot of useful information. 14 | 15 | **Showing support for hekyll** 16 | 17 | Please keep in mind that open source software is built by people like you, who spend their free time creating things the rest the community can use. 18 | 19 | Don't have time to contribute? No worries, here are some other ways to show your support for hekyll: 20 | 21 | - star the [project](https://github.com/jonschlinkert/hekyll) 22 | - tweet your support for hekyll 23 | 24 | ## Issues 25 | 26 | ### Before creating an issue 27 | 28 | Please try to determine if the issue is caused by an underlying library, and if so, create the issue there. Sometimes this is difficult to know. We only ask that you attempt to give a reasonable attempt to find out. Oftentimes the readme will have advice about where to go to create issues. 29 | 30 | Try to follow these guidelines 31 | 32 | - **Investigate the issue**: 33 | - **Check the readme** - oftentimes you will find notes about creating issues, and where to go depending on the type of issue. 34 | - Create the issue in the appropriate repository. 35 | 36 | ### Creating an issue 37 | 38 | Please be as descriptive as possible when creating an issue. Give us the information we need to successfully answer your question or address your issue by answering the following in your issue: 39 | 40 | - **version**: please note the version of hekyll are you using 41 | - **extensions, plugins, helpers, etc** (if applicable): please list any extensions you're using 42 | - **error messages**: please paste any error messages into the issue, or a [gist](https://gist.github.com/) 43 | 44 | ## Above and beyond 45 | 46 | Here are some tips for creating idiomatic issues. Taking just a little bit extra time will make your issue easier to read, easier to resolve, more likely to be found by others who have the same or similar issue in the future. 47 | 48 | - read the [Guide to Idiomatic Contributing](https://github.com/jonschlinkert/idiomatic-contributing) 49 | - take some time to learn basic markdown. This [markdown cheatsheet](https://gist.github.com/jonschlinkert/5854601) is super helpful, as is the GitHub guide to [basic markdown](https://help.github.com/articles/markdown-basics/). 50 | - Learn about [GitHub Flavored Markdown](https://help.github.com/articles/github-flavored-markdown/). And if you want to really go above and beyond, read [mastering markdown](https://guides.github.com/features/mastering-markdown/). 51 | - use backticks to wrap code. This ensures that code will retain its format, making it much more readable to others 52 | - use syntax highlighting by adding the correct language name after the first "code fence" 53 | 54 | 55 | [node-glob]: https://github.com/isaacs/node-glob 56 | [micromatch]: https://github.com/jonschlinkert/micromatch 57 | [so]: http://stackoverflow.com/questions/tagged/hekyll -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # always ignore files 2 | *.DS_Store 3 | .idea 4 | *.sublime-* 5 | 6 | # test related, or directories generated by tests 7 | test/actual 8 | actual 9 | coverage 10 | .nyc* 11 | 12 | # npm 13 | node_modules 14 | npm-debug.log 15 | 16 | # yarn 17 | yarn.lock 18 | yarn-error.log 19 | 20 | # misc 21 | _gh_pages 22 | _draft 23 | _drafts 24 | bower_components 25 | vendor 26 | temp 27 | tmp 28 | TODO.md 29 | package-lock.json -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | os: 3 | - linux 4 | - osx 5 | language: node_js 6 | node_js: 7 | - node 8 | - '8' 9 | - '7' 10 | - '6' 11 | - '5' 12 | - '4' 13 | -------------------------------------------------------------------------------- /.verb.md: -------------------------------------------------------------------------------- 1 | ## Usage 2 | 3 | ### Quickstart 4 | 5 | The easiest way to use hekyll is to call the static `.build` method with an options object. 6 | 7 | **Required options** 8 | 9 | At minimum, you will need to define the following: 10 | 11 | - `options.cwd` - the source directory with the jekyll theme to convert 12 | - `options.destBase` - the base destination directory to write the converted or copied files to. 13 | 14 | **Example** 15 | 16 | ```js 17 | var Hekyll = require('{%= name %}'); 18 | 19 | Hekyll.build({cwd: 'jekyll_theme_folder', destBase: 'output_folder'}) 20 | .then(function() { 21 | console.log('converted!'); 22 | }) 23 | .catch(console.error); 24 | ``` 25 | 26 | ### Custom 27 | 28 | The main export is a constructor function that takes an options object. Once an instance is created, you can use hekyll's methods to convert and copy files however you want. See [the API documentation](#api) for more details. 29 | 30 | **Example** 31 | 32 | ```js 33 | var Hekyll = require('{%= name %}'); 34 | var hekyll = new Hekyll({ 35 | cwd: 'jekyll_theme_folder', 36 | destBase: 'output_folder' 37 | }); 38 | 39 | function dest(dir) { 40 | return function(file) { 41 | return dir || ''; 42 | }; 43 | } 44 | 45 | hekyll.templates([ 46 | `{,_*/**/}*.{html,markdown,mdown,mkdown,mkdn,mkd,md,textile,liquid}`, 47 | '!**/{README*,LICENSE*,CONTRIBUTING*}' 48 | ], dest()) 49 | .then(hekyll.assets('{assets,public}/**', dest())) 50 | .then(hekyll.copy('_config.yml', dest())) 51 | .then(hekyll.copy('_data/**', dest('_data'))) 52 | .then(hekyll.copy('_sass/**', dest('_sass'))) 53 | .then(hekyll.copy('styles.scss', {addImport: 'custom'}, dest('_sass'))) 54 | .then(hekyll.copy('**/*.{xml,txt}', function(file) { 55 | file.extname += '.hbs'; 56 | return ''; 57 | })) 58 | .then(hekyll.text(dest())) 59 | .then(function() { 60 | console.log('done!'); 61 | }) 62 | .catch(console.error) 63 | ``` 64 | 65 | **Required Options** 66 | 67 | - `cwd`: the directory with source files for a Jekyll theme. 68 | - `destBase`: the base destination directory for the converted theme. 69 | 70 | ## API 71 | {%= apidocs("index.js") %} 72 | 73 | ## Choosing a theme 74 | 75 | ~20 jekyll themes were tested during the creation of this library, including all of the [poole/poole themes](https://github.com/poole/poole) from [@mdo](https://github.com/mdo), and all of the built-in [gh-pages themes](https://pages.github.com/themes/). Most themes convert flawlessly, but some have nuances that might require some manual editing. 76 | 77 | **Handlebars helpers** 78 | 79 | To be able to render the migrated templates with handlebars, you will first need to include any missing handlebars helpers that were converted from liquid filters and tags during the migration. 80 | 81 | Here are some libraries that might be useful for this: 82 | 83 | - [template-helpers][] - generic helpers that can be used with any template engine. 84 | - [handlebars-helpers][] - more than 150 handlebars helpers 85 | 86 | 87 | **Bug reports** 88 | 89 | If you find a bug or something that doesn't convert correctly, [please let me know](../../issues/new), I want this to work as seamlessly as possible. 90 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017, Jon Schlinkert. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hekyll [](https://www.npmjs.com/package/hekyll) [](https://npmjs.org/package/hekyll) [](https://npmjs.org/package/hekyll) [](https://travis-ci.org/jonschlinkert/hekyll) 2 | 3 | > Migrate Jekyll (gh-pages) themes to use handlebars instead of liquid. 4 | 5 | Follow this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), for updates on this project and others. 6 | 7 | ## Install 8 | 9 | Install with [npm](https://www.npmjs.com/): 10 | 11 | ```sh 12 | $ npm install --save hekyll 13 | ``` 14 | 15 | ## Usage 16 | 17 | ### Quickstart 18 | 19 | The easiest way to use hekyll is to call the static `.build` method with an options object. 20 | 21 | **Required options** 22 | 23 | At minimum, you will need to define the following: 24 | 25 | * `options.cwd` - the source directory with the jekyll theme to convert 26 | * `options.destBase` - the base destination directory to write the converted or copied files to. 27 | 28 | **Example** 29 | 30 | ```js 31 | var Hekyll = require('hekyll'); 32 | 33 | Hekyll.build({cwd: 'jekyll_theme_folder', destBase: 'output_folder'}) 34 | .then(function() { 35 | console.log('converted!'); 36 | }) 37 | .catch(console.error); 38 | ``` 39 | 40 | ### Custom 41 | 42 | The main export is a constructor function that takes an options object. Once an instance is created, you can use hekyll's methods to convert and copy files however you want. See [the API documentation](#api) for more details. 43 | 44 | **Example** 45 | 46 | ```js 47 | var Hekyll = require('hekyll'); 48 | var hekyll = new Hekyll({ 49 | cwd: 'jekyll_theme_folder', 50 | destBase: 'output_folder' 51 | }); 52 | 53 | function dest(dir) { 54 | return function(file) { 55 | return dir || ''; 56 | }; 57 | } 58 | 59 | hekyll.templates([ 60 | `{,_*/**/}*.{html,markdown,mdown,mkdown,mkdn,mkd,md,textile,liquid}`, 61 | '!**/{README*,LICENSE*,CONTRIBUTING*}' 62 | ], dest()) 63 | .then(hekyll.assets('{assets,public}/**', dest())) 64 | .then(hekyll.copy('_config.yml', dest())) 65 | .then(hekyll.copy('_data/**', dest('_data'))) 66 | .then(hekyll.copy('_sass/**', dest('_sass'))) 67 | .then(hekyll.copy('styles.scss', {addImport: 'custom'}, dest('_sass'))) 68 | .then(hekyll.copy('**/*.{xml,txt}', function(file) { 69 | file.extname += '.hbs'; 70 | return ''; 71 | })) 72 | .then(hekyll.text(dest())) 73 | .then(function() { 74 | console.log('done!'); 75 | }) 76 | .catch(console.error) 77 | ``` 78 | 79 | **Required Options** 80 | 81 | * `cwd`: the directory with source files for a Jekyll theme. 82 | * `destBase`: the base destination directory for the converted theme. 83 | 84 | ## API 85 | 86 | ### [Hekyll](index.js#L20) 87 | 88 | Create an instance of `Hekyll` with the given `options`. 89 | 90 | **Params** 91 | 92 | * `options` **{Object}** 93 | 94 | **Example** 95 | 96 | ```js 97 | var Hekyll = require('hekyll'); 98 | var hekyll = new Hekyll(); 99 | ``` 100 | 101 | ### [.templates](index.js#L42) 102 | 103 | Copies and converts liquid templates to handlebars templates using the given glob `patterns`, `options` and `dest` function. 104 | 105 | **Params** 106 | 107 | * `patterns` **{String|Array}** 108 | * `options` **{Object}** 109 | * `dest` **{Function}**: Must return a string. 110 | * `returns` **{Promise}** 111 | 112 | **Example** 113 | 114 | ```js 115 | hekyll.templates(patterns, {destBase: 'foo'}, function(file) { 116 | // optionally do stuff to vinyl "file" object 117 | // the returned folder is joined to `options.destBase` 118 | return 'folder_name'; 119 | }); 120 | ``` 121 | 122 | ### [.copy](index.js#L98) 123 | 124 | Copies files using the given glob `patterns`, `options` and `dest` function. Converts liquid templates and strips front matter from files. 125 | 126 | **Params** 127 | 128 | * `patterns` **{String|Array}** 129 | * `options` **{Object}** 130 | * `dest` **{Function}**: Must return a string. 131 | * `returns` **{Promise}** 132 | 133 | **Example** 134 | 135 | ```js 136 | hekyll.copy(patterns, {destBase: 'foo'}, function(file) { 137 | return ''; 138 | }); 139 | ``` 140 | 141 | ### [.assets](index.js#L134) 142 | 143 | Copies assets files using the given glob `patterns`, `options` and `dest` function. Does not read the files or modify file contents in any way. 144 | 145 | **Params** 146 | 147 | * `patterns` **{String|Array}** 148 | * `options` **{Object}** 149 | * `dest` **{Function}**: Must return a string. 150 | * `returns` **{Promise}** 151 | 152 | **Example** 153 | 154 | ```js 155 | hekyll.assets(patterns, {destBase: 'foo'}, function(file) { 156 | return ''; 157 | }); 158 | ``` 159 | 160 | ### [.text](index.js#L162) 161 | 162 | Copies plain text files using the given glob `patterns`, `options` and `dest` function. Strips front-matter, but does not attempt to convert templates. 163 | 164 | **Params** 165 | 166 | * `patterns` **{String|Array}** 167 | * `options` **{Object}** 168 | * `dest` **{Function}**: Must return a string. 169 | * `returns` **{Promise}** 170 | 171 | **Example** 172 | 173 | ```js 174 | hekyll.text(patterns, {destBase: 'foo'}, function(file) { 175 | return ''; 176 | }); 177 | ``` 178 | 179 | ## Choosing a theme 180 | 181 | ~20 jekyll themes were tested during the creation of this library, including all of the [poole/poole themes](https://github.com/poole/poole) from [@mdo](https://github.com/mdo), and all of the built-in [gh-pages themes](https://pages.github.com/themes/). Most themes convert flawlessly, but some have nuances that might require some manual editing. 182 | 183 | **Handlebars helpers** 184 | 185 | To be able to render the migrated templates with handlebars, you will first need to include any missing handlebars helpers that were converted from liquid filters and tags during the migration. 186 | 187 | Here are some libraries that might be useful for this: 188 | 189 | * [template-helpers](https://github.com/jonschlinkert/template-helpers) - generic helpers that can be used with any template engine. 190 | * [handlebars-helpers](https://github.com/helpers/handlebars-helpers) - more than 150 handlebars helpers 191 | 192 | **Bug reports** 193 | 194 | If you find a bug or something that doesn't convert correctly, [please let me know](../../issues/new), I want this to work as seamlessly as possible. 195 | 196 | ## About 197 | 198 | ### Related projects 199 | 200 | You might also be interested in these projects: 201 | 202 | * [assemble](https://www.npmjs.com/package/assemble): Get the rocks out of your socks! Assemble makes you fast at creating web projects… [more](https://github.com/assemble/assemble) | [homepage](https://github.com/assemble/assemble "Get the rocks out of your socks! Assemble makes you fast at creating web projects. Assemble is used by thousands of projects for rapid prototyping, creating themes, scaffolds, boilerplates, e-books, UI components, API documentation, blogs, building websit") 203 | * [gulp-liquid-to-handlebars](https://www.npmjs.com/package/gulp-liquid-to-handlebars): Convert liquid templates to handlebars templates. There are so many resources for jekyll and liquid… [more](https://github.com/jonschlinkert/gulp-liquid-to-handlebars) | [homepage](https://github.com/jonschlinkert/gulp-liquid-to-handlebars "Convert liquid templates to handlebars templates. There are so many resources for jekyll and liquid on github, but handlebars is a better engine for javascript. ") 204 | * [liquid-to-handlebars](https://www.npmjs.com/package/liquid-to-handlebars): Convert liquid templates to handlebars templates. | [homepage](https://github.com/jonschlinkert/liquid-to-handlebars "Convert liquid templates to handlebars templates.") 205 | 206 | ### Contributing 207 | 208 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). 209 | 210 | Please read the [contributing guide](.github/contributing.md) for advice on opening issues, pull requests, and coding standards. 211 | 212 | ### Building docs 213 | 214 | _(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_ 215 | 216 | To generate the readme, run the following command: 217 | 218 | ```sh 219 | $ npm install -g verbose/verb#dev verb-generate-readme && verb 220 | ``` 221 | 222 | ### Running tests 223 | 224 | Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command: 225 | 226 | ```sh 227 | $ npm install && npm test 228 | ``` 229 | 230 | ### Author 231 | 232 | **Jon Schlinkert** 233 | 234 | * [github/jonschlinkert](https://github.com/jonschlinkert) 235 | * [twitter/jonschlinkert](https://twitter.com/jonschlinkert) 236 | 237 | ### License 238 | 239 | Copyright © 2017, [Jon Schlinkert](https://github.com/jonschlinkert). 240 | Released under the [MIT License](LICENSE). 241 | 242 | *** 243 | 244 | _This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on September 21, 2017._ -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # Release history 2 | 3 | ## v3.0.0 4 | 5 | **Breaking changes** 6 | 7 | Refactored again to make hekyll more customizable. The API is almost the same, with a couple of differences. 8 | 9 | - call `hekyll.build({cwd: 'foo', destBase: 'bar'})` instead of `hekyll({src: 'foo', dest: 'bar'})` 10 | 11 | ## v2.0.0 12 | 13 | **Breaking changes** 14 | 15 | Refactored to simplify. See [Usage](readme.md#usage) section for the new API. 16 | 17 | ## v1.0.0 18 | 19 | First release. -------------------------------------------------------------------------------- /custom.scss: -------------------------------------------------------------------------------- 1 | // nothing 2 | -------------------------------------------------------------------------------- /examples/build.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var Hekyll = require('./'); 3 | 4 | Hekyll.build({cwd: path.join(__dirname, '../vendor/poole'), destBase: 'temp/src'}) 5 | .then(function() { 6 | console.log('done!'); 7 | }) 8 | .catch(console.error); 9 | -------------------------------------------------------------------------------- /examples/ctor.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var Hekyll = require('..'); 3 | var hekyll = new Hekyll({ 4 | cwd: path.join(__dirname, '../vendor/poole'), 5 | destBase: 'temp/src' 6 | }); 7 | 8 | var patterns = [ 9 | '{,_*/**/}*.{html,markdown,mdown,mkdown,mkdn,mkd,md,textile,liquid}', 10 | '!**/{README*,LICENSE*,CONTRIBUTING*}' 11 | ]; 12 | 13 | function dest(dir) { 14 | return function(file) { 15 | return dir || ''; 16 | }; 17 | } 18 | 19 | hekyll.templates(patterns, dest()) 20 | .then(hekyll.assets('{assets,public}/**', dest())) 21 | .then(hekyll.copy('_config.yml', dest())) 22 | .then(hekyll.copy('_data/**', dest('_data'))) 23 | .then(hekyll.copy('_sass/**', dest('_sass'))) 24 | .then(hekyll.copy('styles.scss', {addImport: 'custom'}, dest('_sass'))) 25 | .then(hekyll.copy('**/*.{xml,txt}', function(file) { 26 | file.extname += '.hbs'; 27 | return ''; 28 | })) 29 | .then(hekyll.text(dest())) 30 | .then(function() { 31 | console.log('done!'); 32 | }) 33 | .catch(console.error); 34 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const vfs = require('vinyl-fs'); 5 | const through = require('through2'); 6 | const plugin = require('./lib/plugins'); 7 | const utils = require('./lib/utils'); 8 | 9 | /** 10 | * Create an instance of `Hekyll` with the given `options`. 11 | * 12 | * ```js 13 | * var Hekyll = require('hekyll'); 14 | * var hekyll = new Hekyll(); 15 | * ``` 16 | * @param {Object} `options` 17 | * @api public 18 | */ 19 | 20 | function Hekyll(options) { 21 | this.options = Object.assign({}, options); 22 | } 23 | 24 | /** 25 | * Copies and converts liquid templates to handlebars templates 26 | * using the given glob `patterns`, `options` and `dest` function. 27 | * 28 | * ```js 29 | * hekyll.templates(patterns, {destBase: 'foo'}, function(file) { 30 | * // optionally do stuff to vinyl "file" object 31 | * // the returned folder is joined to `options.destBase` 32 | * return 'folder_name'; 33 | * }); 34 | * ``` 35 | * @param {String|Array} `patterns` 36 | * @param {Object} `options` 37 | * @param {Function} `dest` Must return a string. 38 | * @return {Promise} 39 | * @api public 40 | */ 41 | 42 | Hekyll.prototype.templates = function(patterns, options, dest) { 43 | const opts = utils.toOptions(this, options, dest); 44 | if (utils.isPromise(opts)) return opts; 45 | 46 | return new Promise(function(resolve, reject) { 47 | vfs.src(patterns, opts) 48 | .pipe(plugin.normalizeNewlines()) 49 | .on('error', reject) 50 | .pipe(plugin.stripEmptyMatter()) 51 | .on('error', reject) 52 | .pipe(plugin.convert({prefix: '@'})) 53 | .on('error', reject) 54 | .pipe(plugin.format()) 55 | .on('error', reject) 56 | .pipe(plugin.wrapFrame(['page', 'site'])) 57 | .on('error', reject) 58 | .pipe(vfs.dest(function(file) { 59 | switch (file.extname) { 60 | case '.html': 61 | case '.liquid': 62 | file.extname = '.hbs'; 63 | break; 64 | case '.markdown': 65 | case '.mkdown': 66 | case '.mkdn': 67 | case '.mkd': 68 | case '.mdown': 69 | case '.md': 70 | file.extname = '.md'; 71 | break; 72 | case '.yaml': 73 | file.extname = '.yml'; 74 | break; 75 | } 76 | return utils.toDest(opts)(file); 77 | })) 78 | .on('error', reject) 79 | .on('end', resolve); 80 | }); 81 | }; 82 | 83 | /** 84 | * Copies files using the given glob `patterns`, `options` and `dest` 85 | * function. Converts liquid templates and strips front matter from files. 86 | * 87 | * ```js 88 | * hekyll.copy(patterns, {destBase: 'foo'}, function(file) { 89 | * return ''; 90 | * }); 91 | * ``` 92 | * @param {String|Array} `patterns` 93 | * @param {Object} `options` 94 | * @param {Function} `dest` Must return a string. 95 | * @return {Promise} 96 | * @api public 97 | */ 98 | 99 | Hekyll.prototype.copy = function(patterns, options, dest) { 100 | const opts = utils.toOptions(this, options, dest); 101 | if (utils.isPromise(opts)) return opts; 102 | 103 | return new Promise(function(resolve, reject) { 104 | vfs.src(patterns, opts) 105 | .pipe(plugin.stripEmptyMatter()) 106 | .on('error', reject) 107 | .pipe(plugin.convert({yfm: false, prefix: '@'})) 108 | .on('error', reject) 109 | .pipe(plugin.wrapFrame(['page', 'site'])) 110 | .pipe(plugin.addImport(opts)) 111 | .on('error', reject) 112 | .pipe(plugin.trim()) 113 | .on('error', reject) 114 | .pipe(vfs.dest(utils.toDest(opts))) 115 | .on('error', reject) 116 | .on('end', resolve); 117 | }); 118 | }; 119 | 120 | /** 121 | * Copies assets files using the given glob `patterns`, `options` and `dest` 122 | * function. Does not read the files or modify file contents in any way. 123 | * 124 | * ```js 125 | * hekyll.assets(patterns, {destBase: 'foo'}, function(file) { 126 | * return ''; 127 | * }); 128 | * ``` 129 | * @param {String|Array} `patterns` 130 | * @param {Object} `options` 131 | * @param {Function} `dest` Must return a string. 132 | * @return {Promise} 133 | * @api public 134 | */ 135 | 136 | Hekyll.prototype.assets = function(patterns, options, dest) { 137 | const opts = utils.toOptions(this, options, dest); 138 | if (utils.isPromise(opts)) return opts; 139 | 140 | return new Promise(function(resolve, reject) { 141 | vfs.src(patterns, opts) 142 | .pipe(vfs.dest(utils.toDest(opts))) 143 | .on('error', reject) 144 | .on('end', resolve); 145 | }); 146 | }; 147 | 148 | /** 149 | * Copies plain text files using the given glob `patterns`, `options` and `dest` 150 | * function. Strips front-matter, but does not attempt to convert templates. 151 | * 152 | * ```js 153 | * hekyll.text(patterns, {destBase: 'foo'}, function(file) { 154 | * return ''; 155 | * }); 156 | * ``` 157 | * @param {String|Array} `patterns` 158 | * @param {Object} `options` 159 | * @param {Function} `dest` Must return a string. 160 | * @return {Promise} 161 | * @api public 162 | */ 163 | 164 | Hekyll.prototype.text = function(options, dest) { 165 | const opts = utils.toOptions(this, options, dest); 166 | if (utils.isPromise(opts)) return opts; 167 | 168 | const patterns = opts.patterns || [ 169 | '**/*', 170 | `!**/{_*,assets,public,*.{html,liquid,${utils.MDEXTS},scss,txt,xml}}`, 171 | '!**/{*.,}gem*', 172 | '!**/script{,/**}', 173 | '!**/.git{,/**}' 174 | ]; 175 | 176 | return new Promise(function(resolve, reject) { 177 | vfs.src(patterns, opts) 178 | .pipe(plugin.stripEmptyMatter()) 179 | .on('error', reject) 180 | .pipe(plugin.convert({prefix: '@'})) 181 | .on('error', reject) 182 | .pipe(vfs.dest(utils.toDest(opts))) 183 | .on('error', reject) 184 | .on('end', resolve); 185 | }); 186 | }; 187 | 188 | Hekyll.build = function(options) { 189 | if (!options) { 190 | return Promise.reject('expected options to be an object'); 191 | } 192 | 193 | const hekyll = new Hekyll(options); 194 | const patterns = hekyll.options.patterns || [ 195 | `{,_*/**/}*.{html,liquid,${utils.MDEXTS},textile}` 196 | ]; 197 | 198 | function dest(dir) { 199 | return function(file) { 200 | return dir || ''; 201 | }; 202 | } 203 | 204 | return hekyll.templates(patterns, dest()) 205 | .then(hekyll.assets('{assets,public}/**', dest())) 206 | .then(hekyll.copy('**/*.{xml,txt}', dest())) 207 | .then(hekyll.copy('_config.yml', dest())) 208 | .then(hekyll.copy('_data/**', dest('_data'))) 209 | .then(hekyll.copy('_sass/**', dest('_sass'))) 210 | .then(hekyll.copy('styles.scss', {addImport: 'custom'}, dest('_sass'))) 211 | .then(hekyll.copy(path.join(__dirname, 'custom.scss'), dest('_sass'))) 212 | .then(hekyll.text(dest())); 213 | }; 214 | 215 | /** 216 | * Expose `Hekyll` 217 | */ 218 | 219 | module.exports = Hekyll; 220 | -------------------------------------------------------------------------------- /lib/plugins.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const convert = require('liquid-to-handlebars'); 4 | const PluginError = require('plugin-error'); 5 | const isBinary = require('file-is-binary'); 6 | const through = require('through2'); 7 | const utils = require('./utils'); 8 | 9 | exports.trim = function() { 10 | return plugin(function(file, next) { 11 | file.contents = new Buffer(file.contents.toString().trim() + '\n'); 12 | next(null, file); 13 | }); 14 | }; 15 | 16 | exports.convert = function(options) { 17 | var md = utils.MDEXTS.split(',').join('|'); 18 | var re = new RegExp(`^\\.(${md}|html|liquid|scss|xml|txt)$`); 19 | return plugin(function(file, next) { 20 | if (!re.test(file.extname)) { 21 | next(null, file); 22 | return; 23 | } 24 | file.contents = new Buffer(convert(file.contents.toString(), options)); 25 | next(null, file); 26 | }); 27 | }; 28 | 29 | exports.wrapFrame = function(props) { 30 | return plugin(function(file, next) { 31 | let str = file.contents.toString(); 32 | if (!/{{/.test(str)) { 33 | next(null, file); 34 | return; 35 | } 36 | 37 | if (str.slice(0, 3) !== '---') { 38 | const hash = props.map(function(prop) { 39 | return prop + '=' + prop; 40 | }); 41 | str = `{{#frame ${hash.join(' ')}}}\n` + str.trim() + '\n{{/frame}}\n'; 42 | file.contents = new Buffer(str); 43 | } 44 | next(null, file); 45 | }); 46 | }; 47 | 48 | exports.format = function() { 49 | return plugin(function(file, next) { 50 | let str = file.contents.toString(); 51 | 52 | // fix main `styles.css` path 53 | str = str.replace(/\/(?=styles\.css)/, '/assets/css/'); 54 | 55 | // strip leading indentation before {{markdown}} tags 56 | str = str.replace(/^\s+(\{\{(\/|#)?(?:markdown|md))/gm, '$1'); 57 | file.contents = new Buffer(str); 58 | next(null, file); 59 | }); 60 | }; 61 | 62 | exports.normalizeNewlines = function() { 63 | return plugin(function(file, next) { 64 | let str = file.contents.toString(); 65 | file.contents = new Buffer(str.replace(/\r\n/g, '\n')); 66 | next(null, file); 67 | }); 68 | }; 69 | 70 | exports.addImport = function(options) { 71 | return plugin(function(file, next) { 72 | if (!options || typeof options.addImport !== 'string') { 73 | next(null, file); 74 | return; 75 | } 76 | let str = file.contents.toString().trim(); 77 | file.contents = new Buffer(str + `\n@import "${options.addImport}";\n`); 78 | next(null, file); 79 | }); 80 | }; 81 | 82 | exports.stripEmptyMatter = function() { 83 | return plugin(function(file, next) { 84 | let str = file.contents.toString(); 85 | if (str.slice(0, 8) === '---\n---\n') { 86 | file.contents = new Buffer(str.slice(8)); 87 | } 88 | next(null, file); 89 | }); 90 | }; 91 | 92 | function plugin(fn) { 93 | return through.obj(function(file, enc, next) { 94 | try { 95 | if (isBinary(file) || file.isNull()) { 96 | next(null, file); 97 | return; 98 | } 99 | fn(file, next); 100 | } catch (err) { 101 | err.fn = fn; 102 | this.emit('error', new PluginError('hekyll', err, {showStack: true})); 103 | next(err); 104 | } 105 | }); 106 | } 107 | -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | exports.MDEXTS = 'markdown,mkdown,mdown,mkdn,mkd,md'; 5 | 6 | exports.isPromise = function(val) { 7 | return val && typeof val.then === 'function'; 8 | }; 9 | 10 | exports.toDest = function(options) { 11 | return function(file) { 12 | file.extname = file.extname.replace(/liquid/, 'hbs'); 13 | return path.resolve(options.destBase, options.dest(file)); 14 | }; 15 | }; 16 | 17 | exports.toOptions = function(app, options, dest) { 18 | if (typeof options === 'function') { 19 | dest = options; 20 | options = null; 21 | } 22 | const defaults = {allowEmpty: true, dot: true, nocase: true, dest: dest}; 23 | const opts = Object.assign({}, defaults, app.options, options); 24 | if (typeof opts.dest !== 'function') { 25 | return Promise.reject(new TypeError('expected options.dest to be a function')); 26 | } 27 | if (typeof opts.destBase !== 'string') { 28 | return Promise.reject(new TypeError('expected options.destBase to be a string')); 29 | } 30 | if (typeof opts.cwd !== 'string') { 31 | return Promise.reject(new TypeError('expected options.cwd to be a string')); 32 | } 33 | return opts; 34 | }; 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hekyll", 3 | "description": "Migrate Jekyll (gh-pages) themes to use handlebars instead of liquid.", 4 | "version": "3.0.3", 5 | "homepage": "https://github.com/jonschlinkert/hekyll", 6 | "author": "Jon Schlinkert (https://github.com/jonschlinkert)", 7 | "repository": "jonschlinkert/hekyll", 8 | "bugs": { 9 | "url": "https://github.com/jonschlinkert/hekyll/issues" 10 | }, 11 | "license": "MIT", 12 | "files": [ 13 | "index.js", 14 | "lib" 15 | ], 16 | "main": "index.js", 17 | "engines": { 18 | "node": ">=4" 19 | }, 20 | "scripts": { 21 | "test": "mocha" 22 | }, 23 | "dependencies": { 24 | "file-is-binary": "^1.0.0", 25 | "gulp-liquid-to-handlebars": "^1.0.1", 26 | "plugin-error": "^0.1.2", 27 | "through2": "^2.0.3", 28 | "vinyl-fs": "^2.4.4" 29 | }, 30 | "devDependencies": { 31 | "delete": "^1.1.0", 32 | "gulp-format-md": "^1.0.0", 33 | "mocha": "^3.5.0" 34 | }, 35 | "keywords": [ 36 | "assemble", 37 | "blog", 38 | "convert", 39 | "converter", 40 | "gh-pages", 41 | "github-pages", 42 | "gulp", 43 | "handlebars", 44 | "hekyll", 45 | "jekyll", 46 | "liquid", 47 | "migrate", 48 | "migrator", 49 | "pages", 50 | "site", 51 | "templates", 52 | "theme", 53 | "website" 54 | ], 55 | "lintDeps": { 56 | "lock": { 57 | "options": { 58 | "cheerio": "0.22.0" 59 | } 60 | }, 61 | "devDependencies": { 62 | "files": { 63 | "patterns": [ 64 | "*.js" 65 | ] 66 | } 67 | } 68 | }, 69 | "verb": { 70 | "toc": false, 71 | "layout": "default", 72 | "tasks": [ 73 | "readme" 74 | ], 75 | "plugins": [ 76 | "gulp-format-md" 77 | ], 78 | "related": { 79 | "list": [ 80 | "assemble", 81 | "gulp-liquid-to-handlebars", 82 | "liquid-to-handlebars" 83 | ] 84 | }, 85 | "reflinks": [ 86 | "assemble", 87 | "gulp", 88 | "handlebars-helpers", 89 | "template-helpers" 90 | ], 91 | "lint": { 92 | "reflinks": true 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /test/fixtures/404.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: "404: Page not found" 4 | permalink: 404.html 5 | --- 6 | 7 |
Sorry, we've misplaced that URL or it's pointing to something that doesn't exist. Head back home to try finding it again.
10 |` element. Snippets of multiple lines of code are supported through Pygments. Longer lines will automatically scroll horizontally when needed.
53 |
54 | {% highlight js %}
55 | // Example can be run directly in your JavaScript console
56 |
57 | // Create a function that takes two arguments and returns the sum of those arguments
58 | var adder = new Function("a", "b", "return a + b");
59 |
60 | // Call the function
61 | adder(2, 6);
62 | // > 8
63 | {% endhighlight %}
64 |
65 | You may also optionally show code snippets with line numbers. Add `linenos` to the Pygments tags.
66 |
67 | {% highlight js linenos %}
68 | // Example can be run directly in your JavaScript console
69 |
70 | // Create a function that takes two arguments and returns the sum of those arguments
71 | var adder = new Function("a", "b", "return a + b");
72 |
73 | // Call the function
74 | adder(2, 6);
75 | // > 8
76 | {% endhighlight %}
77 |
78 | Aenean lacinia bibendum nulla sed consectetur. Etiam porta sem malesuada magna mollis euismod. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa.
79 |
80 | ### Gists via GitHub Pages
81 |
82 | Vestibulum id ligula porta felis euismod semper. Nullam quis risus eget urna mollis ornare vel eu leo. Donec sed odio dui.
83 |
84 | {% gist 13f94b734a4ddb132735 gist.md %}
85 |
86 | Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec sed odio dui. Vestibulum id ligula porta felis euismod semper.
87 |
88 | ### Lists
89 |
90 | Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean lacinia bibendum nulla sed consectetur. Etiam porta sem malesuada magna mollis euismod. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.
91 |
92 | * Praesent commodo cursus magna, vel scelerisque nisl consectetur et.
93 | * Donec id elit non mi porta gravida at eget metus.
94 | * Nulla vitae elit libero, a pharetra augue.
95 |
96 | Donec ullamcorper nulla non metus auctor fringilla. Nulla vitae elit libero, a pharetra augue.
97 |
98 | 1. Vestibulum id ligula porta felis euismod semper.
99 | 2. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
100 | 3. Maecenas sed diam eget risus varius blandit sit amet non magna.
101 |
102 | Cras mattis consectetur purus sit amet fermentum. Sed posuere consectetur est at lobortis.
103 |
104 |
105 | - HyperText Markup Language (HTML)
106 | - The language used to describe and define the content of a Web page
107 |
108 | - Cascading Style Sheets (CSS)
109 | - Used to describe the appearance of Web content
110 |
111 | - JavaScript (JS)
112 | - The programming language used to build advanced Web sites and applications
113 |
114 |
115 | Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Nullam quis risus eget urna mollis ornare vel eu leo.
116 |
117 | ### Images
118 |
119 | Quisque consequat sapien eget quam rhoncus, sit amet laoreet diam tempus. Aliquam aliquam metus erat, a pulvinar turpis suscipit at.
120 |
121 | 
122 | 
123 | 
124 |
125 | ### Tables
126 |
127 | Aenean lacinia bibendum nulla sed consectetur. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
128 |
129 |
130 |
131 |
132 | Name
133 | Upvotes
134 | Downvotes
135 |
136 |
137 |
138 |
139 | Totals
140 | 21
141 | 23
142 |
143 |
144 |
145 |
146 | Alice
147 | 10
148 | 11
149 |
150 |
151 | Bob
152 | 4
153 | 3
154 |
155 |
156 | Charlie
157 | 7
158 | 9
159 |
160 |
161 |
162 |
163 | Nullam id dolor id nibh ultricies vehicula ut id elit. Sed posuere consectetur est at lobortis. Nullam quis risus eget urna mollis ornare vel eu leo.
164 |
165 | -----
166 |
167 | Want to see something else added? Open an issue.
168 |
169 | [^fn-sample_footnote]: Handy! Now click the return link to go back.
170 |
--------------------------------------------------------------------------------
/test/fixtures/_posts/2016-01-03-introduction.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: post
3 | title: Introduction
4 | ---
5 |
6 | *The Strange Case of Dr. Jekyll and Mr. Hyde* tells the story of a lawyer investigating the connection of two persons, Dr. Henry Jekyll and Mr. Edward Hyde. Chief among the novel's supporting cast is a man by the name of Mr. Poole, Dr. Jekyll's loyal butler.
7 |
8 | -----
9 |
10 | Poole is the butler for [Jekyll](http://jekyllrb.com), the static site generator. It's designed and developed by [@mdo](https://twitter.com/mdo) to provide a clear and concise foundational setup for any Jekyll site. It does so by furnishing a full vanilla Jekyll install with example layouts, pages, posts, and styles.
11 |
12 | There are currently three themes built on Poole:
13 |
14 | * [Hyde](http://hyde.getpoole.com)
15 | * [Lanyon](http://lanyon.getpoole.com)
16 | * [Enfield](http://enfield.getpoole.com)
17 |
18 | Learn more and contribute on [GitHub]({{ site.github.repo }}).
19 |
20 | ### What's included
21 |
22 | Poole is a streamlined Jekyll site designed and built as a foundation for building more meaningful themes. Poole, and every theme built on it like this one, includes the following:
23 |
24 | * Complete Jekyll setup included (layouts, config, [404]({{ site.baseurl }}/404.html), [RSS feed]({{ site.baseurl }}/atom.xml), posts, and [example page]({{ site.baseurl }}/about))
25 | * Mobile friendly design and development
26 | * Easily scalable text and component sizing with `rem` units in the CSS
27 | * Support for a wide gamut of HTML elements
28 | * Related posts (time-based, because Jekyll) below each post
29 | * Syntax highlighting, courtesy Jekyll's built-in support for Rouge
30 |
31 | Additional features are available in individual themes.
32 |
33 | ### Browser support
34 |
35 | Poole and its themes are by preference a forward-thinking project. In addition to the latest versions of Chrome, Safari (mobile and desktop), and Firefox, it is only compatible with Internet Explorer 9 and above.
36 |
37 | ### Download
38 |
39 | These themes are developed on and hosted with GitHub. Head to the [GitHub repository]({{ site.github.repo }}) for downloads, bug reports, and features requests.
40 |
41 | Thanks!
42 |
--------------------------------------------------------------------------------
/test/fixtures/_sass/_base.scss:
--------------------------------------------------------------------------------
1 | // Body resets
2 | //
3 | // Update the foundational and global aspects of the page.
4 |
5 | * {
6 | -webkit-box-sizing: border-box;
7 | -moz-box-sizing: border-box;
8 | box-sizing: border-box;
9 | }
10 |
11 | html,
12 | body {
13 | margin: 0;
14 | padding: 0;
15 | }
16 |
17 | html {
18 | font-family: $root-font-family;
19 | font-size: $root-font-size;
20 | line-height: $root-line-height;
21 |
22 | @media (min-width: $large-breakpoint) {
23 | font-size: $large-font-size;
24 | }
25 | }
26 |
27 | body {
28 | color: $body-color;
29 | background-color: $body-bg;
30 | -webkit-text-size-adjust: 100%;
31 | -ms-text-size-adjust: 100%;
32 | }
33 |
34 | // No `:visited` state is required by default (browsers will use `a`)
35 | a {
36 | color: $link-color;
37 | text-decoration: none;
38 |
39 | // `:focus` is linked to `:hover` for basic accessibility
40 | &:hover,
41 | &:focus {
42 | text-decoration: underline;
43 | }
44 |
45 | strong {
46 | color: inherit;
47 | }
48 | }
49 |
50 | img {
51 | display: block;
52 | max-width: 100%;
53 | margin: 0 0 1rem;
54 | border-radius: 5px;
55 | }
56 |
57 | table {
58 | margin-bottom: 1rem;
59 | width: 100%;
60 | font-size: 85%;
61 | border: 1px solid #e5e5e5;
62 | border-collapse: collapse;
63 | }
64 |
65 | td,
66 | th {
67 | padding: .25rem .5rem;
68 | border: 1px solid #e5e5e5;
69 | }
70 |
71 | th {
72 | text-align: left;
73 | }
74 |
75 | tbody tr:nth-child(odd) td,
76 | tbody tr:nth-child(odd) th {
77 | background-color: #f9f9f9;
78 | }
79 |
--------------------------------------------------------------------------------
/test/fixtures/_sass/_code.scss:
--------------------------------------------------------------------------------
1 | // Code
2 | //
3 | // Inline and block-level code snippets. Includes tweaks to syntax highlighted
4 | // snippets from Pygments/Rouge and Gist embeds.
5 |
6 | code,
7 | pre {
8 | font-family: $code-font-family;
9 | }
10 |
11 | code {
12 | padding: .25em .5em;
13 | font-size: 85%;
14 | color: $code-color;
15 | background-color: #f9f9f9;
16 | border-radius: 3px;
17 | }
18 |
19 | pre {
20 | margin-top: 0;
21 | margin-bottom: 1rem;
22 | }
23 |
24 | pre code {
25 | padding: 0;
26 | font-size: 100%;
27 | color: inherit;
28 | background-color: transparent;
29 | }
30 |
31 | // Pygments via Jekyll
32 | .highlight {
33 | padding: 1rem;
34 | margin-bottom: 1rem;
35 | font-size: .8rem;
36 | line-height: 1.4;
37 | background-color: #f9f9f9;
38 | border-radius: .25rem;
39 |
40 | pre {
41 | margin-bottom: 0;
42 | overflow-x: auto;
43 | }
44 |
45 | .lineno {
46 | display: inline-block; // Ensures the null space also isn't selectable
47 | padding-right: .75rem;
48 | padding-left: .25rem;
49 | color: #999;
50 | // Make sure numbers aren't selectable
51 | -webkit-user-select: none;
52 | -moz-user-select: none;
53 | user-select: none;
54 | }
55 | }
56 |
57 |
58 | // Gist via GitHub Pages
59 | // .gist .gist-file {
60 | // font-family: Menlo, Monaco, "Courier New", monospace !important;
61 | // }
62 | // .gist .markdown-body {
63 | // padding: 15px;
64 | // }
65 | // .gist pre {
66 | // padding: 0;
67 | // background-color: transparent;
68 | // }
69 | // .gist .gist-file .gist-data {
70 | // font-size: .8rem !important;
71 | // line-height: 1.4;
72 | // }
73 | // .gist code {
74 | // padding: 0;
75 | // color: inherit;
76 | // background-color: transparent;
77 | // border-radius: 0;
78 | // }
79 |
--------------------------------------------------------------------------------
/test/fixtures/_sass/_layout.scss:
--------------------------------------------------------------------------------
1 | // Layout
2 | //
3 | // Styles for managing the structural hierarchy of the site.
4 |
5 | .container {
6 | max-width: 38rem;
7 | padding-left: 1.5rem;
8 | padding-right: 1.5rem;
9 | margin-left: auto;
10 | margin-right: auto;
11 | }
12 |
13 | footer {
14 | margin-bottom: 2rem;
15 | }
16 |
--------------------------------------------------------------------------------
/test/fixtures/_sass/_masthead.scss:
--------------------------------------------------------------------------------
1 | // Masthead
2 | //
3 | // Super small header above the content for site name and short description.
4 |
5 | .masthead {
6 | padding-top: 1rem;
7 | padding-bottom: 1rem;
8 | margin-bottom: 3rem;
9 | }
10 |
11 | .masthead-title {
12 | margin-top: 0;
13 | margin-bottom: 0;
14 | color: $gray-4;
15 |
16 | a {
17 | color: inherit;
18 | }
19 |
20 | small {
21 | font-size: 75%;
22 | font-weight: 400;
23 | opacity: .5;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test/fixtures/_sass/_message.scss:
--------------------------------------------------------------------------------
1 | // Messages
2 | //
3 | // Show alert messages to users. You may add it to single elements like a ``,
4 | // or to a parent if there are multiple elements to show.
5 |
6 | .message {
7 | margin-bottom: 1rem;
8 | padding: 1rem;
9 | color: #717171;
10 | background-color: #f9f9f9;
11 | }
12 |
--------------------------------------------------------------------------------
/test/fixtures/_sass/_pagination.scss:
--------------------------------------------------------------------------------
1 | // Pagination
2 | //
3 | // Super lightweight (HTML-wise) blog pagination. `span`s are provide for when
4 | // there are no more previous or next posts to show.
5 |
6 | .pagination {
7 | overflow: hidden; // clearfix
8 | margin: 0 -1.5rem 1rem;
9 | color: #ccc;
10 | text-align: center;
11 | }
12 |
13 | // Pagination items can be `span`s or `a`s
14 | .pagination-item {
15 | display: block;
16 | padding: 1rem;
17 | border: solid #eee;
18 | border-width: 1px 0;
19 |
20 | &:first-child {
21 | margin-bottom: -1px;
22 | }
23 | }
24 |
25 | // Only provide a hover state for linked pagination items
26 | a.pagination-item:hover {
27 | background-color: #f5f5f5;
28 | }
29 |
30 | @media (min-width: 30em) {
31 | .pagination {
32 | margin: 3rem 0;
33 | }
34 |
35 | .pagination-item {
36 | float: left;
37 | width: 50%;
38 | border-width: 1px;
39 |
40 | &:first-child {
41 | margin-bottom: 0;
42 | border-top-left-radius: 4px;
43 | border-bottom-left-radius: 4px;
44 | }
45 | &:last-child {
46 | margin-left: -1px;
47 | border-top-right-radius: 4px;
48 | border-bottom-right-radius: 4px;
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/test/fixtures/_sass/_posts.scss:
--------------------------------------------------------------------------------
1 | // Posts and pages
2 | //
3 | // Each post is wrapped in `.post` and is used on default and post layouts. Each
4 | // page is wrapped in `.page` and is only used on the page layout.
5 |
6 | .page,
7 | .post {
8 | margin-bottom: 4em;
9 |
10 | li + li {
11 | margin-top: .25rem;
12 | }
13 | }
14 |
15 | // Blog post or page title
16 | .page-title,
17 | .post-title,
18 | .post-title a {
19 | color: #303030;
20 | }
21 | .page-title,
22 | .post-title {
23 | margin-top: 0;
24 | }
25 |
26 | // Meta data line below post title
27 | .post-date {
28 | display: block;
29 | margin-top: -.5rem;
30 | margin-bottom: 1rem;
31 | color: #9a9a9a;
32 | }
33 |
34 |
35 | // Related posts
36 | .related {
37 | padding-top: 2rem;
38 | padding-bottom: 2rem;
39 | margin-bottom: 2rem;
40 | border-top: 1px solid #eee;
41 | border-bottom: 1px solid #eee;
42 | }
43 |
44 | .related-posts {
45 | padding-left: 0;
46 | list-style: none;
47 |
48 | h3 {
49 | margin-top: 0;
50 | }
51 |
52 | li {
53 | small {
54 | font-size: 75%;
55 | color: #999;
56 | }
57 |
58 | a:hover {
59 | color: #268bd2;
60 | text-decoration: none;
61 |
62 | small {
63 | color: inherit;
64 | }
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/test/fixtures/_sass/_syntax.scss:
--------------------------------------------------------------------------------
1 | .highlight .hll { background-color: #ffc; }
2 | .highlight .c { color: #999; } /* Comment */
3 | .highlight .err { color: #a00; background-color: #faa } /* Error */
4 | .highlight .k { color: #069; } /* Keyword */
5 | .highlight .o { color: #555 } /* Operator */
6 | .highlight .cm { color: #09f; font-style: italic } /* Comment.Multiline */
7 | .highlight .cp { color: #099 } /* Comment.Preproc */
8 | .highlight .c1 { color: #999; } /* Comment.Single */
9 | .highlight .cs { color: #999; } /* Comment.Special */
10 | .highlight .gd { background-color: #fcc; border: 1px solid #c00 } /* Generic.Deleted */
11 | .highlight .ge { font-style: italic } /* Generic.Emph */
12 | .highlight .gr { color: #f00 } /* Generic.Error */
13 | .highlight .gh { color: #030; } /* Generic.Heading */
14 | .highlight .gi { background-color: #cfc; border: 1px solid #0c0 } /* Generic.Inserted */
15 | .highlight .go { color: #aaa } /* Generic.Output */
16 | .highlight .gp { color: #009; } /* Generic.Prompt */
17 | .highlight .gs { } /* Generic.Strong */
18 | .highlight .gu { color: #030; } /* Generic.Subheading */
19 | .highlight .gt { color: #9c6 } /* Generic.Traceback */
20 | .highlight .kc { color: #069; } /* Keyword.Constant */
21 | .highlight .kd { color: #069; } /* Keyword.Declaration */
22 | .highlight .kn { color: #069; } /* Keyword.Namespace */
23 | .highlight .kp { color: #069 } /* Keyword.Pseudo */
24 | .highlight .kr { color: #069; } /* Keyword.Reserved */
25 | .highlight .kt { color: #078; } /* Keyword.Type */
26 | .highlight .m { color: #f60 } /* Literal.Number */
27 | .highlight .s { color: #d44950 } /* Literal.String */
28 | .highlight .na { color: #4f9fcf } /* Name.Attribute */
29 | .highlight .nb { color: #366 } /* Name.Builtin */
30 | .highlight .nc { color: #0a8; } /* Name.Class */
31 | .highlight .no { color: #360 } /* Name.Constant */
32 | .highlight .nd { color: #99f } /* Name.Decorator */
33 | .highlight .ni { color: #999; } /* Name.Entity */
34 | .highlight .ne { color: #c00; } /* Name.Exception */
35 | .highlight .nf { color: #c0f } /* Name.Function */
36 | .highlight .nl { color: #99f } /* Name.Label */
37 | .highlight .nn { color: #0cf; } /* Name.Namespace */
38 | .highlight .nt { color: #2f6f9f; } /* Name.Tag */
39 | .highlight .nv { color: #033 } /* Name.Variable */
40 | .highlight .ow { color: #000; } /* Operator.Word */
41 | .highlight .w { color: #bbb } /* Text.Whitespace */
42 | .highlight .mf { color: #f60 } /* Literal.Number.Float */
43 | .highlight .mh { color: #f60 } /* Literal.Number.Hex */
44 | .highlight .mi { color: #f60 } /* Literal.Number.Integer */
45 | .highlight .mo { color: #f60 } /* Literal.Number.Oct */
46 | .highlight .sb { color: #c30 } /* Literal.String.Backtick */
47 | .highlight .sc { color: #c30 } /* Literal.String.Char */
48 | .highlight .sd { color: #c30; font-style: italic } /* Literal.String.Doc */
49 | .highlight .s2 { color: #c30 } /* Literal.String.Double */
50 | .highlight .se { color: #c30; } /* Literal.String.Escape */
51 | .highlight .sh { color: #c30 } /* Literal.String.Heredoc */
52 | .highlight .si { color: #a00 } /* Literal.String.Interpol */
53 | .highlight .sx { color: #c30 } /* Literal.String.Other */
54 | .highlight .sr { color: #3aa } /* Literal.String.Regex */
55 | .highlight .s1 { color: #c30 } /* Literal.String.Single */
56 | .highlight .ss { color: #fc3 } /* Literal.String.Symbol */
57 | .highlight .bp { color: #366 } /* Name.Builtin.Pseudo */
58 | .highlight .vc { color: #033 } /* Name.Variable.Class */
59 | .highlight .vg { color: #033 } /* Name.Variable.Global */
60 | .highlight .vi { color: #033 } /* Name.Variable.Instance */
61 | .highlight .il { color: #f60 } /* Literal.Number.Integer.Long */
62 |
63 | .css .o,
64 | .css .o + .nt,
65 | .css .nt + .nt { color: #999; }
66 |
--------------------------------------------------------------------------------
/test/fixtures/_sass/_type.scss:
--------------------------------------------------------------------------------
1 | // Typography
2 | //
3 | // Headings, body text, lists, and other misc typographic elements.
4 |
5 | h1, h2, h3, h4, h5, h6 {
6 | margin-bottom: .5rem;
7 | font-weight: 600;
8 | line-height: 1.25;
9 | color: #313131;
10 | text-rendering: optimizeLegibility;
11 | }
12 |
13 | h1 {
14 | font-size: 2rem;
15 | }
16 |
17 | h2 {
18 | margin-top: 1rem;
19 | font-size: 1.5rem;
20 | }
21 |
22 | h3 {
23 | margin-top: 1.5rem;
24 | font-size: 1.25rem;
25 | }
26 |
27 | h4, h5, h6 {
28 | margin-top: 1rem;
29 | font-size: 1rem;
30 | }
31 |
32 | p {
33 | margin-top: 0;
34 | margin-bottom: 1rem;
35 | }
36 |
37 | strong {
38 | color: #303030;
39 | }
40 |
41 | ul, ol, dl {
42 | margin-top: 0;
43 | margin-bottom: 1rem;
44 | }
45 |
46 | dt {
47 | font-weight: bold;
48 | }
49 |
50 | dd {
51 | margin-bottom: .5rem;
52 | }
53 |
54 | hr {
55 | position: relative;
56 | margin: 1.5rem 0;
57 | border: 0;
58 | border-top: 1px solid #eee;
59 | border-bottom: 1px solid #fff;
60 | }
61 |
62 | abbr {
63 | font-size: 85%;
64 | font-weight: bold;
65 | color: #555;
66 | text-transform: uppercase;
67 |
68 | &[title] {
69 | cursor: help;
70 | border-bottom: 1px dotted #e5e5e5;
71 | }
72 | }
73 |
74 | blockquote {
75 | padding: .5rem 1rem;
76 | margin: .8rem 0;
77 | color: #7a7a7a;
78 | border-left: .25rem solid #e5e5e5;
79 |
80 | p:last-child {
81 | margin-bottom: 0;
82 | }
83 |
84 | @media (min-width: 30em) {
85 | padding-right: 5rem;
86 | padding-left: 1.25rem;
87 | }
88 | }
89 |
90 |
91 | // Markdown footnotes
92 | //
93 | // See the example content post for an example.
94 |
95 | // Footnote number within body text
96 | a[href^="#fn:"],
97 | // Back to footnote link
98 | a[href^="#fnref:"] {
99 | display: inline-block;
100 | margin-left: .1rem;
101 | font-weight: bold;
102 | }
103 |
104 | // List of footnotes
105 | .footnotes {
106 | margin-top: 2rem;
107 | font-size: 85%;
108 | }
109 |
110 | // Custom type
111 | //
112 | // Extend paragraphs with `.lead` for larger introductory text.
113 |
114 | .lead {
115 | font-size: 1.25rem;
116 | font-weight: 300;
117 | }
118 |
--------------------------------------------------------------------------------
/test/fixtures/_sass/_variables.scss:
--------------------------------------------------------------------------------
1 | $gray-1: #f9f9f9;
2 | $gray-2: #ccc;
3 | $gray-3: #767676;
4 | $gray-4: #515151;
5 | $gray-5: #313131;
6 |
7 | $red: #ac4142;
8 | $orange: #d28445;
9 | $yellow: #f4bf75;
10 | $green: #90a959;
11 | $cyan: #75b5aa;
12 | $blue: #268bd2;
13 | // $blue: #6a9fb5;
14 | $brown: #8f5536;
15 |
16 | $root-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", Arial, sans-serif;
17 | $root-font-size: 16px;
18 | $root-line-height: 1.5;
19 |
20 | $body-color: #515151;
21 | $body-bg: #fff;
22 | $link-color: $blue;
23 |
24 | $border-color: #e5e5e5;
25 |
26 | $large-breakpoint: 38em;
27 | $large-font-size: 20px;
28 |
29 | $code-font-family: Menlo, Monaco, "Courier New", monospace;
30 | $code-color: #bf616a;
31 |
--------------------------------------------------------------------------------
/test/fixtures/about.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: page
3 | title: About
4 | ---
5 |
6 |
9 |
10 | In the novel, *The Strange Case of Dr. Jekyll and Mr. Hyde*, Mr. Poole is Dr. Jekyll's virtuous and loyal butler. Similarly, Poole is an upstanding and effective butler that helps you build Jekyll themes. It's made by [@mdo](https://twitter.com/mdo).
11 |
12 | There are currently two themes built on Poole:
13 |
14 | * [Hyde](http://hyde.getpoole.com)
15 | * [Lanyon](http://lanyon.getpoole.com)
16 |
17 | Learn more and contribute on [GitHub](https://github.com/poole).
18 |
19 | ## Setup
20 |
21 | Some fun facts about the setup of this project include:
22 |
23 | * Built for [Jekyll](http://jekyllrb.com)
24 | * Developed on GitHub and hosted for free on [GitHub Pages](https://pages.github.com)
25 | * Coded with [Sublime Text 2](http://sublimetext.com), an amazing code editor
26 | * Designed and developed while listening to music like [Blood Bros Trilogy](https://soundcloud.com/maddecent/sets/blood-bros-series)
27 |
28 | Have questions or suggestions? Feel free to [open an issue on GitHub](https://github.com/poole/poole/issues/new) or [ask me on Twitter](https://twitter.com/mdo).
29 |
30 | Thanks for reading!
31 |
--------------------------------------------------------------------------------
/test/fixtures/atom.xml:
--------------------------------------------------------------------------------
1 | ---
2 | layout: null
3 | ---
4 |
5 |
6 |
7 |
8 | {{ site.title }}
9 |
10 |
11 | {{ site.time | date_to_xmlschema }}
12 | {{ site.url }}
13 |
14 | {{ site.author.name }}
15 | {{ site.author.email }}
16 |
17 |
18 | {% for post in site.posts %}
19 |
20 | {{ post.title | xml_escape }}
21 |
22 | {{ post.date | date_to_xmlschema }}
23 | {{ site.url }}{{ post.id }}
24 | {{ post.content | xml_escape }}
25 |
26 | {% endfor %}
27 |
28 |
29 |
--------------------------------------------------------------------------------
/test/fixtures/css/cayman.css:
--------------------------------------------------------------------------------
1 | .highlight table td { padding: 5px; }
2 |
3 | .highlight table pre { margin: 0; }
4 |
5 | .highlight .cm { color: #999988; font-style: italic; }
6 |
7 | .highlight .cp { color: #999999; font-weight: bold; }
8 |
9 | .highlight .c1 { color: #999988; font-style: italic; }
10 |
11 | .highlight .cs { color: #999999; font-weight: bold; font-style: italic; }
12 |
13 | .highlight .c, .highlight .cd { color: #999988; font-style: italic; }
14 |
15 | .highlight .err { color: #a61717; background-color: #e3d2d2; }
16 |
17 | .highlight .gd { color: #000000; background-color: #ffdddd; }
18 |
19 | .highlight .ge { color: #000000; font-style: italic; }
20 |
21 | .highlight .gr { color: #aa0000; }
22 |
23 | .highlight .gh { color: #999999; }
24 |
25 | .highlight .gi { color: #000000; background-color: #ddffdd; }
26 |
27 | .highlight .go { color: #888888; }
28 |
29 | .highlight .gp { color: #555555; }
30 |
31 | .highlight .gs { font-weight: bold; }
32 |
33 | .highlight .gu { color: #aaaaaa; }
34 |
35 | .highlight .gt { color: #aa0000; }
36 |
37 | .highlight .kc { color: #000000; font-weight: bold; }
38 |
39 | .highlight .kd { color: #000000; font-weight: bold; }
40 |
41 | .highlight .kn { color: #000000; font-weight: bold; }
42 |
43 | .highlight .kp { color: #000000; font-weight: bold; }
44 |
45 | .highlight .kr { color: #000000; font-weight: bold; }
46 |
47 | .highlight .kt { color: #445588; font-weight: bold; }
48 |
49 | .highlight .k, .highlight .kv { color: #000000; font-weight: bold; }
50 |
51 | .highlight .mf { color: #009999; }
52 |
53 | .highlight .mh { color: #009999; }
54 |
55 | .highlight .il { color: #009999; }
56 |
57 | .highlight .mi { color: #009999; }
58 |
59 | .highlight .mo { color: #009999; }
60 |
61 | .highlight .m, .highlight .mb, .highlight .mx { color: #009999; }
62 |
63 | .highlight .sb { color: #d14; }
64 |
65 | .highlight .sc { color: #d14; }
66 |
67 | .highlight .sd { color: #d14; }
68 |
69 | .highlight .s2 { color: #d14; }
70 |
71 | .highlight .se { color: #d14; }
72 |
73 | .highlight .sh { color: #d14; }
74 |
75 | .highlight .si { color: #d14; }
76 |
77 | .highlight .sx { color: #d14; }
78 |
79 | .highlight .sr { color: #009926; }
80 |
81 | .highlight .s1 { color: #d14; }
82 |
83 | .highlight .ss { color: #990073; }
84 |
85 | .highlight .s { color: #d14; }
86 |
87 | .highlight .na { color: #008080; }
88 |
89 | .highlight .bp { color: #999999; }
90 |
91 | .highlight .nb { color: #0086B3; }
92 |
93 | .highlight .nc { color: #445588; font-weight: bold; }
94 |
95 | .highlight .no { color: #008080; }
96 |
97 | .highlight .nd { color: #3c5d5d; font-weight: bold; }
98 |
99 | .highlight .ni { color: #800080; }
100 |
101 | .highlight .ne { color: #990000; font-weight: bold; }
102 |
103 | .highlight .nf { color: #990000; font-weight: bold; }
104 |
105 | .highlight .nl { color: #990000; font-weight: bold; }
106 |
107 | .highlight .nn { color: #555555; }
108 |
109 | .highlight .nt { color: #000080; }
110 |
111 | .highlight .vc { color: #008080; }
112 |
113 | .highlight .vg { color: #008080; }
114 |
115 | .highlight .vi { color: #008080; }
116 |
117 | .highlight .nv { color: #008080; }
118 |
119 | .highlight .ow { color: #000000; font-weight: bold; }
120 |
121 | .highlight .o { color: #000000; font-weight: bold; }
122 |
123 | .highlight .w { color: #bbbbbb; }
124 |
125 | .highlight { background-color: #f8f8f8; }
126 |
127 | * { box-sizing: border-box; }
128 |
129 | body { padding: 0; margin: 0; font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 16px; line-height: 1.5; color: #606c71; }
130 |
131 | a { color: #1e6bb8; text-decoration: none; }
132 | a:hover { text-decoration: underline; }
133 |
134 | .btn { display: inline-block; margin-bottom: 1rem; color: rgba(255, 255, 255, 0.7); background-color: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.2); border-style: solid; border-width: 1px; border-radius: 0.3rem; transition: color 0.2s, background-color 0.2s, border-color 0.2s; }
135 | .btn:hover { color: rgba(255, 255, 255, 0.8); text-decoration: none; background-color: rgba(255, 255, 255, 0.2); border-color: rgba(255, 255, 255, 0.3); }
136 | .btn + .btn { margin-left: 1rem; }
137 | @media screen and (min-width: 64em) { .btn { padding: 0.75rem 1rem; } }
138 | @media screen and (min-width: 42em) and (max-width: 64em) { .btn { padding: 0.6rem 0.9rem; font-size: 0.9rem; } }
139 | @media screen and (max-width: 42em) { .btn { display: block; width: 100%; padding: 0.75rem; font-size: 0.9rem; }
140 | .btn + .btn { margin-top: 1rem; margin-left: 0; } }
141 |
142 | .page-header { color: #fff; text-align: center; background-color: #159957; background-image: linear-gradient(120deg, #155799, #159957); }
143 | @media screen and (min-width: 64em) { .page-header { padding: 5rem 6rem; } }
144 | @media screen and (min-width: 42em) and (max-width: 64em) { .page-header { padding: 3rem 4rem; } }
145 | @media screen and (max-width: 42em) { .page-header { padding: 2rem 1rem; } }
146 |
147 | .project-name { margin-top: 0; margin-bottom: 0.1rem; }
148 | @media screen and (min-width: 64em) { .project-name { font-size: 3.25rem; } }
149 | @media screen and (min-width: 42em) and (max-width: 64em) { .project-name { font-size: 2.25rem; } }
150 | @media screen and (max-width: 42em) { .project-name { font-size: 1.75rem; } }
151 |
152 | .project-tagline { margin-bottom: 2rem; font-weight: normal; opacity: 0.7; }
153 | @media screen and (min-width: 64em) { .project-tagline { font-size: 1.25rem; } }
154 | @media screen and (min-width: 42em) and (max-width: 64em) { .project-tagline { font-size: 1.15rem; } }
155 | @media screen and (max-width: 42em) { .project-tagline { font-size: 1rem; } }
156 |
157 | .main-content { word-wrap: break-word; }
158 | .main-content :first-child { margin-top: 0; }
159 | @media screen and (min-width: 64em) { .main-content { max-width: 64rem; padding: 2rem 6rem; margin: 0 auto; font-size: 1.1rem; } }
160 | @media screen and (min-width: 42em) and (max-width: 64em) { .main-content { padding: 2rem 4rem; font-size: 1.1rem; } }
161 | @media screen and (max-width: 42em) { .main-content { padding: 2rem 1rem; font-size: 1rem; } }
162 | .main-content img { max-width: 100%; }
163 | .main-content h1, .main-content h2, .main-content h3, .main-content h4, .main-content h5, .main-content h6 { margin-top: 2rem; margin-bottom: 1rem; font-weight: normal; color: #159957; }
164 | .main-content p { margin-bottom: 1em; }
165 | .main-content code { padding: 2px 4px; font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 0.9rem; color: #567482; background-color: #f3f6fa; border-radius: 0.3rem; }
166 | .main-content pre { padding: 0.8rem; margin-top: 0; margin-bottom: 1rem; font: 1rem Consolas, "Liberation Mono", Menlo, Courier, monospace; color: #567482; word-wrap: normal; background-color: #f3f6fa; border: solid 1px #dce6f0; border-radius: 0.3rem; }
167 | .main-content pre > code { padding: 0; margin: 0; font-size: 0.9rem; color: #567482; word-break: normal; white-space: pre; background: transparent; border: 0; }
168 | .main-content .highlight { margin-bottom: 1rem; }
169 | .main-content .highlight pre { margin-bottom: 0; word-break: normal; }
170 | .main-content .highlight pre, .main-content pre { padding: 0.8rem; overflow: auto; font-size: 0.9rem; line-height: 1.45; border-radius: 0.3rem; -webkit-overflow-scrolling: touch; }
171 | .main-content pre code, .main-content pre tt { display: inline; max-width: initial; padding: 0; margin: 0; overflow: initial; line-height: inherit; word-wrap: normal; background-color: transparent; border: 0; }
172 | .main-content pre code:before, .main-content pre code:after, .main-content pre tt:before, .main-content pre tt:after { content: normal; }
173 | .main-content ul, .main-content ol { margin-top: 0; }
174 | .main-content blockquote { padding: 0 1rem; margin-left: 0; color: #819198; border-left: 0.3rem solid #dce6f0; }
175 | .main-content blockquote > :first-child { margin-top: 0; }
176 | .main-content blockquote > :last-child { margin-bottom: 0; }
177 | .main-content table { display: block; width: 100%; overflow: auto; word-break: normal; word-break: keep-all; -webkit-overflow-scrolling: touch; }
178 | .main-content table th { font-weight: bold; }
179 | .main-content table th, .main-content table td { padding: 0.5rem 1rem; border: 1px solid #e9ebec; }
180 | .main-content dl { padding: 0; }
181 | .main-content dl dt { padding: 0; margin-top: 1rem; font-size: 1rem; font-weight: bold; }
182 | .main-content dl dd { padding: 0; margin-bottom: 1rem; }
183 | .main-content hr { height: 2px; padding: 0; margin: 1rem 0; background-color: #eff0f1; border: 0; }
184 |
185 | .site-footer { padding-top: 2rem; margin-top: 2rem; border-top: solid 1px #eff0f1; }
186 | @media screen and (min-width: 64em) { .site-footer { font-size: 1rem; } }
187 | @media screen and (min-width: 42em) and (max-width: 64em) { .site-footer { font-size: 1rem; } }
188 | @media screen and (max-width: 42em) { .site-footer { font-size: 0.9rem; } }
189 |
190 | .site-footer-owner { display: block; font-weight: bold; }
191 |
192 | .site-footer-credits { color: #819198; }
193 |
--------------------------------------------------------------------------------
/test/fixtures/css/normalize.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */
2 |
3 | /**
4 | * 1. Set default font family to sans-serif.
5 | * 2. Prevent iOS text size adjust after orientation change, without disabling
6 | * user zoom.
7 | */
8 |
9 | html {
10 | font-family: sans-serif; /* 1 */
11 | -ms-text-size-adjust: 100%; /* 2 */
12 | -webkit-text-size-adjust: 100%; /* 2 */
13 | }
14 |
15 | /**
16 | * Remove default margin.
17 | */
18 |
19 | body {
20 | margin: 0;
21 | }
22 |
23 | /* HTML5 display definitions
24 | ========================================================================== */
25 |
26 | /**
27 | * Correct `block` display not defined for any HTML5 element in IE 8/9.
28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11
29 | * and Firefox.
30 | * Correct `block` display not defined for `main` in IE 11.
31 | */
32 |
33 | article,
34 | aside,
35 | details,
36 | figcaption,
37 | figure,
38 | footer,
39 | header,
40 | hgroup,
41 | main,
42 | menu,
43 | nav,
44 | section,
45 | summary {
46 | display: block;
47 | }
48 |
49 | /**
50 | * 1. Correct `inline-block` display not defined in IE 8/9.
51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
52 | */
53 |
54 | audio,
55 | canvas,
56 | progress,
57 | video {
58 | display: inline-block; /* 1 */
59 | vertical-align: baseline; /* 2 */
60 | }
61 |
62 | /**
63 | * Prevent modern browsers from displaying `audio` without controls.
64 | * Remove excess height in iOS 5 devices.
65 | */
66 |
67 | audio:not([controls]) {
68 | display: none;
69 | height: 0;
70 | }
71 |
72 | /**
73 | * Address `[hidden]` styling not present in IE 8/9/10.
74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
75 | */
76 |
77 | [hidden],
78 | template {
79 | display: none;
80 | }
81 |
82 | /* Links
83 | ========================================================================== */
84 |
85 | /**
86 | * Remove the gray background color from active links in IE 10.
87 | */
88 |
89 | a {
90 | background-color: transparent;
91 | }
92 |
93 | /**
94 | * Improve readability when focused and also mouse hovered in all browsers.
95 | */
96 |
97 | a:active,
98 | a:hover {
99 | outline: 0;
100 | }
101 |
102 | /* Text-level semantics
103 | ========================================================================== */
104 |
105 | /**
106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
107 | */
108 |
109 | abbr[title] {
110 | border-bottom: 1px dotted;
111 | }
112 |
113 | /**
114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
115 | */
116 |
117 | b,
118 | strong {
119 | font-weight: bold;
120 | }
121 |
122 | /**
123 | * Address styling not present in Safari and Chrome.
124 | */
125 |
126 | dfn {
127 | font-style: italic;
128 | }
129 |
130 | /**
131 | * Address variable `h1` font-size and margin within `section` and `article`
132 | * contexts in Firefox 4+, Safari, and Chrome.
133 | */
134 |
135 | h1 {
136 | font-size: 2em;
137 | margin: 0.67em 0;
138 | }
139 |
140 | /**
141 | * Address styling not present in IE 8/9.
142 | */
143 |
144 | mark {
145 | background: #ff0;
146 | color: #000;
147 | }
148 |
149 | /**
150 | * Address inconsistent and variable font size in all browsers.
151 | */
152 |
153 | small {
154 | font-size: 80%;
155 | }
156 |
157 | /**
158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers.
159 | */
160 |
161 | sub,
162 | sup {
163 | font-size: 75%;
164 | line-height: 0;
165 | position: relative;
166 | vertical-align: baseline;
167 | }
168 |
169 | sup {
170 | top: -0.5em;
171 | }
172 |
173 | sub {
174 | bottom: -0.25em;
175 | }
176 |
177 | /* Embedded content
178 | ========================================================================== */
179 |
180 | /**
181 | * Remove border when inside `a` element in IE 8/9/10.
182 | */
183 |
184 | img {
185 | border: 0;
186 | }
187 |
188 | /**
189 | * Correct overflow not hidden in IE 9/10/11.
190 | */
191 |
192 | svg:not(:root) {
193 | overflow: hidden;
194 | }
195 |
196 | /* Grouping content
197 | ========================================================================== */
198 |
199 | /**
200 | * Address margin not present in IE 8/9 and Safari.
201 | */
202 |
203 | figure {
204 | margin: 1em 40px;
205 | }
206 |
207 | /**
208 | * Address differences between Firefox and other browsers.
209 | */
210 |
211 | hr {
212 | box-sizing: content-box;
213 | height: 0;
214 | }
215 |
216 | /**
217 | * Contain overflow in all browsers.
218 | */
219 |
220 | pre {
221 | overflow: auto;
222 | }
223 |
224 | /**
225 | * Address odd `em`-unit font size rendering in all browsers.
226 | */
227 |
228 | code,
229 | kbd,
230 | pre,
231 | samp {
232 | font-family: monospace, monospace;
233 | font-size: 1em;
234 | }
235 |
236 | /* Forms
237 | ========================================================================== */
238 |
239 | /**
240 | * Known limitation: by default, Chrome and Safari on OS X allow very limited
241 | * styling of `select`, unless a `border` property is set.
242 | */
243 |
244 | /**
245 | * 1. Correct color not being inherited.
246 | * Known issue: affects color of disabled elements.
247 | * 2. Correct font properties not being inherited.
248 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
249 | */
250 |
251 | button,
252 | input,
253 | optgroup,
254 | select,
255 | textarea {
256 | color: inherit; /* 1 */
257 | font: inherit; /* 2 */
258 | margin: 0; /* 3 */
259 | }
260 |
261 | /**
262 | * Address `overflow` set to `hidden` in IE 8/9/10/11.
263 | */
264 |
265 | button {
266 | overflow: visible;
267 | }
268 |
269 | /**
270 | * Address inconsistent `text-transform` inheritance for `button` and `select`.
271 | * All other form control elements do not inherit `text-transform` values.
272 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
273 | * Correct `select` style inheritance in Firefox.
274 | */
275 |
276 | button,
277 | select {
278 | text-transform: none;
279 | }
280 |
281 | /**
282 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
283 | * and `video` controls.
284 | * 2. Correct inability to style clickable `input` types in iOS.
285 | * 3. Improve usability and consistency of cursor style between image-type
286 | * `input` and others.
287 | */
288 |
289 | button,
290 | html input[type="button"], /* 1 */
291 | input[type="reset"],
292 | input[type="submit"] {
293 | -webkit-appearance: button; /* 2 */
294 | cursor: pointer; /* 3 */
295 | }
296 |
297 | /**
298 | * Re-set default cursor for disabled elements.
299 | */
300 |
301 | button[disabled],
302 | html input[disabled] {
303 | cursor: default;
304 | }
305 |
306 | /**
307 | * Remove inner padding and border in Firefox 4+.
308 | */
309 |
310 | button::-moz-focus-inner,
311 | input::-moz-focus-inner {
312 | border: 0;
313 | padding: 0;
314 | }
315 |
316 | /**
317 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in
318 | * the UA stylesheet.
319 | */
320 |
321 | input {
322 | line-height: normal;
323 | }
324 |
325 | /**
326 | * It's recommended that you don't attempt to style these elements.
327 | * Firefox's implementation doesn't respect box-sizing, padding, or width.
328 | *
329 | * 1. Address box sizing set to `content-box` in IE 8/9/10.
330 | * 2. Remove excess padding in IE 8/9/10.
331 | */
332 |
333 | input[type="checkbox"],
334 | input[type="radio"] {
335 | box-sizing: border-box; /* 1 */
336 | padding: 0; /* 2 */
337 | }
338 |
339 | /**
340 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain
341 | * `font-size` values of the `input`, it causes the cursor style of the
342 | * decrement button to change from `default` to `text`.
343 | */
344 |
345 | input[type="number"]::-webkit-inner-spin-button,
346 | input[type="number"]::-webkit-outer-spin-button {
347 | height: auto;
348 | }
349 |
350 | /**
351 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
352 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
353 | * (include `-moz` to future-proof).
354 | */
355 |
356 | input[type="search"] {
357 | -webkit-appearance: textfield; /* 1 */ /* 2 */
358 | box-sizing: content-box;
359 | }
360 |
361 | /**
362 | * Remove inner padding and search cancel button in Safari and Chrome on OS X.
363 | * Safari (but not Chrome) clips the cancel button when the search input has
364 | * padding (and `textfield` appearance).
365 | */
366 |
367 | input[type="search"]::-webkit-search-cancel-button,
368 | input[type="search"]::-webkit-search-decoration {
369 | -webkit-appearance: none;
370 | }
371 |
372 | /**
373 | * Define consistent border, margin, and padding.
374 | */
375 |
376 | fieldset {
377 | border: 1px solid #c0c0c0;
378 | margin: 0 2px;
379 | padding: 0.35em 0.625em 0.75em;
380 | }
381 |
382 | /**
383 | * 1. Correct `color` not being inherited in IE 8/9/10/11.
384 | * 2. Remove padding so people aren't caught out if they zero out fieldsets.
385 | */
386 |
387 | legend {
388 | border: 0; /* 1 */
389 | padding: 0; /* 2 */
390 | }
391 |
392 | /**
393 | * Remove default vertical scrollbar in IE 8/9/10/11.
394 | */
395 |
396 | textarea {
397 | overflow: auto;
398 | }
399 |
400 | /**
401 | * Don't inherit the `font-weight` (applied by a rule above).
402 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
403 | */
404 |
405 | optgroup {
406 | font-weight: bold;
407 | }
408 |
409 | /* Tables
410 | ========================================================================== */
411 |
412 | /**
413 | * Remove most spacing between table cells.
414 | */
415 |
416 | table {
417 | border-collapse: collapse;
418 | border-spacing: 0;
419 | }
420 |
421 | td,
422 | th {
423 | padding: 0;
424 | }
425 |
--------------------------------------------------------------------------------
/test/fixtures/index.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | title: Home
4 | ---
5 |
6 |
7 | {% for post in paginator.posts %}
8 |
9 |
10 |
11 | {{ post.title }}
12 |
13 |
14 |
15 |
16 |
17 | {{ post.content }}
18 |
19 | {% endfor %}
20 |
21 |
22 |
34 |
--------------------------------------------------------------------------------
/test/fixtures/jekyll-cayman-theme.gemspec:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | Gem::Specification.new do |spec|
4 | spec.name = "jekyll-cayman-theme"
5 | spec.version = "0.1.0"
6 | spec.authors = ["Pietro F. Menna"]
7 | spec.email = ["pietromenna@yahoo.com"]
8 |
9 | spec.summary = %q{A Jekyll theme for the responsive theme for GitHub Pages http://jasonlong.github.io/cayman-theme/ }
10 | spec.homepage = "https://github.com/pietromenna/jekyll-cayman-theme"
11 | spec.license = "MIT"
12 |
13 | spec.files = `git ls-files -z`.split("\x0").select { |f| f.match(%r{^(_layouts|_includes|_sass|LICENSE|README)/i}) }
14 |
15 | spec.add_development_dependency "jekyll", "~> 3.2"
16 | spec.add_development_dependency "bundler", "~> 1.12"
17 | spec.add_development_dependency "rake", "~> 10.0"
18 | end
--------------------------------------------------------------------------------
/test/fixtures/public/apple-touch-icon-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonschlinkert/hekyll/a828d6e2c2203525494494329a2feb0b0a87b823/test/fixtures/public/apple-touch-icon-precomposed.png
--------------------------------------------------------------------------------
/test/fixtures/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jonschlinkert/hekyll/a828d6e2c2203525494494329a2feb0b0a87b823/test/fixtures/public/favicon.ico
--------------------------------------------------------------------------------
/test/fixtures/styles.scss:
--------------------------------------------------------------------------------
1 | ---
2 | # Use a comment to ensure Jekyll reads the file to be transformed into CSS later
3 | # only main files contain this front matter, not partials.
4 | ---
5 |
6 | //
7 | // ___
8 | // /\_ \
9 | // _____ ___ ___\//\ \ __
10 | // /\ '__`\ / __`\ / __`\\ \ \ /'__`\
11 | // \ \ \_\ \/\ \_\ \/\ \_\ \\_\ \_/\ __/
12 | // \ \ ,__/\ \____/\ \____//\____\ \____\
13 | // \ \ \/ \/___/ \/___/ \/____/\/____/
14 | // \ \_\
15 | // \/_/
16 | //
17 | // Designed, built, and released under MIT license by @mdo. Learn more at
18 | // https://github.com/poole/poole.
19 |
20 | @import "variables";
21 | @import "base";
22 | @import "type";
23 | @import "syntax";
24 | @import "code";
25 | @import "layout";
26 | @import "masthead";
27 | @import "posts";
28 | @import "pagination";
29 | @import "message";
30 |
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | require('mocha');
4 | var fs = require('fs');
5 | var path = require('path');
6 | var del = require('delete');
7 | var assert = require('assert');
8 | var hekyll = require('..');
9 |
10 | var fixtures = path.resolve.bind(path, __dirname, 'fixtures');
11 | var actual = path.resolve.bind(path, __dirname, 'actual');
12 |
13 | describe('hekyll', function() {
14 | it('should export a function', function() {
15 | assert.equal(typeof hekyll, 'function');
16 | });
17 |
18 | it('should throw an error when invalid args are passed', function(cb) {
19 | hekyll.build()
20 | .catch(function(err) {
21 | assert(err);
22 | cb();
23 | });
24 | });
25 |
26 | it('should convert a theme to handlebars', function() {
27 | return hekyll.build({cwd: fixtures(), destBase: actual()})
28 | .then(function() {
29 | assert(fs.existsSync(actual()))
30 | assert(fs.existsSync(actual('atom.xml')))
31 | assert(fs.existsSync(actual('_config.yml')))
32 | assert(fs.existsSync(actual('_layouts/default.hbs')))
33 | del.sync(actual());
34 | })
35 | });
36 | });
37 |
--------------------------------------------------------------------------------