content-tag
is a preprocessor for JS files that are using the content-tag proposal. This originated with Ember.js' GJS and GTS functionality. You can read more by checking out the original RFC
This preprocessor can be used to transform files using the content-tag
spec to standard JS. It is built on top of swc using Rust and is deployed as a wasm package.
npm install content-tag
let { Preprocessor } = require("content-tag");
let p = new Preprocessor();
let output = p.process("<template>Hi</template>");
console.log(output);
import { Preprocessor } from "content-tag";
let p = new Preprocessor();
let output = p.process("<template>Hi</template>");
console.log(output);
import { Preprocessor } from "content-tag";
let p = new Preprocessor();
let output = p.process("<template>Hi</template>");
console.log(output);
All content-tag
public API lives on the Preprocessor
object.
Parses a given source code string using the content-tag
spec into standard
JavaScript.
import { Preprocessor } from "content-tag";
let p = new Preprocessor();
let output = p.process("<template>Hi</template>");
Parses a given source code string using the content-tag
spec into an array of
Parsed
content tag objects.
import { Preprocessor } from "content-tag";
let p = new Preprocessor();
let output = p.parse("<template>Hi</template>");
interface PreprocessorOptions {
/** Default is `false` */
inline_source_map?: boolean;
filename?: string;
}
interface Range {
// Range in raw bytes.
startByte: number;
endByte: number;
// Range in unicode codepoints.
// CAUTION: see "Unicode Codepoint Slicing Warning" below.
startChar: number;
endChar: number;
// utf16 is used by JavaScript strings.
// e.g. str.slice(range.startUtf16Codepoint, range.endUtf16Codepoint)
startUtf16Codepoint: number;
endUtf16Codepoint: number;
}
interface Parsed {
/**
* The type for the content tag.
*
* 'expression' corresponds to a tag in an expression position, e.g.
* ```
* const HiComponent = <template>Hi</template>;
* ```
*
* 'class-member' corresponds to a tag in a class-member position, e.g.
* ```
* export default class HiComponent extends Component {
* <template>Hi</template>
* }
* ```
*/
type: "expression" | "class-member";
/**
* Currently, only template tags are parsed.
*/
tagName: "template";
/** Raw template contents. */
contents: string;
/**
* Range of the contents, inclusive of the
* `<template></template>` tags.
*/
range: Range;
/**
* Range of the template contents, not inclusive of the
* `<template></template>` tags.
*/
contentRange: {
start: number;
end: number;
};
/**
* Range of the opening `<template>` tag.
*/
startRange: Range;
/**
* Range of the closing `</template>` tag.
*/
endRange: Range;
}
If you have a string and want to use the range provided by our parse
method to slice out parts of that string, you need avoid two major pitfalls.
First, you want to use our startChar
and endChar
not startByte
and endByte
. Earlier versions of this library only provided start
and end
and they were always bytes, making string slicing unnecessarily difficult.
Second, beware that Javascript's String.prototype.slice
doesn't actually work on Unicode codepoints. It works on UTF-16 units, which are not the same thing. Intead, you can rely on String.prototype[Symbol.iterator]
which does work on Unicode codepoints. So this is safe, even when fancy things like emojis are present:
Array.from(myString).slice(range.startChar, range.endChar).join("");
if you want to just slice from a string you can use
str.slice(range.startUtf16Codepoint, range.endUtf16Codepoint)
See the CONTRIBUTING.md file.