content-tag
v4.1.0
Published
A rust program that uses a fork of swc to parse and transform Javascript containing the content-tag proposal
Readme
content-tag
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.
Installation
npm install content-tagUsage
Node (CommonJS)
let { Preprocessor } = require("content-tag");
let p = new Preprocessor();
let output = p.process("<template>Hi</template>");
console.log(output);Node (ESM)
import { Preprocessor } from "content-tag";
let p = new Preprocessor();
let output = p.process("<template>Hi</template>");
console.log(output);Browser (ESM)
import { Preprocessor } from "content-tag";
let p = new Preprocessor();
let output = p.process("<template>Hi</template>");
console.log(output);API
Preprocessor
All content-tag public API lives on the Preprocessor object.
Preprocessor.process(src: string, options?: PreprocessorOptions): { code: string, map: string };
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>");Preprocessor.parse(src: string, options?: PreprocessorOptions): Parsed[];
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>");PreprocessorOptions
interface PreprocessorOptions {
/** Default is `false` */
inline_source_map?: boolean;
filename?: string;
}Parsed
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;
}Unicode Codepoint Slicing Warning
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)Contributing
See the CONTRIBUTING.md file.
