| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- /* eslint-disable import/no-extraneous-dependencies */
- const Input = require('postcss/lib/input');
- const LessParser = require('./LessParser');
- const LessStringifier = require('./LessStringifier');
- module.exports = {
- parse(less, options) {
- const input = new Input(less, options);
- const parser = new LessParser(input);
- parser.parse();
- // To handle double-slash comments (`//`) we end up creating a new tokenizer
- // in certain cases (see `lib/nodes/inline-comment.js`). However, this means
- // that any following node in the AST will have incorrect start/end positions
- // on the `source` property. To fix that, we'll walk the AST and compute
- // updated positions for all nodes.
- parser.root.walk((node) => {
- const offset = input.css.lastIndexOf(node.source.input.css);
- if (offset === 0) {
- // Short circuit - this node was processed with the original tokenizer
- // and should therefore have correct position information.
- return;
- }
- // This ensures that the chunk of source we're processing corresponds
- // strictly to a terminal substring of the input CSS. This should always
- // be the case, but if it ever isn't, we prefer to fail instead of
- // producing potentially invalid output.
- // istanbul ignore next
- if (offset + node.source.input.css.length !== input.css.length) {
- throw new Error('Invalid state detected in postcss-less');
- }
- const newStartOffset = offset + node.source.start.offset;
- const newStartPosition = input.fromOffset(offset + node.source.start.offset);
- // eslint-disable-next-line no-param-reassign
- node.source.start = {
- offset: newStartOffset,
- line: newStartPosition.line,
- column: newStartPosition.col
- };
- // Not all nodes have an `end` property.
- if (node.source.end) {
- const newEndOffset = offset + node.source.end.offset;
- const newEndPosition = input.fromOffset(offset + node.source.end.offset);
- // eslint-disable-next-line no-param-reassign
- node.source.end = {
- offset: newEndOffset,
- line: newEndPosition.line,
- column: newEndPosition.col
- };
- }
- });
- return parser.root;
- },
- stringify(node, builder) {
- const stringifier = new LessStringifier(builder);
- stringifier.stringify(node);
- },
- nodeToString(node) {
- let result = '';
- module.exports.stringify(node, (bit) => {
- result += bit;
- });
- return result;
- }
- };
|