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,50 @@
|
|
|
1
|
+
import * as ast from "../../ast/index.js";
|
|
2
|
+
import * as files from "../../filesystem/index.js";
|
|
3
|
+
export type MarkdownItAst = MarkdownItNode[];
|
|
4
|
+
export interface MarkdownItNode {
|
|
5
|
+
/** HTML attributes. Format: `[[name1, value1], [name2, value2]]` */
|
|
6
|
+
readonly attrs: [string, string][] | null;
|
|
7
|
+
/** An array of child nodes (inline and img tokens) */
|
|
8
|
+
readonly children: MarkdownItNode[] | null;
|
|
9
|
+
/** In a case of self-closing tag (code, html, fence, etc.), it has contents of this tag. */
|
|
10
|
+
readonly content: string;
|
|
11
|
+
/** Source map info. Format: `[line_begin, line_end]` */
|
|
12
|
+
readonly map: [number, number] | null;
|
|
13
|
+
/** HTML tag name, e.g. "p" */
|
|
14
|
+
readonly tag: string;
|
|
15
|
+
/** Type of the token, e.g. "paragraph_open" */
|
|
16
|
+
readonly type: string;
|
|
17
|
+
}
|
|
18
|
+
export type MarkdownItNodeAttrs = string[][];
|
|
19
|
+
/** MarkdownParser parses Markdown. */
|
|
20
|
+
export declare class MarkdownParser {
|
|
21
|
+
private readonly closingTagParser;
|
|
22
|
+
/** parses HTML snippets into ast.NodeLists */
|
|
23
|
+
private readonly htmlParser;
|
|
24
|
+
/** MarkdownIt instance */
|
|
25
|
+
private readonly markdownIt;
|
|
26
|
+
/** helps map Markdown to HTML node types */
|
|
27
|
+
private readonly tagMapper;
|
|
28
|
+
constructor();
|
|
29
|
+
/** returns the standard AST representing the given Markdown text */
|
|
30
|
+
parse(text: string, sourceDir: files.SourceDir, file: files.FullFilePath): ast.NodeList;
|
|
31
|
+
/** Converts the given MarkdownIt AST into the standard AST format */
|
|
32
|
+
private standardizeAST;
|
|
33
|
+
private standardizeClosingHTMLTag;
|
|
34
|
+
private standardizeClosingNode;
|
|
35
|
+
private standardizeCodeInline;
|
|
36
|
+
private standardizeEmbeddedCodeblock;
|
|
37
|
+
private standardizeFence;
|
|
38
|
+
private standardizeHeadingClose;
|
|
39
|
+
private standardizeHeadingOpen;
|
|
40
|
+
private standardizeHTMLBlock;
|
|
41
|
+
private standardizeImageNode;
|
|
42
|
+
/** Returns the standardized version of the given MarkdownIt node */
|
|
43
|
+
private standardizeNode;
|
|
44
|
+
private standardizeOpeningNode;
|
|
45
|
+
private standardizeTextNode;
|
|
46
|
+
private standizeStandaloneTag;
|
|
47
|
+
}
|
|
48
|
+
/** returns the given attributes from a MarkdownIt node in the standard AST format */
|
|
49
|
+
export declare function standardizeMarkdownItAttributes(attrs: MarkdownItNodeAttrs | null): ast.NodeAttributes;
|
|
50
|
+
//# sourceMappingURL=md-parser.d.ts.map
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import MarkdownIt from "markdown-it";
|
|
2
|
+
import * as util from "util";
|
|
3
|
+
import * as ast from "../../ast/index.js";
|
|
4
|
+
import { UserError } from "../../errors/user-error.js";
|
|
5
|
+
import * as files from "../../filesystem/index.js";
|
|
6
|
+
import * as html from "../html/index.js";
|
|
7
|
+
import { TagMapper } from "../tag-mapper.js";
|
|
8
|
+
import { ClosingTagParser } from "./closing-tag-parser.js";
|
|
9
|
+
import { OpenNodeTracker } from "./open-node-tracker.js";
|
|
10
|
+
/** MarkdownParser parses Markdown. */
|
|
11
|
+
export class MarkdownParser {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.markdownIt = new MarkdownIt({
|
|
14
|
+
html: true,
|
|
15
|
+
linkify: false
|
|
16
|
+
});
|
|
17
|
+
this.tagMapper = new TagMapper();
|
|
18
|
+
this.closingTagParser = new ClosingTagParser(this.tagMapper);
|
|
19
|
+
this.htmlParser = new html.Parser(this.tagMapper);
|
|
20
|
+
}
|
|
21
|
+
/** returns the standard AST representing the given Markdown text */
|
|
22
|
+
parse(text, sourceDir, file) {
|
|
23
|
+
const mdAST = this.markdownIt.parse(text, {});
|
|
24
|
+
return this.standardizeAST(mdAST, new files.Location(sourceDir, file, 1), new OpenNodeTracker());
|
|
25
|
+
}
|
|
26
|
+
/** Converts the given MarkdownIt AST into the standard AST format */
|
|
27
|
+
standardizeAST(mdAST, parentLocation, ont) {
|
|
28
|
+
const result = new ast.NodeList();
|
|
29
|
+
let currentLine = parentLocation.line;
|
|
30
|
+
for (const node of mdAST) {
|
|
31
|
+
currentLine = Math.max((node.map || [0, 0])[0] + 1, currentLine);
|
|
32
|
+
if (node.type === "image") {
|
|
33
|
+
// need to handle images explicitly here because they have a text node as a child
|
|
34
|
+
// but the AST shouldn't contain it
|
|
35
|
+
result.push(...this.standardizeImageNode(node, parentLocation.withLine(currentLine)));
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (node.children) {
|
|
39
|
+
result.push(...this.standardizeAST(node.children, parentLocation.withLine(currentLine), ont));
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (node.type === "softbreak") {
|
|
43
|
+
currentLine += 1;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
result.push(...this.standardizeNode(node, parentLocation.withLine(currentLine), ont));
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
standardizeClosingHTMLTag(mdNode, ont, location) {
|
|
51
|
+
const result = new ast.NodeList();
|
|
52
|
+
const parsed = this.closingTagParser.parse(mdNode.content, location)[0];
|
|
53
|
+
if (parsed.tag === "/a") {
|
|
54
|
+
// </a> could be anchor_close or link_close, figure this out here
|
|
55
|
+
if (ont.has("link_open")) {
|
|
56
|
+
parsed.type = "link_close";
|
|
57
|
+
}
|
|
58
|
+
else if (ont.has("anchor_open")) {
|
|
59
|
+
parsed.type = "anchor_close";
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
throw new UserError(`Found neither open link nor anchor for node '${mdNode.content}'`, "I found a </a> tag here but there isn't an opening <a ...> tag above.", location);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
ont.close(parsed.type, location);
|
|
66
|
+
result.push(parsed);
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
standardizeClosingNode(mdNode, location, ont) {
|
|
70
|
+
const result = new ast.NodeList();
|
|
71
|
+
const openingNodeEndLine = ont.close(mdNode.type, location);
|
|
72
|
+
let closingTagLine = location.line;
|
|
73
|
+
if (openingNodeEndLine) {
|
|
74
|
+
closingTagLine = openingNodeEndLine;
|
|
75
|
+
}
|
|
76
|
+
result.push(new ast.Node({
|
|
77
|
+
attributes: standardizeMarkdownItAttributes(mdNode.attrs),
|
|
78
|
+
content: mdNode.content.trim(),
|
|
79
|
+
location: location.withLine(closingTagLine),
|
|
80
|
+
tag: this.tagMapper.tagForType(mdNode.type),
|
|
81
|
+
type: mdNode.type
|
|
82
|
+
}));
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
standardizeCodeInline(mdNode, location) {
|
|
86
|
+
const result = new ast.NodeList();
|
|
87
|
+
result.push(new ast.Node({
|
|
88
|
+
attributes: standardizeMarkdownItAttributes(mdNode.attrs),
|
|
89
|
+
content: "",
|
|
90
|
+
location,
|
|
91
|
+
tag: "code",
|
|
92
|
+
type: "code_open"
|
|
93
|
+
}));
|
|
94
|
+
result.push(new ast.Node({
|
|
95
|
+
attributes: {},
|
|
96
|
+
content: mdNode.content,
|
|
97
|
+
location,
|
|
98
|
+
tag: "",
|
|
99
|
+
type: "text"
|
|
100
|
+
}));
|
|
101
|
+
result.push(new ast.Node({
|
|
102
|
+
attributes: {},
|
|
103
|
+
content: "",
|
|
104
|
+
location,
|
|
105
|
+
tag: "/code",
|
|
106
|
+
type: "code_close"
|
|
107
|
+
}));
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
110
|
+
standardizeEmbeddedCodeblock(mdNode, location) {
|
|
111
|
+
const result = new ast.NodeList();
|
|
112
|
+
result.push(new ast.Node({
|
|
113
|
+
attributes: standardizeMarkdownItAttributes(mdNode.attrs),
|
|
114
|
+
content: "",
|
|
115
|
+
location,
|
|
116
|
+
tag: "pre",
|
|
117
|
+
type: "fence_open"
|
|
118
|
+
}));
|
|
119
|
+
result.push(new ast.Node({
|
|
120
|
+
attributes: {},
|
|
121
|
+
content: mdNode.content.trim(),
|
|
122
|
+
location,
|
|
123
|
+
tag: "",
|
|
124
|
+
type: "text"
|
|
125
|
+
}));
|
|
126
|
+
result.push(new ast.Node({
|
|
127
|
+
attributes: {},
|
|
128
|
+
content: "",
|
|
129
|
+
location: location.withLine((mdNode.map || [0, 0])[1]),
|
|
130
|
+
tag: "/pre",
|
|
131
|
+
type: "fence_close"
|
|
132
|
+
}));
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
standardizeFence(mdNode, location) {
|
|
136
|
+
const result = new ast.NodeList();
|
|
137
|
+
result.push(new ast.Node({
|
|
138
|
+
attributes: standardizeMarkdownItAttributes(mdNode.attrs),
|
|
139
|
+
content: "",
|
|
140
|
+
location,
|
|
141
|
+
tag: "pre",
|
|
142
|
+
type: "fence_open"
|
|
143
|
+
}));
|
|
144
|
+
result.push(new ast.Node({
|
|
145
|
+
attributes: {},
|
|
146
|
+
content: mdNode.content.trim(),
|
|
147
|
+
location: location.withLine(location.line + 1), // content of fenced blocks has to start on the next line
|
|
148
|
+
tag: "",
|
|
149
|
+
type: "text"
|
|
150
|
+
}));
|
|
151
|
+
result.push(new ast.Node({
|
|
152
|
+
attributes: {},
|
|
153
|
+
content: "",
|
|
154
|
+
location: location.withLine((mdNode.map || [0, 0])[1]),
|
|
155
|
+
tag: "/pre",
|
|
156
|
+
type: "fence_close"
|
|
157
|
+
}));
|
|
158
|
+
return result;
|
|
159
|
+
}
|
|
160
|
+
standardizeHeadingClose(node, location) {
|
|
161
|
+
const result = new ast.NodeList();
|
|
162
|
+
result.push(new ast.Node({
|
|
163
|
+
attributes: standardizeMarkdownItAttributes(node.attrs),
|
|
164
|
+
content: "",
|
|
165
|
+
location,
|
|
166
|
+
tag: ("/" + node.tag),
|
|
167
|
+
type: `${node.tag}_close`
|
|
168
|
+
}));
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
standardizeHeadingOpen(mdNode, location) {
|
|
172
|
+
const result = new ast.NodeList();
|
|
173
|
+
result.push(new ast.Node({
|
|
174
|
+
attributes: standardizeMarkdownItAttributes(mdNode.attrs),
|
|
175
|
+
content: "",
|
|
176
|
+
location,
|
|
177
|
+
tag: mdNode.tag,
|
|
178
|
+
type: `${mdNode.tag}_open`
|
|
179
|
+
}));
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
standardizeHTMLBlock(mdNode, ont, location) {
|
|
183
|
+
const result = new ast.NodeList();
|
|
184
|
+
const parsed = this.htmlParser.parse(mdNode.content, location);
|
|
185
|
+
for (const node of parsed) {
|
|
186
|
+
if (node.type.endsWith("_open")) {
|
|
187
|
+
ont.open(node, (mdNode.map || [0, 0])[1]);
|
|
188
|
+
}
|
|
189
|
+
if (node.type.endsWith("_close")) {
|
|
190
|
+
ont.close(node.type, location);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
result.push(...parsed);
|
|
194
|
+
return result;
|
|
195
|
+
}
|
|
196
|
+
standardizeImageNode(mdNode, location) {
|
|
197
|
+
const result = new ast.NodeList();
|
|
198
|
+
const attributes = standardizeMarkdownItAttributes(mdNode.attrs);
|
|
199
|
+
for (const childNode of mdNode.children || []) {
|
|
200
|
+
attributes.alt += childNode.content;
|
|
201
|
+
}
|
|
202
|
+
result.push(new ast.Node({
|
|
203
|
+
attributes,
|
|
204
|
+
content: "",
|
|
205
|
+
location,
|
|
206
|
+
tag: "img",
|
|
207
|
+
type: "image"
|
|
208
|
+
}));
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
/** Returns the standardized version of the given MarkdownIt node */
|
|
212
|
+
standardizeNode(mdNode, location, ont) {
|
|
213
|
+
// ignore empty text nodes
|
|
214
|
+
// to avoid having to deal with this edge case later
|
|
215
|
+
if (mdNode.type === "text" && mdNode.content === "") {
|
|
216
|
+
return new ast.NodeList();
|
|
217
|
+
}
|
|
218
|
+
// special handling for headings to make them compatible with their HTML counterparts:
|
|
219
|
+
// - they get renamed from heading_open to h1_open etc
|
|
220
|
+
if (mdNode.type === "heading_open") {
|
|
221
|
+
return this.standardizeHeadingOpen(mdNode, location);
|
|
222
|
+
}
|
|
223
|
+
// special handling for headings to make them compatible with their HTML counterparts:
|
|
224
|
+
// - they get renamed from heading_close to h1_close etc
|
|
225
|
+
if (mdNode.type === "heading_close") {
|
|
226
|
+
return this.standardizeHeadingClose(mdNode, location);
|
|
227
|
+
}
|
|
228
|
+
// special handling for embedded code blocks to be compatible with its HTML counterpart:
|
|
229
|
+
// - it is unrolled to code_open, text, code_close
|
|
230
|
+
if (mdNode.type === "code_inline") {
|
|
231
|
+
return this.standardizeCodeInline(mdNode, location);
|
|
232
|
+
}
|
|
233
|
+
// special handling for fenced code blocks to be compatible with its HTML counterpart:
|
|
234
|
+
// - it is unrolled to fence_open, text, fence_close
|
|
235
|
+
// - the content starts on the line below the opening ```
|
|
236
|
+
if (mdNode.type === "fence") {
|
|
237
|
+
return this.standardizeFence(mdNode, location);
|
|
238
|
+
}
|
|
239
|
+
// special handling for indented code blocks to be compatible with their HTML counterpart:
|
|
240
|
+
// - they are expanded to fence_open, text, fence_close
|
|
241
|
+
if (mdNode.type === "code_block") {
|
|
242
|
+
return this.standardizeEmbeddedCodeblock(mdNode, location);
|
|
243
|
+
}
|
|
244
|
+
// handle embedded HTML
|
|
245
|
+
if (mdNode.type === "html_inline" || mdNode.type === "html_block") {
|
|
246
|
+
if (this.closingTagParser.isClosingTag(mdNode.content)) {
|
|
247
|
+
return this.standardizeClosingHTMLTag(mdNode, ont, location);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
return this.standardizeHTMLBlock(mdNode, ont, location);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// handle opening tags
|
|
254
|
+
if (mdNode.type.endsWith("_open")) {
|
|
255
|
+
return this.standardizeOpeningNode(mdNode, location, ont);
|
|
256
|
+
}
|
|
257
|
+
// handle closing tags
|
|
258
|
+
if (mdNode.type.endsWith("_close")) {
|
|
259
|
+
return this.standardizeClosingNode(mdNode, location, ont);
|
|
260
|
+
}
|
|
261
|
+
// handle text nodes
|
|
262
|
+
if (mdNode.type === "text") {
|
|
263
|
+
return this.standardizeTextNode(mdNode, location);
|
|
264
|
+
}
|
|
265
|
+
// handle stand-alone tags
|
|
266
|
+
if (this.tagMapper.isStandaloneTag(mdNode.tag)) {
|
|
267
|
+
return this.standizeStandaloneTag(mdNode, location);
|
|
268
|
+
}
|
|
269
|
+
throw new Error(`unknown MarkdownIt node: ${util.inspect(mdNode, false, Infinity)}`);
|
|
270
|
+
}
|
|
271
|
+
standardizeOpeningNode(mdNode, location, ont) {
|
|
272
|
+
const result = new ast.NodeList();
|
|
273
|
+
result.push(new ast.Node({
|
|
274
|
+
attributes: standardizeMarkdownItAttributes(mdNode.attrs),
|
|
275
|
+
content: mdNode.content.trim(),
|
|
276
|
+
location,
|
|
277
|
+
tag: this.tagMapper.tagForType(mdNode.type),
|
|
278
|
+
type: mdNode.type
|
|
279
|
+
}));
|
|
280
|
+
ont.open(result[0], (mdNode.map || [0, 0])[1]);
|
|
281
|
+
return result;
|
|
282
|
+
}
|
|
283
|
+
standardizeTextNode(mdNode, location) {
|
|
284
|
+
const result = new ast.NodeList();
|
|
285
|
+
result.push(new ast.Node({
|
|
286
|
+
attributes: standardizeMarkdownItAttributes(mdNode.attrs),
|
|
287
|
+
content: mdNode.content.trim(),
|
|
288
|
+
location,
|
|
289
|
+
tag: this.tagMapper.tagForType(mdNode.type),
|
|
290
|
+
type: mdNode.type
|
|
291
|
+
}));
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
294
|
+
standizeStandaloneTag(mdNode, location) {
|
|
295
|
+
const result = new ast.NodeList();
|
|
296
|
+
result.push(new ast.Node({
|
|
297
|
+
attributes: standardizeMarkdownItAttributes(mdNode.attrs),
|
|
298
|
+
content: mdNode.content.trim(),
|
|
299
|
+
location,
|
|
300
|
+
tag: mdNode.tag,
|
|
301
|
+
type: mdNode.type
|
|
302
|
+
}));
|
|
303
|
+
return result;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/** returns the given attributes from a MarkdownIt node in the standard AST format */
|
|
307
|
+
export function standardizeMarkdownItAttributes(attrs) {
|
|
308
|
+
const result = {};
|
|
309
|
+
if (attrs) {
|
|
310
|
+
for (const [name, value] of attrs) {
|
|
311
|
+
result[name] = value;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return result;
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=md-parser.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as ast from "../../ast/index.js";
|
|
2
|
+
import * as files from "../../filesystem/index.js";
|
|
3
|
+
/** helps find open MarkdownIt AST nodes */
|
|
4
|
+
export declare class OpenNodeTracker {
|
|
5
|
+
private readonly entries;
|
|
6
|
+
constructor();
|
|
7
|
+
/** closes the corresponding open ast.Node and returns its endLine */
|
|
8
|
+
close(type: ast.NodeType, location: files.Location): number;
|
|
9
|
+
/** returns whether a node with the given type is open */
|
|
10
|
+
has(type: ast.NodeType): boolean;
|
|
11
|
+
/** registers an opening MarkdownIt AST node */
|
|
12
|
+
open(node: ast.Node, endLine: number): void;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=open-node-tracker.d.ts.map
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { UserError } from "../../errors/user-error.js";
|
|
2
|
+
/** helps find open MarkdownIt AST nodes */
|
|
3
|
+
export class OpenNodeTracker {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.entries = [];
|
|
6
|
+
}
|
|
7
|
+
/** closes the corresponding open ast.Node and returns its endLine */
|
|
8
|
+
close(type, location) {
|
|
9
|
+
const openType = type.replace("_close", "_open");
|
|
10
|
+
for (let i = this.entries.length - 1; i >= 0; i--) {
|
|
11
|
+
if (this.entries[i].node.type === openType) {
|
|
12
|
+
const result = this.entries[i].endLine;
|
|
13
|
+
this.entries.splice(i, 1);
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
throw new UserError(`No opening node '${openType}' found for closing node '${type}'`, `Node </${openType}> does not have a corresponding opening node`, location);
|
|
18
|
+
}
|
|
19
|
+
/** returns whether a node with the given type is open */
|
|
20
|
+
has(type) {
|
|
21
|
+
for (const entry of this.entries) {
|
|
22
|
+
if (entry.node.type === type) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
/** registers an opening MarkdownIt AST node */
|
|
29
|
+
open(node, endLine) {
|
|
30
|
+
this.entries.push({ endLine, node });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=open-node-tracker.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as ast from "../../ast/index.js";
|
|
2
|
+
import * as files from "../../filesystem/index.js";
|
|
3
|
+
/** returns the standard AST for the Markdown files given as paths relative to the given sourceDir */
|
|
4
|
+
export declare function parse(filenames: files.FullFilePath[], sourceDir: files.SourceDir): Promise<ast.NodeList[]>;
|
|
5
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { promises as fs } from "fs";
|
|
2
|
+
import { MarkdownParser } from "./md-parser.js";
|
|
3
|
+
/** returns the standard AST for the Markdown files given as paths relative to the given sourceDir */
|
|
4
|
+
export async function parse(filenames, sourceDir) {
|
|
5
|
+
const result = [];
|
|
6
|
+
const parser = new MarkdownParser();
|
|
7
|
+
for (const filename of filenames) {
|
|
8
|
+
const content = await fs.readFile(sourceDir.joinStr(filename.platformified()), {
|
|
9
|
+
encoding: "utf8"
|
|
10
|
+
});
|
|
11
|
+
result.push(parser.parse(content, sourceDir, filename));
|
|
12
|
+
}
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as ast from "../ast/node.js";
|
|
2
|
+
/**
|
|
3
|
+
* TagMapper maps MarkdownIt node types to HTML tags and vice versa.
|
|
4
|
+
*
|
|
5
|
+
* MarkdownIt node types: bold_open, bold_close, image, explicitly
|
|
6
|
+
* Tag types: "b", "/b", "img", etc
|
|
7
|
+
*/
|
|
8
|
+
export declare class TagMapper {
|
|
9
|
+
/** tags that have opening and closing versions */
|
|
10
|
+
private static readonly OPEN_CLOSE_MAPPINGS;
|
|
11
|
+
/** tags that stand alone, i.e. have no opening and closing versions */
|
|
12
|
+
private static readonly STANDALONE_MAPPINGS;
|
|
13
|
+
/** maps HTML tag names to their corresponding MarkdownIt types */
|
|
14
|
+
private readonly tagTypeMappings;
|
|
15
|
+
/** maps MarkdownIt types to their corresponding HTML tags */
|
|
16
|
+
private readonly typeTagMappings;
|
|
17
|
+
constructor();
|
|
18
|
+
isOpenCloseTag(tagName: ast.NodeTag): boolean;
|
|
19
|
+
isStandaloneTag(tagName: string): boolean;
|
|
20
|
+
/** Returns the opening MarkdownIt type for the given HTML tag. */
|
|
21
|
+
openingTypeForTag(tagName: ast.NodeTag, attributes: ast.NodeAttributes): ast.NodeType;
|
|
22
|
+
/** Returns the HTML tag for the given MarkdownIt type. */
|
|
23
|
+
tagForType(type: ast.NodeType): ast.NodeTag;
|
|
24
|
+
/** Returns the Markdown node type for the given HTML tag. */
|
|
25
|
+
typeForTag(tag: ast.NodeTag, attributes: ast.NodeAttributes): ast.NodeType;
|
|
26
|
+
/** Calculates the mappings from HTML tags to MarkdownIt types */
|
|
27
|
+
private createTagTypeMappings;
|
|
28
|
+
/** Calculates the mappings from MarkdownIt types to HTML tags */
|
|
29
|
+
private createTypeTagMappings;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=tag-mapper.d.ts.map
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TagMapper maps MarkdownIt node types to HTML tags and vice versa.
|
|
3
|
+
*
|
|
4
|
+
* MarkdownIt node types: bold_open, bold_close, image, explicitly
|
|
5
|
+
* Tag types: "b", "/b", "img", etc
|
|
6
|
+
*/
|
|
7
|
+
export class TagMapper {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.typeTagMappings = this.createTypeTagMappings();
|
|
10
|
+
this.tagTypeMappings = this.createTagTypeMappings();
|
|
11
|
+
}
|
|
12
|
+
isOpenCloseTag(tagName) {
|
|
13
|
+
if (tagName === "") {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
return !this.isStandaloneTag(tagName);
|
|
17
|
+
}
|
|
18
|
+
isStandaloneTag(tagName) {
|
|
19
|
+
for (const value of TagMapper.STANDALONE_MAPPINGS.values()) {
|
|
20
|
+
if (value === tagName) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
/** Returns the opening MarkdownIt type for the given HTML tag. */
|
|
27
|
+
openingTypeForTag(tagName, attributes) {
|
|
28
|
+
return this.typeForTag(tagName.replace(/^\//, ""), attributes);
|
|
29
|
+
}
|
|
30
|
+
/** Returns the HTML tag for the given MarkdownIt type. */
|
|
31
|
+
tagForType(type) {
|
|
32
|
+
// handle text tag
|
|
33
|
+
if (type === "text") {
|
|
34
|
+
return "";
|
|
35
|
+
}
|
|
36
|
+
// handle explicitly mapped values
|
|
37
|
+
const result = this.typeTagMappings.get(type);
|
|
38
|
+
if (result) {
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
// handle generic opening tag
|
|
42
|
+
if (type.endsWith("_open")) {
|
|
43
|
+
return type.substring(0, type.length - 5);
|
|
44
|
+
}
|
|
45
|
+
// handle generic closing tag
|
|
46
|
+
if (type.endsWith("_close")) {
|
|
47
|
+
return ("/" + type.substring(0, type.length - 6));
|
|
48
|
+
}
|
|
49
|
+
// handle generic stand-alone tag
|
|
50
|
+
return type;
|
|
51
|
+
}
|
|
52
|
+
/** Returns the Markdown node type for the given HTML tag. */
|
|
53
|
+
typeForTag(tag, attributes) {
|
|
54
|
+
// distinguish anchors from links
|
|
55
|
+
if (tag === "a" && !attributes.href) {
|
|
56
|
+
return "anchor_open";
|
|
57
|
+
}
|
|
58
|
+
if (tag === "/a" && !attributes.href) {
|
|
59
|
+
return "anchor_close";
|
|
60
|
+
}
|
|
61
|
+
// check for known tags
|
|
62
|
+
const result = this.tagTypeMappings.get(tag);
|
|
63
|
+
if (result) {
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
// here it is an unknown tag, we assume it is opening-closing
|
|
67
|
+
if (tag.startsWith("/")) {
|
|
68
|
+
return (tag.substring(1) + "_close");
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
return (tag + "_open");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** Calculates the mappings from HTML tags to MarkdownIt types */
|
|
75
|
+
createTagTypeMappings() {
|
|
76
|
+
const result = new Map();
|
|
77
|
+
for (const [type, tag] of this.typeTagMappings) {
|
|
78
|
+
result.set(tag, type);
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
/** Calculates the mappings from MarkdownIt types to HTML tags */
|
|
83
|
+
createTypeTagMappings() {
|
|
84
|
+
const result = new Map();
|
|
85
|
+
for (const [type, tag] of TagMapper.OPEN_CLOSE_MAPPINGS) {
|
|
86
|
+
result.set((type + "_open"), tag);
|
|
87
|
+
result.set((type + "_close"), ("/" + tag));
|
|
88
|
+
}
|
|
89
|
+
for (const [type, tag] of TagMapper.STANDALONE_MAPPINGS) {
|
|
90
|
+
result.set(type, tag);
|
|
91
|
+
}
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/** tags that have opening and closing versions */
|
|
96
|
+
TagMapper.OPEN_CLOSE_MAPPINGS = new Map([
|
|
97
|
+
["bold", "b"],
|
|
98
|
+
["bullet_list", "ul"],
|
|
99
|
+
["fence", "pre"],
|
|
100
|
+
["italic", "i"],
|
|
101
|
+
["link", "a"],
|
|
102
|
+
["list_item", "li"],
|
|
103
|
+
["ordered_list", "ol"],
|
|
104
|
+
["paragraph", "p"]
|
|
105
|
+
]);
|
|
106
|
+
/** tags that stand alone, i.e. have no opening and closing versions */
|
|
107
|
+
TagMapper.STANDALONE_MAPPINGS = new Map([
|
|
108
|
+
["hr", "hr"],
|
|
109
|
+
["image", "img"],
|
|
110
|
+
["linebreak", "br"]
|
|
111
|
+
]);
|
|
112
|
+
//# sourceMappingURL=tag-mapper.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Activity } from "../activities/index.js";
|
|
2
|
+
import { Command } from "../commands/index.js";
|
|
3
|
+
import * as events from "../events/index.js";
|
|
4
|
+
import { StopWatch } from "./stopwatch.js";
|
|
5
|
+
/** Statistics about a run of Text-Runner */
|
|
6
|
+
interface ActivityResult {
|
|
7
|
+
readonly activity?: Activity;
|
|
8
|
+
readonly error?: Error;
|
|
9
|
+
readonly finalName?: string;
|
|
10
|
+
readonly message?: string;
|
|
11
|
+
readonly output?: string;
|
|
12
|
+
readonly status: events.ResultStatus;
|
|
13
|
+
}
|
|
14
|
+
/** ActivityCollector provides statistics about the Text-Runner command it observes. */
|
|
15
|
+
export declare class ActivityCollector {
|
|
16
|
+
activities: ActivityResult[];
|
|
17
|
+
stopWatch: StopWatch;
|
|
18
|
+
constructor(command: Command);
|
|
19
|
+
onResult(result: events.Result): void;
|
|
20
|
+
results(): ActivityResults;
|
|
21
|
+
}
|
|
22
|
+
export declare class ActivityResults extends Array<ActivityResult> {
|
|
23
|
+
readonly duration: string;
|
|
24
|
+
constructor(results: Array<ActivityResult>, duration: string);
|
|
25
|
+
errorCount(): number;
|
|
26
|
+
errors(): Error[];
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=activity-collector.d.ts.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { StopWatch } from "./stopwatch.js";
|
|
2
|
+
/** ActivityCollector provides statistics about the Text-Runner command it observes. */
|
|
3
|
+
export class ActivityCollector {
|
|
4
|
+
constructor(command) {
|
|
5
|
+
this.activities = [];
|
|
6
|
+
this.stopWatch = new StopWatch();
|
|
7
|
+
command.on("result", this.onResult.bind(this));
|
|
8
|
+
}
|
|
9
|
+
onResult(result) {
|
|
10
|
+
this.activities.push(result);
|
|
11
|
+
}
|
|
12
|
+
results() {
|
|
13
|
+
return new ActivityResults(this.activities, this.stopWatch.duration());
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class ActivityResults extends Array {
|
|
17
|
+
constructor(results, duration) {
|
|
18
|
+
super();
|
|
19
|
+
this.push(...results);
|
|
20
|
+
this.duration = duration;
|
|
21
|
+
}
|
|
22
|
+
errorCount() {
|
|
23
|
+
return this.errors().length;
|
|
24
|
+
}
|
|
25
|
+
errors() {
|
|
26
|
+
const result = [];
|
|
27
|
+
for (const res of this) {
|
|
28
|
+
if (res.error) {
|
|
29
|
+
result.push(res.error);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=activity-collector.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./activity-collector.js";
|
|
2
|
+
export * from "./parallel.js";
|
|
3
|
+
export * from "./sequential.js";
|
|
4
|
+
export * from "./stopwatch.js";
|
|
5
|
+
/** LogFn defines the signature of the "log" function available to actions */
|
|
6
|
+
export type LogFn = (message?: any, ...optionalParams: any[]) => void;
|
|
7
|
+
/** signature of the method that allows actions to set a refined name for the current test step */
|
|
8
|
+
export type RefineNameFn = (newName: string) => void;
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RefineNameFn } from "./index.js";
|
|
2
|
+
/** allows refining the current name of a test step */
|
|
3
|
+
export declare class NameRefiner {
|
|
4
|
+
private name;
|
|
5
|
+
constructor(name: string);
|
|
6
|
+
/** returns the refined name */
|
|
7
|
+
finalName(): string;
|
|
8
|
+
/** returns a function that can be called to refine the name */
|
|
9
|
+
refineFn(): RefineNameFn;
|
|
10
|
+
/** updates the currently stored name to the given name */
|
|
11
|
+
private refineName;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=name-refiner.d.ts.map
|