Skip to content

Commit 49eece1

Browse files
committed
Creates PostCSS plugin boilerplate repo
Adds comment annotation plugin Adds travis.yml Updates README
1 parent 9ace57c commit 49eece1

File tree

8 files changed

+253
-14
lines changed

8 files changed

+253
-14
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Dependencies
2+
node_modules
3+
4+
# Debugging
5+
*.log
6+
.DS_Store

.travis.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
language: node_js
2+
node_js:
3+
- stable
4+
- "6"

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Change Log
2+
This project adheres to [Semantic Versioning](http://semver.org/).

LICENSE

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
1-
MIT License
1+
The MIT License (MIT)
22

3-
Copyright (c) 2017 Matthew Ferry
3+
Copyright 2016 Matthew Ferry <[email protected]>
44

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:
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:
1111

1212
The above copyright notice and this permission notice shall be included in all
1313
copies or substantial portions of the Software.
1414

1515
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 THE
21-
SOFTWARE.
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.

README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# PostCSS Comment Annotation [![Build Status][ci-img]][ci]
2+
3+
[PostCSS] plugin for annotating comments, inspired by and based on
4+
[morishitter](https://github.com/morishitter)'s [CSS Annotation](https://github.com/morishitter/css-annotation).
5+
6+
[PostCSS]: https://github.com/postcss/postcss
7+
[ci-img]: https://travis-ci.org/matthewferry/postcss-comment-annotation.svg
8+
[ci]: https://travis-ci.org/matthewferry/postcss-comment-annotation
9+
10+
## Install
11+
`npm install postcss-comment-annotation`
12+
13+
## Example
14+
Annotate your CSS with key/value pairs. Keys without a defined value
15+
results in a value of `true`.
16+
```css
17+
/*
18+
@define Foo
19+
20+
@description
21+
Foo is a base component
22+
*/
23+
.foo { }
24+
25+
/*
26+
@define Bar
27+
@parent Foo
28+
@modifier
29+
30+
@description
31+
Bar modifies Foo
32+
*/
33+
.foo-bar { }
34+
```
35+
36+
Outputs an array to `result.commentAnnotations`.
37+
```js
38+
[
39+
{
40+
"define": "Foo",
41+
"description": "Foo is a base component"
42+
}, {
43+
"define": "Bar",
44+
"parent": "Foo",
45+
"modifier": true,
46+
"description": "Bar modifies Foo"
47+
}
48+
]
49+
```
50+
51+
## Usage
52+
53+
```js
54+
postcss([
55+
require('postcss-comment-annotation')({
56+
prefix: '@'
57+
})
58+
])
59+
```
60+
61+
## Options
62+
63+
### prefix
64+
65+
Takes `string`.
66+
Define the prefix to signify keys in your annotations.
67+
Default value: `@`.
68+
69+
## [Changelog](./CHANGELOG.md)

index.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
const postcss = require('postcss');
2+
3+
module.exports = postcss.plugin('postcss-comment-annotation', (opts) => {
4+
opts = opts || {};
5+
6+
const prefix = opts.prefix || '@';
7+
const matchComment = `(\\${prefix}(?:\\r?\\n|.)+?)(?=\\${prefix}|$)`;
8+
const matchKeyVal =
9+
`\\${prefix}(\\w*)\\s((?:\\r?\\n|.)*?)(?=\\r?\\n\\r?\\n|$)`;
10+
const matchBool = `\\${prefix}(\\w+)\\s*(?=\\n|$)`;
11+
12+
return (root, result) => {
13+
result.commentAnnotations = [];
14+
15+
root.walkComments((comment) => {
16+
const annotationArray = comment.text.match(
17+
new RegExp(matchComment, 'g')
18+
);
19+
const annotationObj = {};
20+
21+
if (annotationArray) {
22+
annotationArray.forEach((annotation) => {
23+
// Match @rule with single or multiline value after it
24+
if (annotation.match(new RegExp(matchKeyVal, 'g')) &&
25+
RegExp.$2 !== '\n') {
26+
const key = RegExp.$1;
27+
const val = RegExp.$2;
28+
29+
val.replace(/^\s/g, '');
30+
31+
// Create key:value pair
32+
annotationObj[key] = val;
33+
}
34+
35+
// Match single @rule and treat as true
36+
if (annotation.match(new RegExp(matchBool, 'g'))) {
37+
const key = RegExp.$1;
38+
annotationObj[key] = annotationObj[key] || true;
39+
}
40+
});
41+
42+
if (Object.getOwnPropertyNames(annotationObj).length !== 0) {
43+
annotationObj.type = 'comment-annotation';
44+
annotationObj.plugin = 'comment-annotation';
45+
result.commentAnnotations.push(annotationObj);
46+
}
47+
}
48+
});
49+
};
50+
});

index.test.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const postcss = require('postcss');
2+
const plugin = require('./');
3+
4+
const css = `
5+
/*
6+
@define Link
7+
8+
@boolean
9+
10+
@description
11+
Pink anchors
12+
are super hip
13+
*/
14+
a { color: blue; }
15+
/* #define Empty comment block #boolean*/
16+
/* @define Empty comment block @boolean*/
17+
`;
18+
19+
const opts = {
20+
prefix: '#'
21+
};
22+
23+
it('should not modify any output CSS', () => {
24+
return postcss([ plugin ]).process(css)
25+
.then(result => {
26+
expect(result.css).toEqual(css);
27+
});
28+
});
29+
30+
it('should return array of objects for each annotated comment block', () => {
31+
return postcss([ plugin ]).process(css)
32+
.then(result => {
33+
expect(result.commentAnnotations).toHaveLength(2);
34+
});
35+
});
36+
37+
it('should create annotation property for default prefixed keys', () => {
38+
return postcss([ plugin ]).process(css)
39+
.then(result => {
40+
expect(result.commentAnnotations[0]).toHaveProperty('define');
41+
});
42+
});
43+
44+
it('should use option prefix to create annotation property', () => {
45+
return postcss([plugin(opts)]).process(css)
46+
.then(result => {
47+
expect(result.commentAnnotations[0]).toHaveProperty('define');
48+
});
49+
});
50+
51+
it('should create a value for single line annotations', () => {
52+
return postcss([plugin]).process(css)
53+
.then(result => {
54+
expect(result.commentAnnotations[0])
55+
.toHaveProperty('define', 'Link');
56+
});
57+
});
58+
59+
it('should create a value for multi line annotations', () => {
60+
return postcss([plugin]).process(css)
61+
.then(result => {
62+
expect(result.commentAnnotations[0])
63+
.toHaveProperty('description', 'Pink anchors\nare super hip');
64+
});
65+
});
66+
67+
it('should take key without value as boolean', () => {
68+
return postcss([plugin]).process(css)
69+
.then(result => {
70+
expect(result.commentAnnotations[0])
71+
.toHaveProperty('boolean', true);
72+
});
73+
});

package.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "postcss-comment-annotation",
3+
"version": "0.0.0",
4+
"description": "PostCSS plugin for annotating comments",
5+
"keywords": [
6+
"postcss",
7+
"css",
8+
"postcss-plugin",
9+
"comments",
10+
"annotation"
11+
],
12+
"author": "Matthew Ferry <[email protected]>",
13+
"license": "MIT",
14+
"repository": "matthewferry/postcss-comment-annotation",
15+
"bugs": {
16+
"url": "https://github.com/matthewferry/postcss-comment-annotation/issues"
17+
},
18+
"homepage": "https://github.com/matthewferry/postcss-comment-annotation",
19+
"dependencies": {
20+
"postcss": "^6.0.1"
21+
},
22+
"devDependencies": {
23+
"eslint": "^3.19.0",
24+
"eslint-config-postcss": "^2.0.2",
25+
"jest": "^20.0.0"
26+
},
27+
"scripts": {
28+
"test": "jest && eslint *.js"
29+
},
30+
"eslintConfig": {
31+
"extends": "eslint-config-postcss/es5",
32+
"env": {
33+
"jest": true
34+
}
35+
}
36+
}

0 commit comments

Comments
 (0)