webforai 3.0.0 → 4.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 +47 -5
- package/dist/bin.js +3109 -490
- package/dist/cjs/detect-client-shell.js +78 -0
- package/dist/cjs/extract-mdast.js +58 -0
- package/dist/cjs/extract-meta-refresh.js +71 -0
- package/dist/cjs/extractors/index.js +5 -0
- package/dist/cjs/extractors/lib/block-features.js +465 -0
- package/dist/cjs/extractors/lib/block-model.generated.js +45 -0
- package/dist/cjs/extractors/lib/block-model.js +72 -0
- package/dist/cjs/extractors/lib/blocks.js +212 -0
- package/dist/cjs/extractors/lib/code-tabs.js +191 -0
- package/dist/cjs/extractors/lib/constants.js +1 -1
- package/dist/cjs/extractors/lib/layout-tables.js +123 -0
- package/dist/cjs/extractors/lib/sanitize.js +146 -26
- package/dist/cjs/extractors/lib/takumi-signal.js +76 -0
- package/dist/cjs/extractors/lib/ui-chrome.js +7 -0
- package/dist/cjs/extractors/presets/auto.js +3 -3
- package/dist/cjs/extractors/presets/kiwame.js +231 -0
- package/dist/cjs/extractors/presets/takumi.js +34 -3
- package/dist/cjs/html-to-markdown.js +58 -4
- package/dist/cjs/html-to-mdast.js +4 -3
- package/dist/cjs/index.js +16 -0
- package/dist/cjs/link-replacer.js +19 -13
- package/dist/cjs/loaders/cf-puppeteer.js +14 -7
- package/dist/cjs/loaders/fetch.js +14 -2
- package/dist/cjs/loaders/playwright.js +32 -30
- package/dist/cjs/loaders/puppeteer.js +14 -7
- package/dist/cjs/md-splitter.js +24 -11
- package/dist/cjs/mdast-handlers/custom-code-handler.js +32 -9
- package/dist/cjs/mdast-handlers/custom-div-handler.js +14 -35
- package/dist/cjs/mdast-handlers/custom-img-handler.js +10 -1
- package/dist/cjs/mdast-handlers/custom-table-handler.js +18 -1
- package/dist/cjs/mdast-handlers/definition-list-handler.js +17 -6
- package/dist/cjs/mdast-handlers/table-cell-flatten.js +195 -0
- package/dist/cjs/mdast-handlers/twoslash.js +71 -0
- package/dist/cjs/mdast-to-markdown.js +2 -5
- package/dist/cjs/metadata/index.js +4 -3
- package/dist/cjs/normalize/index.js +11 -2
- package/dist/cjs/platform/client.js +73 -16
- package/dist/cjs/platform/index.js +4 -0
- package/dist/cjs/platform/types.js +7 -1
- package/dist/cjs/utils/hast-fast.js +1 -1
- package/dist/cjs/utils/parse-html.js +113 -0
- package/dist/cjs/utils/pre-text.js +104 -0
- package/dist/detect-client-shell.js +53 -0
- package/dist/extract-mdast.js +58 -0
- package/dist/extract-meta-refresh.js +47 -0
- package/dist/extractors/index.js +3 -0
- package/dist/extractors/lib/block-features.js +437 -0
- package/dist/extractors/lib/block-model.generated.js +21 -0
- package/dist/extractors/lib/block-model.js +48 -0
- package/dist/extractors/lib/blocks.js +185 -0
- package/dist/extractors/lib/code-tabs.js +168 -0
- package/dist/extractors/lib/constants.js +1 -1
- package/dist/extractors/lib/layout-tables.js +99 -0
- package/dist/extractors/lib/sanitize.js +144 -26
- package/dist/extractors/lib/takumi-signal.js +53 -0
- package/dist/extractors/lib/ui-chrome.js +5 -0
- package/dist/extractors/presets/auto.js +3 -3
- package/dist/extractors/presets/kiwame.js +206 -0
- package/dist/extractors/presets/takumi.js +34 -3
- package/dist/html-to-markdown.js +57 -4
- package/dist/html-to-mdast.js +4 -3
- package/dist/index.js +18 -0
- package/dist/link-replacer.js +19 -13
- package/dist/loaders/cf-puppeteer.js +15 -8
- package/dist/loaders/fetch.js +14 -2
- package/dist/loaders/playwright.js +32 -30
- package/dist/loaders/puppeteer.js +15 -8
- package/dist/md-splitter.js +24 -11
- package/dist/mdast-handlers/custom-code-handler.js +30 -9
- package/dist/mdast-handlers/custom-div-handler.js +14 -35
- package/dist/mdast-handlers/custom-img-handler.js +10 -1
- package/dist/mdast-handlers/custom-table-handler.js +19 -2
- package/dist/mdast-handlers/definition-list-handler.js +17 -6
- package/dist/mdast-handlers/table-cell-flatten.js +170 -0
- package/dist/mdast-handlers/twoslash.js +48 -0
- package/dist/mdast-to-markdown.js +2 -5
- package/dist/metadata/index.js +4 -3
- package/dist/normalize/index.js +12 -2
- package/dist/platform/client.js +73 -16
- package/dist/platform/index.js +4 -0
- package/dist/platform/types.js +5 -1
- package/dist/types/cli/bin.js.map +1 -1
- package/dist/types/cli/commands/jobs/files.d.ts +28 -0
- package/dist/types/cli/commands/jobs/files.js.map +1 -0
- package/dist/types/cli/commands/jobs/llms-txt.d.ts +33 -0
- package/dist/types/cli/commands/jobs/llms-txt.js.map +1 -0
- package/dist/types/cli/commands/jobs/options.d.ts +58 -0
- package/dist/types/cli/commands/jobs/options.js.map +1 -0
- package/dist/types/cli/commands/jobs/run.d.ts +44 -0
- package/dist/types/cli/commands/jobs/run.js.map +1 -0
- package/dist/types/cli/commands/skill/content.js.map +1 -1
- package/dist/types/cli/commands/webforai/interactive.d.ts +1 -1
- package/dist/types/cli/commands/webforai/interactive.js.map +1 -1
- package/dist/types/cli/commands/webforai/options.d.ts +9 -2
- package/dist/types/cli/commands/webforai/options.js.map +1 -1
- package/dist/types/cli/commands/webforai/run.js.map +1 -1
- package/dist/types/cli/constants.d.ts +3 -1
- package/dist/types/cli/constants.js.map +1 -1
- package/dist/types/cli/utils.d.ts +8 -1
- package/dist/types/cli/utils.js.map +1 -1
- package/dist/types/detect-client-shell.d.ts +24 -0
- package/dist/types/detect-client-shell.js.map +1 -0
- package/dist/types/extract-mdast.js.map +1 -1
- package/dist/types/extract-meta-refresh.d.ts +29 -0
- package/dist/types/extract-meta-refresh.js.map +1 -0
- package/dist/types/extractors/index.d.ts +1 -0
- package/dist/types/extractors/index.js.map +1 -1
- package/dist/types/extractors/lib/block-features.d.ts +43 -0
- package/dist/types/extractors/lib/block-features.js.map +1 -0
- package/dist/types/extractors/lib/block-model.d.ts +28 -0
- package/dist/types/extractors/lib/block-model.generated.d.ts +5 -0
- package/dist/types/extractors/lib/block-model.generated.js.map +1 -0
- package/dist/types/extractors/lib/block-model.js.map +1 -0
- package/dist/types/extractors/lib/blocks.d.ts +53 -0
- package/dist/types/extractors/lib/blocks.js.map +1 -0
- package/dist/types/extractors/lib/code-tabs.d.ts +30 -0
- package/dist/types/extractors/lib/code-tabs.js.map +1 -0
- package/dist/types/extractors/lib/constants.js.map +1 -1
- package/dist/types/extractors/lib/layout-tables.d.ts +17 -0
- package/dist/types/extractors/lib/layout-tables.js.map +1 -0
- package/dist/types/extractors/lib/sanitize.d.ts +33 -3
- package/dist/types/extractors/lib/sanitize.js.map +1 -1
- package/dist/types/extractors/lib/takumi-signal.d.ts +12 -0
- package/dist/types/extractors/lib/takumi-signal.js.map +1 -0
- package/dist/types/extractors/lib/ui-chrome.d.ts +8 -0
- package/dist/types/extractors/lib/ui-chrome.js.map +1 -1
- package/dist/types/extractors/presets/auto.d.ts +6 -1
- package/dist/types/extractors/presets/auto.js.map +1 -1
- package/dist/types/extractors/presets/kiwame.d.ts +31 -0
- package/dist/types/extractors/presets/kiwame.js.map +1 -0
- package/dist/types/extractors/presets/takumi.js.map +1 -1
- package/dist/types/html-to-markdown.d.ts +9 -0
- package/dist/types/html-to-markdown.js.map +1 -1
- package/dist/types/html-to-mdast.js.map +1 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/link-replacer.d.ts +3 -1
- package/dist/types/link-replacer.js.map +1 -1
- package/dist/types/loaders/cf-puppeteer.js.map +1 -1
- package/dist/types/loaders/fetch.d.ts +4 -0
- package/dist/types/loaders/fetch.js.map +1 -1
- package/dist/types/loaders/playwright.js.map +1 -1
- package/dist/types/loaders/puppeteer.js.map +1 -1
- package/dist/types/md-splitter.d.ts +1 -1
- package/dist/types/md-splitter.js.map +1 -1
- package/dist/types/mdast-handlers/custom-code-handler.d.ts +9 -0
- package/dist/types/mdast-handlers/custom-code-handler.js.map +1 -1
- package/dist/types/mdast-handlers/custom-div-handler.js.map +1 -1
- package/dist/types/mdast-handlers/custom-img-handler.js.map +1 -1
- package/dist/types/mdast-handlers/custom-table-handler.js.map +1 -1
- package/dist/types/mdast-handlers/definition-list-handler.d.ts +0 -11
- package/dist/types/mdast-handlers/definition-list-handler.js.map +1 -1
- package/dist/types/mdast-handlers/table-cell-flatten.d.ts +18 -0
- package/dist/types/mdast-handlers/table-cell-flatten.js.map +1 -0
- package/dist/types/mdast-handlers/twoslash.d.ts +14 -0
- package/dist/types/mdast-handlers/twoslash.js.map +1 -0
- package/dist/types/mdast-to-markdown.js.map +1 -1
- package/dist/types/metadata/index.js.map +1 -1
- package/dist/types/normalize/index.js.map +1 -1
- package/dist/types/platform/client.d.ts +2 -1
- package/dist/types/platform/client.js.map +1 -1
- package/dist/types/platform/error.d.ts +5 -3
- package/dist/types/platform/error.js.map +1 -1
- package/dist/types/platform/fetch.d.ts +2 -0
- package/dist/types/platform/fetch.js.map +1 -1
- package/dist/types/platform/index.d.ts +1 -1
- package/dist/types/platform/index.js.map +1 -1
- package/dist/types/platform/types.d.ts +35 -6
- package/dist/types/platform/types.js.map +1 -1
- package/dist/types/utils/hast-fast.d.ts +1 -1
- package/dist/types/utils/hast-fast.js.map +1 -1
- package/dist/types/utils/parse-html.d.ts +33 -0
- package/dist/types/utils/parse-html.js.map +1 -0
- package/dist/types/utils/pre-text.d.ts +12 -0
- package/dist/types/utils/pre-text.js.map +1 -0
- package/dist/utils/hast-fast.js +1 -1
- package/dist/utils/parse-html.js +87 -0
- package/dist/utils/pre-text.js +81 -0
- package/package.json +18 -5
package/dist/md-splitter.js
CHANGED
|
@@ -3,15 +3,13 @@ import { mdastToMarkdown } from "./mdast-to-markdown.js";
|
|
|
3
3
|
import { chunk } from "./utils/common.js";
|
|
4
4
|
import { internalType, unwarpRoot, warpRoot } from "./utils/mdast-utils.js";
|
|
5
5
|
var PRIORITY_SPLITTERS = ["h1", "h2", "h3", "h4", "h5", "h6", "list", "table", "code"];
|
|
6
|
-
var
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
var _mdastSplitter = async (contents, checker, splitterGenerator) => {
|
|
12
|
-
const splitter = splitterGenerator.next().value;
|
|
6
|
+
var _mdastSplitter = async (contents, checker, priority, signal) => {
|
|
7
|
+
signal?.throwIfAborted();
|
|
8
|
+
const splitter = PRIORITY_SPLITTERS[priority];
|
|
13
9
|
const markdown = mdastToMarkdown(warpRoot(contents));
|
|
14
|
-
|
|
10
|
+
const accepted = await checker(markdown);
|
|
11
|
+
signal?.throwIfAborted();
|
|
12
|
+
if (accepted || contents.length === 1) {
|
|
15
13
|
return [contents];
|
|
16
14
|
}
|
|
17
15
|
const chunked = splitter ? contents.reduce((acc, content) => {
|
|
@@ -22,11 +20,26 @@ var _mdastSplitter = async (contents, checker, splitterGenerator) => {
|
|
|
22
20
|
acc[acc.length - 1].push(content);
|
|
23
21
|
return acc;
|
|
24
22
|
}, []) : chunk(contents, Math.ceil(contents.length / 2));
|
|
25
|
-
const splitting = chunked.map((chunk2) => _mdastSplitter(chunk2, checker,
|
|
23
|
+
const splitting = chunked.map((chunk2) => _mdastSplitter(chunk2, checker, priority + 1, signal));
|
|
26
24
|
return Promise.all(splitting).then((chunks) => chunks.flat());
|
|
27
25
|
};
|
|
28
|
-
var mdastSplitter = (mdast, checker,
|
|
29
|
-
|
|
26
|
+
var mdastSplitter = async (mdast, checker, options) => {
|
|
27
|
+
const signal = options?.signal;
|
|
28
|
+
if (!signal) {
|
|
29
|
+
return _mdastSplitter(unwarpRoot(mdast), checker, 0);
|
|
30
|
+
}
|
|
31
|
+
signal.throwIfAborted();
|
|
32
|
+
let onAbort = () => {
|
|
33
|
+
};
|
|
34
|
+
const aborted = new Promise((_, reject) => {
|
|
35
|
+
onAbort = () => reject(signal.reason);
|
|
36
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
37
|
+
});
|
|
38
|
+
try {
|
|
39
|
+
return await Promise.race([_mdastSplitter(unwarpRoot(mdast), checker, 0, signal), aborted]);
|
|
40
|
+
} finally {
|
|
41
|
+
signal.removeEventListener("abort", onAbort);
|
|
42
|
+
}
|
|
30
43
|
};
|
|
31
44
|
export {
|
|
32
45
|
mdastSplitter
|
|
@@ -1,20 +1,41 @@
|
|
|
1
1
|
// src/mdast-handlers/custom-code-handler.ts
|
|
2
|
-
import { toText } from "hast-util-to-text";
|
|
3
2
|
import { trimTrailingLines } from "trim-trailing-lines";
|
|
4
3
|
import { detectLanguage } from "../utils/detect-code-lang.js";
|
|
5
|
-
|
|
4
|
+
import { classList, isElement } from "../utils/hast-fast.js";
|
|
5
|
+
import { preText } from "../utils/pre-text.js";
|
|
6
|
+
import { cleanTwoslash } from "./twoslash.js";
|
|
7
|
+
var LANGUAGE_MATCH_REGEX = [/^language-(\S+)$/, /^highlight-source-(\S+)$/, /^CodeBlock--language-(\S+)$/];
|
|
8
|
+
var LANGUAGE_ATTRIBUTES = ["dataLanguage", "dataLang"];
|
|
9
|
+
var attributeLanguage = (element) => {
|
|
10
|
+
for (const name of LANGUAGE_ATTRIBUTES) {
|
|
11
|
+
const value = element.properties?.[name];
|
|
12
|
+
if (typeof value === "string" && /^[\w+#.-]+$/.test(value.trim()) && value.trim() !== "plaintext") {
|
|
13
|
+
return value.trim();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return void 0;
|
|
17
|
+
};
|
|
18
|
+
var codeLanguage = (...elements) => elements.flatMap(classList).map((className) => LANGUAGE_MATCH_REGEX.map((regex) => className.match(regex)).find(Boolean)?.[1]).find(Boolean) ?? elements.map(attributeLanguage).find(Boolean);
|
|
19
|
+
var codeMeta = (pre) => {
|
|
20
|
+
const title = pre.properties?.dataTitle;
|
|
21
|
+
if (typeof title !== "string") {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const clean = title.replace(/["\r\n]+/g, " ").trim();
|
|
25
|
+
return clean ? `title="${clean}"` : null;
|
|
26
|
+
};
|
|
6
27
|
var customCodeHandler = (state, node) => {
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
return match?.[1];
|
|
12
|
-
}).find((className) => className);
|
|
28
|
+
const twoslashLang = cleanTwoslash(node);
|
|
29
|
+
const code = node.children.find((child) => isElement(child) && child.tagName === "code");
|
|
30
|
+
const codeValue = trimTrailingLines(preText(node));
|
|
31
|
+
const classLang = twoslashLang || codeLanguage(...isElement(code) ? [code, node] : [node]);
|
|
13
32
|
const lang = classLang || detectLanguage(codeValue) || null;
|
|
14
|
-
const result = { type: "code", lang, meta:
|
|
33
|
+
const result = { type: "code", lang, meta: codeMeta(node), value: codeValue };
|
|
15
34
|
state.patch(node, result);
|
|
16
35
|
return result;
|
|
17
36
|
};
|
|
18
37
|
export {
|
|
38
|
+
codeLanguage,
|
|
39
|
+
codeMeta,
|
|
19
40
|
customCodeHandler
|
|
20
41
|
};
|
|
@@ -2,49 +2,28 @@
|
|
|
2
2
|
import { select } from "hast-util-select";
|
|
3
3
|
import { defaultHandlers } from "hast-util-to-mdast";
|
|
4
4
|
import { toString as hastToString } from "hast-util-to-string";
|
|
5
|
-
import { toText } from "hast-util-to-text";
|
|
6
5
|
import { trimTrailingLines } from "trim-trailing-lines";
|
|
7
6
|
import { detectLanguage } from "../utils/detect-code-lang.js";
|
|
7
|
+
import { classList, collectElements, isElement } from "../utils/hast-fast.js";
|
|
8
|
+
import { preText } from "../utils/pre-text.js";
|
|
9
|
+
import { codeLanguage, codeMeta } from "./custom-code-handler.js";
|
|
8
10
|
var CODE_BLOCK_REGEX = /highlight-source|language-|codegroup|codeblock|code-block/i;
|
|
9
11
|
var CODE_FILENAME_SELECTORS = "[class*='fileName'],[class*='fileName'],[class*='title'],[class*='Title']";
|
|
10
|
-
var LANGUAGE_MATCH_REGEX = [/language-(\w+)/, /highlight-source-(\w+)/, /CodeBlock--language-(\w+)/];
|
|
11
|
-
var findRecursive = (array, condition, maxDepth = 3) => {
|
|
12
|
-
if (maxDepth <= 0) {
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
for (const value of array) {
|
|
16
|
-
const result = condition(value);
|
|
17
|
-
if (Array.isArray(result)) {
|
|
18
|
-
return findRecursive(result, condition, maxDepth - 1);
|
|
19
|
-
}
|
|
20
|
-
if (result) {
|
|
21
|
-
return value;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return null;
|
|
25
|
-
};
|
|
26
12
|
var customDivHandler = (state, node) => {
|
|
27
|
-
const classNames =
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return child.children.filter((child2) => child2.type === "element");
|
|
36
|
-
});
|
|
37
|
-
if (codeBlock && classNames.some((className) => CODE_BLOCK_REGEX.test(className))) {
|
|
38
|
-
const codeBlockClassNames = codeBlock.type === "element" ? codeBlock.properties.className ?? [] : [];
|
|
39
|
-
const codeValue = trimTrailingLines(toText(codeBlock)).trim();
|
|
13
|
+
const classNames = classList(node);
|
|
14
|
+
if (!classNames.some((className) => CODE_BLOCK_REGEX.test(className))) {
|
|
15
|
+
return defaultHandlers.div(state, node);
|
|
16
|
+
}
|
|
17
|
+
const codeBlocks = collectElements(node, (element) => element.tagName === "pre");
|
|
18
|
+
const codeBlock = codeBlocks.length === 1 ? codeBlocks[0] : void 0;
|
|
19
|
+
if (codeBlock) {
|
|
20
|
+
const codeValue = trimTrailingLines(preText(codeBlock));
|
|
40
21
|
const filenameElement = select(CODE_FILENAME_SELECTORS, node);
|
|
41
22
|
const fileLang = filenameElement ? hastToString(filenameElement).match(/\.(\w+)$/)?.[1] : null;
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
return match?.[1];
|
|
45
|
-
}).find((className) => className);
|
|
23
|
+
const code = codeBlock.children.find((child) => isElement(child) && child.tagName === "code");
|
|
24
|
+
const classLang = codeLanguage(...isElement(code) ? [code, codeBlock, node] : [codeBlock, node]);
|
|
46
25
|
const lang = fileLang || classLang || detectLanguage(codeValue) || null;
|
|
47
|
-
const result = { type: "code", lang, meta:
|
|
26
|
+
const result = { type: "code", lang, meta: codeMeta(codeBlock), value: codeValue };
|
|
48
27
|
state.patch(node, result);
|
|
49
28
|
return result;
|
|
50
29
|
}
|
|
@@ -12,11 +12,20 @@ var hasNoUsableSource = (node) => {
|
|
|
12
12
|
}
|
|
13
13
|
return false;
|
|
14
14
|
};
|
|
15
|
+
var PLACEHOLDER_FILE = /^(?:[\w-]*[-_.])?placeholder[\w-]*\.(?:gif|png|svg|webp|jpe?g)$|^(?:spacer|blank|transparent|pixel)\.(?:gif|png)$/i;
|
|
16
|
+
var isUndescribedPlaceholder = (node) => {
|
|
17
|
+
if (stringProperty(node, "alt")?.trim() || stringProperty(node, "title")?.trim()) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const src = stringProperty(node, "src") ?? "";
|
|
21
|
+
const file = src.split(/[?#]/)[0].split("/").pop() ?? "";
|
|
22
|
+
return PLACEHOLDER_FILE.test(file);
|
|
23
|
+
};
|
|
15
24
|
var customImgHandler = (options) => (state, node) => {
|
|
16
25
|
if (options?.hideImage) {
|
|
17
26
|
return void 0;
|
|
18
27
|
}
|
|
19
|
-
if (hasNoUsableSource(node)) {
|
|
28
|
+
if (hasNoUsableSource(node) || isUndescribedPlaceholder(node)) {
|
|
20
29
|
return void 0;
|
|
21
30
|
}
|
|
22
31
|
const image = defaultHandlers.image(state, node);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// src/mdast-handlers/custom-table-handler.ts
|
|
2
2
|
import { defaultHandlers } from "hast-util-to-mdast";
|
|
3
3
|
import { toText } from "hast-util-to-text";
|
|
4
|
-
import { isElement, numericProperty, walk } from "../utils/hast-fast.js";
|
|
4
|
+
import { findElement, isElement, numericProperty, walk } from "../utils/hast-fast.js";
|
|
5
|
+
import { flattenTableCells, tableHasCodeSamples, unfoldTable } from "./table-cell-flatten.js";
|
|
5
6
|
var MAX_SPAN = 1e3;
|
|
6
7
|
var clampSpans = (node) => {
|
|
7
8
|
walk(node, (candidate) => {
|
|
@@ -16,6 +17,14 @@ var clampSpans = (node) => {
|
|
|
16
17
|
}
|
|
17
18
|
});
|
|
18
19
|
};
|
|
20
|
+
var startsWithHeaderRow = (table) => {
|
|
21
|
+
const row = findElement(table, (element) => element.tagName === "tr");
|
|
22
|
+
if (!row) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const cells = row.children.filter(isElement);
|
|
26
|
+
return cells.length > 0 && cells.every((cell) => cell.tagName === "th");
|
|
27
|
+
};
|
|
19
28
|
var customTableHandler = (options) => (state, node) => {
|
|
20
29
|
if (options?.asText) {
|
|
21
30
|
const paragraph = { type: "paragraph", children: [{ type: "text", value: toText(node) }] };
|
|
@@ -23,7 +32,15 @@ var customTableHandler = (options) => (state, node) => {
|
|
|
23
32
|
return paragraph;
|
|
24
33
|
}
|
|
25
34
|
clampSpans(node);
|
|
26
|
-
|
|
35
|
+
const result = defaultHandlers.table(state, node);
|
|
36
|
+
if (!result || Array.isArray(result) || result.type !== "table") {
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
if (tableHasCodeSamples(result)) {
|
|
40
|
+
return unfoldTable(result, startsWithHeaderRow(node));
|
|
41
|
+
}
|
|
42
|
+
flattenTableCells(result);
|
|
43
|
+
return result;
|
|
27
44
|
};
|
|
28
45
|
export {
|
|
29
46
|
customTableHandler
|
|
@@ -28,6 +28,20 @@ var hoistBoundaryWhitespace = (nodes) => {
|
|
|
28
28
|
}
|
|
29
29
|
return result;
|
|
30
30
|
};
|
|
31
|
+
var termsAndDefinitions = (parent) => {
|
|
32
|
+
const found = [];
|
|
33
|
+
for (const child of parent.children) {
|
|
34
|
+
if (child.type !== "element") {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (child.tagName === "dt" || child.tagName === "dd") {
|
|
38
|
+
found.push(child);
|
|
39
|
+
} else if (child.tagName === "div") {
|
|
40
|
+
found.push(...termsAndDefinitions(child));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return found;
|
|
44
|
+
};
|
|
31
45
|
var definitionListHandler = (state, node) => {
|
|
32
46
|
const items = [];
|
|
33
47
|
let current;
|
|
@@ -42,11 +56,7 @@ var definitionListHandler = (state, node) => {
|
|
|
42
56
|
items.push({ type: "listItem", spread: false, children: [heading, ...current.definitions] });
|
|
43
57
|
current = void 0;
|
|
44
58
|
};
|
|
45
|
-
for (const
|
|
46
|
-
if (child.type !== "element") {
|
|
47
|
-
continue;
|
|
48
|
-
}
|
|
49
|
-
const element = child;
|
|
59
|
+
for (const element of termsAndDefinitions(node)) {
|
|
50
60
|
if (element.tagName === "dt") {
|
|
51
61
|
if (current && current.definitions.length > 0) {
|
|
52
62
|
flush();
|
|
@@ -65,7 +75,8 @@ var definitionListHandler = (state, node) => {
|
|
|
65
75
|
}
|
|
66
76
|
flush();
|
|
67
77
|
if (items.length === 0) {
|
|
68
|
-
|
|
78
|
+
const fallback = state.toFlow(state.all(node));
|
|
79
|
+
return fallback.length > 0 ? fallback : void 0;
|
|
69
80
|
}
|
|
70
81
|
const result = { type: "list", ordered: false, spread: false, children: items };
|
|
71
82
|
state.patch(node, result);
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// src/mdast-handlers/table-cell-flatten.ts
|
|
2
|
+
var PHRASING_TYPES = /* @__PURE__ */ new Set([
|
|
3
|
+
"text",
|
|
4
|
+
"emphasis",
|
|
5
|
+
"strong",
|
|
6
|
+
"delete",
|
|
7
|
+
"inlineCode",
|
|
8
|
+
"link",
|
|
9
|
+
"linkReference",
|
|
10
|
+
"image",
|
|
11
|
+
"imageReference",
|
|
12
|
+
"html",
|
|
13
|
+
"footnoteReference",
|
|
14
|
+
"inlineMath"
|
|
15
|
+
]);
|
|
16
|
+
var PHRASING_PARENTS = /* @__PURE__ */ new Set(["emphasis", "strong", "delete", "link", "linkReference"]);
|
|
17
|
+
var lineBreak = () => ({ type: "html", value: "<br>" });
|
|
18
|
+
var needsFlattening = (nodes) => nodes.some((node) => {
|
|
19
|
+
if (node.type === "break") {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
if (!PHRASING_TYPES.has(node.type)) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
if ((node.type === "text" || node.type === "inlineCode") && node.value.includes("\n")) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
return PHRASING_PARENTS.has(node.type) && "children" in node && needsFlattening(node.children);
|
|
29
|
+
});
|
|
30
|
+
var CellBuilder = class _CellBuilder {
|
|
31
|
+
constructor() {
|
|
32
|
+
this.out = [];
|
|
33
|
+
this.#pendingBlock = false;
|
|
34
|
+
}
|
|
35
|
+
#pendingBlock;
|
|
36
|
+
/** Starts a new visual line when the previous block left content on the current one. */
|
|
37
|
+
block() {
|
|
38
|
+
const last = this.out.at(-1);
|
|
39
|
+
if (this.#pendingBlock && last && !(last.type === "html" && last.value === "<br>")) {
|
|
40
|
+
this.out.push(lineBreak());
|
|
41
|
+
}
|
|
42
|
+
this.#pendingBlock = true;
|
|
43
|
+
}
|
|
44
|
+
add(nodes) {
|
|
45
|
+
for (const node of nodes) {
|
|
46
|
+
this.#addOne(node);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
#addOne(node) {
|
|
50
|
+
switch (node.type) {
|
|
51
|
+
case "break":
|
|
52
|
+
this.out.push(lineBreak());
|
|
53
|
+
return;
|
|
54
|
+
case "text":
|
|
55
|
+
this.out.push({ type: "text", value: node.value.replace(/\s*\n\s*/g, " ") });
|
|
56
|
+
return;
|
|
57
|
+
case "inlineCode":
|
|
58
|
+
this.#codeLines(node.value);
|
|
59
|
+
return;
|
|
60
|
+
case "code":
|
|
61
|
+
this.block();
|
|
62
|
+
this.#codeLines(node.value);
|
|
63
|
+
return;
|
|
64
|
+
case "math":
|
|
65
|
+
this.block();
|
|
66
|
+
this.out.push({ type: "inlineMath", value: node.value.replace(/\s*\n\s*/g, " ") });
|
|
67
|
+
return;
|
|
68
|
+
case "list":
|
|
69
|
+
node.children.forEach((item, index) => {
|
|
70
|
+
this.block();
|
|
71
|
+
const marker = node.ordered ? `${(node.start ?? 1) + index}. ` : "- ";
|
|
72
|
+
this.out.push({ type: "text", value: marker });
|
|
73
|
+
this.#pendingBlock = false;
|
|
74
|
+
this.add(item.children);
|
|
75
|
+
});
|
|
76
|
+
return;
|
|
77
|
+
case "thematicBreak":
|
|
78
|
+
return;
|
|
79
|
+
default:
|
|
80
|
+
this.#addContainer(node);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
#addContainer(node) {
|
|
84
|
+
if (PHRASING_PARENTS.has(node.type) && "children" in node) {
|
|
85
|
+
const inner = new _CellBuilder();
|
|
86
|
+
inner.add(node.children);
|
|
87
|
+
this.out.push({ ...node, children: inner.out });
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (PHRASING_TYPES.has(node.type)) {
|
|
91
|
+
this.out.push(node);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if ("children" in node) {
|
|
95
|
+
this.block();
|
|
96
|
+
this.add(node.children);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
#codeLines(value) {
|
|
100
|
+
value.split("\n").forEach((line, index) => {
|
|
101
|
+
if (index > 0) {
|
|
102
|
+
this.out.push(lineBreak());
|
|
103
|
+
}
|
|
104
|
+
if (line.trim().length > 0) {
|
|
105
|
+
this.out.push({ type: "inlineCode", value: line });
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
var flattenTableCells = (table) => {
|
|
111
|
+
for (const row of table.children) {
|
|
112
|
+
for (const cell of row.children) {
|
|
113
|
+
if (!needsFlattening(cell.children)) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
const builder = new CellBuilder();
|
|
117
|
+
builder.add(cell.children);
|
|
118
|
+
cell.children = builder.out;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
var hasMultilineCode = (nodes) => nodes.some(
|
|
123
|
+
(node) => node.type === "code" && node.value.includes("\n") || "children" in node && hasMultilineCode(node.children)
|
|
124
|
+
);
|
|
125
|
+
var tableHasCodeSamples = (table) => table.children.some((row) => row.children.some((cell) => hasMultilineCode(cell.children)));
|
|
126
|
+
var unfoldTable = (table, hasHeader) => {
|
|
127
|
+
const [first, ...rest] = table.children;
|
|
128
|
+
const labelled = hasHeader && rest.length > 0;
|
|
129
|
+
const labels = labelled && first ? first.children.map((cell) => cell.children) : [];
|
|
130
|
+
const rows = labelled ? rest : table.children;
|
|
131
|
+
const out = [];
|
|
132
|
+
rows.forEach((row, rowIndex) => {
|
|
133
|
+
if (rowIndex > 0) {
|
|
134
|
+
out.push({ type: "thematicBreak" });
|
|
135
|
+
}
|
|
136
|
+
row.children.forEach((cell, cellIndex) => {
|
|
137
|
+
const label = labels[cellIndex];
|
|
138
|
+
if (label && label.length > 0) {
|
|
139
|
+
out.push({ type: "paragraph", children: [{ type: "strong", children: label }] });
|
|
140
|
+
}
|
|
141
|
+
out.push(...asBlocks(cell.children));
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
return out;
|
|
145
|
+
};
|
|
146
|
+
var asBlocks = (nodes) => {
|
|
147
|
+
const blocks = [];
|
|
148
|
+
let run = [];
|
|
149
|
+
const flush = () => {
|
|
150
|
+
if (run.some((node) => node.type !== "text" || node.value.trim().length > 0)) {
|
|
151
|
+
blocks.push({ type: "paragraph", children: run });
|
|
152
|
+
}
|
|
153
|
+
run = [];
|
|
154
|
+
};
|
|
155
|
+
for (const node of nodes) {
|
|
156
|
+
if (PHRASING_TYPES.has(node.type) || node.type === "break") {
|
|
157
|
+
run.push(node);
|
|
158
|
+
} else {
|
|
159
|
+
flush();
|
|
160
|
+
blocks.push(node);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
flush();
|
|
164
|
+
return blocks;
|
|
165
|
+
};
|
|
166
|
+
export {
|
|
167
|
+
flattenTableCells,
|
|
168
|
+
tableHasCodeSamples,
|
|
169
|
+
unfoldTable
|
|
170
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// src/mdast-handlers/twoslash.ts
|
|
2
|
+
import { classList, isElement } from "../utils/hast-fast.js";
|
|
3
|
+
import { preText } from "../utils/pre-text.js";
|
|
4
|
+
var cleanTwoslash = (pre) => {
|
|
5
|
+
if (!classList(pre).includes("twoslash")) {
|
|
6
|
+
return void 0;
|
|
7
|
+
}
|
|
8
|
+
let language;
|
|
9
|
+
const clean = (element) => {
|
|
10
|
+
element.children = element.children.flatMap((child) => {
|
|
11
|
+
if (!isElement(child)) {
|
|
12
|
+
return [child];
|
|
13
|
+
}
|
|
14
|
+
const classes = classList(child);
|
|
15
|
+
if (classes.includes("language-id")) {
|
|
16
|
+
language ||= preText(child).trim() || void 0;
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
if (classes.includes("playground-link") || classes.includes("error-behind")) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
if (classes.includes("error")) {
|
|
23
|
+
return [errorLine(child)];
|
|
24
|
+
}
|
|
25
|
+
clean(child);
|
|
26
|
+
return [child];
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
clean(pre);
|
|
30
|
+
return language && /^[\w+#.-]+$/.test(language) ? language : void 0;
|
|
31
|
+
};
|
|
32
|
+
var errorLine = (error) => {
|
|
33
|
+
let code = "";
|
|
34
|
+
let message = "";
|
|
35
|
+
for (const child of error.children) {
|
|
36
|
+
if (isElement(child) && classList(child).includes("code")) {
|
|
37
|
+
code = preText(child).trim();
|
|
38
|
+
} else {
|
|
39
|
+
message += isElement(child) ? preText(child) : child.type === "text" ? child.value : "";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const prefix = /^\d+$/.test(code) ? `error TS${code}: ` : "error: ";
|
|
43
|
+
const lines = `${prefix}${message.trim()}`.split("\n").map((line) => `// ${line}`);
|
|
44
|
+
return { type: "element", tagName: "div", properties: {}, children: [{ type: "text", value: lines.join("\n") }] };
|
|
45
|
+
};
|
|
46
|
+
export {
|
|
47
|
+
cleanTwoslash
|
|
48
|
+
};
|
|
@@ -10,11 +10,8 @@ var DEFAULT_MDAST_TO_MARKDOWN_OPTIONS = {
|
|
|
10
10
|
};
|
|
11
11
|
var mdastToMarkdown = (mdast, options) => {
|
|
12
12
|
const { baseUrl, ...toMarkdownOptions } = { ...DEFAULT_MDAST_TO_MARKDOWN_OPTIONS, ...options };
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
markdown = linkReplacer(markdown, baseUrl);
|
|
16
|
-
}
|
|
17
|
-
return markdown;
|
|
13
|
+
const tree = warpRoot(mdast);
|
|
14
|
+
return toMarkdown(baseUrl ? linkReplacer(tree, baseUrl) : tree, toMarkdownOptions);
|
|
18
15
|
};
|
|
19
16
|
export {
|
|
20
17
|
DEFAULT_MDAST_TO_MARKDOWN_OPTIONS,
|
package/dist/metadata/index.js
CHANGED
|
@@ -92,9 +92,10 @@ var readName = (value) => {
|
|
|
92
92
|
};
|
|
93
93
|
var asString = (value) => typeof value === "string" && value.length > 0 ? value : void 0;
|
|
94
94
|
var MAX_TITLE_LENGTH = 160;
|
|
95
|
-
var
|
|
95
|
+
var MAX_DOCUMENT_TITLE_LENGTH = 300;
|
|
96
|
+
var asTitle = (value, maxLength = MAX_TITLE_LENGTH) => {
|
|
96
97
|
const cleaned = clean(value);
|
|
97
|
-
return cleaned && cleaned.length <=
|
|
98
|
+
return cleaned && cleaned.length <= maxLength ? cleaned : void 0;
|
|
98
99
|
};
|
|
99
100
|
var clean = (value) => {
|
|
100
101
|
if (value === void 0) {
|
|
@@ -160,7 +161,7 @@ var extractMetadata = (tree) => {
|
|
|
160
161
|
}
|
|
161
162
|
return void 0;
|
|
162
163
|
};
|
|
163
|
-
const title = asTitle(get("og:title", "twitter:title")) ?? asTitle(asString(article?.headline)) ?? asTitle(asString(article?.name)) ?? asTitle(documentTitle(tree)) ?? asTitle(firstHeading(tree));
|
|
164
|
+
const title = asTitle(get("og:title", "twitter:title")) ?? asTitle(asString(article?.headline)) ?? asTitle(asString(article?.name)) ?? asTitle(documentTitle(tree), MAX_DOCUMENT_TITLE_LENGTH) ?? asTitle(firstHeading(tree));
|
|
164
165
|
return {
|
|
165
166
|
title,
|
|
166
167
|
description: clean(get("og:description", "twitter:description", "description")) ?? clean(asString(article?.description)),
|
package/dist/normalize/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/normalize/index.ts
|
|
2
2
|
import {
|
|
3
3
|
classList,
|
|
4
|
+
findElement,
|
|
4
5
|
isElement,
|
|
5
6
|
numericProperty,
|
|
6
7
|
property,
|
|
@@ -80,14 +81,16 @@ var katexDuplicates = (node) => {
|
|
|
80
81
|
if (!(classes.includes("katex") || classes.includes("katex-display"))) {
|
|
81
82
|
return [];
|
|
82
83
|
}
|
|
83
|
-
const hasMathml = node.children.some(
|
|
84
|
+
const hasMathml = node.children.some(
|
|
85
|
+
(child) => isElement(child) && classList(child).includes("katex-mathml") && hasMathSource(child)
|
|
86
|
+
);
|
|
84
87
|
if (!hasMathml) {
|
|
85
88
|
return [];
|
|
86
89
|
}
|
|
87
90
|
return node.children.filter((child) => isElement(child) && classList(child).includes("katex-html"));
|
|
88
91
|
};
|
|
89
92
|
var mediawikiDuplicates = (node) => {
|
|
90
|
-
if (!classList(node).includes("mwe-math-element")) {
|
|
93
|
+
if (!classList(node).includes("mwe-math-element") || !hasMathSource(node)) {
|
|
91
94
|
return [];
|
|
92
95
|
}
|
|
93
96
|
return node.children.filter(
|
|
@@ -98,8 +101,15 @@ var mathjaxDuplicates = (node) => {
|
|
|
98
101
|
if (node.tagName !== "mjx-container") {
|
|
99
102
|
return [];
|
|
100
103
|
}
|
|
104
|
+
const hasMathml = node.children.some(
|
|
105
|
+
(child) => isElement(child) && child.tagName === "mjx-assistive-mml" && hasMathSource(child)
|
|
106
|
+
);
|
|
107
|
+
if (!hasMathml) {
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
101
110
|
return node.children.filter((child) => isElement(child) && child.tagName !== "mjx-assistive-mml");
|
|
102
111
|
};
|
|
112
|
+
var hasMathSource = (node) => Boolean(findElement(node, (element) => element.tagName === "math" && element.children.length > 0));
|
|
103
113
|
var dedupeRenderedMath = (tree) => {
|
|
104
114
|
const doomed = /* @__PURE__ */ new Set();
|
|
105
115
|
walk(tree, (node) => {
|