Socket
Socket
Sign inDemoInstall

hast-util-from-parse5

Package Overview
Dependencies
Maintainers
2
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hast-util-from-parse5 - npm Package Compare versions

Comparing version 7.1.0 to 7.1.1

1

index.d.ts
export {fromParse5} from './lib/index.js'
export type Options = import('./lib/index.js').Options
export type Space = import('./lib/index.js').Space
/**
* @typedef {import('./lib/index.js').Options} Options
* @typedef {import('./lib/index.js').Space} Space
*/
export {fromParse5} from './lib/index.js'

97

lib/index.d.ts
/**
* Transform Parse5’s AST to a hast tree.
* Transform a `parse5` AST to hast.
*
* @param {P5Node} ast
* @param {Options|VFile} [options]
* @param {P5Node} tree
* `parse5` tree to transform.
* @param {Options | VFile | null | undefined} [options]
* Configuration.
* @returns {Node}
* hast tree.
*/
export function fromParse5(
ast: P5Node,
options?: import('vfile').VFile | Options | undefined
tree: P5Node,
options?: Options | VFile | null | undefined
): Node

@@ -15,52 +19,67 @@ export type VFile = import('vfile').VFile

export type Point = import('unist').Point
export type Parent = import('hast').Parent
export type Element = import('hast').Element
export type Root = import('hast').Root
export type Text = import('hast').Text
export type Comment = import('hast').Comment
export type Doctype = import('hast').DocType
export type Child = Parent['children'][number]
export type ElementChild = Element['children'][number]
export type Node = Child | Root
export type P5Document = import('parse5').Document
export type P5Doctype = import('parse5').DocumentType
export type P5Comment = import('parse5').CommentNode
export type P5Text = import('parse5').TextNode
export type P5Element = import('parse5').Element
export type P5ElementLocation = import('parse5').ElementLocation
export type P5Location = import('parse5').Location
export type P5Attribute = import('parse5').Attribute
export type P5Node = import('parse5').Node
export type Content = import('hast').Content
export type DefaultTreeAdapterMap = import('parse5').DefaultTreeAdapterMap
export type P5ElementLocation = import('parse5').Token.ElementLocation
export type P5Location = import('parse5').Token.Location
export type Node = Content | Root
export type P5Document = DefaultTreeAdapterMap['document']
export type P5DocumentFragment = DefaultTreeAdapterMap['documentFragment']
export type P5DocumentType = DefaultTreeAdapterMap['documentType']
export type P5Comment = DefaultTreeAdapterMap['commentNode']
export type P5Text = DefaultTreeAdapterMap['textNode']
export type P5Element = DefaultTreeAdapterMap['element']
export type P5Node = DefaultTreeAdapterMap['node']
export type P5Template = DefaultTreeAdapterMap['template']
/**
* Namespace.
*/
export type Space = 'html' | 'svg'
export type Handler = (
ctx: Context,
node: P5Node,
children?:
| (
| import('hast').Element
| import('hast').Text
| import('hast').Comment
| import('hast').DocType
)[]
| undefined
) => Node
/**
* Configuration.
*/
export type Options = {
/**
* Whether the root of the tree is in the `'html'` or `'svg'` space. If an element in with the SVG namespace is found in `ast`, `fromParse5` automatically switches to the SVG space when entering the element, and switches back when leaving
* Which space the document is in.
*
* When an `<svg>` element is found in the HTML space, this package already
* automatically switches to and from the SVG space when entering and exiting
* it.
*/
space?: Space | undefined
space?: Space | null | undefined
/**
* `VFile`, used to add positional information to nodes. If given, the file should have the original HTML source as its contents
* File used to add positional info to nodes.
*
* If given, the file should represent the original HTML source.
*/
file?: import('vfile').VFile | undefined
file?: VFile | null | undefined
/**
* Whether to add extra positional information about starting tags, closing tags, and attributes to elements. Note: not used without `file`
* Whether to add extra positional info about starting tags, closing tags,
* and attributes to elements.
*
* > 👉 **Note**: only used when `file` is given.
*/
verbose?: boolean | undefined
}
export type Context = {
/**
* Info passed around about the current state.
*/
export type State = {
/**
* Current schema.
*/
schema: Schema
/**
* Corresponding file.
*/
file: VFile | undefined
/**
* Add extra positional info.
*/
verbose: boolean | undefined
/**
* Whether location info was found.
*/
location: boolean
}

@@ -6,39 +6,52 @@ /**

* @typedef {import('unist').Point} Point
* @typedef {import('hast').Parent} Parent
* @typedef {import('hast').Element} Element
* @typedef {import('hast').Root} Root
* @typedef {import('hast').Text} Text
* @typedef {import('hast').Comment} Comment
* @typedef {import('hast').DocType} Doctype
* @typedef {Parent['children'][number]} Child
* @typedef {Element['children'][number]} ElementChild
* @typedef {Child|Root} Node
* @typedef {import('parse5').Document} P5Document
* @typedef {import('parse5').DocumentType} P5Doctype
* @typedef {import('parse5').CommentNode} P5Comment
* @typedef {import('parse5').TextNode} P5Text
* @typedef {import('parse5').Element} P5Element
* @typedef {import('parse5').ElementLocation} P5ElementLocation
* @typedef {import('parse5').Location} P5Location
* @typedef {import('parse5').Attribute} P5Attribute
* @typedef {import('parse5').Node} P5Node
* @typedef {import('hast').Content} Content
* @typedef {import('parse5').DefaultTreeAdapterMap} DefaultTreeAdapterMap
* @typedef {import('parse5').Token.ElementLocation} P5ElementLocation
* @typedef {import('parse5').Token.Location} P5Location
*/
/**
* @typedef {Content | Root} Node
* @typedef {DefaultTreeAdapterMap['document']} P5Document
* @typedef {DefaultTreeAdapterMap['documentFragment']} P5DocumentFragment
* @typedef {DefaultTreeAdapterMap['documentType']} P5DocumentType
* @typedef {DefaultTreeAdapterMap['commentNode']} P5Comment
* @typedef {DefaultTreeAdapterMap['textNode']} P5Text
* @typedef {DefaultTreeAdapterMap['element']} P5Element
* @typedef {DefaultTreeAdapterMap['node']} P5Node
* @typedef {DefaultTreeAdapterMap['template']} P5Template
*
* @typedef {'html'|'svg'} Space
* @typedef {'html' | 'svg'} Space
* Namespace.
*
* @callback Handler
* @param {Context} ctx
* @param {P5Node} node
* @param {Array.<Child>} [children]
* @returns {Node}
*
* @typedef Options
* @property {Space} [space='html'] Whether the root of the tree is in the `'html'` or `'svg'` space. If an element in with the SVG namespace is found in `ast`, `fromParse5` automatically switches to the SVG space when entering the element, and switches back when leaving
* @property {VFile} [file] `VFile`, used to add positional information to nodes. If given, the file should have the original HTML source as its contents
* @property {boolean} [verbose=false] Whether to add extra positional information about starting tags, closing tags, and attributes to elements. Note: not used without `file`
* Configuration.
* @property {Space | null | undefined} [space='html']
* Which space the document is in.
*
* @typedef Context
* When an `<svg>` element is found in the HTML space, this package already
* automatically switches to and from the SVG space when entering and exiting
* it.
* @property {VFile | null | undefined} [file]
* File used to add positional info to nodes.
*
* If given, the file should represent the original HTML source.
* @property {boolean} [verbose=false]
* Whether to add extra positional info about starting tags, closing tags,
* and attributes to elements.
*
* > 👉 **Note**: only used when `file` is given.
*
* @typedef State
* Info passed around about the current state.
* @property {Schema} schema
* @property {VFile|undefined} file
* @property {boolean|undefined} verbose
* Current schema.
* @property {VFile | undefined} file
* Corresponding file.
* @property {boolean | undefined} verbose
* Add extra positional info.
* @property {boolean} location
* Whether location info was found.
*/

@@ -53,32 +66,28 @@

// Handlers.
const map = {
'#document': root,
'#document-fragment': root,
'#text': text,
'#comment': comment,
'#documentType': doctype
}
/**
* Transform Parse5’s AST to a hast tree.
* Transform a `parse5` AST to hast.
*
* @param {P5Node} ast
* @param {Options|VFile} [options]
* @param {P5Node} tree
* `parse5` tree to transform.
* @param {Options | VFile | null | undefined} [options]
* Configuration.
* @returns {Node}
* hast tree.
*/
export function fromParse5(ast, options = {}) {
export function fromParse5(tree, options) {
const options_ = options || {}
/** @type {Options} */
let settings
/** @type {VFile|undefined} */
/** @type {VFile | undefined} */
let file
if (isFile(options)) {
file = options
if (isFile(options_)) {
file = options_
settings = {}
} else {
file = options.file
settings = options
file = options_.file || undefined
settings = options_
}
return transform(
return one(
{

@@ -90,3 +99,3 @@ schema: settings.space === 'svg' ? svg : html,

},
ast
tree
)

@@ -96,40 +105,68 @@ }

/**
* Transform children.
* Transform a node.
*
* @param {Context} ctx
* @param {P5Node} ast
* @param {State} state
* Info passed around about the current state.
* @param {P5Node} node
* p5 node.
* @returns {Node}
* hast node.
*/
function transform(ctx, ast) {
const schema = ctx.schema
/** @type {Handler} */
// @ts-expect-error: index is fine.
const fn = own.call(map, ast.nodeName) ? map[ast.nodeName] : element
/** @type {Array.<Child>|undefined} */
let children
function one(state, node) {
/** @type {Node} */
let result
// Element.
if ('tagName' in ast) {
ctx.schema = ast.namespaceURI === webNamespaces.svg ? svg : html
}
switch (node.nodeName) {
case '#comment': {
const reference = /** @type {P5Comment} */ (node)
result = {type: 'comment', value: reference.data}
patch(state, reference, result)
return result
}
if ('childNodes' in ast) {
children = nodes(ctx, ast.childNodes)
}
case '#document':
case '#document-fragment': {
const reference = /** @type {P5Document | P5DocumentFragment} */ (node)
const quirksMode =
'mode' in reference
? reference.mode === 'quirks' || reference.mode === 'limited-quirks'
: false
const result = fn(ctx, ast, children)
result = {
type: 'root',
children: all(state, node.childNodes),
data: {quirksMode}
}
if ('sourceCodeLocation' in ast && ast.sourceCodeLocation && ctx.file) {
// @ts-expect-error It’s fine.
const position = createLocation(ctx, result, ast.sourceCodeLocation)
if (state.file && state.location) {
const doc = String(state.file)
const loc = location(doc)
result.position = {start: loc.toPoint(0), end: loc.toPoint(doc.length)}
}
if (position) {
ctx.location = true
result.position = position
return result
}
}
ctx.schema = schema
case '#documentType': {
const reference = /** @type {P5DocumentType} */ (node)
// @ts-expect-error Types are out of date.
result = {type: 'doctype'}
patch(state, reference, result)
return result
}
return result
case '#text': {
const reference = /** @type {P5Text} */ (node)
result = {type: 'text', value: reference.value}
patch(state, reference, result)
return result
}
// Element.
default: {
const reference = /** @type {P5Element} */ (node)
result = element(state, reference)
return result
}
}
}

@@ -140,14 +177,17 @@

*
* @param {Context} ctx
* @param {Array.<P5Node>} children
* @returns {Array.<Child>}
* @param {State} state
* Info passed around about the current state.
* @param {Array<P5Node>} nodes
* Nodes.
* @returns {Array<Content>}
* hast nodes.
*/
function nodes(ctx, children) {
function all(state, nodes) {
let index = -1
/** @type {Array.<Child>} */
/** @type {Array<Content>} */
const result = []
while (++index < children.length) {
// @ts-expect-error Assume no roots in children.
result[index] = transform(ctx, children[index])
while (++index < nodes.length) {
// @ts-expect-error Assume no roots in `nodes`.
result[index] = one(state, nodes[index])
}

@@ -159,79 +199,23 @@

/**
* Transform a document.
* Stores `ast.quirksMode` in `node.data.quirksMode`.
* Transform an element.
*
* @type {Handler}
* @param {P5Document} ast
* @param {Array.<Child>} children
* @returns {Root}
* @param {State} state
* Info passed around about the current state.
* @param {P5Element} node
* `parse5` node to transform.
* @returns {Element}
* hast node.
*/
function root(ctx, ast, children) {
/** @type {Root} */
const result = {
type: 'root',
children,
data: {quirksMode: ast.mode === 'quirks' || ast.mode === 'limited-quirks'}
}
function element(state, node) {
const schema = state.schema
if (ctx.file && ctx.location) {
const doc = String(ctx.file)
const loc = location(doc)
result.position = {
start: loc.toPoint(0),
end: loc.toPoint(doc.length)
}
}
state.schema = node.namespaceURI === webNamespaces.svg ? svg : html
return result
}
/**
* Transform a doctype.
*
* @type {Handler}
* @returns {Doctype}
*/
function doctype() {
// @ts-expect-error Types are out of date.
return {type: 'doctype'}
}
/**
* Transform a text.
*
* @type {Handler}
* @param {P5Text} ast
* @returns {Text}
*/
function text(_, ast) {
return {type: 'text', value: ast.value}
}
/**
* Transform a comment.
*
* @type {Handler}
* @param {P5Comment} ast
* @returns {Comment}
*/
function comment(_, ast) {
return {type: 'comment', value: ast.data}
}
/**
* Transform an element.
*
* @type {Handler}
* @param {P5Element} ast
* @param {Array.<ElementChild>} children
* @returns {Element}
*/
function element(ctx, ast, children) {
const fn = ctx.schema.space === 'svg' ? s : h
// Props.
let index = -1
/** @type {Object.<string, string>} */
/** @type {Record<string, string>} */
const props = {}
while (++index < ast.attrs.length) {
const attribute = ast.attrs[index]
while (++index < node.attrs.length) {
const attribute = node.attrs[index]
props[(attribute.prefix ? attribute.prefix + ':' : '') + attribute.name] =

@@ -241,6 +225,11 @@ attribute.value

const result = fn(ast.tagName, props, children)
// Build.
const fn = state.schema.space === 'svg' ? s : h
const result = fn(node.tagName, props, all(state, node.childNodes))
patch(state, node, result)
if (result.tagName === 'template' && 'content' in ast) {
const pos = ast.sourceCodeLocation
// Switch content.
if (result.tagName === 'template') {
const reference = /** @type {P5Template} */ (node)
const pos = reference.sourceCodeLocation
const startTag = pos && pos.startTag && position(pos.startTag)

@@ -251,5 +240,5 @@ const endTag = pos && pos.endTag && position(pos.endTag)

// @ts-expect-error Types are wrong.
const content = transform(ctx, ast.content)
const content = one(state, reference.content)
if (startTag && endTag && ctx.file) {
if (startTag && endTag && state.file) {
content.position = {start: startTag.end, end: endTag.start}

@@ -261,2 +250,4 @@ }

state.schema = schema
return result

@@ -266,10 +257,37 @@ }

/**
* Patch positional info from `from` onto `to`.
*
* @param {State} state
* Info passed around about the current state.
* @param {P5Node} from
* p5 node.
* @param {Node} to
* hast node.
* @returns {void}
* Nothing.
*/
function patch(state, from, to) {
if ('sourceCodeLocation' in from && from.sourceCodeLocation && state.file) {
const position = createLocation(state, to, from.sourceCodeLocation)
if (position) {
state.location = true
to.position = position
}
}
}
/**
* Create clean positional information.
*
* @param {Context} ctx
* @param {State} state
* Info passed around about the current state.
* @param {Node} node
* hast node.
* @param {P5ElementLocation} location
* @returns {Position|null}
* p5 location info.
* @returns {Position | undefined}
* Position, or nothing.
*/
function createLocation(ctx, node, location) {
function createLocation(state, node, location) {
const result = position(location)

@@ -292,4 +310,4 @@

if (ctx.verbose) {
/** @type {Object.<string, Position|null>} */
if (state.verbose) {
/** @type {Record<string, Position | undefined>} */
const props = {}

@@ -299,5 +317,9 @@ /** @type {string} */

for (key in location.attrs) {
if (own.call(location.attrs, key)) {
props[find(ctx.schema, key).property] = position(location.attrs[key])
if (location.attrs) {
for (key in location.attrs) {
if (own.call(location.attrs, key)) {
props[find(state.schema, key).property] = position(
location.attrs[key]
)
}
}

@@ -308,2 +330,3 @@ }

position: {
// @ts-expect-error: assume not `undefined`.
opening: position(location.startTag),

@@ -321,4 +344,8 @@ closing: location.endTag ? position(location.endTag) : null,

/**
* Turn a p5 location into a position.
*
* @param {P5Location} loc
* @returns {Position|null}
* Location.
* @returns {Position | undefined}
* Position or nothing.
*/

@@ -336,17 +363,25 @@ function position(loc) {

})
// @ts-expect-error `null` is fine.
return start || end ? {start, end} : null
// @ts-expect-error `undefined` is fine.
return start || end ? {start, end} : undefined
}
/**
* Filter out invalid points.
*
* @param {Point} point
* @returns {Point|null}
* Point with potentially `undefined` values.
* @returns {Point | undefined}
* Point or nothing.
*/
function point(point) {
return point.line && point.column ? point : null
return point.line && point.column ? point : undefined
}
/**
* @param {VFile|Options} value
* Check if something is a file.
*
* @param {VFile | Options} value
* File or options.
* @returns {value is VFile}
* Whether `value` is a file.
*/

@@ -353,0 +388,0 @@ function isFile(value) {

{
"name": "hast-util-from-parse5",
"version": "7.1.0",
"version": "7.1.1",
"description": "hast utility to transform from Parse5’s AST",

@@ -37,3 +37,2 @@ "license": "MIT",

"@types/hast": "^2.0.0",
"@types/parse5": "^6.0.0",
"@types/unist": "^2.0.0",

@@ -47,23 +46,21 @@ "hastscript": "^7.0.0",

"devDependencies": {
"@types/tape": "^4.0.0",
"@types/node": "^18.0.0",
"c8": "^7.0.0",
"is-hidden": "^2.0.0",
"parse5": "^6.0.0",
"parse5": "^7.0.0",
"prettier": "^2.0.0",
"remark-cli": "^9.0.0",
"remark-preset-wooorm": "^8.0.0",
"rimraf": "^3.0.0",
"tape": "^5.0.0",
"remark-cli": "^11.0.0",
"remark-preset-wooorm": "^9.0.0",
"to-vfile": "^7.0.0",
"type-coverage": "^2.0.0",
"typescript": "^4.0.0",
"unist-util-visit": "^3.0.0",
"xo": "^0.42.0"
"unist-util-visit": "^4.0.0",
"xo": "^0.53.0"
},
"scripts": {
"prepack": "npm run build && npm run format",
"build": "rimraf \"{test/**,lib/**,}*.d.ts\" && tsc && type-coverage",
"build": "tsc --build --clean && tsc --build && type-coverage",
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
"test-api": "node test/index.js",
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test/index.js",
"test-api": "node --conditions development test/index.js",
"test-coverage": "c8 --check-coverage --100 --reporter lcov npm run test-api",
"test": "npm run build && npm run format && npm run test-coverage"

@@ -80,3 +77,14 @@ },

"xo": {
"prettier": true
"prettier": true,
"rules": {
"max-depth": "off"
},
"overrides": [
{
"files": "test/**/*.js",
"rules": {
"no-await-in-loop": 0
}
}
]
},

@@ -83,0 +91,0 @@ "remarkConfig": {

@@ -11,12 +11,42 @@ # hast-util-from-parse5

[**hast**][hast] utility to transform [Parse5’s AST][ast] to a hast
[*tree*][tree].
[hast][] utility to transform from [`parse5`][parse5]s AST.
## Contents
* [What is this?](#what-is-this)
* [When should I use this?](#when-should-i-use-this)
* [Install](#install)
* [Use](#use)
* [API](#api)
* [`fromParse5(tree[, file|options])`](#fromparse5tree-fileoptions)
* [`Options`](#options)
* [`Space`](#space-1)
* [Types](#types)
* [Compatibility](#compatibility)
* [Security](#security)
* [Related](#related)
* [Contribute](#contribute)
* [License](#license)
## What is this?
This package is a utility that can turn a parse5 tree into a hast tree.
## When should I use this?
You can use this package when using `parse5` as an HTML parser and wanting to
work with hast.
The utility [`hast-util-to-parse5`][hast-util-to-parse5] does the inverse of
this utility.
It generates `parse5`s AST again.
The utility [`hast-util-from-html`][hast-util-from-html] wraps this utility and
`parse5` to both parse HTML and generate hast from it.
## Install
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c):
Node 12+ is needed to use it and it must be `import`ed instead of `require`d.
This package is [ESM only][esm].
In Node.js (version 14.14+ and 16.0+), install with [npm][]:
[npm][]:
```sh

@@ -26,5 +56,19 @@ npm install hast-util-from-parse5

In Deno with [`esm.sh`][esmsh]:
```js
import {fromParse5} from "https://esm.sh/hast-util-from-parse5@7"
```
In browsers with [`esm.sh`][esmsh]:
```html
<script type="module">
import {fromParse5} from "https://esm.sh/hast-util-from-parse5@7?bundle"
</script>
```
## Use
Say we have the following file, `example.html`:
Say our document `example.html` contains:

@@ -35,12 +79,12 @@ ```html

And our script, `example.js`, looks as follows:
…and our module `example.js` looks as follows:
```js
import parse5 from 'parse5'
import {readSync} from 'to-vfile'
import {parse} from 'parse5'
import {read} from 'to-vfile'
import {inspect} from 'unist-util-inspect'
import {fromParse5} from 'hast-util-from-parse5'
const file = readSync('example.html')
const p5ast = parse5.parse(String(file), {sourceCodeLocationInfo: true})
const file = await read('example.html')
const p5ast = parse(String(file), {sourceCodeLocationInfo: true})
const hast = fromParse5(p5ast, file)

@@ -51,3 +95,3 @@

Now, running `node example` yields:
…now running `node example.js` yields:

@@ -78,35 +122,49 @@ ```text

This package exports the following identifiers: `fromParse5`.
This package exports the identifier [`fromParse5`][fromparse5].
There is no default export.
### `fromParse5(ast[, file|options])`
### `fromParse5(tree[, file|options])`
Transform [Parse5’s AST][ast] to a [**hast**][hast] [*tree*][tree].
Transform a `parse5` AST to hast.
##### `options`
###### Parameters
If `options` is a [`VFile`][vfile], it’s treated as `{file: options}`.
* `tree` ([`Parse5Node`][parse5-node])
— `parse5` tree to transform
* `file` ([`VFile`][vfile], optional)
— corresponding file (treated as `{file: file}`)
* `options` ([`Options`][options], optional)
— configuration
###### `options.space`
###### Returns
Whether the [*root*][root] of the [*tree*][tree] is in the `'html'` or `'svg'`
space (enum, `'svg'` or `'html'`, default: `'html'`).
hast tree ([`HastNode`][hast-node]).
If an element in with the SVG namespace is found in `ast`, `fromParse5`
automatically switches to the SVG space when entering the element, and switches
back when leaving.
### `Options`
###### `options.file`
Configuration (TypeScript type).
[`VFile`][vfile], used to add [positional information][positional-information]
to [*nodes*][node].
If given, the [*file*][file] should have the original HTML source as its
contents.
##### Fields
###### `options.verbose`
###### `space`
Whether to add extra positional information about starting tags, closing tags,
Which space the document is in ([`Space`][space], default: `'html'`).
When an `<svg>` element is found in the HTML space, this package already
automatically switches to and from the SVG space when entering and exiting
it.
###### `file`
File used to add positional info to nodes ([`VFile`][vfile], optional).
If given, the file should represent the original HTML source.
###### `verbose`
Whether to add extra positional info about starting tags, closing tags,
and attributes to elements (`boolean`, default: `false`).
Note: not used without `file`.
> 👉 **Note**: only used when `file` is given.
For the following HTML:

@@ -156,2 +214,24 @@

### `Space`
Namespace (TypeScript type).
###### Type
```ts
type Space = 'html' | 'svg'
```
## Types
This package is fully typed with [TypeScript][].
It exports the additional types [`Options`][options] and [`Space`][space].
## Compatibility
Projects maintained by the unified collective are compatible with all maintained
versions of Node.js.
As of now, that is Node.js 12.20+, 14.14+, 16.0+, and 18.0+.
Our projects sometimes work with older versions, but this is not guaranteed.
## Security

@@ -179,4 +259,4 @@

See [`contributing.md` in `syntax-tree/.github`][contributing] for ways to get
started.
See [`contributing.md`][contributing] in [`syntax-tree/.github`][health] for
ways to get started.
See [`support.md`][support] for ways to get help.

@@ -222,2 +302,8 @@

[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
[esmsh]: https://esm.sh
[typescript]: https://www.typescriptlang.org
[license]: license

@@ -227,24 +313,30 @@

[contributing]: https://github.com/syntax-tree/.github/blob/HEAD/contributing.md
[health]: https://github.com/syntax-tree/.github
[support]: https://github.com/syntax-tree/.github/blob/HEAD/support.md
[contributing]: https://github.com/syntax-tree/.github/blob/main/contributing.md
[coc]: https://github.com/syntax-tree/.github/blob/HEAD/code-of-conduct.md
[support]: https://github.com/syntax-tree/.github/blob/main/support.md
[ast]: https://github.com/inikulin/parse5/blob/HEAD/packages/parse5/docs/tree-adapter/default/interface-list.md
[coc]: https://github.com/syntax-tree/.github/blob/main/code-of-conduct.md
[vfile]: https://github.com/vfile/vfile
[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting
[tree]: https://github.com/syntax-tree/unist#tree
[parse5]: https://github.com/inikulin/parse5
[root]: https://github.com/syntax-tree/unist#root
[parse5-node]: https://github.com/inikulin/parse5/blob/master/packages/parse5/lib/tree-adapters/default.ts
[positional-information]: https://github.com/syntax-tree/unist#positional-information
[vfile]: https://github.com/vfile/vfile
[file]: https://github.com/syntax-tree/unist#file
[hast-util-to-parse5]: https://github.com/syntax-tree/hast-util-to-parse5
[hast]: https://github.com/syntax-tree/hast
[node]: https://github.com/syntax-tree/hast#nodes
[hast-util-from-html]: https://github.com/syntax-tree/hast-util-from-html
[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting
[hast-node]: https://github.com/syntax-tree/hast#nodes
[fromparse5]: #fromparse5tree-fileoptions
[options]: #options
[space]: #space-1
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc