Utilities for writing tools that work with content-tag and converting bytes-indexes to character-indexes.
Aimed at sharing logic between:
Note
This utility is meant for local tooling and not the browser, or transforming runtime code. No sourcemaps are involved. (Sourcemaps should be used when transforming code meant for runtime).
npm add content-tag-utils
Using from source / github, via package.json:
{
"dependencies": {
"content-tag-utils": "github:NullVoxPopuli/content-tag-utils"
}
}
import {
transform,
transformSync,
coordinatesOf,
Transformer,
} from "content-tag-utils";
A general utility for working with content-tag, keeping tracked of each template as you apply transformations.
Transformations are recorded and then applied later when calling .toString()
.
For example:
import { Transformer } from "content-tag-utils";
let file = `
export const Foo = <template>
Hello there
</template>
`;
let t = new Transformer(file);
// apply some transformations, with their coordinates
await t.asyncMap((contents, coordinates => {
/* ... */
return 'new content';
});
t.map((contents, coordinates) => {
/* ... */
return 'new content 2';
});
// iterate over the templates, with their coordinates
await t.asyncEach((contents, coordinates => {
/* ... */
});
t.each((contents, coordinates) => {
/* ... */
});
// get the output
t.toString();
// can also do more transformations and get the output again later
await t.transform(/* ... */ )
t.toString();
Properties / Methods:
t.toString()
returns a string of the original file with all applied transformst.parseResults
output fromcontent-tag
, but frozen / read-only - these are used as keys for other methodst.map()
t.each()
t.asyncMap()
t.asyncEach()
t.transformOneSync()
t.transformOne()
t.reverseInnerCoordinatesOf()
Given in-template coordinates, returns the coordinates in the context of the file
Transforms each template within a gjs or gts file in one go.
These are convenience functions that wraps the Transformer
.
The first argument to the callback will be the previous template-contents, and the second argument will be the coordinates of that template.
import { transform, transformSync } from "content-tag-utils";
let file = `
export const Foo = <template>
Hello there
</template>
`;
let result = await transform(file, (contents, coordinates) => `${contents}!`);
let result2 = transformSync(file, (contents, coordinates) => `${contents}!`);
result / result 2 ( a ! character is added right before the closing ):
export const Foo = <template>
Hello there
!</template>
For a given source document (gjs or gts), and a single parseResult (one of the entries from the array returned from content-tag's parse), what is the line/column number of the first character for that parseResult, and the columnOffset (useful for extracting templates to do work on and then put back, or giving pointers to errors present in the template).
import { coordinatesOf } from "content-tag-utils";
import { Preprocessor } from "content-tag";
let p = new Preprocessor();
let file = `
export const Foo = <template>
Hello there
</template>
`;
let parsed = p.parse(file);
let result = coordinatesOf(file, parsed[0]);
result (all values are character-indexes):
{
line: 2,
column: 29,
columnOffset: 0,
start: 30,
end: 47,
}
Given inner coordinates scoped to a template, this function returns the coordinates in the overall source file.
import { reverseInnerCoordinates } from 'content-tag-utils';
let file = `
export const Foo = <template>
Hello there
</template>
`;
// e.g.: a lint result
let innerCoordinates = {
line: 2,
column: 4,
endColumn: 5,
endLine: 2,
// extraneous, but may be present in your tool
error: 'no capital letters!',
};
const templateInfos = extractTemplates(file);
const result = reverseInnerCoordinates(templateInfos[0]!, innerCoordinates);
result:
{
column: 4,
endColumn: 5,
endLine: 3,
line: 3,
}