Sequence Generation Examples
Relevant source files
The following files were used as context for generating this wiki page:
The nth-check library provides specialized utilities for generating sequences of indices based on CSS nth-child formulas. While the primary use case of the library is validating if a specific index matches a rule, the sequence generation feature allows developers to programmatically iterate through all matching indices in a monotonously increasing order.
This functionality is exposed through the generate and sequence functions. These tools handle complex CSS selector logic, such as positive and negative steps, ensuring that the generated values remain within valid bounds and follow the mathematical requirements of the CSS3 Selectors specification.
Sources: README.md:12-16, src/index.ts:40-42, src/compile.ts:80-82
Core APIs for Sequence Generation
The library provides two primary entry points for sequence generation, catering to both raw parsed data and raw string formulas.
| Function | Input | Returns | Description |
|---|---|---|---|
sequence(formula) | string | () => number | null | Parses a string formula and returns a sequence generator. |
generate([a, b]) | [number, number] | () => number | null | Takes a pre-parsed tuple and returns a sequence generator. |
Sources: src/index.ts:40-75, src/compile.ts:114-116, README.md:66-105
The Sequence Generation Flow
The following diagram illustrates the internal process when a user requests a sequence from a string formula.
The flow shows how a string is first transformed into a numeric tuple [a, b] before being processed by the generator logic.
Sources: src/index.ts:74, src/compile.ts:117-149
Mathematical Logic and Implementations
The generator logic differs significantly based on the value of the step size a.
Positive Step Sequences (a > 0)
When a is positive, the sequence is infinite. The generator starts from the offset b (adjusted to zero-indexing) and adds a for every subsequent call. If the initial b is negative, the generator calculates the first non-negative value in the sequence.
Sources: src/compile.ts:143-148
Negative Step Sequences (a < 0)
Negative steps represent sequences that eventually end. The library ensures these are returned in increasing order by finding the smallest valid non-negative value and incrementing until the upper bound (the offset b) is exceeded.
Sources: src/compile.ts:125-133
Static Sequences (a = 0)
If a is 0, the rule identifies a single specific index. The generator returns this index once and then returns null for all subsequent calls.
Sources: src/compile.ts:135-141
The logic path determined by the 'a' coefficient ensures the resulting sequence is always increasing.
Sources: src/compile.ts:122-148
Practical Examples
Infinite Increasing Sequence
Using 2n+3, the sequence starts at the 3rd element (index 2) and increases by 2.
const gen = sequence("2n+3");
gen(); // 2
gen(); // 4
gen(); // 6
Sources: src/index.ts:50-59, src/compile.spec.ts:98-105
Finite Sequence with Negative Step
Using -2n+5, the sequence finds indices matching the rule that are $\ge 0$.
const gen = sequence("-2n+5");
gen(); // 0
gen(); // 2
gen(); // 4
gen(); // null
Sources: src/index.ts:63-72, src/compile.spec.ts:116-121
Comparison of Valid Rules
The following table shows how various CSS formulas are translated into numeric tuples used by the generator.
| CSS Formula | Parsed [a, b] | First Generated Index |
|---|---|---|
even | [2, 0] | 1 |
odd | [2, 1] | 0 |
n | [1, 0] | 0 |
-n+3 | [-1, 3] | 0 |
5 | [0, 5] | 4 |
Sources: src/fixtures/rules.ts:1-30, src/compile.ts:117-120
Implementation Details
The generator maintains internal state using a counter n and a modified offset b.
// From src/compile.ts
export function generate(parsed: [a: number, b: number]): () => number | null {
const a = parsed[0];
let b = parsed[1] - 1; // Convert to 0-indexed
let n = 0;
if (a < 0) {
const aPos = -a;
const minValue = ((b % aPos) + aPos) % aPos;
return () => {
const value = minValue + aPos * n++;
return value > b ? null : value;
};
}
// ... logic for a >= 0
}
Sources: src/compile.ts:117-133
The library handles the transition from CSS 1-based indexing to JavaScript 0-based indexing by subtracting 1 from the b parameter before processing.
Sources: src/compile.ts:120
Conclusion
Sequence generation in nth-check provides a robust way to iterate over elements matching CSS nth-child patterns. By abstracting the complex sign handling and boundary conditions into the generate and sequence functions, the library allows for efficient index iteration that remains compliant with CSS specifications while being optimized for performance.
Sources: README.md:9-11, src/compile.spec.ts:80-123