├── .gitignore ├── .npmignore ├── .travis.yml ├── package.json ├── LICENSE ├── index.js ├── README.md └── test └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .idea 3 | npm-debug.log 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | 3 | node_modules/ 4 | .idea 5 | 6 | test/ 7 | .travis.yml -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - iojs 5 | - "0.12" 6 | - "0.10" 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "postcss-color-hcl", 3 | "version": "0.0.5", 4 | "description": "PostCSS plugin to transform hcl() function to more compatible CSS (rgb() or rgba()).", 5 | "keywords": [ 6 | "postcss", 7 | "css", 8 | "postcss-plugin", 9 | "color", 10 | "rgb", 11 | "hcl" 12 | ], 13 | "author": "Dima Devgru ", 14 | "license": "MIT", 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/devgru/postcss-color-hcl.git" 18 | }, 19 | "dependencies": { 20 | "d3-color": "0.4", 21 | "postcss": "5", 22 | "reduce-function-call": "1" 23 | }, 24 | "devDependencies": { 25 | "tap-spec": "^3.0.0", 26 | "tape": "^4.0.0" 27 | }, 28 | "scripts": { 29 | "test": "node test/test.js | tap-spec" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright 2015 Dmitriy Semyushkin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var postcss = require('postcss'); 2 | var reduceFunctionCall = require('reduce-function-call'); 3 | var d3 = require('d3-color'); 4 | 5 | function justFloat(n) { 6 | return parseFloat(n); 7 | } 8 | 9 | function objectToArray(o) { 10 | return Object.keys(o).map(function (key) { 11 | return o[key]; 12 | }); 13 | } 14 | 15 | function colorValuesDefined(hcl) { 16 | return !objectToArray(hcl).some(isNaN); 17 | } 18 | 19 | function transformDecl(decl) { 20 | var value = decl.value; 21 | 22 | function reduceHcl(body) { 23 | var hclaValues = body.split(',').map(justFloat); 24 | var hclColor = d3.hcl.apply(null, hclaValues); 25 | if (!colorValuesDefined(hclColor)) { 26 | throw decl.error('Unable to parse color: "' + value + '"'); 27 | } 28 | if (!hclColor.displayable()) { 29 | throw decl.error('HCL color out of range: "' + value + '"'); 30 | } 31 | return hclColor.toString(); 32 | } 33 | 34 | decl.value = reduceFunctionCall(value, 'hcl', reduceHcl); 35 | } 36 | 37 | function colorHcl(css) { 38 | css.walkDecls(transformDecl); 39 | } 40 | 41 | module.exports = postcss.plugin('postcss-color-hcl', function colorHclPlugin() { 42 | return colorHcl; 43 | }); 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # postcss-color-hcl [![Build Status](https://travis-ci.org/devgru/postcss-color-hcl.png)](https://travis-ci.org/postcss/postcss-color-hcl) 2 | 3 | > [PostCSS](https://github.com/postcss/postcss) plugin to transform [hcl() color](http://hclwizard.org/hcl-color-scheme/) to compatible CSS (#hex or rgba()). 4 | 5 | ## Installation 6 | 7 | ```bash 8 | $ npm install postcss-color-hcl 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```js 14 | // dependencies 15 | var fs = require("fs") 16 | var postcss = require("postcss") 17 | var colorHcl = require("postcss-color-hcl") 18 | 19 | // css to be processed 20 | var css = fs.readFileSync("input.css", "utf8") 21 | 22 | // process css 23 | var output = postcss() 24 | .use(colorHcl()) 25 | .process(css) 26 | .css 27 | ``` 28 | 29 | Using this `input.css`: 30 | 31 | ```css 32 | body { 33 | color: hcl(21, 70%, 50%, 0.5); 34 | background: hcl(0, 0%, 50%); 35 | } 36 | 37 | ``` 38 | 39 | you will get: 40 | 41 | ```css 42 | body { 43 | color: rgba(221, 52, 80, 0.5); 44 | background: rgb(119, 119, 119); 45 | } 46 | ``` 47 | 48 | Checkout [tests](test) for more examples. 49 | 50 | --- 51 | 52 | ## Contributing 53 | 54 | Work on a branch, install dev-dependencies, respect coding style & run tests before submitting a bug fix or a feature. 55 | 56 | $ git clone https://github.com/devgru/postcss-color-hcl.git 57 | $ git checkout -b patch-1 58 | $ npm install 59 | $ npm test 60 | 61 | ## [Changelog](CHANGELOG.md) 62 | 63 | ## [License](LICENSE) 64 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var postcss = require('postcss'); 4 | var hcl = require('./../index'); 5 | var test = require('tape'); 6 | 7 | function useHcl() { 8 | return postcss().use(hcl()); 9 | } 10 | 11 | test('filterDeclarations()', function (t) { 12 | t.plan(9); 13 | 14 | t.equal( 15 | useHcl().process('a { color: hcl(0, 0, 50); }').css, 16 | 'a { color: rgb(119, 119, 119); }', 17 | 'should convert hcl(H, C, L) to rgb(R, G, B).' 18 | ); 19 | 20 | t.equal( 21 | useHcl().process('a { color: hcl(0, 0%, 50%); }').css, 22 | 'a { color: rgb(119, 119, 119); }', 23 | 'should convert hcl(H, C%, L%) to rgb(R, G, B).' 24 | ); 25 | 26 | t.equal( 27 | useHcl().process('a { color: hcl(21, 70, 50, 0.5); }').css, 28 | 'a { color: rgba(221, 52, 80, 0.5); }', 29 | 'should convert hcl(H, C, L, α) to rgba(R, G, B, α).' 30 | ); 31 | 32 | t.equal( 33 | useHcl().process('a { color: rgb(255, 0, 0); }').css, 34 | 'a { color: rgb(255, 0, 0); }', 35 | 'should not modify original CSS when hcl() is not used.' 36 | ); 37 | 38 | t.throws( 39 | function () { 40 | useHcl().process('a { color: hcl(180, 80, 80); }').css; 41 | }, 42 | /HCL color out of range: "hcl\(180, 80, 80\)"/, 43 | 'should throw an error when color is out of range.' 44 | ); 45 | 46 | t.throws( 47 | function () { 48 | useHcl().process('a { color: hcl(); }').css; 49 | }, 50 | /Unable to parse color: "hcl\(\)"/, 51 | 'should throw an error when hcl() doesn\'t take any arguments.' 52 | ); 53 | 54 | t.throws( 55 | function () { 56 | useHcl().process('a { color: hcl(,foo); }').css; 57 | }, 58 | /Unable to parse color: "hcl\(,foo\)"/, 59 | 'should throw an error when hcl() takes invalid arguments.' 60 | ); 61 | 62 | t.throws( 63 | function () { 64 | useHcl().process('a {color: hcl(red); }', {from: 'fixture.css'}).css; 65 | }, 66 | /fixture\.css:1:4: Unable to parse color: "hcl\(red\)"/, 67 | 'should throw a detailed error when a source file is specified.' 68 | ); 69 | 70 | t.throws( 71 | function () { 72 | useHcl().process('a {color: hcl(,)}', {map: true}).css; 73 | }, 74 | /:1:4: Unable to parse color: "hcl\(,\)"/, 75 | 'should throw a detailed error when source map is enabled but file isn\'t specified.' 76 | ); 77 | }); --------------------------------------------------------------------------------