webforai 1.2.2 → 1.2.3

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.
Files changed (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +74 -74
  3. package/dist/cjs/extract-hast/index.js +35 -3
  4. package/dist/cjs/extract-hast/readability.js +57 -29
  5. package/dist/cjs/extract-hast/strongly.js +6 -3
  6. package/dist/cjs/extract-hast/utils.js +8 -4
  7. package/dist/cjs/html-to-mdast.js +6 -19
  8. package/dist/cjs/index.js +18 -9
  9. package/dist/cjs/link-replacer.js +2 -1
  10. package/dist/cjs/loaders/playwright.js +8 -16
  11. package/dist/cjs/md-splitter.js +5 -3
  12. package/dist/cjs/mdast-handlers/custom-a-handler.js +2 -1
  13. package/dist/cjs/mdast-handlers/custom-code-handler.js +43 -0
  14. package/dist/cjs/mdast-handlers/custom-div-handler.js +15 -9
  15. package/dist/cjs/mdast-handlers/custom-img-handler.js +2 -1
  16. package/dist/cjs/mdast-handlers/empty-handler.js +29 -0
  17. package/dist/cjs/mdast-to-markdown.js +2 -1
  18. package/dist/cjs/utils/mdast-utils.js +6 -3
  19. package/dist/extract-hast/index.js +28 -1
  20. package/dist/extract-hast/readability.js +62 -34
  21. package/dist/extract-hast/strongly.js +6 -3
  22. package/dist/extract-hast/utils.js +8 -4
  23. package/dist/html-to-mdast.js +7 -20
  24. package/dist/index.js +10 -4
  25. package/dist/link-replacer.js +2 -1
  26. package/dist/loaders/playwright.js +8 -6
  27. package/dist/md-splitter.js +5 -3
  28. package/dist/mdast-handlers/custom-a-handler.js +4 -3
  29. package/dist/mdast-handlers/custom-code-handler.js +20 -0
  30. package/dist/mdast-handlers/custom-div-handler.js +17 -11
  31. package/dist/mdast-handlers/custom-img-handler.js +2 -1
  32. package/dist/mdast-handlers/empty-handler.js +6 -0
  33. package/dist/mdast-to-markdown.js +2 -1
  34. package/dist/types/extract-hast/index.d.ts +10 -1
  35. package/dist/types/extract-hast/index.js.map +1 -1
  36. package/dist/types/extract-hast/readability.js.map +1 -1
  37. package/dist/types/extract-hast/strongly.js.map +1 -1
  38. package/dist/types/extract-hast/utils.js.map +1 -1
  39. package/dist/types/html-to-markdown.d.ts +1 -1
  40. package/dist/types/html-to-markdown.js.map +1 -1
  41. package/dist/types/html-to-mdast.d.ts +2 -4
  42. package/dist/types/html-to-mdast.js.map +1 -1
  43. package/dist/types/index.d.ts +4 -4
  44. package/dist/types/index.js.map +1 -1
  45. package/dist/types/link-replacer.js.map +1 -1
  46. package/dist/types/loaders/playwright.d.ts +2 -2
  47. package/dist/types/loaders/playwright.js.map +1 -1
  48. package/dist/types/md-splitter.d.ts +1 -1
  49. package/dist/types/md-splitter.js.map +1 -1
  50. package/dist/types/mdast-handlers/custom-a-handler.js.map +1 -1
  51. package/dist/types/mdast-handlers/custom-code-handler.d.ts +2 -0
  52. package/dist/types/mdast-handlers/custom-code-handler.js.map +1 -0
  53. package/dist/types/mdast-handlers/custom-div-handler.js.map +1 -1
  54. package/dist/types/mdast-handlers/custom-img-handler.js.map +1 -1
  55. package/dist/types/mdast-handlers/empty-handler.d.ts +1 -0
  56. package/dist/types/mdast-handlers/empty-handler.js.map +1 -0
  57. package/dist/types/mdast-to-markdown.js.map +1 -1
  58. package/dist/types/utils/mdast-utils.js.map +1 -1
  59. package/dist/utils/mdast-utils.js +6 -3
  60. package/package.json +118 -118
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var custom_code_handler_exports = {};
20
+ __export(custom_code_handler_exports, {
21
+ customCodeHandler: () => customCodeHandler
22
+ });
23
+ module.exports = __toCommonJS(custom_code_handler_exports);
24
+ var import_hast_util_to_text = require("hast-util-to-text");
25
+ var import_trim_trailing_lines = require("trim-trailing-lines");
26
+ var import_detect_code_lang = require("../utils/detect-code-lang");
27
+ const LANGUAGE_MATCH_REGEX = [/language-(\w+)/, /highlight-source-(\w+)/, /CodeBlock--language-(\w+)/];
28
+ const customCodeHandler = (state, node) => {
29
+ const classNames = node.properties?.className || [];
30
+ const codeValue = (0, import_trim_trailing_lines.trimTrailingLines)((0, import_hast_util_to_text.toText)(node)).trim();
31
+ const classLang = classNames.map((className) => {
32
+ const match = LANGUAGE_MATCH_REGEX.map((regex) => className.match(regex)).find((match2) => match2);
33
+ return match?.[1];
34
+ }).find((className) => className);
35
+ const lang = classLang || (0, import_detect_code_lang.detectLanguage)(codeValue) || null;
36
+ const result = { type: "code", lang, meta: null, value: codeValue };
37
+ state.patch(node, result);
38
+ return result;
39
+ };
40
+ // Annotate the CommonJS export names for ESM import in node:
41
+ 0 && (module.exports = {
42
+ customCodeHandler
43
+ });
@@ -29,35 +29,41 @@ var import_trim_trailing_lines = require("trim-trailing-lines");
29
29
  var import_detect_code_lang = require("../utils/detect-code-lang");
30
30
  const CODE_BLOCK_REGEX = /highlight-source|language-|codegroup|codeblock|code-block/i;
31
31
  const CODE_FILENAME_SELECTORS = "[class*='fileName'],[class*='fileName'],[class*='title'],[class*='Title']";
32
- const LANGUAGE_MATCH_REGEX = /language-(\w+)|highlight-source-(\w+)/;
32
+ const LANGUAGE_MATCH_REGEX = [/language-(\w+)/, /highlight-source-(\w+)/, /CodeBlock--language-(\w+)/];
33
33
  const findRecursive = (array, condition, maxDepth = 3) => {
34
- if (maxDepth <= 0)
34
+ if (maxDepth <= 0) {
35
35
  return null;
36
+ }
36
37
  for (const value of array) {
37
38
  const result = condition(value);
38
- if (Array.isArray(result))
39
+ if (Array.isArray(result)) {
39
40
  return findRecursive(result, condition, maxDepth - 1);
40
- if (result)
41
+ }
42
+ if (result) {
41
43
  return value;
44
+ }
42
45
  }
43
46
  return null;
44
47
  };
45
48
  const customDivHandler = (state, node) => {
46
49
  const classNames = Array.isArray(node.properties.className) ? node.properties.className : [];
47
50
  const codeBlock = findRecursive(node.children, (child) => {
48
- if (child.type !== "element")
51
+ if (child.type !== "element") {
49
52
  return false;
50
- if (child.tagName === "pre")
53
+ }
54
+ if (child.tagName === "pre") {
51
55
  return true;
56
+ }
52
57
  return child.children.filter((child2) => child2.type === "element");
53
58
  });
54
59
  if (codeBlock && classNames.some((className) => CODE_BLOCK_REGEX.test(className))) {
60
+ const codeBlockClassNames = codeBlock.type === "element" ? codeBlock.properties.className ?? [] : [];
55
61
  const codeValue = (0, import_trim_trailing_lines.trimTrailingLines)((0, import_hast_util_to_text.toText)(codeBlock)).trim();
56
62
  const filenameElement = (0, import_hast_util_select.select)(CODE_FILENAME_SELECTORS, node);
57
63
  const fileLang = filenameElement ? (0, import_hast_util_to_string.toString)(filenameElement).match(/\.(\w+)$/)?.[1] : null;
58
- const classLang = classNames.map((className) => {
59
- const match = className.match(LANGUAGE_MATCH_REGEX);
60
- return match?.[1] || match?.[2];
64
+ const classLang = [...classNames, ...codeBlockClassNames].map((className) => {
65
+ const match = LANGUAGE_MATCH_REGEX.map((regex) => className.match(regex)).find((match2) => match2);
66
+ return match?.[1];
61
67
  }).find((className) => className);
62
68
  const lang = fileLang || classLang || (0, import_detect_code_lang.detectLanguage)(codeValue) || null;
63
69
  const result = { type: "code", lang, meta: null, value: codeValue };
@@ -23,8 +23,9 @@ __export(custom_img_handler_exports, {
23
23
  module.exports = __toCommonJS(custom_img_handler_exports);
24
24
  var import_hast_util_to_mdast = require("hast-util-to-mdast");
25
25
  const customImgHandler = (options) => (state, node) => {
26
- if (options?.hideImage)
26
+ if (options?.hideImage) {
27
27
  return void 0;
28
+ }
28
29
  return import_hast_util_to_mdast.defaultHandlers.image(state, node);
29
30
  };
30
31
  // Annotate the CommonJS export names for ESM import in node:
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var empty_handler_exports = {};
20
+ __export(empty_handler_exports, {
21
+ emptyHandler: () => emptyHandler
22
+ });
23
+ module.exports = __toCommonJS(empty_handler_exports);
24
+ const emptyHandler = () => {
25
+ };
26
+ // Annotate the CommonJS export names for ESM import in node:
27
+ 0 && (module.exports = {
28
+ emptyHandler
29
+ });
@@ -30,8 +30,9 @@ const mdastToMarkdown = (mdast, options) => {
30
30
  let markdown = (0, import_mdast_util_to_markdown.toMarkdown)((0, import_mdast_utils.warpRoot)(mdast), {
31
31
  extensions: [(0, import_mdast_util_gfm.gfmToMarkdown)(), (0, import_mdast_util_math.mathToMarkdown)()]
32
32
  });
33
- if (options?.url)
33
+ if (options?.url) {
34
34
  markdown = (0, import_link_replacer.linkReplacer)(markdown, options.url);
35
+ }
35
36
  return markdown;
36
37
  };
37
38
  // Annotate the CommonJS export names for ESM import in node:
@@ -24,18 +24,21 @@ __export(mdast_utils_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(mdast_utils_exports);
26
26
  const unwarpRoot = (mdast) => {
27
- if (mdast.type === "root")
27
+ if (mdast.type === "root") {
28
28
  return mdast.children;
29
+ }
29
30
  return [mdast];
30
31
  };
31
32
  const warpRoot = (mdast) => {
32
- if (Array.isArray(mdast))
33
+ if (Array.isArray(mdast)) {
33
34
  return { type: "root", children: mdast };
35
+ }
34
36
  return mdast;
35
37
  };
36
38
  const internalType = (content) => {
37
- if (content.type === "heading")
39
+ if (content.type === "heading") {
38
40
  return `h${content.depth}`;
41
+ }
39
42
  return content.type;
40
43
  };
41
44
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,2 +1,29 @@
1
1
  // src/extract-hast/index.ts
2
- export * from "./strongly.js";
2
+ import { readabilityExtractHast } from "./readability.js";
3
+ import { stronglyExtractHast } from "./strongly.js";
4
+ var PRESET_EXTRACT_HAST = {
5
+ strongly: stronglyExtractHast,
6
+ readability: readabilityExtractHast
7
+ };
8
+ var DEFAULT_EXTRACT_HAST = ["readability"];
9
+ var extractHast = (hast, extractors = DEFAULT_EXTRACT_HAST) => {
10
+ const _extractors = Array.isArray(extractors) ? extractors : [extractors];
11
+ const extracted = _extractors.reduce((acc, extractor) => {
12
+ if (extractor === false) {
13
+ return acc;
14
+ }
15
+ if (typeof extractor === "string" && extractor in DEFAULT_EXTRACT_HAST) {
16
+ return PRESET_EXTRACT_HAST[extractor](acc);
17
+ }
18
+ if (typeof extractor === "function") {
19
+ return extractor(acc);
20
+ }
21
+ throw new Error(`Invalid extractor: ${extractor}`);
22
+ }, hast) || hast;
23
+ return extracted;
24
+ };
25
+ export {
26
+ DEFAULT_EXTRACT_HAST,
27
+ PRESET_EXTRACT_HAST,
28
+ extractHast
29
+ };
@@ -1,6 +1,6 @@
1
1
  // src/extract-hast/readability.ts
2
2
  import { select, selectAll } from "hast-util-select";
3
- import { toString } from "hast-util-to-string";
3
+ import { toString as hastToString } from "hast-util-to-string";
4
4
  import { filter } from "unist-util-filter";
5
5
  import { parents } from "unist-util-parents";
6
6
  import { classnames, hasAncestors, isStrInclude, matchString } from "./utils.js";
@@ -9,7 +9,7 @@ var REGEXPS = {
9
9
  hidden: /hidden|invisible|fallback-image/i,
10
10
  byline: /byline|author|dateline|writtenby|p-author/i,
11
11
  unlikelyCandidates: /-ad-|ai2html|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|footer|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote|speechify-ignore/i,
12
- okMaybeItsACandidate: /and|article|body|column|content|main|shadow|code/i
12
+ okMaybeItsaCandidate: /and|article|body|column|content|main|shadow|code/i
13
13
  };
14
14
  var BODY_SELECTORS = ["article", "#article", ".article_body", ".article-body", "#content", ".entry", "main"];
15
15
  var PARAGRAPH_TAGS = ["p", "div", "section", "article", "main", "ul", "ol", "li"];
@@ -18,60 +18,79 @@ var BASE_MINIMAL_LENGTH = {
18
18
  en: 500
19
19
  };
20
20
  var tryGetLang = (node) => {
21
- if (node.type !== "element")
21
+ if (node.type !== "element") {
22
22
  return;
23
+ }
23
24
  const element = node;
24
- if (element.tagName !== "html")
25
+ if (element.tagName !== "html") {
25
26
  return;
27
+ }
26
28
  const langAttr = element.properties.lang || element.properties["xml:lang"];
27
- if (langAttr)
29
+ if (langAttr) {
28
30
  return langAttr;
31
+ }
29
32
  };
30
33
  var metadataFilter = (node) => !["comment", "doctype"].includes(node.type);
31
34
  var universalElementFilter = (node) => {
32
- if (node.type !== "element")
35
+ if (node.type !== "element") {
33
36
  return true;
37
+ }
34
38
  const element = node;
35
- if (["script", "aside"].includes(element.tagName))
39
+ if (["script", "aside"].includes(element.tagName)) {
36
40
  return false;
37
- if (["hidden", "aria-hidden"].some((key) => element.properties[key]))
41
+ }
42
+ if (["hidden", "aria-hidden"].some((key) => element.properties[key])) {
38
43
  return false;
39
- if (classnames(element).some((classname) => REGEXPS.hidden.test(classname)))
44
+ }
45
+ if (classnames(element).some((classname) => REGEXPS.hidden.test(classname))) {
40
46
  return false;
41
- if (element.tagName === "dialog")
47
+ }
48
+ if (element.tagName === "dialog") {
42
49
  return false;
43
- if (element.properties.role === "dialog" && element.properties["aria-modal"])
50
+ }
51
+ if (element.properties.role === "dialog" && element.properties["aria-modal"]) {
44
52
  return false;
45
- if (element.properties.rel === "author" && isStrInclude(element.properties.itemprop, "author"))
53
+ }
54
+ if (element.properties.rel === "author" && isStrInclude(element.properties.itemprop, "author")) {
46
55
  return false;
47
- if (REGEXPS.byline.test(matchString(element)))
56
+ }
57
+ if (REGEXPS.byline.test(matchString(element))) {
48
58
  return false;
49
- if (element.properties.role && UNLIKELY_ROLES.includes(element.properties.role))
59
+ }
60
+ if (element.properties.role && UNLIKELY_ROLES.includes(element.properties.role)) {
50
61
  return false;
62
+ }
51
63
  return true;
52
64
  };
53
65
  var unlikelyElementFilter = (node) => {
54
- if (node.type !== "element")
66
+ if (node.type !== "element") {
55
67
  return true;
68
+ }
56
69
  const element = node;
57
70
  const match = matchString(element);
58
- if (["body", "article", "main", "section", "a"].includes(element.tagName))
71
+ if (["body", "article", "main", "section", "a"].includes(element.tagName)) {
59
72
  return true;
60
- if (hasAncestors(element, ["table", "code"], 3))
73
+ }
74
+ if (hasAncestors(element, ["table", "code"], 3)) {
61
75
  return true;
62
- if (REGEXPS.unlikelyCandidates.test(match) && !REGEXPS.okMaybeItsACandidate.test(match))
76
+ }
77
+ if (REGEXPS.unlikelyCandidates.test(match) && !REGEXPS.okMaybeItsaCandidate.test(match)) {
63
78
  return false;
79
+ }
64
80
  return true;
65
81
  };
66
82
  var removeEmptyFilter = (node) => {
67
- if (node.type !== "element")
83
+ if (node.type !== "element") {
68
84
  return true;
85
+ }
69
86
  const element = node;
70
- if (!PARAGRAPH_TAGS.includes(element.tagName))
87
+ if (!PARAGRAPH_TAGS.includes(element.tagName)) {
71
88
  return true;
72
- const text = toString(element);
73
- if (text.length < 10)
89
+ }
90
+ const text = hastToString(element);
91
+ if (text.length < 10) {
74
92
  return false;
93
+ }
75
94
  return true;
76
95
  };
77
96
  var readabilityExtractHast = (hast) => {
@@ -79,45 +98,54 @@ var readabilityExtractHast = (hast) => {
79
98
  const body = select("body", hast) ?? hast;
80
99
  const proxiedHast = parents(body);
81
100
  let baseFilterd = filter(proxiedHast, (node) => {
82
- if (!metadataFilter(node))
101
+ if (!metadataFilter(node)) {
83
102
  return false;
84
- if (!universalElementFilter(node))
103
+ }
104
+ if (!universalElementFilter(node)) {
85
105
  return false;
106
+ }
86
107
  return true;
87
108
  });
88
- if (!baseFilterd)
109
+ if (!baseFilterd) {
89
110
  return { type: "root", children: [] };
90
- const baseText = toString(baseFilterd);
111
+ }
112
+ const baseText = hastToString(baseFilterd);
91
113
  let minimalLength = lang in BASE_MINIMAL_LENGTH ? BASE_MINIMAL_LENGTH[lang] : 500;
92
114
  if (baseText.length > minimalLength) {
93
115
  const filterd = filter(baseFilterd, (node) => {
94
- if (!unlikelyElementFilter(node))
116
+ if (!unlikelyElementFilter(node)) {
95
117
  return false;
118
+ }
96
119
  return true;
97
120
  });
98
- if (filterd)
121
+ if (filterd) {
99
122
  baseFilterd = filterd;
100
- } else
123
+ }
124
+ } else {
101
125
  minimalLength = Math.max(0, baseText.length - 200);
126
+ }
102
127
  let bodyTree = baseFilterd;
103
128
  for (const selector of BODY_SELECTORS) {
104
129
  const body2 = { type: "root", children: selectAll(selector, baseFilterd) };
105
- const bodyText = toString(body2);
106
- if (bodyText.length < 25)
130
+ const bodyText = hastToString(body2);
131
+ if (bodyText.length < 25) {
107
132
  continue;
133
+ }
108
134
  const links = selectAll("a", body2);
109
- const linkText = links.map((link) => toString(link)).join("");
135
+ const linkText = links.map((link) => hastToString(link)).join("");
110
136
  const linkDensity = linkText.length / bodyText.length;
111
- if (linkDensity > 0.4)
137
+ if (linkDensity > 0.4) {
112
138
  continue;
139
+ }
113
140
  if (bodyText.length > minimalLength) {
114
141
  bodyTree = body2;
115
142
  break;
116
143
  }
117
144
  }
118
145
  const finalTree = filter(bodyTree, (node) => {
119
- if (!removeEmptyFilter(node))
146
+ if (!removeEmptyFilter(node)) {
120
147
  return false;
148
+ }
121
149
  return true;
122
150
  });
123
151
  return finalTree;
@@ -13,14 +13,17 @@ var stronglyExtractHast = (hast) => {
13
13
  }
14
14
  }
15
15
  const removedElements = filter(selectedElement, (node) => {
16
- if (node.type === "comment")
16
+ if (node.type === "comment") {
17
17
  return false;
18
- if (node.type !== "element")
18
+ }
19
+ if (node.type !== "element") {
19
20
  return true;
21
+ }
20
22
  const element = node;
21
23
  const elementName = `${element.tagName} ${element.properties.id} ${element.properties.className}`;
22
- if (REMOVE_REGEX.test(elementName))
24
+ if (REMOVE_REGEX.test(elementName)) {
23
25
  return false;
26
+ }
24
27
  return true;
25
28
  });
26
29
  return removedElements;
@@ -1,22 +1,26 @@
1
1
  // src/extract-hast/utils.ts
2
2
  var matchString = (element) => `${element.tagName} ${element.properties.id} ${classnames(element).join(" ")} }`;
3
3
  var classnames = (element) => {
4
- if (Array.isArray(element.properties.className))
4
+ if (Array.isArray(element.properties.className)) {
5
5
  return element.properties.className;
6
+ }
6
7
  return [];
7
8
  };
8
9
  var isStrInclude = (value, match) => {
9
- if (typeof value === "string")
10
+ if (typeof value === "string") {
10
11
  return value.includes(match);
12
+ }
11
13
  return false;
12
14
  };
13
15
  var hasAncestors = (element, tagNames, depth = 3) => {
14
16
  let parent = element.parent;
15
17
  for (let i = 0; i < depth; i++) {
16
- if (!parent || parent.type !== "element")
18
+ if (!parent || parent.type !== "element") {
17
19
  return false;
18
- if (tagNames.includes(parent.tagName))
20
+ }
21
+ if (tagNames.includes(parent.tagName)) {
19
22
  return true;
23
+ }
20
24
  parent = parent.parent;
21
25
  }
22
26
  return false;
@@ -1,40 +1,27 @@
1
1
  // src/html-to-mdast.ts
2
2
  import { fromHtml } from "hast-util-from-html";
3
3
  import { toMdast } from "hast-util-to-mdast";
4
- import { stronglyExtractHast } from "./extract-hast/index.js";
5
- import { readabilityExtractHast } from "./extract-hast/readability.js";
4
+ import { extractHast } from "./extract-hast/index.js";
6
5
  import { customAHandler } from "./mdast-handlers/custom-a-handler.js";
6
+ import { customCodeHandler } from "./mdast-handlers/custom-code-handler.js";
7
7
  import { customDivHandler } from "./mdast-handlers/custom-div-handler.js";
8
8
  import { customImgHandler } from "./mdast-handlers/custom-img-handler.js";
9
9
  import { customTableHandler } from "./mdast-handlers/custom-table-handler.js";
10
+ import { emptyHandler } from "./mdast-handlers/empty-handler.js";
10
11
  import { mathHandler } from "./mdast-handlers/math-handler.js";
11
- var PRESET_EXTRACT_HAST = {
12
- strongly: stronglyExtractHast,
13
- readability: readabilityExtractHast
14
- };
15
- var DEFAULT_EXTRACT_HAST = ["readability"];
16
12
  var htmlToMdast = (html, options) => {
17
- const { extractHast = DEFAULT_EXTRACT_HAST } = options || {};
18
- const _extractHast = Array.isArray(extractHast) ? extractHast : [extractHast];
13
+ const { extractHast: _extractHast } = options || {};
19
14
  const hast = fromHtml(html, { fragment: true });
20
- const extractedHast = _extractHast.reduce((acc, extractHast2) => {
21
- if (extractHast2 === false)
22
- return acc;
23
- if (typeof extractHast2 === "string" && extractHast2 in PRESET_EXTRACT_HAST)
24
- return PRESET_EXTRACT_HAST[extractHast2](acc);
25
- if (typeof extractHast2 === "function")
26
- return extractHast2(acc);
27
- throw new Error(`Invalid extractHast: ${extractHast2}`);
28
- }, hast) || hast;
15
+ const extractedHast = extractHast(hast, _extractHast);
29
16
  const mdast = toMdast(extractedHast, {
30
17
  handlers: {
31
18
  math: mathHandler,
32
19
  div: customDivHandler,
20
+ pre: customCodeHandler,
33
21
  a: customAHandler({ asText: options?.linkAsText }),
34
22
  img: customImgHandler({ hideImage: options?.hideImage }),
35
23
  table: customTableHandler({ asText: options?.tableAsText }),
36
- br: () => {
37
- }
24
+ br: emptyHandler
38
25
  }
39
26
  });
40
27
  return mdast;
package/dist/index.js CHANGED
@@ -1,5 +1,11 @@
1
1
  // src/index.ts
2
- export * from "./html-to-markdown.js";
3
- export * from "./md-splitter.js";
4
- export * from "./html-to-mdast.js";
5
- export * from "./mdast-to-markdown.js";
2
+ import { htmlToMarkdown } from "./html-to-markdown.js";
3
+ import { mdastSplitter } from "./md-splitter.js";
4
+ import { htmlToMdast } from "./html-to-mdast.js";
5
+ import { mdastToMarkdown } from "./mdast-to-markdown.js";
6
+ export {
7
+ htmlToMarkdown,
8
+ htmlToMdast,
9
+ mdastSplitter,
10
+ mdastToMarkdown
11
+ };
@@ -2,8 +2,9 @@
2
2
  var linkReplacer = (markdown, link) => {
3
3
  const regex = /(!?\[.*?\]\()(.+?)(\))/g;
4
4
  return markdown.replace(regex, (match, pre, thisUrl, post) => {
5
- if (thisUrl.startsWith("http") || thisUrl.startsWith("#"))
5
+ if (thisUrl.startsWith("http") || thisUrl.startsWith("#")) {
6
6
  return match;
7
+ }
7
8
  return `${pre}${new URL(thisUrl, link).href}${post}`;
8
9
  });
9
10
  };
@@ -1,21 +1,23 @@
1
1
  // src/loaders/playwright.ts
2
- import * as playwright from "playwright";
2
+ import { chromium } from "playwright";
3
3
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
4
4
  var loadHtml = async (url, context) => {
5
5
  let _browser = null;
6
6
  let _context;
7
- if (!context) {
8
- _browser = await playwright.chromium.launch({ headless: true });
9
- _context = await _browser.newContext();
10
- } else
7
+ if (context) {
11
8
  _context = context;
9
+ } else {
10
+ _browser = await chromium.launch({ headless: true });
11
+ _context = await _browser.newContext();
12
+ }
12
13
  const page = await _context.newPage();
13
14
  await page.goto(url);
14
15
  await Promise.race([page.waitForLoadState("networkidle"), sleep(1e4)]);
15
16
  const html = await page.content();
16
17
  await page.close();
17
- if (_browser)
18
+ if (_browser) {
18
19
  await _browser.close();
20
+ }
19
21
  return html;
20
22
  };
21
23
  export {
@@ -4,14 +4,16 @@ 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
6
  var getSplitterGenerator = function* () {
7
- for (const splitter of PRIORITY_SPLITTERS)
7
+ for (const splitter of PRIORITY_SPLITTERS) {
8
8
  yield splitter;
9
+ }
9
10
  };
10
11
  var _mdastSplitter = async (contents, checker, splitterGenerator) => {
11
12
  const splitter = splitterGenerator.next().value;
12
13
  const markdown = mdastToMarkdown(warpRoot(contents));
13
- if (await checker(markdown) || contents.length === 1)
14
+ if (await checker(markdown) || contents.length === 1) {
14
15
  return [contents];
16
+ }
15
17
  const chunked = splitter ? contents.reduce((acc, content) => {
16
18
  if (internalType(content) === splitter || acc.length === 0) {
17
19
  acc.push([content]);
@@ -23,7 +25,7 @@ var _mdastSplitter = async (contents, checker, splitterGenerator) => {
23
25
  const splitting = chunked.map((chunk2) => _mdastSplitter(chunk2, checker, splitterGenerator));
24
26
  return Promise.all(splitting).then((chunks) => chunks.flat());
25
27
  };
26
- var mdastSplitter = async (mdast, checker, options) => {
28
+ var mdastSplitter = (mdast, checker, _options) => {
27
29
  return _mdastSplitter(unwarpRoot(mdast), checker, getSplitterGenerator());
28
30
  };
29
31
  export {
@@ -1,15 +1,16 @@
1
1
  // src/mdast-handlers/custom-a-handler.ts
2
2
  import { defaultHandlers } from "hast-util-to-mdast";
3
- import { toString } from "hast-util-to-string";
3
+ import { toString as hastToString } from "hast-util-to-string";
4
4
  var customAHandler = (options) => (state, node) => {
5
5
  if (options?.asText) {
6
- const link2 = { type: "text", value: toString(node) };
6
+ const link2 = { type: "text", value: hastToString(node) };
7
7
  state.patch(node, link2);
8
8
  return link2;
9
9
  }
10
10
  const link = defaultHandlers.a(state, node);
11
- if (link.children.length > 0)
11
+ if (link.children.length > 0) {
12
12
  return link;
13
+ }
13
14
  return void 0;
14
15
  };
15
16
  export {
@@ -0,0 +1,20 @@
1
+ // src/mdast-handlers/custom-code-handler.ts
2
+ import { toText } from "hast-util-to-text";
3
+ import { trimTrailingLines } from "trim-trailing-lines";
4
+ import { detectLanguage } from "../utils/detect-code-lang.js";
5
+ var LANGUAGE_MATCH_REGEX = [/language-(\w+)/, /highlight-source-(\w+)/, /CodeBlock--language-(\w+)/];
6
+ var customCodeHandler = (state, node) => {
7
+ const classNames = node.properties?.className || [];
8
+ const codeValue = trimTrailingLines(toText(node)).trim();
9
+ const classLang = classNames.map((className) => {
10
+ const match = LANGUAGE_MATCH_REGEX.map((regex) => className.match(regex)).find((match2) => match2);
11
+ return match?.[1];
12
+ }).find((className) => className);
13
+ const lang = classLang || detectLanguage(codeValue) || null;
14
+ const result = { type: "code", lang, meta: null, value: codeValue };
15
+ state.patch(node, result);
16
+ return result;
17
+ };
18
+ export {
19
+ customCodeHandler
20
+ };