├── .gitignore ├── test ├── dest │ ├── mia.json │ ├── nullSearch.json │ ├── fonts.json │ ├── colors.json │ └── globSearch.json ├── dest--expected │ ├── mia.json │ ├── nullSearch.json │ ├── fonts.json │ ├── colors.json │ └── globSearch.json ├── src │ ├── colors.scss │ └── fonts.scss └── pattern_lab_component_builder_test.js ├── .jshintrc ├── .editorconfig ├── templates └── colors.mustache ├── package.json ├── tasks ├── pattern_lab_component_builder.js └── pattern_lab_component_builder--old.js ├── readme.md └── Gruntfile.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | tmp 4 | -------------------------------------------------------------------------------- /test/dest/mia.json: -------------------------------------------------------------------------------- 1 | { 2 | "missingFile": [] 3 | } -------------------------------------------------------------------------------- /test/dest/nullSearch.json: -------------------------------------------------------------------------------- 1 | { 2 | "nullSearch": [] 3 | } -------------------------------------------------------------------------------- /test/dest--expected/mia.json: -------------------------------------------------------------------------------- 1 | { 2 | "missingFile": [] 3 | } -------------------------------------------------------------------------------- /test/dest--expected/nullSearch.json: -------------------------------------------------------------------------------- 1 | { 2 | "nullSearch": [] 3 | } -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "eqeqeq": true, 4 | "immed": true, 5 | "latedef": true, 6 | "newcap": true, 7 | "noarg": true, 8 | "sub": true, 9 | "undef": true, 10 | "boss": true, 11 | "eqnull": true, 12 | "node": true 13 | } 14 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /templates/colors.mustache: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /test/src/colors.scss: -------------------------------------------------------------------------------- 1 | /* Colors 2 | ========================================================================== */ 3 | 4 | $color--white: hsl(0, 0%, 100%); 5 | $color--gray--white: hsl(0, 0%, 94.1%); 6 | $color--gray--lightest: hsl(0, 0%, 85.9%); 7 | $color--gray--lighter: hsl(0, 0%, 78%); 8 | $color--gray--light: hsl(0, 0%, 70.2%); 9 | $color--gray: hsl(228, 2.3%, 41.8%); 10 | $color--gray--dark: hsl(0, 0%, 40%); 11 | $color--gray--darker: hsl(0, 0%, 20%); 12 | $color--gray--darkest: hsl(0, 0%, 16.1%); 13 | $color--gray--black: hsl(0, 0%, 7.8%); 14 | $color--black: hsl(0, 0%, 0%); 15 | 16 | $white: $color--white; 17 | $black: $color--black; 18 | 19 | // Semantic Colors 20 | $color--font: $color--black; 21 | $color--link: $color--black; 22 | $color--border: $color--gray; 23 | $color--error: red; 24 | -------------------------------------------------------------------------------- /test/dest/fonts.json: -------------------------------------------------------------------------------- 1 | { 2 | "fonts": [ 3 | { 4 | "name": "$typesize--11px", 5 | "value": "11px" 6 | }, 7 | { 8 | "name": "$typesize--12px", 9 | "value": "12px" 10 | }, 11 | { 12 | "name": "$typesize--14px", 13 | "value": "14px" 14 | }, 15 | { 16 | "name": "$typesize--18px", 17 | "value": "18px" 18 | }, 19 | { 20 | "name": "$typesize--24px", 21 | "value": "24px" 22 | }, 23 | { 24 | "name": "$typesize--30px", 25 | "value": "30px" 26 | }, 27 | { 28 | "name": "$typesize--36px", 29 | "value": "36px" 30 | }, 31 | { 32 | "name": "$typesize--48px", 33 | "value": "48px" 34 | }, 35 | { 36 | "name": "$typesize--60px", 37 | "value": "60px" 38 | }, 39 | { 40 | "name": "$typesize--100px", 41 | "value": "100px" 42 | } 43 | ] 44 | } -------------------------------------------------------------------------------- /test/dest--expected/fonts.json: -------------------------------------------------------------------------------- 1 | { 2 | "fonts": [ 3 | { 4 | "name": "$typesize--11px", 5 | "value": "11px" 6 | }, 7 | { 8 | "name": "$typesize--12px", 9 | "value": "12px" 10 | }, 11 | { 12 | "name": "$typesize--14px", 13 | "value": "14px" 14 | }, 15 | { 16 | "name": "$typesize--18px", 17 | "value": "18px" 18 | }, 19 | { 20 | "name": "$typesize--24px", 21 | "value": "24px" 22 | }, 23 | { 24 | "name": "$typesize--30px", 25 | "value": "30px" 26 | }, 27 | { 28 | "name": "$typesize--36px", 29 | "value": "36px" 30 | }, 31 | { 32 | "name": "$typesize--48px", 33 | "value": "48px" 34 | }, 35 | { 36 | "name": "$typesize--60px", 37 | "value": "60px" 38 | }, 39 | { 40 | "name": "$typesize--100px", 41 | "value": "100px" 42 | } 43 | ] 44 | } -------------------------------------------------------------------------------- /test/src/fonts.scss: -------------------------------------------------------------------------------- 1 | /* Type Scale 2 | ========================================================================== */ 3 | $typesize--11px : 11px; 4 | $typesize--12px : 12px; 5 | $typesize--14px : 14px; 6 | $typesize--18px : 18px; 7 | $typesize--24px : 24px; 8 | $typesize--30px : 30px; 9 | $typesize--36px : 36px; 10 | $typesize--48px : 48px; 11 | $typesize--60px : 60px; 12 | $typesize--100px : 100px; 13 | 14 | $lineheight--13-11: 13px / $typesize--11px; 15 | $lineheight--14-12: 14px / $typesize--12px; 16 | $lineheight--18-12: 18px / $typesize--12px; 17 | $lineheight--18-14: 18px / $typesize--14px; 18 | $lineheight--20-18: 20px / $typesize--18px; 19 | $lineheight--30-24: 30px / $typesize--24px; 20 | $lineheight--30-30: 30px / $typesize--30px; 21 | $lineheight--44-36: 44px / $typesize--36px; 22 | $lineheight--42-48: 42px / $typesize--48px; 23 | $lineheight--48-60: 48px / $typesize--60px; 24 | $lineheight--86-100: 86px / $typesize--100px; 25 | -------------------------------------------------------------------------------- /test/dest/colors.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | { 4 | "name": "$color--white", 5 | "value": "hsl(0, 0%, 100%)" 6 | }, 7 | { 8 | "name": "$color--gray--white", 9 | "value": "hsl(0, 0%, 94.1%)" 10 | }, 11 | { 12 | "name": "$color--gray--lightest", 13 | "value": "hsl(0, 0%, 85.9%)" 14 | }, 15 | { 16 | "name": "$color--gray--lighter", 17 | "value": "hsl(0, 0%, 78%)" 18 | }, 19 | { 20 | "name": "$color--gray--light", 21 | "value": "hsl(0, 0%, 70.2%)" 22 | }, 23 | { 24 | "name": "$color--gray", 25 | "value": "hsl(228, 2.3%, 41.8%)" 26 | }, 27 | { 28 | "name": "$color--gray--dark", 29 | "value": "hsl(0, 0%, 40%)" 30 | }, 31 | { 32 | "name": "$color--gray--darker", 33 | "value": "hsl(0, 0%, 20%)" 34 | }, 35 | { 36 | "name": "$color--gray--darkest", 37 | "value": "hsl(0, 0%, 16.1%)" 38 | }, 39 | { 40 | "name": "$color--gray--black", 41 | "value": "hsl(0, 0%, 7.8%)" 42 | }, 43 | { 44 | "name": "$color--black", 45 | "value": "hsl(0, 0%, 0%)" 46 | }, 47 | { 48 | "name": "$color--error", 49 | "value": "red" 50 | } 51 | ] 52 | } -------------------------------------------------------------------------------- /test/dest--expected/colors.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | { 4 | "name": "$color--white", 5 | "value": "hsl(0, 0%, 100%)" 6 | }, 7 | { 8 | "name": "$color--gray--white", 9 | "value": "hsl(0, 0%, 94.1%)" 10 | }, 11 | { 12 | "name": "$color--gray--lightest", 13 | "value": "hsl(0, 0%, 85.9%)" 14 | }, 15 | { 16 | "name": "$color--gray--lighter", 17 | "value": "hsl(0, 0%, 78%)" 18 | }, 19 | { 20 | "name": "$color--gray--light", 21 | "value": "hsl(0, 0%, 70.2%)" 22 | }, 23 | { 24 | "name": "$color--gray", 25 | "value": "hsl(228, 2.3%, 41.8%)" 26 | }, 27 | { 28 | "name": "$color--gray--dark", 29 | "value": "hsl(0, 0%, 40%)" 30 | }, 31 | { 32 | "name": "$color--gray--darker", 33 | "value": "hsl(0, 0%, 20%)" 34 | }, 35 | { 36 | "name": "$color--gray--darkest", 37 | "value": "hsl(0, 0%, 16.1%)" 38 | }, 39 | { 40 | "name": "$color--gray--black", 41 | "value": "hsl(0, 0%, 7.8%)" 42 | }, 43 | { 44 | "name": "$color--black", 45 | "value": "hsl(0, 0%, 0%)" 46 | }, 47 | { 48 | "name": "$color--error", 49 | "value": "red" 50 | } 51 | ] 52 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grunt-pattern-lab-component-builder", 3 | "version": "0.0.12", 4 | "description": "Automatically Create Pattern Lab Components", 5 | "homepage": "https://github.com/EvanLovely/grunt-pattern-lab-component-builder", 6 | "repository": { 7 | "type": "git", 8 | "url": "git@github.com:EvanLovely/grunt-pattern-lab-component-builder.git" 9 | }, 10 | "bugs": { 11 | "url": "https://github.com/EvanLovely/grunt-pattern-lab-component-builder/issues" 12 | }, 13 | "author": { 14 | "name": "Evan Lovely", 15 | "url": "http://evanlovely.com" 16 | }, 17 | "keywords": [ 18 | "gruntplugin", 19 | "pattern-lab" 20 | ], 21 | "main": "Gruntfile.js", 22 | "engines": { 23 | "node": ">= 0.8.0" 24 | }, 25 | "license": "MIT", 26 | "dependencies": { 27 | "underscore": "^1.6.0" 28 | }, 29 | "devDependencies": { 30 | "grunt": "~0.4.2", 31 | "grunt-bump": "0.0.15", 32 | "grunt-contrib-clean": "~0.5.0", 33 | "grunt-contrib-jshint": "~0.8.0", 34 | "grunt-contrib-nodeunit": "~0.3.0", 35 | "grunt-contrib-watch": "^0.6.1", 36 | "jshint-stylish": "~0.1.5", 37 | "load-grunt-tasks": "~0.3.0" 38 | }, 39 | "scripts": { 40 | "test": "grunt test", 41 | "dev": "grunt watch:plugin" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test/pattern_lab_component_builder_test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var grunt = require('grunt'); 4 | 5 | /* 6 | ======== A Handy Little Nodeunit Reference ======== 7 | https://github.com/caolan/nodeunit 8 | 9 | Test methods: 10 | test.expect(numAssertions) 11 | test.done() 12 | Test assertions: 13 | test.ok(value, [message]) 14 | test.equal(actual, expected, [message]) 15 | test.notEqual(actual, expected, [message]) 16 | test.deepEqual(actual, expected, [message]) 17 | test.notDeepEqual(actual, expected, [message]) 18 | test.strictEqual(actual, expected, [message]) 19 | test.notStrictEqual(actual, expected, [message]) 20 | test.throws(block, [error], [message]) 21 | test.doesNotThrow(block, [error], [message]) 22 | test.ifError(value) 23 | */ 24 | 25 | exports.pattern_lab_component_builder = { 26 | setUp: function (done) { 27 | // setup here if necessary 28 | done(); 29 | }, 30 | //colors: function (test) { 31 | // test.expect(1); 32 | // 33 | // var actual = grunt.file.read('tmp/colors.mustache').trim(); 34 | // var expected = grunt.file.read('test/expected/colors.mustache').trim(); 35 | // test.equal(actual, expected, 'Color Mustache file needs to render correctly'); 36 | // 37 | // test.done(); 38 | //} 39 | }; 40 | -------------------------------------------------------------------------------- /tasks/pattern_lab_component_builder.js: -------------------------------------------------------------------------------- 1 | /* 2 | * pattern-lab-component-builder 3 | * Copyright (c) 2015 Evan Lovely 4 | * Licensed under the MIT license. 5 | */ 6 | 7 | 'use strict'; 8 | var _ = require('underscore'); 9 | module.exports = function (grunt) { 10 | 11 | grunt.registerMultiTask('pattern_lab_component_builder', 'Automatically Create Pattern Lab Components', function () { 12 | 13 | // Merge task-specific and/or target-specific options with these defaults. 14 | var options = this.options({ 15 | 'regex': "^\\$.*", 16 | 'allow_var_values': true 17 | }); 18 | var regex = new RegExp(options.regex, "mg"); 19 | var target = this.target; 20 | //var x = JSON.stringify(this, null, ' '); 21 | //grunt.log.debug(x); 22 | 23 | function colonBreaker(theString) { 24 | var name = theString.split(":")[0].trim(); 25 | var value = theString.split(":")[1].trim().replace(";", ""); 26 | var result = { 27 | "name": name, 28 | "value": value 29 | }; 30 | if (options.allow_var_values) { 31 | return result; 32 | } else { 33 | if (!value.match(/\$/)) { 34 | return result; 35 | } 36 | } 37 | } 38 | 39 | this.files.forEach(function (file) { 40 | grunt.log.debug(JSON.stringify(file, null, ' ')); 41 | var src = file.src.filter(function (filepath) { 42 | if (!grunt.file.exists(filepath)) { 43 | grunt.log.warn('Source file "' + filepath + '" not found.'); 44 | return false; 45 | } else { 46 | return true; 47 | } 48 | }).map(function (filepath) { 49 | var results = grunt.file.read(filepath).match(regex); 50 | var organizedResults = []; 51 | if (results) { 52 | results.forEach(function (line) { 53 | organizedResults.push(colonBreaker(line)); 54 | }); 55 | } 56 | //console.log(typeof results, results); 57 | return organizedResults; 58 | }); 59 | src = _.flatten(src); 60 | src = _.compact(src); 61 | grunt.log.debug(JSON.stringify(src, null, ' ')); 62 | var finalResults = {}; 63 | finalResults[target] = src; 64 | grunt.file.write(file.dest, JSON.stringify(finalResults, null, ' ')); 65 | grunt.log.writeln("File created from matches: " + file.dest); 66 | }); 67 | 68 | 69 | }); 70 | 71 | }; 72 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # grunt-pattern-lab-component-builder 2 | 3 | > Automatically Create Pattern Lab Components 4 | 5 | ## Getting Started 6 | This plugin requires Grunt. 7 | 8 | If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started) guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command: 9 | 10 | ```shell 11 | npm install grunt-pattern-lab-component-builder --save-dev 12 | ``` 13 | 14 | Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript: 15 | 16 | ```js 17 | grunt.loadNpmTasks('pattern-lab-component-builder'); 18 | ``` 19 | 20 | ## The "pattern_lab_component_builder" task 21 | 22 | ### Overview 23 | In your project's Gruntfile, add a section named `pattern_lab_component_builder` to the data object passed into `grunt.initConfig()`. 24 | 25 | ```js 26 | grunt.initConfig({ 27 | pattern_lab_component_builder: { 28 | colors: { 29 | options: { 30 | regex: "^\\$color--.*", 31 | allow_var_values: false 32 | }, 33 | src: 'scss/global/variables/_colors.scss', 34 | dest: 'source/_patterns/00-atoms/01-global/00-colors.json' 35 | }, 36 | fonts: { 37 | options: { 38 | 'regex': "^\\$type.*" 39 | }, 40 | src: "scss/global/variables/_type-sizes.scss", 41 | dest: "source/_patterns/00-atoms/02-text/02-type-sizes.json" 42 | }, 43 | }, 44 | }) 45 | ``` 46 | 47 | The `src` is the file that the plugin reads from and infers your Pattern Lab component, which then gets written to `dest`. 48 | 49 | ### Options 50 | 51 | #### options.component 52 | Type: `String` 53 | 54 | Which Pattern Lab component to work with. Available options: 55 | 56 | - `colors` 57 | 58 | #### options.template 59 | Type: `path` 60 | 61 | The Mustache template to render the Pattern Lab compoenent with. See `templates/` for examples (which are the defaults). 62 | 63 | ### Usage Examples 64 | 65 | The only current usage is in the overview. 66 | 67 | ## Contributing 68 | In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/). 69 | 70 | ## Release History 71 | _(Nothing yet)_ 72 | 73 | ## License 74 | Copyright (c) 2014 Evan Lovely. Licensed under the MIT license. 75 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | /* 2 | * pattern-lab-component-builder 3 | * 4 | * 5 | * Copyright (c) 2014 Evan Lovely 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | 'use strict'; 10 | 11 | module.exports = function (grunt) { 12 | // load all npm grunt tasks 13 | require('load-grunt-tasks')(grunt); 14 | 15 | // Project configuration. 16 | grunt.initConfig({ 17 | jshint: { 18 | all: [ 19 | 'Gruntfile.js', 20 | 'tasks/*.js', 21 | '<%= nodeunit.tests %>' 22 | ], 23 | options: { 24 | jshintrc: '.jshintrc', 25 | reporter: require('jshint-stylish') 26 | } 27 | }, 28 | 29 | // Before generating any new files, remove any previously-created files. 30 | clean: { 31 | tests: ['test/dest*'] 32 | }, 33 | 34 | // Configuration to be run (and then tested). 35 | pattern_lab_component_builder: { 36 | colors: { 37 | options: { 38 | 'regex': "^\\$color--.*", 39 | allow_var_values: false 40 | }, 41 | src: 'test/src/*.scss', 42 | dest: 'test/dest/colors.json' 43 | }, 44 | fonts: { 45 | options: { 46 | regex: "^\\$type.*" 47 | }, 48 | src: ['test/src/fonts.scss'], 49 | dest: 'test/dest/fonts.json' 50 | }, 51 | nullSearch: { 52 | options: { 53 | regex: "^\\$asdf.*" 54 | }, 55 | src: ['test/src/fonts.scss'], 56 | dest: 'test/dest/nullSearch.json' 57 | }, 58 | globSearch: { 59 | options: { 60 | //regex: "^\\$.*" 61 | }, 62 | src: ['test/src/*.scss'], 63 | dest: 'test/dest/globSearch.json' 64 | }, 65 | missingFile: { 66 | src: ['test/src/mia.scss'], 67 | dest: 'test/dest/mia.json' 68 | } 69 | }, 70 | 71 | watch: { 72 | plugin: { 73 | options: { 74 | atBegin: true 75 | }, 76 | files: [ 77 | 'Gruntfile.js', 78 | 'tasks/*' 79 | ], 80 | tasks: [ 81 | 'pattern_lab_component_builder' 82 | ] 83 | } 84 | }, 85 | 86 | // Unit tests. 87 | nodeunit: { 88 | tests: ['test/*_test.js'] 89 | }, 90 | 91 | bump: {// https://github.com/vojtajina/grunt-bump 92 | options: { 93 | files: ['package.json'], 94 | updateConfigs: [], 95 | commit: true, 96 | commitMessage: 'Release v%VERSION%', 97 | commitFiles: ['package.json'], 98 | createTag: true, 99 | tagName: 'v%VERSION%', 100 | tagMessage: 'Version %VERSION%', 101 | push: true, 102 | pushTo: 'origin', 103 | gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d' 104 | } 105 | } 106 | 107 | }); 108 | 109 | // Actually load this plugin's task(s). 110 | grunt.loadTasks('tasks'); 111 | 112 | // Whenever the "test" task is run, first clean the "tmp" dir, then run this 113 | // plugin's task(s), then test the result. 114 | grunt.registerTask('test', [ 115 | 'clean', 116 | 'pattern_lab_component_builder' 117 | // 'nodeunit' 118 | ]); 119 | 120 | // By default, lint and run all tests. 121 | grunt.registerTask('default', ['jshint', 'test']); 122 | 123 | }; 124 | -------------------------------------------------------------------------------- /test/dest/globSearch.json: -------------------------------------------------------------------------------- 1 | { 2 | "globSearch": [ 3 | { 4 | "name": "$color--white", 5 | "value": "hsl(0, 0%, 100%)" 6 | }, 7 | { 8 | "name": "$color--gray--white", 9 | "value": "hsl(0, 0%, 94.1%)" 10 | }, 11 | { 12 | "name": "$color--gray--lightest", 13 | "value": "hsl(0, 0%, 85.9%)" 14 | }, 15 | { 16 | "name": "$color--gray--lighter", 17 | "value": "hsl(0, 0%, 78%)" 18 | }, 19 | { 20 | "name": "$color--gray--light", 21 | "value": "hsl(0, 0%, 70.2%)" 22 | }, 23 | { 24 | "name": "$color--gray", 25 | "value": "hsl(228, 2.3%, 41.8%)" 26 | }, 27 | { 28 | "name": "$color--gray--dark", 29 | "value": "hsl(0, 0%, 40%)" 30 | }, 31 | { 32 | "name": "$color--gray--darker", 33 | "value": "hsl(0, 0%, 20%)" 34 | }, 35 | { 36 | "name": "$color--gray--darkest", 37 | "value": "hsl(0, 0%, 16.1%)" 38 | }, 39 | { 40 | "name": "$color--gray--black", 41 | "value": "hsl(0, 0%, 7.8%)" 42 | }, 43 | { 44 | "name": "$color--black", 45 | "value": "hsl(0, 0%, 0%)" 46 | }, 47 | { 48 | "name": "$white", 49 | "value": "$color--white" 50 | }, 51 | { 52 | "name": "$black", 53 | "value": "$color--black" 54 | }, 55 | { 56 | "name": "$color--font", 57 | "value": "$color--black" 58 | }, 59 | { 60 | "name": "$color--link", 61 | "value": "$color--black" 62 | }, 63 | { 64 | "name": "$color--border", 65 | "value": "$color--gray" 66 | }, 67 | { 68 | "name": "$color--error", 69 | "value": "red" 70 | }, 71 | { 72 | "name": "$typesize--11px", 73 | "value": "11px" 74 | }, 75 | { 76 | "name": "$typesize--12px", 77 | "value": "12px" 78 | }, 79 | { 80 | "name": "$typesize--14px", 81 | "value": "14px" 82 | }, 83 | { 84 | "name": "$typesize--18px", 85 | "value": "18px" 86 | }, 87 | { 88 | "name": "$typesize--24px", 89 | "value": "24px" 90 | }, 91 | { 92 | "name": "$typesize--30px", 93 | "value": "30px" 94 | }, 95 | { 96 | "name": "$typesize--36px", 97 | "value": "36px" 98 | }, 99 | { 100 | "name": "$typesize--48px", 101 | "value": "48px" 102 | }, 103 | { 104 | "name": "$typesize--60px", 105 | "value": "60px" 106 | }, 107 | { 108 | "name": "$typesize--100px", 109 | "value": "100px" 110 | }, 111 | { 112 | "name": "$lineheight--13-11", 113 | "value": "13px / $typesize--11px" 114 | }, 115 | { 116 | "name": "$lineheight--14-12", 117 | "value": "14px / $typesize--12px" 118 | }, 119 | { 120 | "name": "$lineheight--18-12", 121 | "value": "18px / $typesize--12px" 122 | }, 123 | { 124 | "name": "$lineheight--18-14", 125 | "value": "18px / $typesize--14px" 126 | }, 127 | { 128 | "name": "$lineheight--20-18", 129 | "value": "20px / $typesize--18px" 130 | }, 131 | { 132 | "name": "$lineheight--30-24", 133 | "value": "30px / $typesize--24px" 134 | }, 135 | { 136 | "name": "$lineheight--30-30", 137 | "value": "30px / $typesize--30px" 138 | }, 139 | { 140 | "name": "$lineheight--44-36", 141 | "value": "44px / $typesize--36px" 142 | }, 143 | { 144 | "name": "$lineheight--42-48", 145 | "value": "42px / $typesize--48px" 146 | }, 147 | { 148 | "name": "$lineheight--48-60", 149 | "value": "48px / $typesize--60px" 150 | }, 151 | { 152 | "name": "$lineheight--86-100", 153 | "value": "86px / $typesize--100px" 154 | } 155 | ] 156 | } -------------------------------------------------------------------------------- /test/dest--expected/globSearch.json: -------------------------------------------------------------------------------- 1 | { 2 | "globSearch": [ 3 | { 4 | "name": "$color--white", 5 | "value": "hsl(0, 0%, 100%)" 6 | }, 7 | { 8 | "name": "$color--gray--white", 9 | "value": "hsl(0, 0%, 94.1%)" 10 | }, 11 | { 12 | "name": "$color--gray--lightest", 13 | "value": "hsl(0, 0%, 85.9%)" 14 | }, 15 | { 16 | "name": "$color--gray--lighter", 17 | "value": "hsl(0, 0%, 78%)" 18 | }, 19 | { 20 | "name": "$color--gray--light", 21 | "value": "hsl(0, 0%, 70.2%)" 22 | }, 23 | { 24 | "name": "$color--gray", 25 | "value": "hsl(228, 2.3%, 41.8%)" 26 | }, 27 | { 28 | "name": "$color--gray--dark", 29 | "value": "hsl(0, 0%, 40%)" 30 | }, 31 | { 32 | "name": "$color--gray--darker", 33 | "value": "hsl(0, 0%, 20%)" 34 | }, 35 | { 36 | "name": "$color--gray--darkest", 37 | "value": "hsl(0, 0%, 16.1%)" 38 | }, 39 | { 40 | "name": "$color--gray--black", 41 | "value": "hsl(0, 0%, 7.8%)" 42 | }, 43 | { 44 | "name": "$color--black", 45 | "value": "hsl(0, 0%, 0%)" 46 | }, 47 | { 48 | "name": "$white", 49 | "value": "$color--white" 50 | }, 51 | { 52 | "name": "$black", 53 | "value": "$color--black" 54 | }, 55 | { 56 | "name": "$color--font", 57 | "value": "$color--black" 58 | }, 59 | { 60 | "name": "$color--link", 61 | "value": "$color--black" 62 | }, 63 | { 64 | "name": "$color--border", 65 | "value": "$color--gray" 66 | }, 67 | { 68 | "name": "$color--error", 69 | "value": "red" 70 | }, 71 | { 72 | "name": "$typesize--11px", 73 | "value": "11px" 74 | }, 75 | { 76 | "name": "$typesize--12px", 77 | "value": "12px" 78 | }, 79 | { 80 | "name": "$typesize--14px", 81 | "value": "14px" 82 | }, 83 | { 84 | "name": "$typesize--18px", 85 | "value": "18px" 86 | }, 87 | { 88 | "name": "$typesize--24px", 89 | "value": "24px" 90 | }, 91 | { 92 | "name": "$typesize--30px", 93 | "value": "30px" 94 | }, 95 | { 96 | "name": "$typesize--36px", 97 | "value": "36px" 98 | }, 99 | { 100 | "name": "$typesize--48px", 101 | "value": "48px" 102 | }, 103 | { 104 | "name": "$typesize--60px", 105 | "value": "60px" 106 | }, 107 | { 108 | "name": "$typesize--100px", 109 | "value": "100px" 110 | }, 111 | { 112 | "name": "$lineheight--13-11", 113 | "value": "13px / $typesize--11px" 114 | }, 115 | { 116 | "name": "$lineheight--14-12", 117 | "value": "14px / $typesize--12px" 118 | }, 119 | { 120 | "name": "$lineheight--18-12", 121 | "value": "18px / $typesize--12px" 122 | }, 123 | { 124 | "name": "$lineheight--18-14", 125 | "value": "18px / $typesize--14px" 126 | }, 127 | { 128 | "name": "$lineheight--20-18", 129 | "value": "20px / $typesize--18px" 130 | }, 131 | { 132 | "name": "$lineheight--30-24", 133 | "value": "30px / $typesize--24px" 134 | }, 135 | { 136 | "name": "$lineheight--30-30", 137 | "value": "30px / $typesize--30px" 138 | }, 139 | { 140 | "name": "$lineheight--44-36", 141 | "value": "44px / $typesize--36px" 142 | }, 143 | { 144 | "name": "$lineheight--42-48", 145 | "value": "42px / $typesize--48px" 146 | }, 147 | { 148 | "name": "$lineheight--48-60", 149 | "value": "48px / $typesize--60px" 150 | }, 151 | { 152 | "name": "$lineheight--86-100", 153 | "value": "86px / $typesize--100px" 154 | } 155 | ] 156 | } -------------------------------------------------------------------------------- /tasks/pattern_lab_component_builder--old.js: -------------------------------------------------------------------------------- 1 | /* 2 | * pattern-lab-component-builder 3 | * 4 | * 5 | * Copyright (c) 2014 Evan Lovely 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | 'use strict'; 10 | var _ = require('underscore'); 11 | module.exports = function (grunt) { 12 | 13 | // Please see the Grunt documentation for more information regarding task 14 | // creation: http://gruntjs.com/creating-tasks 15 | 16 | var parse = function (sassFile, options) { 17 | // grunt.log.verbose.writeln("Contents path: " + sassFile); 18 | var contents = grunt.file.read(sassFile); 19 | // grunt.log.verbose.writeln("Contents: " + JSON.stringify(contents)); 20 | var regex = new RegExp(options.regex, "mg"); 21 | var results = contents.match(regex); 22 | if (results == null) { 23 | grunt.fail.fatal("No matching items found in `" + sassFile + "` while searching it with the RegEx `" + $options.regex + '`\n' + "Consider running again with --verbose"); 24 | } 25 | grunt.log.verbose.subhead("Results:"); 26 | grunt.log.verbose.writeln(JSON.stringify(results, null, '\t')); 27 | grunt.log.write("Parsed `" + sassFile + "` with `" + options.regex + "` ... "); 28 | return results; 29 | }; 30 | 31 | var colonBreaker = function (theString, options) { 32 | var $name = theString.split(":")[0].trim(); 33 | var $value = theString.split(":")[1].trim().replace(";", ""); 34 | var result = { 35 | "name": $name, 36 | "value": $value 37 | }; 38 | if (options.allow_var_values) { 39 | return result; 40 | } else { 41 | if (!$value.match(/\$/)) { 42 | return result; 43 | } 44 | } 45 | // var results = []; 46 | // results.push("with_var_values"); 47 | // results.push({"name": $name, "value": $value, "uses": []}); 48 | // } 49 | // @todo restore uses 50 | // else { 51 | // results["with_var_values"].push({"name": $name, "value": $value}); 52 | // } 53 | // grunt.log.verbose.writeln("Name : " + $name); 54 | // grunt.log.verbose.writeln("Value: " + $value); 55 | }; 56 | 57 | grunt.registerMultiTask('pattern_lab_component_builder', 'Automatically Create Pattern Lab Components', function () { 58 | 59 | // Merge task-specific and/or target-specific options with these defaults. 60 | var $options = this.options({ 61 | 'regex': "^\\$.*", 62 | 'allow_var_values': true 63 | }); 64 | 65 | // Iterate over all specified file groups. 66 | this.files.forEach(function ($file) { 67 | var cleanResults = []; 68 | var results = parse($file.src, $options); 69 | results.forEach(function(result) { 70 | cleanResults.push(colonBreaker(result, $options)); 71 | }); 72 | cleanResults = _.compact(cleanResults); 73 | 74 | // grunt.log.verbose.subhead("Clean Results:"); 75 | // grunt.log.verbose.writeln(JSON.stringify(cleanResults, null, '\t')); 76 | grunt.log.writeln("organized parsing"); 77 | grunt.log.verbose.subhead("Clean Results:"); 78 | grunt.log.verbose.writeln(JSON.stringify(cleanResults, null, '\t')); 79 | var finalResults = {}; 80 | finalResults[grunt.task.current.target] = cleanResults; 81 | grunt.log.verbose.subhead("Final Results:"); 82 | grunt.log.verbose.writeln(JSON.stringify(finalResults, null, '\t')); 83 | grunt.file.write($file.dest, JSON.stringify(finalResults, null, ' ')); 84 | grunt.log.ok('Stored results OK in: ' + $file.dest); 85 | 86 | // if ($options.component === "colors") { 87 | // grunt.log.writeln("Source File: " + $file.src); 88 | // grunt.log.writeln("Template File: " + $options.template); 89 | // grunt.log.writeln("Destination File: " + $file.dest); 90 | // 91 | // var $sass = grunt.file.read($file.src); 92 | // var $regExForSassVars = $options.regex; 93 | // var $sass_filtered = $sass.match($regExForSassVars); 94 | // if ($sass_filtered == null) { 95 | // grunt.fail.fatal("No matching items found in `" + $file.src + "` while searching it with the RegEx `" + $options.regex + '`\n' + "Consider running again with --verbose"); 96 | // } 97 | // 98 | // var $colors = [], 99 | // $colors_with_var_values = []; 100 | // 101 | // $sass_filtered.forEach(function ($color) { 102 | // var $name = $color.split(":")[0]; 103 | // var $value = $color.split(":")[1].trim().replace(";", ""); 104 | // if (!$value.match(/\$/)) { 105 | // $colors.push({"name": $name, "value": $value, "uses": []}); 106 | // } else { 107 | // $colors_with_var_values.push({"name": $name, "value": $value}); 108 | // } 109 | // grunt.log.verbose.writeln("Name : " + $name); 110 | // grunt.log.verbose.writeln("Value: " + $value); 111 | // }); 112 | // 113 | // var $target = grunt.task.current.target; 114 | // var $plInfo = {}; 115 | // $plInfo[$target] = $colors; 116 | // 117 | // $colors_with_var_values.forEach(function ($varColor) { 118 | // $plInfo[$target].forEach(function ($color) { 119 | // if ($color.name === $varColor.value) { 120 | // $color["uses"].push($varColor.name); 121 | // } 122 | // }); 123 | // }); 124 | // 125 | // var $template = grunt.file.read($options.template); 126 | // var $plComponent = mustache.render($template, $plInfo); 127 | // grunt.file.write($file.dest, $plComponent); 128 | // grunt.log.ok("Rendered!"); 129 | // 130 | // grunt.log.verbose.subhead("PL Info JSON:"); 131 | // grunt.log.verbose.writeln(JSON.stringify($plInfo, null, '\t')); 132 | // grunt.log.verbose.subhead("Colors with Var Values:"); 133 | // grunt.log.verbose.writeln(JSON.stringify($colors_with_var_values, null, '\t')); 134 | // grunt.log.verbose.subhead("Template Contents:"); 135 | // grunt.log.verbose.writeln($template); 136 | // grunt.log.verbose.subhead("View Contents:"); 137 | // grunt.log.verbose.writeln(JSON.stringify($plInfo, null, '\t')); 138 | // grunt.log.verbose.subhead("Destination Contents:"); 139 | // grunt.log.verbose.writeln($plComponent); 140 | // } 141 | }); 142 | }); 143 | 144 | }; 145 | --------------------------------------------------------------------------------