Combinatorial string generator using spintax syntax
npm install spintax
A combinatorial string generation library that creates all possible combinations from templates with variable elements.
``bash`
npm install spintax
`javascript`
import parse from "spintax";
You can also import the library directly in your HTML file using a CDN:
`html`
Note that https://ga.jspm.io/npm:spintax@1.1.2/src/index.mjs is also available.
- String pattern parsing: Create string variations using intuitive pattern syntax
- Combinatorial expansion: Generate all possible combinations of variable elements
- Memory-efficient: Uses JavaScript iterators for lazy evaluation
- Multiple variable types: Choose from predefined options or numerical ranges
Spintax is a JavaScript library for generating all possible combinations of template strings with variable elements. It uses a simple, intuitive pattern syntax ({...}) to define variables within templates.
`javascript
import parse from "spintax";
// Basic usage with choices
const variations = parse("Hello, {world|friend|universe}!");
// Iterate through all combinations
for (const variation of variations) {
console.log(variation);
}
// Output:
// Hello, world!
// Hello, friend!
// Hello, universe!
// With numerical ranges
const counts = parse("Count: {1,5}");
// Generates: "Count: 1", "Count: 2", "Count: 3", "Count: 4", "Count: 5"
// Multiple variables
const products = parse("{Product|Service} #{1,3} ({Standard|Premium})");
// Generates all combinations: "Product #1 (Standard)", "Product #1 (Premium)", etc.
// Back references
const associations = parse(
"The {blue|straw|rasp}berries taste like {$0}berries)"
);
// Generates all combinations with back references: "The blueberries taste like blueberries", "The strawberries taste like strawberries", "The raspberries taste like raspberries", etc.
`
Define choices with the pipe (|) separator:
`javascript`
parse("Color: {red|green|blue}");
// Generates: "Color: red", "Color: green", "Color: blue"
Define ranges with comma-separated numbers:
`javascript
parse("Value: {1,5}");
// Generates: "Value: 1", "Value: 2", "Value: 3", "Value: 4", "Value: 5"
// With step value
parse("Value: {0,10,2}");
// Generates: "Value: 0", "Value: 2", "Value: 4", "Value: 6", "Value: 8", "Value: 10"
`
Multiple patterns in a template will generate all possible combinations:
`javascript`
parse("{small|large} {box|circle} in {red|blue}");
// Generates 8 combinations of size, shape and color
- In range patterns (containing numbers and commas), all whitespace is ignored
- {1,5} is the same as { 1, 5 }|
- In choices patterns (with separators), whitespace is preserved as part of the option{option1|option2}
- is different from {option1 |option2}
- In the second case, the first option is "option1 " (with a trailing space)
`javascript`
parse("https://example.com/{products|users}/{1,5}");
// Generates:
// https://example.com/products/1
// https://example.com/products/2
// ...
// https://example.com/users/5
`javascript`
parse("/api/v{1,3}/{users|items}/{1,100,10}");
// Generates:
// /api/v1/users/1
// /api/v1/users/11
// ...
// /api/v3/items/91
`javascript`
parse(
'{"timeout": {1000,5000,1000}, "retries": {1,3}, "mode": "{strict|lenient}"}'
);
// Generates valid JSON strings with all combinations of parameters
When multiple patterns are in a template, combinations are generated by iterating through the rightmost pattern first (inner loop), then the next one to the left, and so on:
`javascript
parse("The color is {red|green|blue}. The letter is {A|B|C}");
// Produces:
// The color is red. The letter is A
// The color is red. The letter is B
// The color is red. The letter is C
// The color is green. The letter is A
// The color is green. The letter is B
// The color is green. The letter is C
// The color is blue. The letter is A
// The color is blue. The letter is B
// The color is blue. The letter is C
`
Be cautious when creating templates with many variable parts, as the number of combinations can grow exponentially:
- 3 variables with 4 options each: 4³ = 64 combinations
- 5 variables with 4 options each: 4⁵ = 1,024 combinations
- 10 variables with 4 options each: 4¹⁰ = 1,048,576 combinations
When dealing with extremely large sets of combinations, consider processing them in chunks:
`javascript
const template = parse("..."); // Large combination space
const iterator = template[Symbol.iterator]();
const chunkSize = 1000;
function processNextChunk() {
let count = 0;
let result;
while (count < chunkSize && !(result = iterator.next()).done) {
process(result.value);
count++;
}
if (!result.done) {
// Schedule next chunk processing
setTimeout(processNextChunk, 0);
}
}
processNextChunk();
`
1. Limit Pattern Count: Keep the number of variable patterns reasonable to avoid combinatorial explosion
2. Use Meaningful Options: Create patterns that produce meaningful variations
3. Process Lazily: Process combinations lazily when dealing with large result sets
While parse is the primary function exported from the library, there are additional utility functions available for more advanced use cases:
`javascript`
import { compile, range, count } from "spintax";
For programmatic template creation with JavaScript expressions:
`javascriptHello ${["world", "universe"]}!
compile;`
Creates a numerical range generator:
`javascript`
range(1, 5); // 1, 2, 3, 4, 5
range(0, 10, 2); // 0, 2, 4, 6, 8, 10
Counts the number of combinations a template would generate:
`javascript`
count("Hello!"); // 1
count("Hello {world|people|nurse}!"); // 3
Produces a function that yields specific combinations based on the indexs passed to it:
`javascript`
const gen = choose("Hello {world|nurse}!");
gen(0); // "Hello world!"
gen(1); // "Hello nurse!"
Omitting the index returns a random combination:
`javascript`
gen(); // "Hello world!" or "Hello nurse!"
The library uses modern JavaScript features:
- Template literals
- Generator functions
- Iterable protocol
If you are migrating from version 0.0.x to 1.0.0, please note that the API has changed significantly.
- The unspin function has been replaced with choose.
Old:
`javascript`
import spintax from "spintax";
const result = spintax.unspin("{Hello|Hi} John!");
console.log(result); // "Hello John!" or "Hi John"
Current:
`javascript`
import { choose } from "spintax";
const result = choose("{Hello|Hi} John!");
console.log(result()); // "Hello John!" or "Hi John"
#### spintax.countVariations to count
- The countVariations function has been replaced with count.
Old:
`javascript`
import spintax from "spintax";
const count = spintax.countVariations("{Hello|Hi} John!");
console.log(count); // 2
Current:
`javascript``
import { count } from "spintax";
const count = count("{Hello|Hi} John!");
console.log(count); // 2
MIT