From 0938ca01c5cae4d8d7a8a1d9e328132fef77d8ab Mon Sep 17 00:00:00 2001 From: CharlieHelps Date: Mon, 3 Nov 2025 14:50:17 +0000 Subject: [PATCH 1/6] docs(v7): correct parser details, ESM usage, walker registration, and outdated options across README and docs --- README.md | 31 ++++++---- docs/Comment.md | 7 +-- docs/Container.md | 8 ++- docs/Examples.md | 19 +----- docs/Exports.md | 82 +++++------------------- docs/Node.md | 4 +- docs/Parentheses.md | 4 +- docs/Parser.md | 147 ++++++++------------------------------------ docs/Punctuation.md | 2 +- docs/README.md | 16 +++-- docs/Root.md | 10 ++- docs/Stringify.md | 8 +-- docs/Walker.md | 14 +++-- docs/Word.md | 2 +- 14 files changed, 107 insertions(+), 247 deletions(-) diff --git a/README.md b/README.md index 457018f..dbf936c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ -[tests]: https://img.shields.io/circleci/project/github/shellscape/postcss-values-parser.svg -[tests-url]: https://circleci.com/gh/shellscape/postcss-values-parser -[cover]: https://codecov.io/gh/shellscape/postcss-values-parser/branch/master/graph/badge.svg -[cover-url]: https://codecov.io/gh/shellscape/postcss-values-parser +[actions]: https://github.com/shellscape/postcss-values-parser/actions/workflows/validate.yml/badge.svg?branch=master +[actions-url]: https://github.com/shellscape/postcss-values-parser/actions/workflows/validate.yml [size]: https://packagephobia.now.sh/badge?p=postcss-values-parser [size-url]: https://packagephobia.now.sh/result?p=postcss-values-parser @@ -9,10 +7,10 @@

-# postcss-values-parser [![tests][tests]][tests-url] [![cover][cover]][cover-url] [![size][size]][size-url] +# postcss-values-parser [![actions][actions]][actions-url] [![size][size]][size-url] -A CSS property value parser built upon [PostCSS](https://github.com/postcss/postcss), -following the same node and traversal patterns as PostCSS. +A CSS property value parser that uses [css-tree](https://github.com/csstree/csstree) for parsing, +and models nodes on top of PostCSS’s `Node`/`Container`/`Root` classes so the API feels familiar to PostCSS users. This package powers part of [Prettier](https://prettier.io/). Please consider becoming a sponsor if you find this package useful or are a Prettier user. https://github.com/sponsors/shellscape @@ -26,16 +24,23 @@ npm install postcss-values-parser --save-dev ## Requirements -`postcss-values-parser` Node version v6.14.0+ and PostCSS v7.0.0+. +- Node.js >= 20.19.0 +- PostCSS >= 8.4.14 (peer dependency) + +Note: This package is ESM‑only. Use `import` in Node.js or load from CommonJS via dynamic import: + +```js +const mod = await import('postcss-values-parser'); +``` ## Benefits -- Leverages PostCSS and its tokenizer under the hood -- Doesn't strip characters; eg. parenthesis +- Uses css-tree for fast, standards‑compliant parsing +- Builds PostCSS‑style nodes for a familiar API +- Doesn't strip characters; e.g., parentheses are preserved in the AST - Full [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) traversal -- Ability to walk the AST for every Node type -- Convenience methods to stringify Nodes -- Follows PostCSS patterns for whitespace between Nodes +- Optional walker helpers (`registerWalkers(Container)`) to walk by node type +- Convenience methods to stringify nodes - Provides convenience properties for number units, colors, etc. ## Usage diff --git a/docs/Comment.md b/docs/Comment.md index f25de92..c5614b9 100644 --- a/docs/Comment.md +++ b/docs/Comment.md @@ -1,6 +1,6 @@ # Comment Node -The `Comment` node inherits directly from `Node` in PostCSS. This node represents a CSS comment; either inline (`//`) or block (`/* */`). +The `Comment` node inherits directly from `Node` in PostCSS. This node represents a CSS block comment (`/* … */`). ## Properties @@ -8,7 +8,7 @@ The `Comment` node inherits directly from `Node` in PostCSS. This node represent Type: `Boolean`
-If `true`, indicates that the type of comment is "inline," or a comment that begins with `//`. If `false`, indicates that the comment is a traditional block comment. +Always `false` for CSS values. Inline `//` comments are not part of standard CSS values and are not produced by the parser. ### `text` @@ -25,11 +25,10 @@ Value: `'comment'` Type: `String`
-A `String` representation of the original comment including comment markers. +The original comment including comment markers, e.g. `/* comment */`. ## Example Values ```css -// na na na na na na na na batmannnnn /* joker cheats at poker */ ``` diff --git a/docs/Container.md b/docs/Container.md index 1733021..33bded1 100644 --- a/docs/Container.md +++ b/docs/Container.md @@ -57,7 +57,7 @@ This class inherits all properties and methods from PostCSS's `Container` class. ## Example Usage ```js -const { parse } = require('postcss-values-parser'); +import { parse, Word } from 'postcss-values-parser'; const root = parse('calc(100px + 20%)'); const func = root.nodes[0]; // This is a Func node, which extends Container @@ -85,7 +85,9 @@ Container nodes have access to all walker methods for traversing their child nod - `walkType(type, callback)` - Walk through all nodes of a specific type ```js -const { parse } = require('postcss-values-parser'); +import { parse, registerWalkers, Container } from 'postcss-values-parser'; + +registerWalkers(Container); const root = parse('calc(100px + 20%) url("image.jpg")'); const func = root.nodes[0]; // calc function @@ -108,5 +110,5 @@ See the [Walker](./Walker.md) documentation for more details on walker methods. - Container nodes automatically handle source mapping and position tracking when nodes are added - Child nodes maintain references to their parent container - The Container class provides the foundation for complex nodes like `Func`, `Root`, and `Parentheses` -- Walker methods are registered automatically when the module is loaded +- Walker helpers must be registered once via `registerWalkers(Container)` before use - Walker methods traverse all descendants, not just direct children diff --git a/docs/Examples.md b/docs/Examples.md index c2ec6f8..592ee5c 100644 --- a/docs/Examples.md +++ b/docs/Examples.md @@ -333,22 +333,7 @@ root.walkWords((word) => { }); ``` -### SCSS/LESS Variables - -```js -const { parse } = require('postcss-values-parser'); - -// Parse SCSS variables -const root = parse('$primary-color', { - variables: { prefixes: ['--', '$'] } -}); - -root.walkWords((word) => { - if (word.isVariable) { - console.log(`SCSS Variable: ${word.value}`); - } -}); -``` +> Note: In v7, `Word.isVariable` only detects CSS custom properties (values starting with `--`). SCSS/LESS variable prefixes are not detected. ## Error Handling @@ -627,4 +612,4 @@ describe('Value Parser', () => { - Consider caching parsed results for frequently used values - Custom stringifiers allow for powerful value transformations - The parser preserves source mapping information for debugging -- All examples can be adapted for use in various build tools and frameworks \ No newline at end of file +- All examples can be adapted for use in various build tools and frameworks diff --git a/docs/Exports.md b/docs/Exports.md index 51929d3..54ba528 100644 --- a/docs/Exports.md +++ b/docs/Exports.md @@ -1,12 +1,12 @@ -# Exported Methods +# Exported API This module exports the following methods and classes: -### `parse(css, options)` +### `parse(css, options?)` Returns: `Root`
-Parses a given `String` and returns an AST with a `Root` node. If the input is an invalid CSS value, a `ParseError` is thrown. +Parses a given string and returns an AST with a `Root` node. If the input is an invalid CSS value, a `ParseError` is thrown. #### Parameters @@ -17,36 +17,13 @@ _Required_ #### `options` -Type: `ParseOptions`
-_Optional_ +Type: `ParseOptions` (optional) -##### Properties - -##### `ignoreUnknownWords` - -Type: `Boolean`
-Default: `false` - -If `true`, will allow all unknown parts of the value to be parsed and added to the AST. If `false`, unknown values will throw `ParseError`. - -##### `interpolation` - -Type: `Boolean|InterpolationOptions`
-Default: `false` - -Set this option to enable parsing of interpolated values for languages such as SCSS. For example: -`interpolation: { prefix: '@' }` will allow parsing of the interpolated value `@{batman}` which uses `@` as the "prefix". For SCSS one might use `interpolation: { prefix: '#' }`. - -##### `variables` - -Type: `VariablesOptions`
-Default: `{ prefixes: ['--'] }` - -Set this option to modify how variables are identified in a value. By default, this option is set to recognize CSS variables. For languages such as LESS and SCSS which have their own variable prefixes, additional prefixes can be added to the `prefixes` array. +Reserved for future use. In v7, options are accepted by the signature but are not used by the parser. ### `stringify(node, builder)` -A `Function` with a signature matching `(bit) => {}` used to concatenate or manipulate each portion (or bit) of the Node's own AST. The `nodeToString` method makes use of this, as a simple example. +A function used to concatenate or manipulate each portion (or bit) of a node during stringification. The `nodeToString` helper uses this under the hood. #### Parameters @@ -79,7 +56,7 @@ Returns: `String` ### `registerWalkers(Container)` -Registers custom walker methods on the Container prototype to enable walking specific node types. This function is called automatically when the module is loaded, but can be called manually if needed. +Registers custom walker methods on the Container prototype to enable walking specific node types. This function is not called automatically; call it once before using any `walk*` helpers. #### Parameters @@ -92,7 +69,7 @@ The Container class to register walker methods on. ## Exported Classes -All Node classes are exported and can be imported individually: +All node classes are exported and can be imported individually: ### Node Classes @@ -116,40 +93,16 @@ All Node classes are exported and can be imported individually: ### Type Definitions -- `ParseOptions` - Options interface for the parse function -- `InterpolationOptions` - Options for interpolation parsing -- `VariablesOptions` - Options for variable recognition +- `ParseOptions` - Placeholder in v7 (forward‑compatibility) - `Stringifier` - Function interface for custom stringifiers - `Builder` - Function interface for string building during stringify - `NodeOptions` - Options interface for node construction -## Type Interfaces +## Types ### `ParseOptions` -```typescript -interface ParseOptions { - ignoreUnknownWords?: boolean; - interpolation?: boolean | InterpolationOptions; - variables?: VariablesOptions; -} -``` - -### `InterpolationOptions` - -```typescript -interface InterpolationOptions { - prefix: string; -} -``` - -### `VariablesOptions` - -```typescript -interface VariablesOptions { - prefixes: string[]; -} -``` +An empty placeholder interface in v7. Kept for forward‑compatibility. ### `Stringifier` @@ -181,19 +134,16 @@ interface NodeOptions { ```js // Import specific classes -const { parse, Node, Container, Root } = require('postcss-values-parser'); +import { parse, Node, Container, Root } from 'postcss-values-parser'; // Import error classes -const { ParseError, AstError } = require('postcss-values-parser'); +import { ParseError, AstError } from 'postcss-values-parser'; // Import utility functions -const { stringify, nodeToString, registerWalkers } = require('postcss-values-parser'); +import { stringify, nodeToString, registerWalkers } from 'postcss-values-parser'; -// Parse with options -const root = parse('calc(100px + 20%)', { - ignoreUnknownWords: true, - variables: { prefixes: ['--', '$'] } -}); +// Parse +const root = parse('calc(100px + 20%)'); // Custom stringifier const customStringifier = (node, builder) => { diff --git a/docs/Node.md b/docs/Node.md index f142d82..e8c7caf 100644 --- a/docs/Node.md +++ b/docs/Node.md @@ -56,7 +56,7 @@ This class inherits all properties and methods from PostCSS's `Node` class. Plea ## Example Usage ```js -const { parse, Word } = require('postcss-values-parser'); +import { parse, Word } from 'postcss-values-parser'; const root = parse('bold italic'); const firstNode = root.nodes[0]; @@ -78,4 +78,4 @@ console.log(newNode.value); // 'underline' - All nodes automatically maintain parent-child relationships when added to containers - Source mapping information is preserved throughout parsing and manipulation - The Node class provides the foundation for all AST traversal and manipulation operations -- The `value` property is readonly and should be set during construction via the options parameter \ No newline at end of file +- The `value` property is readonly and should be set during construction via the options parameter diff --git a/docs/Parentheses.md b/docs/Parentheses.md index c51ce3c..bd92ed9 100644 --- a/docs/Parentheses.md +++ b/docs/Parentheses.md @@ -64,7 +64,7 @@ This class inherits all properties and methods from the `Container` class and Po ## Example Usage ```js -const { parse } = require('postcss-values-parser'); +import { parse } from 'postcss-values-parser'; const root = parse('calc((100px + 20px) * 2)'); const func = root.nodes[0]; // calc function @@ -85,4 +85,4 @@ parentheses.nodes.forEach(node => { - Parentheses nodes are automatically created when the parser encounters parentheses groupings in CSS values - The content within parentheses is parsed as separate child nodes - Parentheses nodes maintain the structural integrity of grouped expressions -- They are commonly found within function arguments and mathematical expressions \ No newline at end of file +- They are commonly found within function arguments and mathematical expressions diff --git a/docs/Parser.md b/docs/Parser.md index ac296cd..6c21c6b 100644 --- a/docs/Parser.md +++ b/docs/Parser.md @@ -1,133 +1,47 @@ # Parser -The parser is the core component that converts CSS value strings into Abstract Syntax Trees (ASTs). It handles the lexical analysis and parsing of CSS values, creating appropriate node types for different value components. +The parser converts CSS value strings into an Abstract Syntax Tree (AST). It uses [css-tree](https://github.com/csstree/csstree) under the hood, then maps css-tree nodes to this package’s node classes. -## parse(css, options) +## parse(css) -The main parsing function that converts a CSS value string into an AST with a Root node. +Converts a CSS value string into an AST with a `Root` node. ### Parameters #### `css` -Type: `String`
-_Required_ +Type: `string` (required) -The CSS value string to parse. This can be any valid CSS value such as: -- `'10px solid red'` -- `'calc(100% - 20px)'` -- `'rgba(255, 0, 0, 0.5)'` -- `'url("image.jpg") center/cover'` - -#### `options` - -Type: `ParseOptions`
-_Optional_ - -Configuration options for the parser. See [ParseOptions](#parseoptions) below for details. +Any valid CSS value string, such as: +- `10px solid red` +- `calc(100% - 20px)` +- `rgba(255, 0, 0, 0.5)` +- `url("image.jpg") center/cover` ### Returns -Type: `Root`
+`Root` — the root of the parsed AST. -A Root node containing the parsed AST. The Root node has walker methods registered and provides access to all child nodes. - -### Example Usage +### Example ```js -const { parse } = require('postcss-values-parser'); +import { parse } from 'postcss-values-parser'; -// Basic parsing const root = parse('10px solid red'); console.log(root.nodes.length); // 3 - -// Parsing with options -const root2 = parse('calc(100px + var(--size))', { - variables: { prefixes: ['--', '$'] } -}); -``` - -## ParseOptions - -The options object that configures parser behavior. - -### Properties - -#### `ignoreUnknownWords` - -Type: `Boolean`
-Default: `false` - -If `true`, allows unknown parts of the value to be parsed and added to the AST as Word nodes. If `false`, unknown values may cause parsing to fail or be handled with fallback behavior. - -```js -const root = parse('custom-property-value', { - ignoreUnknownWords: true -}); -``` - -#### `interpolation` - -Type: `Boolean | InterpolationOptions`
-Default: `false` - -Enables parsing of interpolated values for preprocessor languages like SCSS, LESS, etc. When set to `true`, uses default interpolation settings. When set to an object, uses the specified interpolation configuration. - -```js -// Enable basic interpolation -const root = parse('#{$variable}', { - interpolation: true -}); - -// Custom interpolation prefix -const root2 = parse('@{variable}', { - interpolation: { prefix: '@' } -}); -``` - -#### `variables` - -Type: `VariablesOptions`
-Default: `{ prefixes: ['--'] }` - -Configures how variables are identified in the CSS value. By default, recognizes CSS custom properties (variables starting with `--`). - -```js -// Support SCSS and LESS variables -const root = parse('$primary-color', { - variables: { prefixes: ['--', '$', '@'] } -}); -``` - -## Type Interfaces - -### InterpolationOptions - -```typescript -interface InterpolationOptions { - prefix: string; -} ``` -Defines the prefix character used for interpolation syntax. - -### VariablesOptions - -```typescript -interface VariablesOptions { - prefixes: string[]; -} -``` +### Notes on options -Defines the prefix characters that identify variables in CSS values. +The `parse(css, options?)` signature accepts an optional second argument for forward‑compatibility, but the current implementation does not use any options. Passing options has no effect in v7. -## Parser Implementation Details +## Implementation details -The parser uses the `css-tree` library for lexical analysis and AST generation, then transforms the generic CSS tree into postcss-values-parser specific node types. +The parser uses css-tree for tokenization and parsing, then maps css-tree node types to postcss-values-parser node types: ### Node Type Mapping -The parser maps CSS-tree node types to postcss-values-parser node types: +Node type mapping: - `Function` → `Func` - `Dimension` → `Numeric` @@ -143,29 +57,24 @@ The parser maps CSS-tree node types to postcss-values-parser node types: ### Special Handling -#### URL Nodes - -When the parser encounters a `Url` node from css-tree, it creates a `Word` node instead of a separate URL node type. This provides consistency with how URLs are handled in CSS values. +#### URL nodes -```js -const root = parse('url("image.jpg")'); -const funcNode = root.nodes[0]; // Func node for url() -// The URL content is parsed as child nodes within the function -``` +When css-tree produces a `Url` node, it is represented as a `Word` node whose `value` is the URL string. URLs inside `url()` appear as a `Func` node named `url`. #### Fallback Behavior Unknown or unrecognized node types are parsed as `Word` nodes to ensure the parser doesn't fail on unexpected input. -#### Source Mapping +#### Source mapping -The parser preserves source mapping information from the original CSS string, including: +The parser preserves source locations from the original CSS string, including: - Line and column positions - Start and end offsets - Original source text ```js -const root = parse('calc(100px + 20%)', { positions: true }); +import { parse } from 'postcss-values-parser'; +const root = parse('calc(100px + 20%)'); // Each node maintains source position information ``` @@ -178,7 +87,7 @@ The parser throws specific error types for different failure scenarios: Thrown when the underlying css-tree parser encounters invalid syntax: ```js -const { parse, ParseError } = require('postcss-values-parser'); +import { parse, ParseError } from 'postcss-values-parser'; try { const root = parse('invalid @#$% syntax'); @@ -194,7 +103,7 @@ try { Thrown when the parsed AST is invalid or empty: ```js -const { parse, AstError } = require('postcss-values-parser'); +import { parse, AstError } from 'postcss-values-parser'; try { const root = parse(''); @@ -283,9 +192,7 @@ root.walkFuncs(func => { ### Variable Parsing ```js -const root = parse('var(--primary-color)', { - variables: { prefixes: ['--'] } -}); +const root = parse('var(--primary-color)'); const func = root.nodes[0]; console.log(func.isVar); // true ``` @@ -296,4 +203,4 @@ console.log(func.isVar); // true - All CSS value types are supported including functions, calculations, and variables - Source mapping information is preserved for debugging and tooling - The parser is designed to be fault-tolerant and handle edge cases gracefully -- Performance is optimized for typical CSS value parsing use cases \ No newline at end of file +- Performance is optimized for typical CSS value parsing use cases diff --git a/docs/Punctuation.md b/docs/Punctuation.md index ebeac5c..136f6c3 100644 --- a/docs/Punctuation.md +++ b/docs/Punctuation.md @@ -1,6 +1,6 @@ # Punctuation Node -The `Punctuation` node inherits directly from `Node` in PostCSS. This node represents various types of characters used for punctuation in CSS; `, : ( ) { } [ ]` are all parsed as punctuation nodes. +The `Punctuation` node inherits directly from `Node` in PostCSS. This node represents punctuation characters in CSS values. In v7, most separators (like commas) are represented as `operator` nodes by the parser, and parentheses are represented by `parentheses` nodes. `Punctuation` nodes are uncommon in typical value parsing and may not appear for many inputs. ## Properties diff --git a/docs/README.md b/docs/README.md index 2438303..81b312b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,13 +7,16 @@ This is the extended documentation for `postcss-values-parser`. Parsing is accomplished by leveraging the `parse` method. For example: ```js -const { parse } = require('postcss-values-parser'); +import { parse } from 'postcss-values-parser'; + const root = parse('#fff'); ``` Please see the [Exports](./Exports.md) documentation for further information. -The parser used in this module is derived and inherits from the PostCSS `Parser` class. Methods for the base parser can be found in the [PostCSS Documentation](https://github.com/postcss/postcss/tree/master/docs). +Parsing is powered by [css-tree](https://github.com/csstree/csstree). Nodes in this package extend PostCSS `Node`/`Container`/`Root` so the API feels familiar, but there is no PostCSS parser involved. + +> Note: This package is ESM‑only. Use `import` syntax in Node.js. If you must use CommonJS, load it via dynamic import: `const mod = await import('postcss-values-parser')`. ## Nodes @@ -44,12 +47,15 @@ Additionally, this module provides several other foundational classes: ## Walking The AST -PostCSS provides a means to walk the entire AST to examine nodes of a particular type, regardless of how they are nested in the tree. Each Node type listed above registers a custom walker function with PostCSS to allow walking on those types. +PostCSS provides a means to walk the entire AST to examine nodes of a particular type, regardless of how they are nested in the tree. This package exposes a `registerWalkers(Container)` helper to add convenience walkers (e.g. `walkNumerics`) onto `Root`/`Container` instances. -Each walker function has a signature of `walk{Node}s` (plural). If wishing to walk all of the numeric values in a value, one would accomplish that like so: +Walker methods are not registered by default. Call `registerWalkers(Container)` once before using them. Each walker function has a signature of `walk{Node}s` (plural). For example, to walk all numeric values: ```js -const { parse } = require('postcss-values-parser'); +import { Container, parse, registerWalkers } from 'postcss-values-parser'; + +// enable walker helpers +registerWalkers(Container); const root = parse('10px 1em 2rem 3pt'); let nodes = []; diff --git a/docs/Root.md b/docs/Root.md index 1691084..7f7e92f 100644 --- a/docs/Root.md +++ b/docs/Root.md @@ -56,7 +56,7 @@ This class inherits all properties and methods from PostCSS's `Root` class. Plea ## Example Usage ```js -const { parse } = require('postcss-values-parser'); +import { parse } from 'postcss-values-parser'; const root = parse('10px solid red'); @@ -87,6 +87,10 @@ The Root node has access to all walker methods for traversing the AST. These met - `walkType(type, callback)` - Walk through all nodes of a specific type ```js +import { parse, registerWalkers, Container } from 'postcss-values-parser'; + +registerWalkers(Container); + const root = parse('calc(100px + 20%) "test" #fff'); // Find all numeric values @@ -111,6 +115,6 @@ See the [Walker](./Walker.md) documentation for more details on walker methods. - The Root node is always the top-level node returned by the `parse()` function - It automatically handles source mapping and position tracking for all child nodes -- The Root node provides access to all walker methods for traversing the AST +- The Root node provides access to all walker methods for traversing the AST once registered via `registerWalkers(Container)` - When stringified, the Root node reconstructs the original CSS value from its child nodes -- Walker methods are registered automatically when the module is loaded \ No newline at end of file +- Register walker methods via `registerWalkers(Container)` before using them diff --git a/docs/Stringify.md b/docs/Stringify.md index 1cca1f4..e1e401e 100644 --- a/docs/Stringify.md +++ b/docs/Stringify.md @@ -46,7 +46,7 @@ The stringify function handles different node types appropriately: ### Example Usage ```js -const { parse, stringify } = require('postcss-values-parser'); +import { parse, stringify } from 'postcss-values-parser'; const root = parse('calc(100px + 20%)'); let result = ''; @@ -82,7 +82,7 @@ The string representation of the node. ### Example Usage ```js -const { parse, nodeToString } = require('postcss-values-parser'); +import { parse, nodeToString } from 'postcss-values-parser'; const root = parse('10px solid red'); const numericNode = root.nodes[0]; @@ -162,7 +162,7 @@ When nodes have source mapping information, the stringify function can utilize t ```js const { parse } = require('postcss-values-parser'); -const root = parse('calc(100px + 20%)', { positions: true }); +const root = parse('calc(100px + 20%)'); // Source mapping information is preserved during stringification ``` @@ -192,4 +192,4 @@ console.log(parts); // Array of string parts with metadata - The builder pattern allows for flexible string construction and manipulation - Source mapping information is preserved and utilized when available - The stringify function handles all node types defined in the parser -- Node order and structure are preserved during stringification \ No newline at end of file +- Node order and structure are preserved during stringification diff --git a/docs/Walker.md b/docs/Walker.md index f2f3fe8..2f28a2e 100644 --- a/docs/Walker.md +++ b/docs/Walker.md @@ -1,13 +1,13 @@ # Walker -The walker functionality provides methods to traverse the AST and find nodes of specific types. Walker methods are automatically registered on Container and Root nodes, allowing you to search for and iterate over nodes throughout the entire AST. +The walker helpers provide methods to traverse the AST and find nodes of specific types. These helpers are not registered by default; you must call `registerWalkers(Container)` once before using them. ## Registration Walker methods are registered using the `registerWalkers` function: ```js -const { registerWalkers, Container } = require('postcss-values-parser'); +import { registerWalkers, Container } from 'postcss-values-parser'; // Register all walker methods on the Container prototype registerWalkers(Container); @@ -15,7 +15,7 @@ registerWalkers(Container); ## Available Walker Methods -The following walker methods are automatically registered and available on all Container and Root nodes: +After registration, the following walker methods are available on all `Container` and `Root` nodes: ### `walkFuncs(callback)` @@ -238,7 +238,9 @@ function callback(node, index) { ## Example Usage ```js -const { parse } = require('postcss-values-parser'); +import { parse, registerWalkers, Container } from 'postcss-values-parser'; + +registerWalkers(Container); const root = parse('calc(100px + 20%) url("image.jpg") #fff'); @@ -276,8 +278,8 @@ root.walkWords((node, index) => { - Walker methods traverse the entire AST recursively, visiting nested nodes - The index parameter in callbacks represents the count of nodes of that specific type encountered - Returning `false` from a callback stops the walking process -- Walker methods are available on all Container and Root nodes +- Walker methods are available on `Container` and `Root` instances after calling `registerWalkers(Container)` - Walking is depth-first, visiting parent nodes before their children - Walker methods respect the AST structure and only visit nodes of the specified type - The `walkType` method is particularly useful for programmatic traversal where the node type is determined at runtime -- All walker methods are registered automatically when the module is loaded via `registerWalkers()` \ No newline at end of file +- Register once per process: call `registerWalkers(Container)` before invoking any `walk*` helpers diff --git a/docs/Word.md b/docs/Word.md index 1a4717f..aa269b6 100644 --- a/docs/Word.md +++ b/docs/Word.md @@ -55,7 +55,7 @@ The value of the word. The Word node has special handling for URLs that appear outside of function contexts. When a standalone URL is encountered in a CSS value, it is parsed as a Word node with the `isUrl` property set to `true`. This is different from URLs that appear within `url()` functions. ```js -const { parse } = require('postcss-values-parser'); +import { parse } from 'postcss-values-parser'; const root = parse('https://example.com'); const wordNode = root.nodes[0]; From af27d8e975f005892b57ccf1831a452c2fbc8e31 Mon Sep 17 00:00:00 2001 From: CharlieHelps Date: Mon, 3 Nov 2025 14:56:49 +0000 Subject: [PATCH 2/6] docs: update CJS guidance to use require() on Node >= 20.19.0 (no dynamic import needed) --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dbf936c..3806a4e 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,11 @@ npm install postcss-values-parser --save-dev - Node.js >= 20.19.0 - PostCSS >= 8.4.14 (peer dependency) -Note: This package is ESM‑only. Use `import` in Node.js or load from CommonJS via dynamic import: +Note: This package is ESM‑only. Use `import` in Node.js. In CommonJS on Node.js 20.19.0+ you can `require()` it: ```js -const mod = await import('postcss-values-parser'); +// CommonJS (Node >= 20.19.0) +const { parse } = require('postcss-values-parser'); ``` ## Benefits From 887f581ba25c595bffab5f11a83b0c6045a23943 Mon Sep 17 00:00:00 2001 From: CharlieHelps Date: Mon, 3 Nov 2025 14:58:55 +0000 Subject: [PATCH 3/6] docs: fix CJS guidance for Node >=20.19 (use require), align Parser signature, and convert remaining Stringify examples to ESM --- README.md | 1 + docs/Parser.md | 20 ++++++++++++-------- docs/README.md | 16 +++++++++++++++- docs/Stringify.md | 14 +++++++------- 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 3806a4e..d4d5bd6 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Note: This package is ESM‑only. Use `import` in Node.js. In CommonJS on Node.j // CommonJS (Node >= 20.19.0) const { parse } = require('postcss-values-parser'); ``` +``` ## Benefits diff --git a/docs/Parser.md b/docs/Parser.md index 6c21c6b..b4a57e2 100644 --- a/docs/Parser.md +++ b/docs/Parser.md @@ -2,9 +2,9 @@ The parser converts CSS value strings into an Abstract Syntax Tree (AST). It uses [css-tree](https://github.com/csstree/csstree) under the hood, then maps css-tree nodes to this package’s node classes. -## parse(css) +## parse(css, options?) -Converts a CSS value string into an AST with a `Root` node. +Converts a CSS value string into an AST with a `Root` node. The optional `options` argument is accepted for forward‑compatibility in v7 but is currently ignored. ### Parameters @@ -13,6 +13,7 @@ Converts a CSS value string into an AST with a `Root` node. Type: `string` (required) Any valid CSS value string, such as: + - `10px solid red` - `calc(100% - 20px)` - `rgba(255, 0, 0, 0.5)` @@ -68,12 +69,14 @@ Unknown or unrecognized node types are parsed as `Word` nodes to ensure the pars #### Source mapping The parser preserves source locations from the original CSS string, including: + - Line and column positions - Start and end offsets - Original source text ```js import { parse } from 'postcss-values-parser'; + const root = parse('calc(100px + 20%)'); // Each node maintains source position information ``` @@ -103,7 +106,7 @@ try { Thrown when the parsed AST is invalid or empty: ```js -import { parse, AstError } from 'postcss-values-parser'; +import { AstError, parse } from 'postcss-values-parser'; try { const root = parse(''); @@ -122,9 +125,9 @@ The parser creates nodes using the NodeOptions interface: ```typescript interface NodeOptions { - node?: CssNode; // Original css-tree node - value?: string; // String value - parent?: any; // Parent node + node?: CssNode; // Original css-tree node + value?: string; // String value + parent?: any; // Parent node } ``` @@ -157,6 +160,7 @@ console.log(calcFunc.nodes.length); // Contains parsed parameters ## Browser and Environment Support The parser works in all environments where css-tree is supported: + - Node.js (all supported versions) - Modern browsers (ES2015+) - Webpack/Rollup bundled applications @@ -168,7 +172,7 @@ The parser works in all environments where css-tree is supported: ```js const root = parse('10px solid red'); -console.log(root.nodes.map(n => n.type)); // ['numeric', 'word', 'word'] +console.log(root.nodes.map((n) => n.type)); // ['numeric', 'word', 'word'] ``` ### Function Parsing @@ -184,7 +188,7 @@ console.log(func.isColor); // true ```js const root = parse('calc(100% - 20px) url("bg.jpg") center/cover'); -root.walkFuncs(func => { +root.walkFuncs((func) => { console.log(`Function: ${func.name}`); }); ``` diff --git a/docs/README.md b/docs/README.md index 81b312b..878913f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,7 +16,21 @@ Please see the [Exports](./Exports.md) documentation for further information. Parsing is powered by [css-tree](https://github.com/csstree/csstree). Nodes in this package extend PostCSS `Node`/`Container`/`Root` so the API feels familiar, but there is no PostCSS parser involved. -> Note: This package is ESM‑only. Use `import` syntax in Node.js. If you must use CommonJS, load it via dynamic import: `const mod = await import('postcss-values-parser')`. +> Note: This package is ESM‑only. Prefer `import` in Node.js. For CommonJS on Node >= 20.19.0 you can use: +> +> ```js +> // CommonJS (Node >= 20.19.0) +> const { parse } = require('postcss-values-parser'); +> ``` +> +> On older Node versions, use dynamic import instead. +> +> ```js +> // CommonJS (older Node) +> (async () => { +> const { parse } = await import('postcss-values-parser'); +> })(); +> ``` ## Nodes diff --git a/docs/Stringify.md b/docs/Stringify.md index e1e401e..d150889 100644 --- a/docs/Stringify.md +++ b/docs/Stringify.md @@ -82,7 +82,7 @@ The string representation of the node. ### Example Usage ```js -import { parse, nodeToString } from 'postcss-values-parser'; +import { nodeToString, parse } from 'postcss-values-parser'; const root = parse('10px solid red'); const numericNode = root.nodes[0]; @@ -103,7 +103,7 @@ interface Stringifier { ### Example Custom Stringifier ```js -const { parse } = require('postcss-values-parser'); +import { parse } from 'postcss-values-parser'; // Custom stringifier that uppercases all word values const upperCaseStringifier = (node, builder) => { @@ -113,7 +113,7 @@ const upperCaseStringifier = (node, builder) => { builder(node.value + node.unit); } else if (node.nodes) { // Handle container nodes - node.nodes.forEach(child => { + node.nodes.forEach((child) => { upperCaseStringifier(child, builder); }); } else { @@ -131,7 +131,7 @@ console.log(root.toString(upperCaseStringifier)); // '10pxSOLIDRED' All nodes have a `toString()` method that accepts an optional stringifier parameter: ```js -const { parse } = require('postcss-values-parser'); +import { parse } from 'postcss-values-parser'; const root = parse('calc(100px + 20%)'); @@ -149,7 +149,7 @@ console.log(root.toString(customStringifier)); The stringify function can preserve original formatting and spacing when nodes maintain source mapping information: ```js -const { parse } = require('postcss-values-parser'); +import { parse } from 'postcss-values-parser'; const root = parse('calc( 100px + 20% )'); // Note the extra spaces console.log(root.toString()); // Preserves original spacing @@ -160,7 +160,7 @@ console.log(root.toString()); // Preserves original spacing When nodes have source mapping information, the stringify function can utilize this information to maintain accurate positioning: ```js -const { parse } = require('postcss-values-parser'); +import { parse } from 'postcss-values-parser'; const root = parse('calc(100px + 20%)'); // Source mapping information is preserved during stringification @@ -171,7 +171,7 @@ const root = parse('calc(100px + 20%)'); The builder function can be used to create complex string manipulations: ```js -const { parse, stringify } = require('postcss-values-parser'); +import { parse, stringify } from 'postcss-values-parser'; const root = parse('10px solid red'); const parts = []; From ac6a459a57713c7771d8bd7983e30fcde829db48 Mon Sep 17 00:00:00 2001 From: CharlieHelps Date: Mon, 3 Nov 2025 15:01:11 +0000 Subject: [PATCH 4/6] resolve: docs rebase conflicts; keep dynamic-import CJS guidance and parser header wording --- README.md | 9 +++++---- docs/README.md | 16 +++++++--------- docs/Stringify.md | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index d4d5bd6..343c00d 100644 --- a/README.md +++ b/README.md @@ -27,12 +27,13 @@ npm install postcss-values-parser --save-dev - Node.js >= 20.19.0 - PostCSS >= 8.4.14 (peer dependency) -Note: This package is ESM‑only. Use `import` in Node.js. In CommonJS on Node.js 20.19.0+ you can `require()` it: +Note: This package is ESM‑only. Use `import` in Node.js. In CommonJS, load it via dynamic import: ```js -// CommonJS (Node >= 20.19.0) -const { parse } = require('postcss-values-parser'); -``` +// CommonJS +import('postcss-values-parser').then(({ parse }) => { + // use parse(...) +}); ``` ## Benefits diff --git a/docs/README.md b/docs/README.md index 878913f..54efe3f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,19 +16,17 @@ Please see the [Exports](./Exports.md) documentation for further information. Parsing is powered by [css-tree](https://github.com/csstree/csstree). Nodes in this package extend PostCSS `Node`/`Container`/`Root` so the API feels familiar, but there is no PostCSS parser involved. -> Note: This package is ESM‑only. Prefer `import` in Node.js. For CommonJS on Node >= 20.19.0 you can use: +> Note: This package is ESM‑only. Use `import` syntax in Node.js. If you must use CommonJS, load it via dynamic import: > > ```js -> // CommonJS (Node >= 20.19.0) -> const { parse } = require('postcss-values-parser'); -> ``` -> -> On older Node versions, use dynamic import instead. -> -> ```js -> // CommonJS (older Node) +> // CommonJS +> import('postcss-values-parser').then(({ parse }) => { +> const root = parse('#fff'); +> }); +> // or > (async () => { > const { parse } = await import('postcss-values-parser'); +> const root = parse('#fff'); > })(); > ``` diff --git a/docs/Stringify.md b/docs/Stringify.md index d150889..3d2f24d 100644 --- a/docs/Stringify.md +++ b/docs/Stringify.md @@ -139,7 +139,7 @@ const root = parse('calc(100px + 20%)'); console.log(root.toString()); // 'calc(100px + 20%)' // Custom stringification -console.log(root.toString(customStringifier)); +console.log(root.toString(upperCaseStringifier)); ``` ## Advanced Usage From 6030ecee33248da0ef3e2c9807d7e3fae4ed088f Mon Sep 17 00:00:00 2001 From: CharlieHelps Date: Mon, 3 Nov 2025 15:03:36 +0000 Subject: [PATCH 5/6] docs: reflect Node >=20.19 support for require(ESM) in CJS in README and docs/README --- README.md | 8 +++----- docs/README.md | 13 +++---------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 343c00d..2f9e655 100644 --- a/README.md +++ b/README.md @@ -27,13 +27,11 @@ npm install postcss-values-parser --save-dev - Node.js >= 20.19.0 - PostCSS >= 8.4.14 (peer dependency) -Note: This package is ESM‑only. Use `import` in Node.js. In CommonJS, load it via dynamic import: +Note: This package is ESM‑only. Use `import` in Node.js. In CommonJS on Node >= 20.19.0, `require()` can load ES modules: ```js -// CommonJS -import('postcss-values-parser').then(({ parse }) => { - // use parse(...) -}); +// CommonJS (Node >= 20.19.0) +const { parse } = require('postcss-values-parser'); ``` ## Benefits diff --git a/docs/README.md b/docs/README.md index 54efe3f..2a4b214 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,18 +16,11 @@ Please see the [Exports](./Exports.md) documentation for further information. Parsing is powered by [css-tree](https://github.com/csstree/csstree). Nodes in this package extend PostCSS `Node`/`Container`/`Root` so the API feels familiar, but there is no PostCSS parser involved. -> Note: This package is ESM‑only. Use `import` syntax in Node.js. If you must use CommonJS, load it via dynamic import: +> Note: This package is ESM‑only. Use `import` syntax in Node.js. In CommonJS on Node >= 20.19.0, `require()` can load ES modules: > > ```js -> // CommonJS -> import('postcss-values-parser').then(({ parse }) => { -> const root = parse('#fff'); -> }); -> // or -> (async () => { -> const { parse } = await import('postcss-values-parser'); -> const root = parse('#fff'); -> })(); +> // CommonJS (Node >= 20.19.0) +> const { parse } = require('postcss-values-parser'); > ``` ## Nodes From cdeacddbeace7c9139f27e5058f80a4c3cf842aa Mon Sep 17 00:00:00 2001 From: CharlieHelps Date: Mon, 3 Nov 2025 15:29:03 +0000 Subject: [PATCH 6/6] docs(Parser): register walker helpers in example (v7) --- docs/Parser.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/Parser.md b/docs/Parser.md index b4a57e2..e7db829 100644 --- a/docs/Parser.md +++ b/docs/Parser.md @@ -187,6 +187,11 @@ console.log(func.isColor); // true ### Complex Value Parsing ```js +import { Container, parse, registerWalkers } from 'postcss-values-parser'; + +// Walker helpers are not auto-registered in v7 +registerWalkers(Container); + const root = parse('calc(100% - 20px) url("bg.jpg") center/cover'); root.walkFuncs((func) => { console.log(`Function: ${func.name}`);