A rust program that uses a fork of swc to parse and transform Javascript containing the content-tag proposal
npm install content-tagcontent-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.
``sh`
npm install content-tag
`js
let { Preprocessor } = require("content-tag");
let p = new Preprocessor();
let output = p.process("Hi");
console.log(output);
`
`js
import { Preprocessor } from "content-tag";
let p = new Preprocessor();
let output = p.process("Hi");
console.log(output);
`
`js
import { Preprocessor } from "content-tag";
let p = new Preprocessor();
let output = p.process("Hi");
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.
`ts`
import { Preprocessor } from "content-tag";
let p = new Preprocessor();
let output = p.process("Hi");
Parses a given source code string using the content-tag spec into an array ofParsed content tag objects.
`ts`
import { Preprocessor } from "content-tag";
let p = new Preprocessor();
let output = p.parse("Hi");
#### PreprocessorOptions
`tsfalse
interface PreprocessorOptions {
/* Default is /
inline_source_map?: boolean;
filename?: string;
}
`
#### Parsed
``ts
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 = Hi;
* `
*
* 'class-member' corresponds to a tag in a class-member position, e.g.
* `
* export default class HiComponent extends Component {
* Hi
* }
*
*/
type: "expression" | "class-member";
/**
* Currently, only template tags are parsed.
*/
tagName: "template";
/* Raw template contents. /
contents: string;
/**
* Range of the contents, inclusive of the
* tags.
*/
range: Range;
/**
* Range of the template contents, not inclusive of the
* tags.
*/
contentRange: {
start: number;
end: number;
};
/**
* Range of the opening tag.
*/
startRange: Range;
/**
* Range of the closing 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:
`js`
Array.from(myString).slice(range.startChar, range.endChar).join("");
if you want to just slice from a string you can use
`js``
str.slice(range.startUtf16Codepoint, range.endUtf16Codepoint)
See the CONTRIBUTING.md file.