text-runner-engine 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -0
- package/dist/actions/actions.d.ts +11 -0
- package/dist/actions/actions.js +36 -0
- package/dist/actions/built-in/check-image.d.ts +4 -0
- package/dist/actions/built-in/check-image.js +59 -0
- package/dist/actions/built-in/check-link.d.ts +4 -0
- package/dist/actions/built-in/check-link.js +127 -0
- package/dist/actions/built-in/test.d.ts +3 -0
- package/dist/actions/built-in/test.js +4 -0
- package/dist/actions/export.d.ts +18 -0
- package/dist/actions/export.js +2 -0
- package/dist/actions/external-action-manager.d.ts +10 -0
- package/dist/actions/external-action-manager.js +44 -0
- package/dist/actions/finder.d.ts +29 -0
- package/dist/actions/finder.js +99 -0
- package/dist/actions/index.d.ts +37 -0
- package/dist/actions/index.js +3 -0
- package/dist/actions/name.d.ts +2 -0
- package/dist/actions/name.js +6 -0
- package/dist/activities/extract-dynamic.d.ts +5 -0
- package/dist/activities/extract-dynamic.js +29 -0
- package/dist/activities/extract-images-and-links.d.ts +5 -0
- package/dist/activities/extract-images-and-links.js +32 -0
- package/dist/activities/index.d.ts +20 -0
- package/dist/activities/index.js +14 -0
- package/dist/activities/normalize-action-name.d.ts +3 -0
- package/dist/activities/normalize-action-name.js +13 -0
- package/dist/ast/index.d.ts +3 -0
- package/dist/ast/index.js +3 -0
- package/dist/ast/node-list.d.ts +41 -0
- package/dist/ast/node-list.js +128 -0
- package/dist/ast/node.d.ts +49 -0
- package/dist/ast/node.js +53 -0
- package/dist/commands/command.d.ts +9 -0
- package/dist/commands/command.js +2 -0
- package/dist/commands/debug.d.ts +16 -0
- package/dist/commands/debug.js +122 -0
- package/dist/commands/dynamic.d.ts +13 -0
- package/dist/commands/dynamic.js +57 -0
- package/dist/commands/index.d.ts +7 -0
- package/dist/commands/index.js +7 -0
- package/dist/commands/run.d.ts +14 -0
- package/dist/commands/run.js +66 -0
- package/dist/commands/static.d.ts +13 -0
- package/dist/commands/static.js +60 -0
- package/dist/commands/unused.d.ts +13 -0
- package/dist/commands/unused.js +43 -0
- package/dist/configuration/data.d.ts +46 -0
- package/dist/configuration/data.js +2 -0
- package/dist/configuration/defaults.d.ts +5 -0
- package/dist/configuration/defaults.js +50 -0
- package/dist/configuration/index.d.ts +5 -0
- package/dist/configuration/index.js +4 -0
- package/dist/configuration/publication.d.ts +42 -0
- package/dist/configuration/publication.js +51 -0
- package/dist/configuration/publications.d.ts +9 -0
- package/dist/configuration/publications.js +25 -0
- package/dist/errors/error.d.ts +2 -0
- package/dist/errors/error.js +9 -0
- package/dist/errors/node-error.d.ts +3 -0
- package/dist/errors/node-error.js +5 -0
- package/dist/errors/user-error.d.ts +13 -0
- package/dist/errors/user-error.js +16 -0
- package/dist/events/index.d.ts +49 -0
- package/dist/events/index.js +13 -0
- package/dist/filesystem/absolute-dir.d.ts +25 -0
- package/dist/filesystem/absolute-dir.js +42 -0
- package/dist/filesystem/absolute-file.d.ts +18 -0
- package/dist/filesystem/absolute-file.js +28 -0
- package/dist/filesystem/full-dir.d.ts +11 -0
- package/dist/filesystem/full-dir.js +15 -0
- package/dist/filesystem/full-file.d.ts +22 -0
- package/dist/filesystem/full-file.js +35 -0
- package/dist/filesystem/full-link.d.ts +40 -0
- package/dist/filesystem/full-link.js +80 -0
- package/dist/filesystem/full-path.d.ts +31 -0
- package/dist/filesystem/full-path.js +61 -0
- package/dist/filesystem/get-filenames.d.ts +15 -0
- package/dist/filesystem/get-filenames.js +73 -0
- package/dist/filesystem/has-directory.d.ts +2 -0
- package/dist/filesystem/has-directory.js +11 -0
- package/dist/filesystem/index.d.ts +15 -0
- package/dist/filesystem/index.js +15 -0
- package/dist/filesystem/is-markdown-file.d.ts +2 -0
- package/dist/filesystem/is-markdown-file.js +11 -0
- package/dist/filesystem/location.d.ts +17 -0
- package/dist/filesystem/location.js +26 -0
- package/dist/filesystem/relative-dir.d.ts +6 -0
- package/dist/filesystem/relative-dir.js +7 -0
- package/dist/filesystem/relative-link.d.ts +16 -0
- package/dist/filesystem/relative-link.js +18 -0
- package/dist/filesystem/source-dir.d.ts +19 -0
- package/dist/filesystem/source-dir.js +35 -0
- package/dist/filesystem/unknown-link.d.ts +15 -0
- package/dist/filesystem/unknown-link.js +23 -0
- package/dist/helpers/add-leading-dot-unless-empty.d.ts +2 -0
- package/dist/helpers/add-leading-dot-unless-empty.js +10 -0
- package/dist/helpers/add-leading-slash.d.ts +2 -0
- package/dist/helpers/add-leading-slash.js +9 -0
- package/dist/helpers/add-trailing-slash.d.ts +2 -0
- package/dist/helpers/add-trailing-slash.js +7 -0
- package/dist/helpers/index.d.ts +16 -0
- package/dist/helpers/index.js +16 -0
- package/dist/helpers/is-external-link.d.ts +2 -0
- package/dist/helpers/is-external-link.js +5 -0
- package/dist/helpers/is-link-to-anchor-in-other-file.d.ts +2 -0
- package/dist/helpers/is-link-to-anchor-in-other-file.js +4 -0
- package/dist/helpers/is-link-to-anchor-in-same-file.d.ts +2 -0
- package/dist/helpers/is-link-to-anchor-in-same-file.js +4 -0
- package/dist/helpers/is-mailto-link.d.ts +2 -0
- package/dist/helpers/is-mailto-link.js +4 -0
- package/dist/helpers/remove-double-slash.d.ts +3 -0
- package/dist/helpers/remove-double-slash.js +6 -0
- package/dist/helpers/remove-leading-slash.d.ts +2 -0
- package/dist/helpers/remove-leading-slash.js +7 -0
- package/dist/helpers/remove-trailing-colon.d.ts +2 -0
- package/dist/helpers/remove-trailing-colon.js +9 -0
- package/dist/helpers/straighten-link.d.ts +3 -0
- package/dist/helpers/straighten-link.js +15 -0
- package/dist/helpers/trim-all-line-ends.d.ts +3 -0
- package/dist/helpers/trim-all-line-ends.js +5 -0
- package/dist/helpers/trim-extension.d.ts +2 -0
- package/dist/helpers/trim-extension.js +5 -0
- package/dist/helpers/unixify.d.ts +3 -0
- package/dist/helpers/unixify.js +6 -0
- package/dist/link-targets/find.d.ts +4 -0
- package/dist/link-targets/find.js +9 -0
- package/dist/link-targets/index.d.ts +15 -0
- package/dist/link-targets/index.js +3 -0
- package/dist/link-targets/list.d.ts +18 -0
- package/dist/link-targets/list.js +74 -0
- package/dist/link-targets/target-url.d.ts +2 -0
- package/dist/link-targets/target-url.js +8 -0
- package/dist/parsers/html/html-parser.d.ts +28 -0
- package/dist/parsers/html/html-parser.js +153 -0
- package/dist/parsers/html/index.d.ts +2 -0
- package/dist/parsers/html/index.js +2 -0
- package/dist/parsers/html/parse-html-files.d.ts +6 -0
- package/dist/parsers/html/parse-html-files.js +16 -0
- package/dist/parsers/index.d.ts +3 -0
- package/dist/parsers/index.js +3 -0
- package/dist/parsers/markdown/closing-tag-parser.d.ts +13 -0
- package/dist/parsers/markdown/closing-tag-parser.js +29 -0
- package/dist/parsers/markdown/index.d.ts +3 -0
- package/dist/parsers/markdown/index.js +3 -0
- package/dist/parsers/markdown/md-parser.d.ts +50 -0
- package/dist/parsers/markdown/md-parser.js +316 -0
- package/dist/parsers/markdown/open-node-tracker.d.ts +14 -0
- package/dist/parsers/markdown/open-node-tracker.js +33 -0
- package/dist/parsers/markdown/parse.d.ts +5 -0
- package/dist/parsers/markdown/parse.js +15 -0
- package/dist/parsers/tag-mapper.d.ts +31 -0
- package/dist/parsers/tag-mapper.js +112 -0
- package/dist/run/activity-collector.d.ts +29 -0
- package/dist/run/activity-collector.js +35 -0
- package/dist/run/index.d.ts +9 -0
- package/dist/run/index.js +5 -0
- package/dist/run/name-refiner.d.ts +13 -0
- package/dist/run/name-refiner.js +20 -0
- package/dist/run/output-collector.d.ts +13 -0
- package/dist/run/output-collector.js +30 -0
- package/dist/run/parallel.d.ts +11 -0
- package/dist/run/parallel.js +13 -0
- package/dist/run/run-activity.d.ts +8 -0
- package/dist/run/run-activity.js +76 -0
- package/dist/run/sequential.d.ts +7 -0
- package/dist/run/sequential.js +10 -0
- package/dist/run/stopwatch.d.ts +12 -0
- package/dist/run/stopwatch.js +19 -0
- package/dist/text-runner.d.ts +15 -0
- package/dist/text-runner.js +15 -0
- package/dist/workspace/create.d.ts +4 -0
- package/dist/workspace/create.js +10 -0
- package/dist/workspace/index.d.ts +2 -0
- package/dist/workspace/index.js +2 -0
- package/package.json +45 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export * from "../actions/name.js";
|
|
2
|
+
export * from "./add-leading-dot-unless-empty.js";
|
|
3
|
+
export * from "./add-leading-slash.js";
|
|
4
|
+
export * from "./add-trailing-slash.js";
|
|
5
|
+
export * from "./is-external-link.js";
|
|
6
|
+
export * from "./is-link-to-anchor-in-other-file.js";
|
|
7
|
+
export * from "./is-link-to-anchor-in-same-file.js";
|
|
8
|
+
export * from "./is-mailto-link.js";
|
|
9
|
+
export * from "./remove-double-slash.js";
|
|
10
|
+
export * from "./remove-leading-slash.js";
|
|
11
|
+
export * from "./remove-trailing-colon.js";
|
|
12
|
+
export * from "./straighten-link.js";
|
|
13
|
+
export * from "./trim-all-line-ends.js";
|
|
14
|
+
export * from "./trim-extension.js";
|
|
15
|
+
export * from "./unixify.js";
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export * from "../actions/name.js";
|
|
2
|
+
export * from "./add-leading-dot-unless-empty.js";
|
|
3
|
+
export * from "./add-leading-slash.js";
|
|
4
|
+
export * from "./add-trailing-slash.js";
|
|
5
|
+
export * from "./is-external-link.js";
|
|
6
|
+
export * from "./is-link-to-anchor-in-other-file.js";
|
|
7
|
+
export * from "./is-link-to-anchor-in-same-file.js";
|
|
8
|
+
export * from "./is-mailto-link.js";
|
|
9
|
+
export * from "./remove-double-slash.js";
|
|
10
|
+
export * from "./remove-leading-slash.js";
|
|
11
|
+
export * from "./remove-trailing-colon.js";
|
|
12
|
+
export * from "./straighten-link.js";
|
|
13
|
+
export * from "./trim-all-line-ends.js";
|
|
14
|
+
export * from "./trim-extension.js";
|
|
15
|
+
export * from "./unixify.js";
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const replaceDoubleSlashRE = /\/\//g;
|
|
2
|
+
const replaceDotRE = /\/\.\//;
|
|
3
|
+
const replaceDotDotRE = /\/[^/]+\/\.\.\//;
|
|
4
|
+
/** Removes intermediate directory expressions from the given link */
|
|
5
|
+
export function straightenLink(link) {
|
|
6
|
+
let result = link.replace(replaceDoubleSlashRE, "/");
|
|
7
|
+
while (result.includes("/./")) {
|
|
8
|
+
result = result.replace(replaceDotRE, "/");
|
|
9
|
+
}
|
|
10
|
+
while (replaceDotDotRE.test(result)) {
|
|
11
|
+
result = result.replace(replaceDotDotRE, "/");
|
|
12
|
+
}
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=straighten-link.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export * from "./find.js";
|
|
2
|
+
export * from "./list.js";
|
|
3
|
+
/**
|
|
4
|
+
* Target is a position in a Markdown file that links can point to:
|
|
5
|
+
* headers or anchors
|
|
6
|
+
*/
|
|
7
|
+
export interface Target {
|
|
8
|
+
readonly level?: number;
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly text?: string;
|
|
11
|
+
readonly type: Types;
|
|
12
|
+
}
|
|
13
|
+
/** types of link targets */
|
|
14
|
+
export type Types = "anchor" | "heading";
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as ast from "../ast/index.js";
|
|
2
|
+
import * as files from "../filesystem/index.js";
|
|
3
|
+
import { Target, Types } from "./index.js";
|
|
4
|
+
export declare class List {
|
|
5
|
+
readonly targets: Record<string, Target[]>;
|
|
6
|
+
constructor();
|
|
7
|
+
addAnchor(node: ast.Node): void;
|
|
8
|
+
addHeading(node: ast.Node, nodeList: ast.NodeList): void;
|
|
9
|
+
addLinkTarget(file: files.FullFilePath, type: Types, name: string): void;
|
|
10
|
+
addNodeList(nodeList: ast.NodeList): void;
|
|
11
|
+
anchorType(file: files.FullFilePath, name: string): string;
|
|
12
|
+
getAnchor(file: files.FullFilePath, name: string): null | Target;
|
|
13
|
+
/** provides all the anchors for the given file */
|
|
14
|
+
getAnchors(file: files.FullFilePath): string[];
|
|
15
|
+
hasAnchor(file: files.FullFilePath, name: string): boolean;
|
|
16
|
+
hasFile(filePath: files.FullFilePath): boolean;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { targetURL } from "./target-url.js";
|
|
2
|
+
export class List {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.targets = {};
|
|
5
|
+
}
|
|
6
|
+
addAnchor(node) {
|
|
7
|
+
if (node.attributes.href !== undefined) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (!node.attributes.name) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
this.addLinkTarget(node.location.file, "anchor", node.attributes.name);
|
|
14
|
+
}
|
|
15
|
+
addHeading(node, nodeList) {
|
|
16
|
+
const content = nodeList.textInNode(node);
|
|
17
|
+
if (!content) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
this.addLinkTarget(node.location.file, "heading", content);
|
|
21
|
+
}
|
|
22
|
+
addLinkTarget(file, type, name) {
|
|
23
|
+
const key = file.platformified();
|
|
24
|
+
this.targets[key] = this.targets[key] || [];
|
|
25
|
+
this.targets[key].push({ name: targetURL(name), type });
|
|
26
|
+
}
|
|
27
|
+
addNodeList(nodeList) {
|
|
28
|
+
for (const node of nodeList) {
|
|
29
|
+
const key = node.location.file.platformified();
|
|
30
|
+
this.targets[key] = this.targets[key] || [];
|
|
31
|
+
if (node.type === "anchor_open") {
|
|
32
|
+
this.addAnchor(node);
|
|
33
|
+
}
|
|
34
|
+
else if (/h[1-6]_open/.test(node.type)) {
|
|
35
|
+
this.addHeading(node, nodeList);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Returns the type of the given anchor
|
|
40
|
+
// with the given name in the given file
|
|
41
|
+
anchorType(file, name) {
|
|
42
|
+
const anchorsForFile = this.targets[file.platformified()];
|
|
43
|
+
if (!anchorsForFile) {
|
|
44
|
+
// TODO: make UserError
|
|
45
|
+
throw new Error(`no anchors in file ${file.platformified()}`);
|
|
46
|
+
}
|
|
47
|
+
const anchor = anchorsForFile.find(linkTarget => linkTarget.name === name);
|
|
48
|
+
if (!anchor) {
|
|
49
|
+
// TODO: make UserError
|
|
50
|
+
throw new Error(`no anchor '${name}' in file '${file.platformified()}'`);
|
|
51
|
+
}
|
|
52
|
+
return anchor.type;
|
|
53
|
+
}
|
|
54
|
+
getAnchor(file, name) {
|
|
55
|
+
for (const target of this.targets[file.platformified()] || []) {
|
|
56
|
+
if (target.name === name) {
|
|
57
|
+
return target;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
/** provides all the anchors for the given file */
|
|
63
|
+
getAnchors(file) {
|
|
64
|
+
return (this.targets[file.platformified()] || []).map(target => target.name);
|
|
65
|
+
}
|
|
66
|
+
hasAnchor(file, name) {
|
|
67
|
+
return this.getAnchor(file, name) != null;
|
|
68
|
+
}
|
|
69
|
+
// Returns whether this link target list knows about the given file
|
|
70
|
+
hasFile(filePath) {
|
|
71
|
+
return this.targets[filePath.platformified()] != null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// @ts-expect-error: no types available
|
|
2
|
+
import anchor from "anchor-markdown-header";
|
|
3
|
+
export function targetURL(targetName) {
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
5
|
+
const link = anchor(targetName, "github.com");
|
|
6
|
+
return link.substring(link.indexOf("#") + 1, link.indexOf(")"));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=target-url.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as parse5 from "parse5";
|
|
2
|
+
import * as ast from "../../ast/index.js";
|
|
3
|
+
import * as files from "../../filesystem/index.js";
|
|
4
|
+
import { TagMapper } from "../tag-mapper.js";
|
|
5
|
+
/** Parser converts HTML5 source into the standardized AST format. */
|
|
6
|
+
export declare class Parser {
|
|
7
|
+
private readonly tagMapper;
|
|
8
|
+
constructor(tagMapper: TagMapper);
|
|
9
|
+
/**
|
|
10
|
+
* Parse returns the standard AST for the given HTML text.
|
|
11
|
+
*/
|
|
12
|
+
parse(text: string, startingLocation: files.Location): ast.NodeList;
|
|
13
|
+
/** returns the subtree of the given HTML AST whose root node has the given name */
|
|
14
|
+
private findNodeWithName;
|
|
15
|
+
/** returns whether the given HTML node is an empty text node */
|
|
16
|
+
private isEmptyTextNode;
|
|
17
|
+
/** converts the given HTML AST node into the standard format */
|
|
18
|
+
private standardizeNode;
|
|
19
|
+
/** converts the given HTML tag with open and closing tag into the standard format */
|
|
20
|
+
private standardizeOpenCloseTag;
|
|
21
|
+
/** converts the given HTML standalone node into the standard format */
|
|
22
|
+
private standardizeStandaloneNode;
|
|
23
|
+
/** converts the given HTML text node into the standard format */
|
|
24
|
+
private standardizeTextNode;
|
|
25
|
+
}
|
|
26
|
+
/** converts the given HTML AST node attributes into the standard AST format */
|
|
27
|
+
export declare function standardizeHTMLAttributes(attrs: parse5.Token.Attribute[]): ast.NodeAttributes;
|
|
28
|
+
//# sourceMappingURL=html-parser.d.ts.map
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import * as parse5 from "parse5";
|
|
2
|
+
import * as util from "util";
|
|
3
|
+
import * as ast from "../../ast/index.js";
|
|
4
|
+
/** Parser converts HTML5 source into the standardized AST format. */
|
|
5
|
+
export class Parser {
|
|
6
|
+
constructor(tagMapper) {
|
|
7
|
+
this.tagMapper = tagMapper;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Parse returns the standard AST for the given HTML text.
|
|
11
|
+
*/
|
|
12
|
+
parse(text, startingLocation) {
|
|
13
|
+
const htmlDoc = parse5.parse(text, { sourceCodeLocationInfo: true });
|
|
14
|
+
const htmlNode = this.findNodeWithName(htmlDoc.childNodes, "html");
|
|
15
|
+
const bodyNode = this.findNodeWithName(htmlNode.childNodes, "body");
|
|
16
|
+
const result = new ast.NodeList();
|
|
17
|
+
for (const childNode of bodyNode.childNodes) {
|
|
18
|
+
result.push(...this.standardizeNode(childNode, startingLocation.withLine(startingLocation.line)));
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
/** returns the subtree of the given HTML AST whose root node has the given name */
|
|
23
|
+
findNodeWithName(nodes, name) {
|
|
24
|
+
for (const node of nodes) {
|
|
25
|
+
if (node.nodeName === name) {
|
|
26
|
+
if (!instanceOfElement(node)) {
|
|
27
|
+
throw new Error("Expected parse5.Element");
|
|
28
|
+
}
|
|
29
|
+
return node;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
throw new Error(`child node '${name}' not found in AST: ${util.inspect(nodes, false, Infinity)}`);
|
|
33
|
+
}
|
|
34
|
+
/** returns whether the given HTML node is an empty text node */
|
|
35
|
+
isEmptyTextNode(node) {
|
|
36
|
+
return instanceOfTextNode(node) && node.value.trim() === "";
|
|
37
|
+
}
|
|
38
|
+
/** converts the given HTML AST node into the standard format */
|
|
39
|
+
standardizeNode(node, startingLocation) {
|
|
40
|
+
if (this.isEmptyTextNode(node)) {
|
|
41
|
+
return new ast.NodeList();
|
|
42
|
+
}
|
|
43
|
+
if (instanceOfTextNode(node)) {
|
|
44
|
+
return this.standardizeTextNode(node, startingLocation);
|
|
45
|
+
}
|
|
46
|
+
if (!instanceOfElement(node)) {
|
|
47
|
+
throw new Error("unknown tree node: " + util.inspect(node, false, Infinity));
|
|
48
|
+
}
|
|
49
|
+
if (this.tagMapper.isStandaloneTag(node.nodeName)) {
|
|
50
|
+
return this.standardizeStandaloneNode(node, startingLocation);
|
|
51
|
+
}
|
|
52
|
+
return this.standardizeOpenCloseTag(node, startingLocation);
|
|
53
|
+
}
|
|
54
|
+
/** converts the given HTML tag with open and closing tag into the standard format */
|
|
55
|
+
standardizeOpenCloseTag(node, startingLocation) {
|
|
56
|
+
const result = new ast.NodeList();
|
|
57
|
+
const attributes = standardizeHTMLAttributes(node.attrs);
|
|
58
|
+
// store the opening node
|
|
59
|
+
let startLine = startingLocation.line;
|
|
60
|
+
if (node.sourceCodeLocation) {
|
|
61
|
+
startLine += node.sourceCodeLocation.startLine - 1;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
const parentNode = node.parentNode;
|
|
65
|
+
if (parentNode == null) {
|
|
66
|
+
throw new Error(`node "${node} has no parent`);
|
|
67
|
+
}
|
|
68
|
+
if (parentNode.sourceCodeLocation) {
|
|
69
|
+
startLine += parentNode.sourceCodeLocation.startLine;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
result.push(new ast.Node({
|
|
73
|
+
attributes,
|
|
74
|
+
content: "",
|
|
75
|
+
location: startingLocation.withLine(startLine),
|
|
76
|
+
tag: node.tagName,
|
|
77
|
+
type: this.tagMapper.openingTypeForTag(node.tagName, attributes)
|
|
78
|
+
}));
|
|
79
|
+
// store the child nodes in between the opening and closing node
|
|
80
|
+
for (const childNode of node.childNodes) {
|
|
81
|
+
const standardizedChildNodes = this.standardizeNode(childNode, startingLocation);
|
|
82
|
+
result.push(...standardizedChildNodes);
|
|
83
|
+
}
|
|
84
|
+
// store the closing node
|
|
85
|
+
let endLine;
|
|
86
|
+
if (node.sourceCodeLocation) {
|
|
87
|
+
endLine = node.sourceCodeLocation.endLine + startingLocation.line - 1;
|
|
88
|
+
}
|
|
89
|
+
else if (node.parentNode && instanceOfElement(node.parentNode) && node.parentNode.sourceCodeLocation) {
|
|
90
|
+
endLine = node.parentNode.sourceCodeLocation.endLine + startingLocation.line - 1;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
throw new Error(`cannot determine end line for node ${node}`);
|
|
94
|
+
}
|
|
95
|
+
if (!node.sourceCodeLocation || (node.sourceCodeLocation && node.sourceCodeLocation.endTag)) {
|
|
96
|
+
const tag = ("/" + node.tagName);
|
|
97
|
+
result.push(new ast.Node({
|
|
98
|
+
attributes: {},
|
|
99
|
+
content: "",
|
|
100
|
+
location: startingLocation.withLine(endLine),
|
|
101
|
+
tag,
|
|
102
|
+
type: this.tagMapper.typeForTag(tag, attributes)
|
|
103
|
+
}));
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
/** converts the given HTML standalone node into the standard format */
|
|
108
|
+
standardizeStandaloneNode(node, startingLocation) {
|
|
109
|
+
var _a;
|
|
110
|
+
const result = new ast.NodeList();
|
|
111
|
+
const attributes = standardizeHTMLAttributes(node.attrs);
|
|
112
|
+
result.push(new ast.Node({
|
|
113
|
+
attributes,
|
|
114
|
+
content: "",
|
|
115
|
+
location: startingLocation.withLine((((_a = node.sourceCodeLocation) === null || _a === void 0 ? void 0 : _a.startLine) || 0) + startingLocation.line - 1),
|
|
116
|
+
tag: node.tagName,
|
|
117
|
+
type: this.tagMapper.typeForTag(node.tagName, attributes)
|
|
118
|
+
}));
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
/** converts the given HTML text node into the standard format */
|
|
122
|
+
standardizeTextNode(node, startingLocation) {
|
|
123
|
+
var _a, _b;
|
|
124
|
+
const result = new ast.NodeList();
|
|
125
|
+
if (node.value !== "\n") {
|
|
126
|
+
result.push(new ast.Node({
|
|
127
|
+
attributes: {},
|
|
128
|
+
content: node.value.trim(),
|
|
129
|
+
location: startingLocation.withLine(((_b = (_a = node.sourceCodeLocation) === null || _a === void 0 ? void 0 : _a.startLine) !== null && _b !== void 0 ? _b : 0) + startingLocation.line - 1),
|
|
130
|
+
tag: "",
|
|
131
|
+
type: "text"
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/** converts the given HTML AST node attributes into the standard AST format */
|
|
138
|
+
export function standardizeHTMLAttributes(attrs) {
|
|
139
|
+
const result = {};
|
|
140
|
+
if (attrs) {
|
|
141
|
+
for (const attr of attrs) {
|
|
142
|
+
result[attr.name] = attr.value;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
function instanceOfElement(object) {
|
|
148
|
+
return !!object.nodeName && !!object.tagName && !!object.attrs;
|
|
149
|
+
}
|
|
150
|
+
function instanceOfTextNode(object) {
|
|
151
|
+
return object.nodeName === "#text";
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=html-parser.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as ast from "../../ast/index.js";
|
|
2
|
+
import * as files from "../../filesystem/index.js";
|
|
3
|
+
import { TagMapper } from "../tag-mapper.js";
|
|
4
|
+
/** returns the standard AST for the HTML files with the given paths */
|
|
5
|
+
export declare function parseHTMLFiles(filenames: files.FullFilePath[], sourceDir: files.SourceDir, tagMapper: TagMapper): Promise<ast.NodeList[]>;
|
|
6
|
+
//# sourceMappingURL=parse-html-files.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { promises as fs } from "fs";
|
|
2
|
+
import * as files from "../../filesystem/index.js";
|
|
3
|
+
import { Parser } from "./html-parser.js";
|
|
4
|
+
/** returns the standard AST for the HTML files with the given paths */
|
|
5
|
+
export async function parseHTMLFiles(filenames, sourceDir, tagMapper) {
|
|
6
|
+
const result = [];
|
|
7
|
+
const parser = new Parser(tagMapper);
|
|
8
|
+
for (const filename of filenames) {
|
|
9
|
+
const content = await fs.readFile(sourceDir.joinFullFile(filename).platformified(), {
|
|
10
|
+
encoding: "utf8"
|
|
11
|
+
});
|
|
12
|
+
result.push(parser.parse(content, new files.Location(sourceDir, filename, 1)));
|
|
13
|
+
}
|
|
14
|
+
return Promise.all(result);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=parse-html-files.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as ast from "../../ast/index.js";
|
|
2
|
+
import * as files from "../../filesystem/index.js";
|
|
3
|
+
import { TagMapper } from "../tag-mapper.js";
|
|
4
|
+
/** ClosingTagParser parses HTML blocks containing just a closing tag. */
|
|
5
|
+
export declare class ClosingTagParser {
|
|
6
|
+
private readonly closingTagRE;
|
|
7
|
+
private readonly tagMapper;
|
|
8
|
+
constructor(tagMapper: TagMapper);
|
|
9
|
+
/** Returns whether the given tag is a closing tag */
|
|
10
|
+
isClosingTag(tag: string): boolean;
|
|
11
|
+
parse(tag: string, location: files.Location): ast.NodeList;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=closing-tag-parser.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as ast from "../../ast/index.js";
|
|
2
|
+
/** ClosingTagParser parses HTML blocks containing just a closing tag. */
|
|
3
|
+
export class ClosingTagParser {
|
|
4
|
+
constructor(tagMapper) {
|
|
5
|
+
this.closingTagRE = /^\s*<[ ]*(\/[ ]*\w+)[ ]*>\s*$/;
|
|
6
|
+
this.tagMapper = tagMapper;
|
|
7
|
+
}
|
|
8
|
+
/** Returns whether the given tag is a closing tag */
|
|
9
|
+
isClosingTag(tag) {
|
|
10
|
+
return this.closingTagRE.test(tag);
|
|
11
|
+
}
|
|
12
|
+
parse(tag, location) {
|
|
13
|
+
const match = this.closingTagRE.exec(tag);
|
|
14
|
+
if (!match) {
|
|
15
|
+
throw new Error(`no tag parsed in ${tag}`);
|
|
16
|
+
}
|
|
17
|
+
const tagName = match[1].replace(/ /g, "");
|
|
18
|
+
const result = new ast.NodeList();
|
|
19
|
+
result.push(new ast.Node({
|
|
20
|
+
attributes: {},
|
|
21
|
+
content: "",
|
|
22
|
+
location,
|
|
23
|
+
tag: tagName,
|
|
24
|
+
type: this.tagMapper.typeForTag(tagName, {})
|
|
25
|
+
}));
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=closing-tag-parser.js.map
|