spintax
v1.1.2
Published
Combinatorial string generator using spintax syntax
Maintainers
Readme
Spintax
A combinatorial string generation library that creates all possible combinations from templates with variable elements.
Installation
npm install spintaximport parse from "spintax";Web Usage
You can also import the library directly in your HTML file using a CDN:
<script type="module">
import parse from "https://cdn.jsdelivr.net/npm/[email protected]/src/index.mjs";
</script>Note that https://ga.jspm.io/npm:[email protected]/src/index.mjs is also available.
Key Features
- 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
Overview
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.
Basic Usage
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.Pattern Syntax
Choices
Define choices with the pipe (|) separator:
parse("Color: {red|green|blue}");
// Generates: "Color: red", "Color: green", "Color: blue"Ranges
Define ranges with comma-separated numbers:
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"Pattern Combinations
Multiple patterns in a template will generate all possible combinations:
parse("{small|large} {box|circle} in {red|blue}");
// Generates 8 combinations of size, shape and colorWhitespace Handling
- 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)
Advanced Examples
URL Generation
parse("https://example.com/{products|users}/{1,5}");
// Generates:
// https://example.com/products/1
// https://example.com/products/2
// ...
// https://example.com/users/5API Testing
parse("/api/v{1,3}/{users|items}/{1,100,10}");
// Generates:
// /api/v1/users/1
// /api/v1/users/11
// ...
// /api/v3/items/91Configuration Generation
parse(
'{"timeout": {1000,5000,1000}, "retries": {1,3}, "mode": "{strict|lenient}"}'
);
// Generates valid JSON strings with all combinations of parametersIteration Order
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:
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 CPerformance Considerations
Combinatorial Explosion
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
Chunking for Large Result Sets
When dealing with extremely large sets of combinations, consider processing them in chunks:
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();Best Practices
- Limit Pattern Count: Keep the number of variable patterns reasonable to avoid combinatorial explosion
- Use Meaningful Options: Create patterns that produce meaningful variations
- Process Lazily: Process combinations lazily when dealing with large result sets
Advanced API
While parse is the primary function exported from the library, there are additional utility functions available for more advanced use cases:
Supporting Utilities
import { compile, range, count } from "spintax";compile Tagged Template Function
For programmatic template creation with JavaScript expressions:
compile`Hello ${["world", "universe"]}!`;range(start, end, step = 1, includeEnd = true)
Creates a numerical range generator:
range(1, 5); // 1, 2, 3, 4, 5
range(0, 10, 2); // 0, 2, 4, 6, 8, 10count(template)
Counts the number of combinations a template would generate:
count("Hello!"); // 1
count("Hello {world|people|nurse}!"); // 3choose(template)
Produces a function that yields specific combinations based on the indexs passed to it:
const gen = choose("Hello {world|nurse}!");
gen(0); // "Hello world!"
gen(1); // "Hello nurse!"Omitting the index returns a random combination:
gen(); // "Hello world!" or "Hello nurse!"Browser Compatibility
The library uses modern JavaScript features:
- Template literals
- Generator functions
- Iterable protocol
Migrating from 0.0.x
If you are migrating from version 0.0.x to 1.0.0, please note that the API has changed significantly.
spintax.unspin to choose
- The
unspinfunction has been replaced withchoose.
Old:
import spintax from "spintax";
const result = spintax.unspin("{Hello|Hi} John!");
console.log(result); // "Hello John!" or "Hi John"Current:
import { choose } from "spintax";
const result = choose("{Hello|Hi} John!");
console.log(result()); // "Hello John!" or "Hi John"spintax.countVariations to count
- The
countVariationsfunction has been replaced withcount.
Old:
import spintax from "spintax";
const count = spintax.countVariations("{Hello|Hi} John!");
console.log(count); // 2Current:
import { count } from "spintax";
const count = count("{Hello|Hi} John!");
console.log(count); // 2License
MIT
