asttpl
Generating code with AST templates made easy
![Dependency Status](https://dependencyci.com/github/nfroidure/asttpl/badge)
Motivations
JavaScript templating is often done through string based template engines.
I wanted to try using AST trees directly instead, it has some advantages:
- templates remain valid JavaScript. You can just test it by running
node my.tpl.js
. - your linter/syntax highlighter, auto-completer just works,
- i had fun coding it :p
Since JavaScript identifiers syntax accepts some Emojis, we can add some extra
informations right into them to bring some logic in.
Disclaimer: This module is just an experiment, use it at your own risks.
Usage
const asttpl = require('asttpl');
const template = `
module.exports = {
𐅙repeat𐅙methods𐅙name: 𐅙literal𐅙name𐅂upper
};
`;
const filters = {
upper: str => str.toUpperCase()
};
const data = {
methods: [{
name: 'get'
}, {
name: 'put'
}]
};
assert.equal(asttpl({ filters }, template, [data])`
module.exports = {
get: 'GET',
put: 'PUT',
};
`);
Transformations
This is just a simple summary but you should look at the tests to see how it
really works.
Variable replacement
Pattern: 𐅙variable𐅙${path}
𐅂${filter1}
𐅂${filter2}
𐅂${filterN}
Usage:
- function names
- variables declarations
- variables lookups
- property names
Replace a variable name by its matched value after applying it given filters if
any. Changing:
let 𐅙variable𐅙myPath𐅂myFilter;
To:
let myShinyNewName;
Literal replacement
Pattern: 𐅙literal𐅙${path}
𐅂${filter1}
𐅂${filter2}
𐅂${filterN}
Usage:
Change a variable by a literal with its matched value. Changing:
const myConstant = 𐅙literal𐅙myPath𐅂myFilter;
To:
const myConstant = 'myGeneratedValue';
Loops
Pattern: 𐅙repeat𐅙${entriesPath}𐅂${filter1}
𐅂${...filterN}``𐅙${namePath}𐅂
${filter1}𐅂
${...filterN}
Usage:
- variables declarations
- functions declarations
- object patterns
Repeat functions/variable/properties declarations. Changing:
const myConstant = {
𐅙repeat𐅙myEntriesPath𐅂myFilter𐅙myNamePath𐅂myFilter: 𐅙literal𐅙myRelativePath
};
To:
const myConstant = {
myProp1: 'myRelativeValue1',
myProp2: 'myRelativeValue2',
myProp3: 'myRelativeValue3'
};
Custom transformations
Pattern: 𐅙transform𐅙${transformationName}𐅙${path}
Usage:
Apply custom transformationName
to the identifier and the path
resolved
values.
Template values picker
Values used for templates are picked with miniquery
. Refer to
its documentation for more details.
The following path characters had to be mapped in order to keep syntactically
valid templates:
- the path separator
.
becomes 𐅞
, - the wildcard
*
becomes 𐅆
, - the array items matcher
#
becomes 𐅅
, - the object properties matcher
@
becomes 𐅄
.