diff options
author | 2020-11-18 23:26:45 +0100 | |
---|---|---|
committer | 2020-11-18 23:26:45 +0100 | |
commit | 81ddf9b700bc48a1f8e472209f080f9c1d9a9b09 (patch) | |
tree | 8b959d50c5a614cbf9fcb346ed556140374d4b6d /node_modules/postcss/docs/syntax.md | |
parent | 1870f3fdf43707a15fda0f609a021f516f45eb63 (diff) | |
download | website_creator-81ddf9b700bc48a1f8e472209f080f9c1d9a9b09.tar.gz website_creator-81ddf9b700bc48a1f8e472209f080f9c1d9a9b09.tar.bz2 website_creator-81ddf9b700bc48a1f8e472209f080f9c1d9a9b09.zip |
rm node_modules
Diffstat (limited to 'node_modules/postcss/docs/syntax.md')
-rw-r--r-- | node_modules/postcss/docs/syntax.md | 231 |
1 files changed, 0 insertions, 231 deletions
diff --git a/node_modules/postcss/docs/syntax.md b/node_modules/postcss/docs/syntax.md deleted file mode 100644 index 2e79c2d..0000000 --- a/node_modules/postcss/docs/syntax.md +++ /dev/null @@ -1,231 +0,0 @@ -# How to Write Custom Syntax - -PostCSS can transform styles in any syntax, and is not limited to just CSS. -By writing a custom syntax, you can transform styles in any desired format. - -Writing a custom syntax is much harder than writing a PostCSS plugin, but -it is an awesome adventure. - -There are 3 types of PostCSS syntax packages: - -* **Parser** to parse input string to node’s tree. -* **Stringifier** to generate output string by node’s tree. -* **Syntax** contains both parser and stringifier. - -## Syntax - -A good example of a custom syntax is [SCSS]. Some users may want to transform -SCSS sources with PostCSS plugins, for example if they need to add vendor -prefixes or change the property order. So this syntax should output SCSS from -an SCSS input. - -The syntax API is a very simple plain object, with `parse` & `stringify` -functions: - -```js -module.exports = { - parse: require('./parse'), - stringify: require('./stringify') -}; -``` - -[SCSS]: https://github.com/postcss/postcss-scss - -## Parser - -A good example of a parser is [Safe Parser], which parses malformed/broken CSS. -Because there is no point to generate broken output, this package only provides -a parser. - -The parser API is a function which receives a string & returns a [`Root`] node. -The second argument is a function which receives an object with PostCSS options. - -```js -var postcss = require('postcss'); - -module.exports = function (css, opts) { - var root = postcss.root(); - // Add other nodes to root - return root; -}; -``` - -[Safe Parser]: https://github.com/postcss/postcss-safe-parser -[`Root`]: http://api.postcss.org/Root.html - -### Main Theory - -There are many books about parsers; but do not worry because CSS syntax is -very easy, and so the parser will be much simpler than a programming language -parser. - -The default PostCSS parser contains two steps: - -1. [Tokenizer] which reads input string character by character and builds a - tokens array. For example, it joins space symbols to a `['space', '\n ']` - token, and detects strings to a `['string', '"\"{"']` token. -2. [Parser] which reads the tokens array, creates node instances and - builds a tree. - -[Tokenizer]: https://github.com/postcss/postcss/blob/master/lib/tokenize.es6 -[Parser]: https://github.com/postcss/postcss/blob/master/lib/parser.es6 - -### Performance - -Parsing input is often the most time consuming task in CSS processors. So it -is very important to have a fast parser. - -The main rule of optimization is that there is no performance without a -benchmark. You can look at [PostCSS benchmarks] to build your own. - -Of parsing tasks, the tokenize step will often take the most time, so its -performance should be prioritized. Unfortunately, classes, functions and -high level structures can slow down your tokenizer. Be ready to write dirty -code with repeated statements. This is why it is difficult to extend the -default [PostCSS tokenizer]; copy & paste will be a necessary evil. - -Second optimization is using character codes instead of strings. - -```js -// Slow -string[i] === '{'; - -// Fast -const OPEN_CURLY = 123; // `{' -string.charCodeAt(i) === OPEN_CURLY; -``` - -Third optimization is “fast jumps”. If you find open quotes, you can find -next closing quote much faster by `indexOf`: - -```js -// Simple jump -next = string.indexOf('"', currentPosition + 1); - -// Jump by RegExp -regexp.lastIndex = currentPosion + 1; -regexp.test(string); -next = regexp.lastIndex; -``` - -The parser can be a well written class. There is no need in copy-paste and -hardcore optimization there. You can extend the default [PostCSS parser]. - -[PostCSS benchmarks]: https://github.com/postcss/benchmark -[PostCSS tokenizer]: https://github.com/postcss/postcss/blob/master/lib/tokenize.es6 -[PostCSS parser]: https://github.com/postcss/postcss/blob/master/lib/parser.es6 - -### Node Source - -Every node should have `source` property to generate correct source map. -This property contains `start` and `end` properties with `{ line, column }`, -and `input` property with an [`Input`] instance. - -Your tokenizer should save the original position so that you can propagate -the values to the parser, to ensure that the source map is correctly updated. - -[`Input`]: https://github.com/postcss/postcss/blob/master/lib/input.es6 - -### Raw Values - -A good PostCSS parser should provide all information (including spaces symbols) -to generate byte-to-byte equal output. It is not so difficult, but respectful -for user input and allow integration smoke tests. - -A parser should save all additional symbols to `node.raws` object. -It is an open structure for you, you can add additional keys. -For example, [SCSS parser] saves comment types (`/* */` or `//`) -in `node.raws.inline`. - -The default parser cleans CSS values from comments and spaces. -It saves the original value with comments to `node.raws.value.raw` and uses it, -if the node value was not changed. - -[SCSS parser]: https://github.com/postcss/postcss-scss - -### Tests - -Of course, all parsers in the PostCSS ecosystem must have tests. - -If your parser just extends CSS syntax (like [SCSS] or [Safe Parser]), -you can use the [PostCSS Parser Tests]. It contains unit & integration tests. - -[PostCSS Parser Tests]: https://github.com/postcss/postcss-parser-tests - -## Stringifier - -A style guide generator is a good example of a stringifier. It generates output -HTML which contains CSS components. For this use case, a parser isn't necessary, -so the package should just contain a stringifier. - -The Stringifier API is little bit more complicated, than the parser API. -PostCSS generates a source map, so a stringifier can’t just return a string. -It must link every substring with its source node. - -A Stringifier is a function which receives [`Root`] node and builder callback. -Then it calls builder with every node’s string and node instance. - -```js -module.exports = function (root, builder) { - // Some magic - var string = decl.prop + ':' + decl.value + ';'; - builder(string, decl); - // Some science -}; -``` - -### Main Theory - -PostCSS [default stringifier] is just a class with a method for each node type -and many methods to detect raw properties. - -In most cases it will be enough just to extend this class, -like in [SCSS stringifier]. - -[default stringifier]: https://github.com/postcss/postcss/blob/master/lib/stringifier.es6 -[SCSS stringifier]: https://github.com/postcss/postcss-scss/blob/master/lib/scss-stringifier.es6 - -### Builder Function - -A builder function will be passed to `stringify` function as second argument. -For example, the default PostCSS stringifier class saves it -to `this.builder` property. - -Builder receives output substring and source node to append this substring -to the final output. - -Some nodes contain other nodes in the middle. For example, a rule has a `{` -at the beginning, many declarations inside and a closing `}`. - -For these cases, you should pass a third argument to builder function: -`'start'` or `'end'` string: - -```js -this.builder(rule.selector + '{', rule, 'start'); -// Stringify declarations inside -this.builder('}', rule, 'end'); -``` - -### Raw Values - -A good PostCSS custom syntax saves all symbols and provide byte-to-byte equal -output if there were no changes. - -This is why every node has `node.raws` object to store space symbol, etc. - -Be careful, because sometimes these raw properties will not be present; some -nodes may be built manually, or may lose their indentation when they are moved -to another parent node. - -This is why the default stringifier has a `raw()` method to autodetect raw -properties by other nodes. For example, it will look at other nodes to detect -indent size and them multiply it with the current node depth. - -### Tests - -A stringifier must have tests too. - -You can use unit and integration test cases from [PostCSS Parser Tests]. -Just compare input CSS with CSS after your parser and stringifier. - -[PostCSS Parser Tests]: https://github.com/postcss/postcss-parser-tests |