├── .gitignore ├── yaml-front-matter ├── test ├── fixtures │ ├── json.txt │ ├── safeYaml.txt │ ├── yaml.txt │ └── yamlWithExtraDashes.txt └── js-yaml-front.test.js ├── webpack.config.js ├── LICENSE.md ├── package.json ├── src └── index.js ├── bin └── js-yaml-front.js ├── dist └── yamlFront.js ├── docs ├── js │ └── yamlFront.js ├── css │ ├── layout.css │ ├── skeleton.css │ └── base.css └── index.html ├── CHANGELOG.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | components 3 | .c9* 4 | .settings 5 | *.sublime-* 6 | *.swp 7 | *.log 8 | -------------------------------------------------------------------------------- /yaml-front-matter: -------------------------------------------------------------------------------- 1 | --- 2 | {"post": "title one", 3 | "anArray": ["one","two"], 4 | "subObject": 5 | {"obj1": "cool", "obj2": "two"}} 6 | --- 7 | content 8 | more -------------------------------------------------------------------------------- /test/fixtures/json.txt: -------------------------------------------------------------------------------- 1 | --- 2 | {"post": "title one", 3 | "anArray": ["one","two"], 4 | "subObject": 5 | {"obj1": "cool", "obj2": "two"}} 6 | --- 7 | content 8 | more -------------------------------------------------------------------------------- /test/fixtures/safeYaml.txt: -------------------------------------------------------------------------------- 1 | --- 2 | post: title one 3 | anArray: 4 | - one 5 | - two 6 | subObject: 7 | obj1: cool 8 | obj2: two 9 | --- 10 | content 11 | more -------------------------------------------------------------------------------- /test/fixtures/yaml.txt: -------------------------------------------------------------------------------- 1 | --- 2 | post: title one 3 | anArray: 4 | - one 5 | - two 6 | subObject: 7 | obj1: cool 8 | obj2: two 9 | reg: !!js/regexp /pattern/gim 10 | fun: !!js/function function() { } 11 | --- 12 | content 13 | more -------------------------------------------------------------------------------- /test/fixtures/yamlWithExtraDashes.txt: -------------------------------------------------------------------------------- 1 | --- 2 | post: title one 3 | anArray: 4 | - one 5 | - two 6 | subObject: 7 | obj1: cool 8 | obj2: two --- 9 | reg: !!js/regexp /pattern/gim 10 | fun: !!js/function function() { } 11 | --- 12 | content 13 | more 14 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require("path"); 2 | 3 | module.exports = function(env) { 4 | const isBrowser = env && env.browser; 5 | return { 6 | entry: "./src/index.js", 7 | output: { 8 | path: path.resolve(__dirname, isBrowser ? "docs/js" : "dist"), 9 | filename: "yamlFront.js", 10 | library: "yamlFront", 11 | libraryTarget: "umd", 12 | globalObject: "this" 13 | }, 14 | externals: { 15 | "js-yaml": { 16 | commonjs: "js-yaml", 17 | commonjs2: "js-yaml", 18 | root: "jsyaml" 19 | } 20 | }, 21 | module: { 22 | rules: [ 23 | { 24 | test: /\.js$/, 25 | exclude: /node_modules/, 26 | loader: "babel-loader", 27 | options: { presets: ["@babel/preset-env"] } 28 | } 29 | ] 30 | } 31 | }; 32 | }; 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 - Present Derek Worthen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Derek Worthen", 3 | "license": "MIT", 4 | "name": "yaml-front-matter", 5 | "description": "yaml front matter for JS. Parse yaml or JSON from the beginning of files.", 6 | "main": "dist/yamlFront.js", 7 | "module": "src/index.js", 8 | "version": "4.1.1", 9 | "keywords": [ 10 | "yaml", 11 | "front matter", 12 | "json" 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/dworthen/js-yaml-front-matter" 17 | }, 18 | "dependencies": { 19 | "commander": "^6.2.0", 20 | "js-yaml": "^3.14.1" 21 | }, 22 | "devDependencies": { 23 | "@babel/core": "^7.12.10", 24 | "@babel/preset-env": "^7.12.10", 25 | "babel-loader": "^8.2.2", 26 | "mocha": "^8.2.1", 27 | "should": "^13.2.3", 28 | "standard-version": "^9.0.0", 29 | "webpack": "^4.44.2", 30 | "webpack-cli": "^4.2.0" 31 | }, 32 | "bin": { 33 | "yaml-front-matter": "bin/js-yaml-front.js" 34 | }, 35 | "scripts": { 36 | "test": "npm run build && mocha -u bdd --reporter spec", 37 | "start": "npm run build:browser && http-server ./docs -p 8080", 38 | "release": "standard-version", 39 | "build": "webpack --mode production", 40 | "build:browser": "webpack --mode production --env.browser" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | var jsYaml = require('js-yaml'); 2 | 3 | function parse(text, options, loadSafe) { 4 | let contentKeyName = options && typeof options === 'string' 5 | ? options 6 | : options && options.contentKeyName 7 | ? options.contentKeyName 8 | : '__content'; 9 | 10 | let passThroughOptions = options && typeof options === 'object' 11 | ? options 12 | : undefined; 13 | 14 | let re = /^(-{3}(?:\n|\r)([\w\W]+?)(?:\n|\r)-{3})?([\w\W]*)*/ 15 | , results = re.exec(text) 16 | , conf = {} 17 | , yamlOrJson; 18 | 19 | if ((yamlOrJson = results[2])) { 20 | if (yamlOrJson.charAt(0) === '{') { 21 | conf = JSON.parse(yamlOrJson); 22 | } else { 23 | if(loadSafe) { 24 | conf = jsYaml.safeLoad(yamlOrJson, passThroughOptions); 25 | } else { 26 | conf = jsYaml.load(yamlOrJson, passThroughOptions); 27 | } 28 | } 29 | } 30 | 31 | conf[contentKeyName] = results[3] || ''; 32 | 33 | return conf; 34 | }; 35 | 36 | export function loadFront (content, options) { 37 | return parse(content, options, false); 38 | }; 39 | 40 | export function safeLoadFront (content, options) { 41 | return parse(content, options, true) 42 | } 43 | -------------------------------------------------------------------------------- /bin/js-yaml-front.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var program = require('commander') 4 | , yamlFront = require('../') 5 | , package = require('../package.json'); 6 | 7 | program 8 | .version(package.version, '-v, --version') 9 | .usage('[options] ') 10 | .option('-c, --content [name]', 'set the property name for the files contents [__content]') 11 | .option('--pretty', 'prints the json output with spaces.') 12 | .on('--help', function() { 13 | console.log(''); 14 | console.log(' Examples') 15 | console.log(''); 16 | console.log(' Basic'); 17 | console.log(' yaml-front-matter '); 18 | console.log(''); 19 | console.log(' Piping content from an input file to an output file') 20 | console.log(' cat ./some/file.txt | yaml-front-matter > output.txt'); 21 | }); 22 | 23 | program.parse(process.argv); 24 | 25 | if (program.args.length > 0) { 26 | processData(program.args[0]); 27 | } else { 28 | var data = ''; 29 | process.stdin.on('readable', function () { 30 | var chunk; 31 | while (chunk = process.stdin.read()) { 32 | data += chunk; 33 | } 34 | }); 35 | 36 | process.stdin.on('end', function () { 37 | // There will be a trailing \n from the user hitting enter. Get rid of it. 38 | // data = data.replace("\r\n", '\n'); 39 | processData(data); 40 | }); 41 | } 42 | 43 | function processData(data) { 44 | console.log(JSON.stringify(yamlFront.safeLoadFront(data, 45 | { contentKeyName: program.content || '__content' }), 46 | undefined, 47 | program.pretty ? 2 : 0)); 48 | } -------------------------------------------------------------------------------- /dist/yamlFront.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("js-yaml")):"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.yamlFront=t(require("js-yaml")):e.yamlFront=t(e.jsyaml)}(this,(function(e){return function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}n.r(t),n.d(t,"loadFront",(function(){return f})),n.d(t,"safeLoadFront",(function(){return i}));var r=n(1);function u(e,t,n){var u,f=t&&"string"==typeof t?t:t&&t.contentKeyName?t.contentKeyName:"__content",i=t&&"object"===o(t)?t:void 0,c=/^(-{3}(?:\n|\r)([\w\W]+?)(?:\n|\r)-{3})?([\w\W]*)*/.exec(e),l={};return(u=c[2])&&(l="{"===u.charAt(0)?JSON.parse(u):n?r.safeLoad(u,i):r.load(u,i)),l[f]=c[3]||"",l}function f(e,t){return u(e,t,!1)}function i(e,t){return u(e,t,!0)}},function(t,n){t.exports=e}])})); -------------------------------------------------------------------------------- /docs/js/yamlFront.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("js-yaml")):"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.yamlFront=t(require("js-yaml")):e.yamlFront=t(e.jsyaml)}(this,(function(e){return function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}n.r(t),n.d(t,"loadFront",(function(){return f})),n.d(t,"safeLoadFront",(function(){return i}));var r=n(1);function u(e,t,n){var u,f=t&&"string"==typeof t?t:t&&t.contentKeyName?t.contentKeyName:"__content",i=t&&"object"===o(t)?t:void 0,c=/^(-{3}(?:\n|\r)([\w\W]+?)(?:\n|\r)-{3})?([\w\W]*)*/.exec(e),l={};return(u=c[2])&&(l="{"===u.charAt(0)?JSON.parse(u):n?r.safeLoad(u,i):r.load(u,i)),l[f]=c[3]||"",l}function f(e,t){return u(e,t,!1)}function i(e,t){return u(e,t,!0)}},function(t,n){t.exports=e}])})); -------------------------------------------------------------------------------- /docs/css/layout.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Skeleton V1.2 3 | * Copyright 2011, Dave Gamache 4 | * www.getskeleton.com 5 | * Free to use under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 6/20/2012 8 | */ 9 | 10 | /* Table of Content 11 | ================================================== 12 | #Site Styles 13 | #Page Styles 14 | #Media Queries 15 | #Font-Face */ 16 | 17 | /* #Site Styles 18 | ================================================== */ 19 | 20 | /* #Page Styles 21 | ================================================== */ 22 | 23 | /* #Media Queries 24 | ================================================== */ 25 | 26 | /* Smaller than standard 960 (devices and browsers) */ 27 | @media only screen and (max-width: 959px) {} 28 | 29 | /* Tablet Portrait size to standard 960 (devices and browsers) */ 30 | @media only screen and (min-width: 768px) and (max-width: 959px) {} 31 | 32 | /* All Mobile Sizes (devices and browser) */ 33 | @media only screen and (max-width: 767px) {} 34 | 35 | /* Mobile Landscape Size to Tablet Portrait (devices and browsers) */ 36 | @media only screen and (min-width: 480px) and (max-width: 767px) {} 37 | 38 | /* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */ 39 | @media only screen and (max-width: 479px) {} 40 | 41 | 42 | /* #Font-Face 43 | ================================================== */ 44 | /* This is the proper syntax for an @font-face file 45 | Just create a "fonts" folder at the root, 46 | copy your FontName into code below and remove 47 | comment brackets */ 48 | 49 | /* @font-face { 50 | font-family: 'FontName'; 51 | src: url('../fonts/FontName.eot'); 52 | src: url('../fonts/FontName.eot?iefix') format('eot'), 53 | url('../fonts/FontName.woff') format('woff'), 54 | url('../fonts/FontName.ttf') format('truetype'), 55 | url('../fonts/FontName.svg#webfontZam02nTh') format('svg'); 56 | font-weight: normal; 57 | font-style: normal; } 58 | */ -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ### [4.1.1](https://github.com/dworthen/js-yaml-front-matter/compare/v4.1.0...v4.1.1) (2020-12-13) 6 | 7 | 8 | ### Bug Fixes 9 | 10 | * update dependencies ([70fba4a](https://github.com/dworthen/js-yaml-front-matter/commit/70fba4af22c95eacaf5370a5b198602c452e3d68)) 11 | 12 | ## [4.1.0](https://github.com/dworthen/js-yaml-front-matter/compare/v4.0.0...v4.1.0) (2019-12-24) 13 | 14 | 15 | ### Features 16 | 17 | * Upgrade package dependencies ([39a68d2](https://github.com/dworthen/js-yaml-front-matter/commit/39a68d2c10de16b411cccb90865856c8cacbe265)) 18 | 19 | ### [3.4.1](https://github.com/dworthen/js-yaml-front-matter/compare/v4.0.0-2...v3.4.1) (2018-02-27) 20 | 21 | 22 | # [4.0.0](https://github.com/dworthen/js-yaml-front-matter/compare/v4.0.0-4...v4.0.0) (2018-03-08) 23 | 24 | 25 | 26 | 27 | # [4.0.0-4](https://github.com/dworthen/js-yaml-front-matter/compare/v4.0.0-3...v4.0.0-4) (2018-02-28) 28 | 29 | 30 | ### Bug Fixes 31 | 32 | * Update API to be backward compatible with 3.x ([4a9aa0e](https://github.com/dworthen/js-yaml-front-matter/commit/4a9aa0e)) 33 | 34 | 35 | 36 | 37 | # [4.0.0-3](https://github.com/dworthen/js-yaml-front-matter/compare/v4.0.0-2...v4.0.0-3) (2018-02-27) 38 | 39 | 40 | ### Bug Fixes 41 | 42 | * list umd module as main entry point ([a63d69a](https://github.com/dworthen/js-yaml-front-matter/commit/a63d69a)) 43 | 44 | 45 | 46 | 47 | # [4.0.0-2](https://github.com/dworthen/js-yaml-front-matter/compare/v4.0.0-1...v4.0.0-2) (2018-02-27) 48 | 49 | 50 | ### Features 51 | 52 | * Add --pretty flag to print formatted json ([f119924](https://github.com/dworthen/js-yaml-front-matter/commit/f119924)) 53 | 54 | 55 | 56 | 57 | # [4.0.0-1](https://github.com/dworthen/js-yaml-front-matter/compare/v4.0.0-0...v4.0.0-1) (2018-02-27) 58 | 59 | 60 | ### Bug Fixes 61 | 62 | * **cli:** Update cli to support latest version ([1f0bd9e](https://github.com/dworthen/js-yaml-front-matter/commit/1f0bd9e)) 63 | 64 | 65 | 66 | 67 | # [4.0.0-0](https://github.com/dworthen/js-yaml-front-matter/compare/v3.4.0...v4.0.0-0) (2018-02-27) 68 | 69 | 70 | ### Features 71 | 72 | * Rewrite using es2015 ([2c24190](https://github.com/dworthen/js-yaml-front-matter/commit/2c24190)) 73 | 74 | 75 | ### BREAKING CHANGES 76 | 77 | * Changed: 78 | - No longer modifies or exposes js-yaml. May need to 79 | include js-yaml for yaml parsing needs outside of parsing 80 | front-matter 81 | - No longer supports reading contents from the file system. 82 | Instead, us fs to load the contents. 83 | - Browser global is now exposed was yamlFront instead of jsYaml 84 | - Browser script no longer comes bundled with underlying js-yaml. 85 | Must now include js-yaml as a separate script. 86 | Added: 87 | - safeLoadFront to behave the same as safeLoad from js-yaml. 88 | - loadFront and safeLoadFront now support all the same options 89 | as the corresponding methods in js-yaml 90 | 91 | 92 | 93 | # Change Log 94 | 95 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 96 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | parsing example 7 | 8 | 9 | 10 | 11 | 12 | 50 | 51 | 52 | 53 | 82 | 83 | 84 | 85 |
86 |
87 |
88 | 89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |

97 | An example demonstrating 98 | js yaml front matter. 99 |

100 |
101 |
102 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /test/js-yaml-front.test.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); 2 | var path = require("path"); 3 | var jsYaml = require("../dist/yamlFront"); 4 | var should = require("should"); 5 | 6 | describe("js-yaml-front", function() { 7 | var results = null; 8 | var testStr = null; 9 | var testStrWithExtraDashes = null; 10 | var testJsonStr = null; 11 | var testSafeYamlStr = null; 12 | 13 | var simpleYaml = fs.readFileSync( 14 | path.resolve(__dirname, "./fixtures/yaml.txt"), 15 | "utf8" 16 | ); 17 | var yamlWithDashes = fs.readFileSync( 18 | path.resolve(__dirname, "./fixtures/yamlWithExtraDashes.txt"), 19 | "utf8" 20 | ); 21 | var safeYaml = fs.readFileSync( 22 | path.resolve(__dirname, "./fixtures/safeYaml.txt"), 23 | "utf8" 24 | ); 25 | 26 | var json = fs.readFileSync( 27 | path.resolve(__dirname, "./fixtures/json.txt"), 28 | "utf8" 29 | ); 30 | 31 | // var testJsonStr = '---\n{"post": "title one",\n"anArray": ["one","two"],\n"subObject":\n'; 32 | // testJsonStr += '{"obj1": "cool", "obj2": "two"}}\n---\ncontent\nmore'; 33 | 34 | beforeEach(function() { 35 | results = null; 36 | testStr = simpleYaml; 37 | testStrWithExtraDashes = yamlWithDashes; 38 | testJsonStr = json; 39 | testSafeYamlStr = safeYaml; 40 | }); 41 | 42 | function testSimpleYaml(key) { 43 | key = key || "__content"; 44 | results.should.have.property("post", "title one"); 45 | results.should.have.property("anArray"); 46 | results.anArray.should.containEql("one"); 47 | results.anArray.should.containEql("two"); 48 | results.should.have.property("subObject"); 49 | results.subObject.should.have.property("obj1", "cool"); 50 | results.subObject.should.have.property("obj2", "two"); 51 | results.should.have.property("reg"); 52 | results.reg.should.be.an.instanceOf(RegExp); 53 | results.should.have.property("fun"); 54 | results.fun.should.Function(); 55 | results.should.have.property(key); 56 | results[key].should.match(/content\r?\nmore/); 57 | } 58 | 59 | function testYamlWithDashes(key) { 60 | key = key || "__content"; 61 | results.subObject.should.have.property("obj2", "two ---"); 62 | results.should.have.property(key); 63 | results[key].should.match(/content\r?\nmore/); 64 | } 65 | 66 | function testSafeYaml(key) { 67 | key = key || "__content"; 68 | results.should.not.have.property("reg"); 69 | results.should.not.have.property("fun"); 70 | results.should.have.property(key); 71 | results[key].should.match(/content\r?\nmore/); 72 | } 73 | 74 | function testJson(key) { 75 | key = key || "__content"; 76 | results.should.have.property("post", "title one"); 77 | results.should.have.property("anArray"); 78 | results.anArray.should.containEql("one"); 79 | results.anArray.should.containEql("two"); 80 | results.should.have.property("subObject"); 81 | results.subObject.should.have.property("obj1", "cool"); 82 | results.subObject.should.have.property("obj2", "two"); 83 | results.should.have.property(key); 84 | results[key].should.match(/content\r?\nmore/); 85 | } 86 | 87 | describe("loadFront", function() { 88 | describe("loading yaml", function() { 89 | it("should support loading yaml-front-matter", function() { 90 | results = jsYaml.loadFront(testStr); 91 | testSimpleYaml(); 92 | }); 93 | }); 94 | 95 | describe("loading yaml with arbitrary dashes", function() { 96 | it("should support loading yaml-front-matter with dashes", function() { 97 | results = jsYaml.loadFront(testStrWithExtraDashes); 98 | testYamlWithDashes(); 99 | }); 100 | }); 101 | 102 | describe("loading json", function() { 103 | it("should support loading json-front-matter", function() { 104 | results = jsYaml.loadFront(testJsonStr); 105 | testJson(); 106 | }); 107 | }); 108 | 109 | describe("loading without yaml", function() { 110 | it("should support loading files without yaml-front-matter", function() { 111 | results = jsYaml.loadFront("Hello World"); 112 | results.should.have.property("__content", "Hello World"); 113 | }); 114 | }); 115 | 116 | describe("loading empty string", function() { 117 | it("should support loading no content", function() { 118 | results = jsYaml.loadFront(""); 119 | results.should.have.property("__content", ""); 120 | }); 121 | }); 122 | 123 | describe("loading with options", function() { 124 | it("should support changing content key name through options object", function() { 125 | results = jsYaml.loadFront(testStr, { contentKeyName: "fileContents" }); 126 | testSimpleYaml("fileContents"); 127 | }); 128 | }); 129 | 130 | describe("loading with specifying content key name", function() { 131 | it("should support changing content key name with a string", function() { 132 | results = jsYaml.loadFront(testStr, "fileContents"); 133 | testSimpleYaml("fileContents"); 134 | }); 135 | }); 136 | }); // End describe loadFront 137 | 138 | describe("safeLoadFront", function() { 139 | describe("loading safe yaml", function() { 140 | it("should support loading yaml-front-matter without RegExp or functions", function() { 141 | results = jsYaml.safeLoadFront(testSafeYamlStr); 142 | testSafeYaml(); 143 | }); 144 | }); 145 | 146 | describe("loading yaml", function() { 147 | it("should not support loading yaml-front-matter that contain RegExp or functions", function() { 148 | jsYaml.safeLoadFront.bind(this, testStr).should.throw(); 149 | }); 150 | }); 151 | }); // End describe safeLoadFront 152 | }); // End describe js-yaml-front 153 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Yaml Front Matter 2 | 3 | Parses yaml or json at the front of a string. Places the parsed content, plus the rest of the string content, into an object literal. 4 | 5 | [Online Demo](https://dworthen.github.io/js-yaml-front-matter/). 6 | 7 | #### Breaking Changes 8 | 9 | This readme is for the 4.x release, which introduces breaking changes. View the [changelog](CHANGELOG.md) for more information. 10 | 11 | [3.x readme](https://github.com/dworthen/js-yaml-front-matter/tree/v3.4.0) 12 | 13 | ## Example 14 | 15 | This 16 | 17 | ```yaml 18 | --- 19 | name: Derek Worthen 20 | age: 127 21 | contact: 22 | email: email@domain.com 23 | address: some location 24 | pets: 25 | - cat 26 | - dog 27 | - bat 28 | match: !!js/regexp /pattern/gim 29 | run: !!js/function function() { } 30 | --- 31 | Some Other content 32 | ``` 33 | 34 | ```js 35 | var fs = require('fs'); 36 | var yamlFront = require('yaml-front-matter'); 37 | 38 | fs.readFile('./some/file.txt', 'utf8', function(fileContents) { 39 | console.log(yamlFront.loadFront(fileContents)); 40 | }); 41 | 42 | ``` 43 | 44 | outputs 45 | 46 | ```js 47 | { 48 | name: 'Derek Worthen', 49 | age: 127, 50 | contact: { email: 'email@domain.com', address: 'some location' }, 51 | pets: [ 'cat', 'dog', 'bat' ], 52 | match: /pattern/gim, 53 | run: [Function], 54 | __content: '\nSome Other Content' 55 | } 56 | ``` 57 | 58 | May also use JSON 59 | 60 | ```json 61 | --- 62 | { 63 | "name": "Derek Worthen", 64 | "age": "young", 65 | "anArray": ["one","two"], 66 | "subObj":{"field1": "one"} 67 | } 68 | --- 69 | Some content 70 | ``` 71 | 72 | > __NOTE:__ The `---` are required to denote the start and end of front matter. There must be a newline after the opening `---` and a newline preceding the closing `---`. 73 | 74 | ## Install 75 | 76 | ### npm 77 | 78 | ```shell 79 | $ npm install yaml-front-matter 80 | ``` 81 | 82 | Use the `-g` flag if you plan on using the command line tool. 83 | 84 | ```shell 85 | $ npm install yaml-front-matter -g 86 | ``` 87 | 88 | ### Node or client with module bundler (webpack or browsify) 89 | 90 | ```js 91 | var yamlFront = require('yaml-front-matter'); 92 | ``` 93 | 94 | ### Browser Bundle 95 | 96 | The [dist/yamlFront.js](dist/yamlFront.js) client script will expose the yaml-front-matter library as a global, `yamlFront`. The client script for [js-yaml](https://github.com/nodeca/js-yaml) is also required. May need to load espirma for some use cases. See [js-yaml](https://github.com/nodeca/js-yaml) for more information. 97 | 98 | ```html 99 | 100 | 101 | 104 | ``` 105 | 106 | > **Note**: yaml-front-matter is delivered as a umd package so it should work within commonjs, amd and browser (as a global) environments. 107 | 108 | ## Running Browser Example 109 | 110 | ```shell 111 | $ npm install --dev && npm start 112 | ``` 113 | 114 | Then visit `localhost:8080`. 115 | 116 | ## Building from source 117 | 118 | Outputs build files to `dist/`. 119 | 120 | ```shell 121 | $ npm install --dev && npm run build 122 | ``` 123 | 124 | ## Running Tests 125 | 126 | ```shell 127 | npm install --dev && npm test 128 | ``` 129 | 130 | ## Command Line 131 | 132 | ```shell 133 | Usage: yaml-front-matter [options] 134 | 135 | Options: 136 | 137 | -h, --help output usage information 138 | -v, --version output the version number 139 | -c, --content [name] set the property name for the files contents [__content] 140 | --pretty formats json output with spaces. 141 | ``` 142 | 143 | > **Note** The cli uses `safeLoadFront` and therefore will not parse yaml containing regexps, functions or undefined values. 144 | 145 | ### Example 146 | 147 | ```shell 148 | # Piping content from one file, through yaml parser and into another file 149 | cat ./some/file.txt | yaml-front-matter > output.txt 150 | ``` 151 | 152 | ## JS-YAML 153 | 154 | Yaml front matter wraps [js-yaml](https://github.com/nodeca/js-yaml) to support parsing yaml front-matter. 155 | 156 | ## API 157 | 158 | ### loadFront(string, [options]) 159 | 160 | ```js 161 | var input = [ 162 | '---\npost: title one\n', 163 | 'anArray:\n - one\n - two\n', 164 | 'subObject:\n prop1: cool\n prop2: two', 165 | '\nreg: !!js/regexp /pattern/gim', 166 | '\nfun: !!js/function function() { }\n---\n', 167 | 'content\nmore' 168 | ].join(''); 169 | 170 | var results = yamlFront.loadFront(input); 171 | console.log(results); 172 | ``` 173 | 174 | outputs 175 | 176 | ```shell 177 | { post: 'title one', 178 | anArray: [ 'one', 'two' ], 179 | subObject: { obj1: 'cool', obj2: 'two' }, 180 | reg: /pattern/gim, 181 | fun: [Function], 182 | __content: '\ncontent\nmore' } 183 | ``` 184 | 185 | Front-matter is optional. 186 | 187 | ```js 188 | yamlFront.loadFront('Hello World'); 189 | // => { __content: "Hello World!" } 190 | ``` 191 | 192 | Content is optional 193 | 194 | ```js 195 | yamlFront.loadFront(''); 196 | // => { __content: '' } 197 | ``` 198 | 199 | ### safeLoadFront(string, [options]) 200 | 201 | Same api as loadFront except it does not support regexps, functions or undefined. See [js-yaml](https://github.com/nodeca/js-yaml) for more information. 202 | 203 | ### Options 204 | 205 | The options object supports the same options available to [js-yaml](https://github.com/nodeca/js-yaml) and adds support for an additional key. 206 | 207 | - `options.contentKeyName`: Specify the object key where to store content not parsed by yaml-front-matter. defaults to `__content`. 208 | 209 | ```js 210 | yamlFront.loadFront('Hello World', { 211 | contentKeyName: 'fileContents' 212 | }); 213 | // => { fileContents: "Hello World" } 214 | ``` 215 | 216 | -------------------------------------------------------------------------------- /docs/css/skeleton.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Skeleton V1.2 3 | * Copyright 2011, Dave Gamache 4 | * www.getskeleton.com 5 | * Free to use under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 6/20/2012 8 | */ 9 | 10 | 11 | /* Table of Contents 12 | ================================================== 13 | #Base 960 Grid 14 | #Tablet (Portrait) 15 | #Mobile (Portrait) 16 | #Mobile (Landscape) 17 | #Clearing */ 18 | 19 | 20 | 21 | /* #Base 960 Grid 22 | ================================================== */ 23 | 24 | .container { position: relative; width: 960px; margin: 0 auto; padding: 0; } 25 | .container .column, 26 | .container .columns { float: left; display: inline; margin-left: 10px; margin-right: 10px; } 27 | .row { margin-bottom: 20px; } 28 | 29 | /* Nested Column Classes */ 30 | .column.alpha, .columns.alpha { margin-left: 0; } 31 | .column.omega, .columns.omega { margin-right: 0; } 32 | 33 | /* Base Grid */ 34 | .container .one.column, 35 | .container .one.columns { width: 40px; } 36 | .container .two.columns { width: 100px; } 37 | .container .three.columns { width: 160px; } 38 | .container .four.columns { width: 220px; } 39 | .container .five.columns { width: 280px; } 40 | .container .six.columns { width: 340px; } 41 | .container .seven.columns { width: 400px; } 42 | .container .eight.columns { width: 460px; } 43 | .container .nine.columns { width: 520px; } 44 | .container .ten.columns { width: 580px; } 45 | .container .eleven.columns { width: 640px; } 46 | .container .twelve.columns { width: 700px; } 47 | .container .thirteen.columns { width: 760px; } 48 | .container .fourteen.columns { width: 820px; } 49 | .container .fifteen.columns { width: 880px; } 50 | .container .sixteen.columns { width: 940px; } 51 | 52 | .container .one-third.column { width: 300px; } 53 | .container .two-thirds.column { width: 620px; } 54 | 55 | /* Offsets */ 56 | .container .offset-by-one { padding-left: 60px; } 57 | .container .offset-by-two { padding-left: 120px; } 58 | .container .offset-by-three { padding-left: 180px; } 59 | .container .offset-by-four { padding-left: 240px; } 60 | .container .offset-by-five { padding-left: 300px; } 61 | .container .offset-by-six { padding-left: 360px; } 62 | .container .offset-by-seven { padding-left: 420px; } 63 | .container .offset-by-eight { padding-left: 480px; } 64 | .container .offset-by-nine { padding-left: 540px; } 65 | .container .offset-by-ten { padding-left: 600px; } 66 | .container .offset-by-eleven { padding-left: 660px; } 67 | .container .offset-by-twelve { padding-left: 720px; } 68 | .container .offset-by-thirteen { padding-left: 780px; } 69 | .container .offset-by-fourteen { padding-left: 840px; } 70 | .container .offset-by-fifteen { padding-left: 900px; } 71 | 72 | 73 | 74 | /* #Tablet (Portrait) 75 | ================================================== */ 76 | 77 | /* Note: Design for a width of 768px */ 78 | 79 | @media only screen and (min-width: 768px) and (max-width: 959px) { 80 | .container { width: 768px; } 81 | .container .column, 82 | .container .columns { margin-left: 10px; margin-right: 10px; } 83 | .column.alpha, .columns.alpha { margin-left: 0; margin-right: 10px; } 84 | .column.omega, .columns.omega { margin-right: 0; margin-left: 10px; } 85 | .alpha.omega { margin-left: 0; margin-right: 0; } 86 | 87 | .container .one.column, 88 | .container .one.columns { width: 28px; } 89 | .container .two.columns { width: 76px; } 90 | .container .three.columns { width: 124px; } 91 | .container .four.columns { width: 172px; } 92 | .container .five.columns { width: 220px; } 93 | .container .six.columns { width: 268px; } 94 | .container .seven.columns { width: 316px; } 95 | .container .eight.columns { width: 364px; } 96 | .container .nine.columns { width: 412px; } 97 | .container .ten.columns { width: 460px; } 98 | .container .eleven.columns { width: 508px; } 99 | .container .twelve.columns { width: 556px; } 100 | .container .thirteen.columns { width: 604px; } 101 | .container .fourteen.columns { width: 652px; } 102 | .container .fifteen.columns { width: 700px; } 103 | .container .sixteen.columns { width: 748px; } 104 | 105 | .container .one-third.column { width: 236px; } 106 | .container .two-thirds.column { width: 492px; } 107 | 108 | /* Offsets */ 109 | .container .offset-by-one { padding-left: 48px; } 110 | .container .offset-by-two { padding-left: 96px; } 111 | .container .offset-by-three { padding-left: 144px; } 112 | .container .offset-by-four { padding-left: 192px; } 113 | .container .offset-by-five { padding-left: 240px; } 114 | .container .offset-by-six { padding-left: 288px; } 115 | .container .offset-by-seven { padding-left: 336px; } 116 | .container .offset-by-eight { padding-left: 384px; } 117 | .container .offset-by-nine { padding-left: 432px; } 118 | .container .offset-by-ten { padding-left: 480px; } 119 | .container .offset-by-eleven { padding-left: 528px; } 120 | .container .offset-by-twelve { padding-left: 576px; } 121 | .container .offset-by-thirteen { padding-left: 624px; } 122 | .container .offset-by-fourteen { padding-left: 672px; } 123 | .container .offset-by-fifteen { padding-left: 720px; } 124 | } 125 | 126 | 127 | /* #Mobile (Portrait) 128 | ================================================== */ 129 | 130 | /* Note: Design for a width of 320px */ 131 | 132 | @media only screen and (max-width: 767px) { 133 | .container { width: 300px; } 134 | .container .columns, 135 | .container .column { margin: 0; } 136 | 137 | .container .one.column, 138 | .container .one.columns, 139 | .container .two.columns, 140 | .container .three.columns, 141 | .container .four.columns, 142 | .container .five.columns, 143 | .container .six.columns, 144 | .container .seven.columns, 145 | .container .eight.columns, 146 | .container .nine.columns, 147 | .container .ten.columns, 148 | .container .eleven.columns, 149 | .container .twelve.columns, 150 | .container .thirteen.columns, 151 | .container .fourteen.columns, 152 | .container .fifteen.columns, 153 | .container .sixteen.columns, 154 | .container .one-third.column, 155 | .container .two-thirds.column { width: 300px; } 156 | 157 | /* Offsets */ 158 | .container .offset-by-one, 159 | .container .offset-by-two, 160 | .container .offset-by-three, 161 | .container .offset-by-four, 162 | .container .offset-by-five, 163 | .container .offset-by-six, 164 | .container .offset-by-seven, 165 | .container .offset-by-eight, 166 | .container .offset-by-nine, 167 | .container .offset-by-ten, 168 | .container .offset-by-eleven, 169 | .container .offset-by-twelve, 170 | .container .offset-by-thirteen, 171 | .container .offset-by-fourteen, 172 | .container .offset-by-fifteen { padding-left: 0; } 173 | 174 | } 175 | 176 | 177 | /* #Mobile (Landscape) 178 | ================================================== */ 179 | 180 | /* Note: Design for a width of 480px */ 181 | 182 | @media only screen and (min-width: 480px) and (max-width: 767px) { 183 | .container { width: 420px; } 184 | .container .columns, 185 | .container .column { margin: 0; } 186 | 187 | .container .one.column, 188 | .container .one.columns, 189 | .container .two.columns, 190 | .container .three.columns, 191 | .container .four.columns, 192 | .container .five.columns, 193 | .container .six.columns, 194 | .container .seven.columns, 195 | .container .eight.columns, 196 | .container .nine.columns, 197 | .container .ten.columns, 198 | .container .eleven.columns, 199 | .container .twelve.columns, 200 | .container .thirteen.columns, 201 | .container .fourteen.columns, 202 | .container .fifteen.columns, 203 | .container .sixteen.columns, 204 | .container .one-third.column, 205 | .container .two-thirds.column { width: 420px; } 206 | } 207 | 208 | 209 | /* #Clearing 210 | ================================================== */ 211 | 212 | /* Self Clearing Goodness */ 213 | .container:after { content: "\0020"; display: block; height: 0; clear: both; visibility: hidden; } 214 | 215 | /* Use clearfix class on parent to clear nested columns, 216 | or wrap each row of columns in a
*/ 217 | .clearfix:before, 218 | .clearfix:after, 219 | .row:before, 220 | .row:after { 221 | content: '\0020'; 222 | display: block; 223 | overflow: hidden; 224 | visibility: hidden; 225 | width: 0; 226 | height: 0; } 227 | .row:after, 228 | .clearfix:after { 229 | clear: both; } 230 | .row, 231 | .clearfix { 232 | zoom: 1; } 233 | 234 | /* You can also use a
to clear columns */ 235 | .clear { 236 | clear: both; 237 | display: block; 238 | overflow: hidden; 239 | visibility: hidden; 240 | width: 0; 241 | height: 0; 242 | } -------------------------------------------------------------------------------- /docs/css/base.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Skeleton V1.2 3 | * Copyright 2011, Dave Gamache 4 | * www.getskeleton.com 5 | * Free to use under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 6/20/2012 8 | */ 9 | 10 | 11 | /* Table of Content 12 | ================================================== 13 | #Reset & Basics 14 | #Basic Styles 15 | #Site Styles 16 | #Typography 17 | #Links 18 | #Lists 19 | #Images 20 | #Buttons 21 | #Forms 22 | #Misc */ 23 | 24 | 25 | /* #Reset & Basics (Inspired by E. Meyers) 26 | ================================================== */ 27 | html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { 28 | margin: 0; 29 | padding: 0; 30 | border: 0; 31 | font-size: 100%; 32 | font: inherit; 33 | vertical-align: baseline; } 34 | article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { 35 | display: block; } 36 | body { 37 | line-height: 1; } 38 | ol, ul { 39 | list-style: none; } 40 | blockquote, q { 41 | quotes: none; } 42 | blockquote:before, blockquote:after, 43 | q:before, q:after { 44 | content: ''; 45 | content: none; } 46 | table { 47 | border-collapse: collapse; 48 | border-spacing: 0; } 49 | 50 | 51 | /* #Basic Styles 52 | ================================================== */ 53 | body { 54 | background: #fff; 55 | font: 14px/21px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; 56 | color: #444; 57 | -webkit-font-smoothing: antialiased; /* Fix for webkit rendering */ 58 | -webkit-text-size-adjust: 100%; 59 | } 60 | 61 | 62 | /* #Typography 63 | ================================================== */ 64 | h1, h2, h3, h4, h5, h6 { 65 | color: #181818; 66 | font-family: "Georgia", "Times New Roman", serif; 67 | font-weight: normal; } 68 | h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-weight: inherit; } 69 | h1 { font-size: 46px; line-height: 50px; margin-bottom: 14px;} 70 | h2 { font-size: 35px; line-height: 40px; margin-bottom: 10px; } 71 | h3 { font-size: 28px; line-height: 34px; margin-bottom: 8px; } 72 | h4 { font-size: 21px; line-height: 30px; margin-bottom: 4px; } 73 | h5 { font-size: 17px; line-height: 24px; } 74 | h6 { font-size: 14px; line-height: 21px; } 75 | .subheader { color: #777; } 76 | 77 | p { margin: 0 0 20px 0; } 78 | p img { margin: 0; } 79 | p.lead { font-size: 21px; line-height: 27px; color: #777; } 80 | 81 | em { font-style: italic; } 82 | strong { font-weight: bold; color: #333; } 83 | small { font-size: 80%; } 84 | 85 | /* Blockquotes */ 86 | blockquote, blockquote p { font-size: 17px; line-height: 24px; color: #777; font-style: italic; } 87 | blockquote { margin: 0 0 20px; padding: 9px 20px 0 19px; border-left: 1px solid #ddd; } 88 | blockquote cite { display: block; font-size: 12px; color: #555; } 89 | blockquote cite:before { content: "\2014 \0020"; } 90 | blockquote cite a, blockquote cite a:visited, blockquote cite a:visited { color: #555; } 91 | 92 | hr { border: solid #ddd; border-width: 1px 0 0; clear: both; margin: 10px 0 30px; height: 0; } 93 | 94 | 95 | /* #Links 96 | ================================================== */ 97 | a, a:visited { color: #333; text-decoration: underline; outline: 0; } 98 | a:hover, a:focus { color: #000; } 99 | p a, p a:visited { line-height: inherit; } 100 | 101 | 102 | /* #Lists 103 | ================================================== */ 104 | ul, ol { margin-bottom: 20px; } 105 | ul { list-style: none outside; } 106 | ol { list-style: decimal; } 107 | ol, ul.square, ul.circle, ul.disc { margin-left: 30px; } 108 | ul.square { list-style: square outside; } 109 | ul.circle { list-style: circle outside; } 110 | ul.disc { list-style: disc outside; } 111 | ul ul, ul ol, 112 | ol ol, ol ul { margin: 4px 0 5px 30px; font-size: 90%; } 113 | ul ul li, ul ol li, 114 | ol ol li, ol ul li { margin-bottom: 6px; } 115 | li { line-height: 18px; margin-bottom: 12px; } 116 | ul.large li { line-height: 21px; } 117 | li p { line-height: 21px; } 118 | 119 | /* #Images 120 | ================================================== */ 121 | 122 | img.scale-with-grid { 123 | max-width: 100%; 124 | height: auto; } 125 | 126 | 127 | /* #Buttons 128 | ================================================== */ 129 | 130 | .button, 131 | button, 132 | input[type="submit"], 133 | input[type="reset"], 134 | input[type="button"] { 135 | background: #eee; /* Old browsers */ 136 | background: #eee -moz-linear-gradient(top, rgba(255,255,255,.2) 0%, rgba(0,0,0,.2) 100%); /* FF3.6+ */ 137 | background: #eee -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.2)), color-stop(100%,rgba(0,0,0,.2))); /* Chrome,Safari4+ */ 138 | background: #eee -webkit-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Chrome10+,Safari5.1+ */ 139 | background: #eee -o-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Opera11.10+ */ 140 | background: #eee -ms-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* IE10+ */ 141 | background: #eee linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* W3C */ 142 | border: 1px solid #aaa; 143 | border-top: 1px solid #ccc; 144 | border-left: 1px solid #ccc; 145 | -moz-border-radius: 3px; 146 | -webkit-border-radius: 3px; 147 | border-radius: 3px; 148 | color: #444; 149 | display: inline-block; 150 | font-size: 11px; 151 | font-weight: bold; 152 | text-decoration: none; 153 | text-shadow: 0 1px rgba(255, 255, 255, .75); 154 | cursor: pointer; 155 | margin-bottom: 20px; 156 | line-height: normal; 157 | padding: 8px 10px; 158 | font-family: "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; } 159 | 160 | .button:hover, 161 | button:hover, 162 | input[type="submit"]:hover, 163 | input[type="reset"]:hover, 164 | input[type="button"]:hover { 165 | color: #222; 166 | background: #ddd; /* Old browsers */ 167 | background: #ddd -moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); /* FF3.6+ */ 168 | background: #ddd -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.3)), color-stop(100%,rgba(0,0,0,.3))); /* Chrome,Safari4+ */ 169 | background: #ddd -webkit-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Chrome10+,Safari5.1+ */ 170 | background: #ddd -o-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Opera11.10+ */ 171 | background: #ddd -ms-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* IE10+ */ 172 | background: #ddd linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* W3C */ 173 | border: 1px solid #888; 174 | border-top: 1px solid #aaa; 175 | border-left: 1px solid #aaa; } 176 | 177 | .button:active, 178 | button:active, 179 | input[type="submit"]:active, 180 | input[type="reset"]:active, 181 | input[type="button"]:active { 182 | border: 1px solid #666; 183 | background: #ccc; /* Old browsers */ 184 | background: #ccc -moz-linear-gradient(top, rgba(255,255,255,.35) 0%, rgba(10,10,10,.4) 100%); /* FF3.6+ */ 185 | background: #ccc -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.35)), color-stop(100%,rgba(10,10,10,.4))); /* Chrome,Safari4+ */ 186 | background: #ccc -webkit-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Chrome10+,Safari5.1+ */ 187 | background: #ccc -o-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Opera11.10+ */ 188 | background: #ccc -ms-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* IE10+ */ 189 | background: #ccc linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* W3C */ } 190 | 191 | .button.full-width, 192 | button.full-width, 193 | input[type="submit"].full-width, 194 | input[type="reset"].full-width, 195 | input[type="button"].full-width { 196 | width: 100%; 197 | padding-left: 0 !important; 198 | padding-right: 0 !important; 199 | text-align: center; } 200 | 201 | /* Fix for odd Mozilla border & padding issues */ 202 | button::-moz-focus-inner, 203 | input::-moz-focus-inner { 204 | border: 0; 205 | padding: 0; 206 | } 207 | 208 | 209 | /* #Forms 210 | ================================================== */ 211 | 212 | form { 213 | margin-bottom: 20px; } 214 | fieldset { 215 | margin-bottom: 20px; } 216 | input[type="text"], 217 | input[type="password"], 218 | input[type="email"], 219 | textarea, 220 | select { 221 | border: 1px solid #ccc; 222 | padding: 6px 4px; 223 | outline: none; 224 | -moz-border-radius: 2px; 225 | -webkit-border-radius: 2px; 226 | border-radius: 2px; 227 | font: 13px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; 228 | color: #777; 229 | margin: 0; 230 | width: 210px; 231 | max-width: 100%; 232 | display: block; 233 | margin-bottom: 20px; 234 | background: #fff; } 235 | select { 236 | padding: 0; } 237 | input[type="text"]:focus, 238 | input[type="password"]:focus, 239 | input[type="email"]:focus, 240 | textarea:focus { 241 | border: 1px solid #aaa; 242 | color: #444; 243 | -moz-box-shadow: 0 0 3px rgba(0,0,0,.2); 244 | -webkit-box-shadow: 0 0 3px rgba(0,0,0,.2); 245 | box-shadow: 0 0 3px rgba(0,0,0,.2); } 246 | textarea { 247 | min-height: 60px; } 248 | label, 249 | legend { 250 | display: block; 251 | font-weight: bold; 252 | font-size: 13px; } 253 | select { 254 | width: 220px; } 255 | input[type="checkbox"] { 256 | display: inline; } 257 | label span, 258 | legend span { 259 | font-weight: normal; 260 | font-size: 13px; 261 | color: #444; } 262 | 263 | /* #Misc 264 | ================================================== */ 265 | .remove-bottom { margin-bottom: 0 !important; } 266 | .half-bottom { margin-bottom: 10px !important; } 267 | .add-bottom { margin-bottom: 20px !important; } 268 | 269 | --------------------------------------------------------------------------------