@ryangarber/markitdown-ts 0.1.0 → 0.1.2

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/LICENSE CHANGED
@@ -1,5 +1,6 @@
1
1
  MIT License
2
2
 
3
+ Copyright (c) 2026 Ryan Garber
3
4
  Copyright (c) 2024 Vaibhav Raj
4
5
 
5
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # markitdown-ts
2
2
 
3
- `markitdown-ts` converts web-native document data to Markdown without filesystem, process, stream, or other runtime-specific dependencies. It is designed for browsers, workers, edge functions, and all other modern JavaScript environments.
3
+ `markitdown-ts` converts various file types to Markdown without filesystem, process, stream, or any other runtime-specific dependencies. It can run in browsers, workers, edge functions, and all other modern JavaScript environments.
4
4
 
5
5
  ## Supported formats
6
6
 
@@ -10,24 +10,25 @@
10
10
  - Jupyter notebooks (`.ipynb`)
11
11
  - Word documents (`.docx`)
12
12
  - Excel workbooks (`.xlsx`)
13
+ - PDF documents (`.pdf`)
14
+ - ZIP archives (`.zip`), with nested files converted recursively
13
15
  - Wikipedia, YouTube metadata, and Bing result pages supplied as HTML
14
16
 
15
- PDF, archive, audio, image metadata, local-path, and YouTube transcript features from the original project are intentionally not included because their implementations depended on runtime-specific modules, binaries, streams, or filesystem access.
17
+ Audio, image metadata, local-path, and YouTube transcript features from the original project are intentionally left out because their implementations depended on runtime-specific modules, binaries, streams, or filesystem access. They may be added back over time as alternative implementations are found. Want to see one added? Contributions are welcome!
16
18
 
17
19
  ## Installation
18
20
 
19
21
  ```sh
20
- npm install @ryangarber/markitdown-ts
22
+ pnpm install @ryangarber/markitdown-ts
21
23
  ```
22
24
 
23
25
  ## Usage
24
26
 
25
- ### `Uint8Array` (preferred)
26
-
27
27
  ```ts
28
- import { MarkItDown } from "markitdown-ts";
28
+ import { MarkItDown } from "@ryangarber/markitdown-ts";
29
+
30
+ const bytes: Uint8Array = /* plain bytes */;
29
31
 
30
- const bytes = new TextEncoder().encode("Hello from the web");
31
32
  const result = await new MarkItDown().convert(bytes, {
32
33
  file_extension: ".txt"
33
34
  });
@@ -35,14 +36,11 @@ const result = await new MarkItDown().convert(bytes, {
35
36
  console.log(result?.markdown);
36
37
  ```
37
38
 
38
- Any `Uint8Array` subclass is accepted as well. This keeps byte data from other modern JavaScript runtimes interoperable without requiring runtime-specific types.
39
-
40
- ### Other in-memory sources
41
-
42
39
  The same `convert` method accepts:
43
40
 
41
+ - `Uint8Array`
44
42
  - `ArrayBuffer` and `SharedArrayBuffer`
45
- - Any typed array or `DataView`
43
+ - `DataView` or any other typed array
46
44
  - `Blob` and `File`
47
45
  - `Response`
48
46
 
@@ -102,4 +100,5 @@ Biome handles both formatting and linting. `tsup` produces ESM, CommonJS, source
102
100
 
103
101
  ## License
104
102
 
103
+ MIT License © 2026 Ryan Garber\
105
104
  MIT License © 2024 Vaibhav Raj
package/dist/index.cjs CHANGED
@@ -28,9 +28,11 @@ turndown = __toESM(turndown, 1);
28
28
  let linkedom = require("linkedom");
29
29
  let mammoth = require("mammoth");
30
30
  mammoth = __toESM(mammoth, 1);
31
+ let unpdf = require("unpdf");
31
32
  let xlsx = require("xlsx");
32
33
  xlsx = __toESM(xlsx, 1);
33
34
  let _xmldom_xmldom = require("@xmldom/xmldom");
35
+ let fflate = require("fflate");
34
36
  //#region src/bytes.ts
35
37
  async function toUint8Array(source) {
36
38
  if (source instanceof Uint8Array) return source;
@@ -210,11 +212,32 @@ var IpynbConverter = class {
210
212
  }
211
213
  };
212
214
  //#endregion
215
+ //#region src/converters/pdf.ts
216
+ var PdfConverter = class {
217
+ async convert(source, options) {
218
+ if (options.file_extension?.toLowerCase() !== ".pdf") return null;
219
+ const pdf = await (0, unpdf.getDocumentProxy)(source.slice());
220
+ try {
221
+ const [{ text }, { info }] = await Promise.all([(0, unpdf.extractText)(pdf, { mergePages: true }), (0, unpdf.getMeta)(pdf)]);
222
+ return {
223
+ title: typeof info.Title === "string" && info.Title.trim() ? info.Title : null,
224
+ markdown: text,
225
+ text_content: text
226
+ };
227
+ } finally {
228
+ await pdf.loadingTask.destroy();
229
+ }
230
+ }
231
+ };
232
+ //#endregion
213
233
  //#region src/mime.ts
214
234
  const MIME_EXTENSIONS = {
215
235
  "application/atom+xml": ".atom",
216
236
  "application/json": ".json",
237
+ "application/pdf": ".pdf",
238
+ "application/zip": ".zip",
217
239
  "application/rss+xml": ".rss",
240
+ "application/x-pdf": ".pdf",
218
241
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ".xlsx",
219
242
  "application/vnd.openxmlformats-officedocument.wordprocessingml.document": ".docx",
220
243
  "application/xml": ".xml",
@@ -448,18 +471,55 @@ function isRecord(value) {
448
471
  return typeof value === "object" && value !== null;
449
472
  }
450
473
  //#endregion
474
+ //#region src/converters/zip.ts
475
+ var ZipConverter = class {
476
+ async convert(source, options = {}) {
477
+ if (options.file_extension?.toLowerCase() !== ".zip") return null;
478
+ const files = (0, fflate.unzipSync)(source, { filter: (file) => !file.name.endsWith("/") });
479
+ const converters = options._parent_converters ?? [];
480
+ const sections = [`Content from the zip file \`${options.url ?? "archive.zip"}\`:`];
481
+ for (const [name, bytes] of Object.entries(files)) {
482
+ const result = await convertEntry(bytes, name, converters, options);
483
+ if (result) sections.push(`## File: ${name}\n\n${result.markdown}`);
484
+ }
485
+ const markdown = sections.join("\n\n");
486
+ return {
487
+ title: null,
488
+ markdown,
489
+ text_content: markdown
490
+ };
491
+ }
492
+ };
493
+ async function convertEntry(source, name, converters, options) {
494
+ const extension = extensionFromPathname(name);
495
+ if (!extension) return null;
496
+ const entryOptions = {
497
+ ...options,
498
+ file_extension: extension,
499
+ url: void 0,
500
+ _parent_converters: converters
501
+ };
502
+ for (const converter of converters) try {
503
+ const result = await converter.convert(source, entryOptions);
504
+ if (result) return result;
505
+ } catch {}
506
+ return null;
507
+ }
508
+ //#endregion
451
509
  //#region src/markitdown.ts
452
510
  var MarkItDown = class {
453
511
  constructor() {
454
512
  this.converters = [];
455
513
  this.registerConverter(new PlainTextConverter());
456
514
  this.registerConverter(new HtmlConverter());
515
+ this.registerConverter(new ZipConverter());
457
516
  this.registerConverter(new RSSConverter());
458
517
  this.registerConverter(new WikipediaConverter());
459
518
  this.registerConverter(new YouTubeConverter());
460
519
  this.registerConverter(new BingSerpConverter());
461
520
  this.registerConverter(new DocxConverter());
462
521
  this.registerConverter(new XlsxConverter());
522
+ this.registerConverter(new PdfConverter());
463
523
  this.registerConverter(new IpynbConverter());
464
524
  }
465
525
  /** Convert a URL, response, blob, array buffer, data view, or typed array. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["TurndownService","turndownPluginGfm","parseHTML","XLSX","DOMParser"],"sources":["../src/bytes.ts","../src/custom-turndown.ts","../src/html-document.ts","../src/converters/bingserp.ts","../src/converters/html.ts","../src/converters/docx.ts","../src/converters/ipynb.ts","../src/mime.ts","../src/converters/plain-text.ts","../src/converters/wikipedia.ts","../src/converters/xlsx.ts","../src/converters/xml-rss-atom.ts","../src/converters/youtube.ts","../src/markitdown.ts"],"sourcesContent":["import type { ByteSource } from \"./types\";\n\nexport async function toUint8Array(source: ByteSource): Promise<Uint8Array> {\n if (source instanceof Uint8Array) {\n return source;\n }\n\n if (isBlob(source)) {\n return new Uint8Array(await source.arrayBuffer());\n }\n\n if (ArrayBuffer.isView(source)) {\n return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);\n }\n\n return new Uint8Array(source);\n}\n\nexport function toArrayBuffer(source: Uint8Array): ArrayBuffer {\n return source.slice().buffer;\n}\n\nexport function decodeText(source: Uint8Array): string {\n return new TextDecoder().decode(source);\n}\n\nexport function isBlob(value: unknown): value is Blob {\n return typeof Blob !== \"undefined\" && value instanceof Blob;\n}\n\nexport function normalizeExtension(extension: string): string {\n if (!extension) {\n return \"\";\n }\n\n const normalized = extension.toLowerCase();\n return normalized.startsWith(\".\") ? normalized : `.${normalized}`;\n}\n","import turndownPluginGfm from \"@joplin/turndown-plugin-gfm\";\nimport TurndownService from \"turndown\";\n\nexport class CustomTurnDown {\n convertSoup(document: string | Node): string {\n const service = new TurndownService({ headingStyle: \"atx\" });\n service.use(turndownPluginGfm.gfm);\n\n service.addRule(\"anchor tags\", {\n filter: [\"a\"],\n replacement(content, node) {\n if (!content) return \"\";\n\n const prefix = content.startsWith(\" \") ? \" \" : \"\";\n const suffix = content.endsWith(\" \") ? \" \" : \"\";\n const text = content.trim().replace(/\\n\\n.*/g, \"\");\n if (!text) return \"\";\n\n const element = node as unknown as Element;\n const href = element.getAttribute(\"href\");\n let title = element.getAttribute(\"title\") ?? \"\";\n if (!href) return `${prefix}${text}${suffix}`;\n\n try {\n const url = new URL(href);\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n return `${prefix}${text}${suffix}`;\n }\n } catch {\n if (\n !href.startsWith(\"/\") &&\n !href.startsWith(\"#\") &&\n !href.startsWith(\"./\") &&\n !href.startsWith(\"../\")\n ) {\n return `${prefix}${text}${suffix}`;\n }\n }\n\n if (text.replace(/\\\\_/g, \"_\") === href && !title) {\n return `<${href}>`;\n }\n if (!title) title = href;\n return `${prefix}[${text}](${href}${title ? ` \"${title}\"` : \"\"})${suffix}`;\n }\n });\n\n service.addRule(\"img tags\", {\n filter: [\"img\"],\n replacement(_content, node) {\n const element = node as unknown as Element;\n const alt = element.getAttribute(\"alt\") ?? \"\";\n let source = element.getAttribute(\"src\") ?? \"\";\n const title = element.getAttribute(\"title\");\n if (source.startsWith(\"data:\")) {\n source = `${source.split(\",\", 1)[0]}...`;\n }\n return `![${alt}](${source}${title ? ` \"${title}\"` : \"\"})`;\n }\n });\n\n return service.turndown(document as TurndownService.Node);\n }\n}\n","import { parseHTML } from \"linkedom\";\n\nexport function parseHtmlDocument(html: string): Document {\n return parseHTML(html).document as unknown as Document;\n}\n","import { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nconst BING_SEARCH_URL = /^https:\\/\\/www\\.bing\\.com\\/search\\?q=/i;\nconst BASE64_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\nexport class BingSerpConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n const url = options.url ?? \"\";\n if ((extension !== \".html\" && extension !== \".htm\") || !BING_SEARCH_URL.test(url)) {\n return null;\n }\n\n const document = parseHtmlDocument(decodeText(source));\n const query = new URL(url).searchParams.get(\"q\") ?? \"\";\n\n document.querySelectorAll(\".tptt\").forEach((element) => {\n if (element.textContent) {\n element.textContent += \" \";\n }\n });\n document.querySelectorAll(\".algoSlug_icon\").forEach((element) => {\n element.remove();\n });\n\n const turndown = new CustomTurnDown();\n const results = [...document.querySelectorAll(\".b_algo\")].map((result) => {\n result.querySelectorAll(\"a[href]\").forEach((anchor) => {\n const href = anchor.getAttribute(\"href\");\n if (!href) {\n return;\n }\n try {\n const encoded = new URL(href, url).searchParams.get(\"u\");\n if (encoded) {\n anchor.setAttribute(\"href\", decodeBingUrl(encoded));\n }\n } catch {\n // Preserve malformed links as they appeared in the source document.\n }\n });\n\n return turndown\n .convertSoup(result)\n .split(/\\n+/)\n .map((line) => line.trim())\n .filter(Boolean)\n .join(\"\\n\");\n });\n\n const markdown = `## A Bing search for '${query}' found the following results:\\n\\n${results.join(\"\\n\\n\")}`;\n return { title: document.title || null, markdown, text_content: markdown };\n }\n}\n\nfunction decodeBingUrl(encoded: string): string {\n const input = encoded.slice(2).replace(/-/g, \"+\").replace(/_/g, \"/\").replace(/=+$/, \"\");\n const bytes: number[] = [];\n let bits = 0;\n let bitCount = 0;\n\n for (const character of input) {\n const value = BASE64_ALPHABET.indexOf(character);\n if (value < 0) {\n return encoded;\n }\n bits = (bits << 6) | value;\n bitCount += 6;\n if (bitCount >= 8) {\n bitCount -= 8;\n bytes.push((bits >> bitCount) & 0xff);\n }\n }\n\n return new TextDecoder().decode(new Uint8Array(bytes));\n}\n","import { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class HtmlConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if (extension !== \".html\" && extension !== \".htm\") {\n return null;\n }\n\n return this.convertHtml(decodeText(source));\n }\n\n async convertHtml(html: string): Promise<ConverterResult> {\n const document = parseHtmlDocument(html);\n document.querySelectorAll(\"script, style\").forEach((element) => {\n element.remove();\n });\n\n const markdown = new CustomTurnDown().convertSoup(document.body ?? document);\n return {\n title: document.title || null,\n markdown,\n text_content: markdown\n };\n }\n}\n","import mammoth from \"mammoth\";\nimport { toArrayBuffer } from \"../bytes\";\nimport type { ConverterOptions, ConverterResult } from \"../types\";\nimport { HtmlConverter } from \"./html\";\n\nexport class DocxConverter extends HtmlConverter {\n async convert(source: Uint8Array, options: ConverterOptions): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".docx\") {\n return null;\n }\n\n const html = await mammoth.convertToHtml(\n { arrayBuffer: toArrayBuffer(source) },\n {\n styleMap: options.styleMap,\n includeEmbeddedStyleMap: options.includeEmbeddedStyleMap,\n includeDefaultStyleMap: options.includeDefaultStyleMap,\n ignoreEmptyParagraphs: options.ignoreEmptyParagraphs,\n idPrefix: options.idPrefix,\n transformDocument: options.transformDocument\n }\n );\n return this.convertHtml(html.value);\n }\n}\n","import { decodeText } from \"../bytes\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\ntype NotebookCell = {\n cell_type?: string;\n source?: string[];\n};\n\ntype Notebook = {\n cells?: NotebookCell[];\n metadata?: { title?: string };\n};\n\nexport class IpynbConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".ipynb\") {\n return null;\n }\n\n const notebook = JSON.parse(decodeText(source)) as Notebook;\n const output: string[] = [];\n let title: string | null = notebook.metadata?.title ?? null;\n\n for (const cell of notebook.cells ?? []) {\n const lines = cell.source ?? [];\n if (cell.cell_type === \"markdown\") {\n output.push(lines.join(\"\"));\n title ??=\n lines\n .find((line) => line.startsWith(\"# \"))\n ?.slice(2)\n .trim() ?? null;\n } else if (cell.cell_type === \"code\") {\n output.push(`\\`\\`\\`python\\n${lines.join(\"\")}\\n\\`\\`\\``);\n } else if (cell.cell_type === \"raw\") {\n output.push(`\\`\\`\\`\\n${lines.join(\"\")}\\n\\`\\`\\``);\n }\n }\n\n const markdown = output.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n}\n","const MIME_EXTENSIONS: Record<string, string> = {\n \"application/atom+xml\": \".atom\",\n \"application/json\": \".json\",\n \"application/rss+xml\": \".rss\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\": \".xlsx\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\": \".docx\",\n \"application/xml\": \".xml\",\n \"text/csv\": \".csv\",\n \"text/html\": \".html\",\n \"text/markdown\": \".md\",\n \"text/plain\": \".txt\",\n \"text/xml\": \".xml\"\n};\n\nconst TEXT_EXTENSIONS = new Set([\".csv\", \".json\", \".log\", \".markdown\", \".md\", \".text\", \".txt\"]);\n\nexport function extensionFromMime(contentType: string | null | undefined): string | null {\n if (!contentType) {\n return null;\n }\n\n const mime = contentType.split(\";\", 1)[0]?.trim().toLowerCase() ?? \"\";\n return MIME_EXTENSIONS[mime] ?? (mime.startsWith(\"text/\") ? \".txt\" : null);\n}\n\nexport function isTextExtension(extension: string): boolean {\n return TEXT_EXTENSIONS.has(extension.toLowerCase());\n}\n\nexport function extensionFromPathname(pathname: string): string | null {\n const filename = pathname.split(\"/\").pop() ?? \"\";\n const dot = filename.lastIndexOf(\".\");\n return dot > 0 ? filename.slice(dot).toLowerCase() : null;\n}\n","import { decodeText } from \"../bytes\";\nimport { isTextExtension } from \"../mime\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class PlainTextConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n if (!isTextExtension(options.file_extension ?? \"\")) {\n return null;\n }\n\n const content = decodeText(source);\n return { title: null, markdown: content, text_content: content };\n }\n}\n","import { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nconst WIKIPEDIA_URL = /^https?:\\/\\/[a-z]{2,3}\\.wikipedia\\.org\\//i;\n\nexport class WikipediaConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if ((extension !== \".html\" && extension !== \".htm\") || !WIKIPEDIA_URL.test(options.url ?? \"\")) {\n return null;\n }\n\n const document = parseHtmlDocument(decodeText(source));\n document.querySelectorAll(\"script, style\").forEach((element) => {\n element.remove();\n });\n\n const body = document.querySelector(\"div#mw-content-text\");\n const pageTitle = document.querySelector(\"span.mw-page-title-main\")?.textContent?.trim();\n const title = pageTitle || document.title || null;\n const markdown = body\n ? `# ${title ?? \"Wikipedia\"}\\n\\n${new CustomTurnDown().convertSoup(body)}`\n : new CustomTurnDown().convertSoup(document);\n\n return { title, markdown, text_content: markdown };\n }\n}\n","import * as XLSX from \"xlsx\";\nimport type { ConverterOptions, ConverterResult } from \"../types\";\nimport { HtmlConverter } from \"./html\";\n\nexport class XlsxConverter extends HtmlConverter {\n async convert(source: Uint8Array, options: ConverterOptions): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".xlsx\") {\n return null;\n }\n\n const workbook = XLSX.read(source, { type: \"array\" });\n const sections: string[] = [];\n\n for (const sheetName of workbook.SheetNames) {\n const sheet = workbook.Sheets[sheetName];\n if (sheet?.[\"!ref\"]) {\n const result = await this.convertHtml(XLSX.utils.sheet_to_html(sheet));\n sections.push(`## ${sheetName}\\n${result?.markdown.trim() ?? \"\"}`);\n }\n }\n\n const markdown = sections.join(\"\\n\\n\");\n return {\n title: workbook.Props?.Title || \"Untitled\",\n markdown,\n text_content: markdown\n };\n }\n}\n","import type { Document, Element } from \"@xmldom/xmldom\";\nimport { DOMParser } from \"@xmldom/xmldom\";\nimport { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class RSSConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if (![\".xml\", \".rss\", \".atom\"].includes(extension)) {\n return null;\n }\n\n const document = new DOMParser().parseFromString(decodeText(source), \"text/xml\");\n if (document.getElementsByTagName(\"rss\").length > 0) {\n return this.parseRss(document);\n }\n if (document.getElementsByTagName(\"feed\")[0]?.getElementsByTagName(\"entry\").length) {\n return this.parseAtom(document);\n }\n return null;\n }\n\n private parseAtom(document: Document): ConverterResult {\n const root = document.getElementsByTagName(\"feed\")[0];\n if (!root) return null;\n\n const title = getText(root, \"title\");\n const subtitle = getText(root, \"subtitle\");\n const sections = [`# ${title ?? \"Feed\"}`];\n if (subtitle) sections.push(subtitle);\n\n for (const entry of [...root.getElementsByTagName(\"entry\")]) {\n const entryTitle = getText(entry, \"title\");\n const updated = getText(entry, \"updated\");\n const summary = getText(entry, \"summary\");\n const content = getText(entry, \"content\");\n const lines: string[] = [];\n if (entryTitle) lines.push(`## ${entryTitle}`);\n if (updated) lines.push(`Updated on: ${updated}`);\n if (summary) lines.push(parseContent(summary));\n if (content) lines.push(parseContent(content));\n sections.push(lines.join(\"\\n\"));\n }\n\n const markdown = sections.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n\n private parseRss(document: Document): ConverterResult {\n const channel = document.getElementsByTagName(\"rss\")[0]?.getElementsByTagName(\"channel\")[0];\n if (!channel) return null;\n\n const title = getText(channel, \"title\");\n const description = getText(channel, \"description\");\n const sections: string[] = title ? [`# ${title}`] : [];\n if (description) sections.push(description);\n\n for (const item of [...channel.getElementsByTagName(\"item\")]) {\n const itemTitle = getText(item, \"title\");\n const published = getText(item, \"pubDate\");\n const itemDescription = getText(item, \"description\");\n const content = getText(item, \"content:encoded\");\n const lines: string[] = [];\n if (itemTitle) lines.push(`## ${itemTitle}`);\n if (published) lines.push(`Published on: ${published}`);\n if (itemDescription) lines.push(parseContent(itemDescription));\n if (content) lines.push(parseContent(content));\n sections.push(lines.join(\"\\n\"));\n }\n\n const markdown = sections.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n}\n\nfunction parseContent(content: string): string {\n return new CustomTurnDown().convertSoup(parseHtmlDocument(content).documentElement);\n}\n\nfunction getText(element: Element, tagName: string): string | null {\n const node = element.getElementsByTagName(tagName)[0];\n return node?.textContent?.trim() || null;\n}\n","import { decodeText } from \"../bytes\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class YouTubeConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if (\n (extension !== \".html\" && extension !== \".htm\") ||\n !options.url?.startsWith(\"https://www.youtube.com/watch?\")\n ) {\n return null;\n }\n\n const document = parseHtmlDocument(decodeText(source));\n const metadata: Record<string, string> = { title: document.title };\n\n document.querySelectorAll(\"meta\").forEach((meta) => {\n const content = meta.getAttribute(\"content\");\n const key =\n meta.getAttribute(\"itemprop\") ?? meta.getAttribute(\"property\") ?? meta.getAttribute(\"name\");\n if (key && content) {\n metadata[key] = content;\n }\n });\n\n try {\n for (const script of document.querySelectorAll(\"script\")) {\n const content = script.textContent ?? \"\";\n if (!content.includes(\"ytInitialData\")) {\n continue;\n }\n const start = content.indexOf(\"{\");\n const end = content.lastIndexOf(\"}\");\n if (start >= 0 && end > start) {\n const description = findKey(\n JSON.parse(content.slice(start, end + 1)),\n \"attributedDescriptionBodyText\"\n );\n if (isRecord(description) && typeof description.content === \"string\") {\n metadata.description = description.content;\n }\n }\n break;\n }\n } catch {\n // Meta description remains available when the page implementation changes.\n }\n\n const title = first(metadata, [\"title\", \"og:title\", \"name\"]) || document.title || null;\n const lines = [\"# YouTube\"];\n if (title) {\n lines.push(`## ${title}`);\n }\n\n const stats: string[] = [];\n const views = first(metadata, [\"interactionCount\"]);\n const keywords = first(metadata, [\"keywords\"]);\n const runtime = first(metadata, [\"duration\"]);\n if (views) stats.push(`- **Views:** ${views}`);\n if (keywords) stats.push(`- **Keywords:** ${keywords}`);\n if (runtime) stats.push(`- **Runtime:** ${runtime}`);\n if (stats.length > 0) {\n lines.push(`### Video Metadata\\n${stats.join(\"\\n\")}`);\n }\n\n const description = first(metadata, [\"description\", \"og:description\"]);\n if (description) {\n lines.push(`### Description\\n${description}`);\n }\n\n const markdown = lines.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n}\n\nfunction first(metadata: Record<string, string>, keys: string[]): string | null {\n for (const key of keys) {\n if (metadata[key]) return metadata[key];\n }\n return null;\n}\n\nfunction findKey(value: unknown, key: string): unknown {\n if (Array.isArray(value)) {\n for (const item of value) {\n const match = findKey(item, key);\n if (match !== undefined) return match;\n }\n } else if (isRecord(value)) {\n if (key in value) return value[key];\n for (const item of Object.values(value)) {\n const match = findKey(item, key);\n if (match !== undefined) return match;\n }\n }\n return undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n","import { isBlob, toUint8Array } from \"./bytes\";\nimport { BingSerpConverter } from \"./converters/bingserp\";\nimport { DocxConverter } from \"./converters/docx\";\nimport { HtmlConverter } from \"./converters/html\";\nimport { IpynbConverter } from \"./converters/ipynb\";\nimport { PlainTextConverter } from \"./converters/plain-text\";\nimport { WikipediaConverter } from \"./converters/wikipedia\";\nimport { XlsxConverter } from \"./converters/xlsx\";\nimport { RSSConverter } from \"./converters/xml-rss-atom\";\nimport { YouTubeConverter } from \"./converters/youtube\";\nimport { extensionFromMime, extensionFromPathname } from \"./mime\";\nimport type { ByteSource, ConverterOptions, ConverterResult, DocumentConverter } from \"./types\";\n\nexport type ConversionSource = ByteSource | Response | URL | string;\n\nexport class MarkItDown {\n private readonly converters: DocumentConverter[] = [];\n\n constructor() {\n this.registerConverter(new PlainTextConverter());\n this.registerConverter(new HtmlConverter());\n this.registerConverter(new RSSConverter());\n this.registerConverter(new WikipediaConverter());\n this.registerConverter(new YouTubeConverter());\n this.registerConverter(new BingSerpConverter());\n this.registerConverter(new DocxConverter());\n this.registerConverter(new XlsxConverter());\n this.registerConverter(new IpynbConverter());\n }\n\n /** Convert a URL, response, blob, array buffer, data view, or typed array. */\n async convert(\n source: ConversionSource,\n options: ConverterOptions = {}\n ): Promise<ConverterResult> {\n if (typeof source === \"string\" || source instanceof URL) {\n return this.convertUrl(source.toString(), options);\n }\n\n if (isResponse(source)) {\n return this.convertResponse(source, options);\n }\n\n const extensions = new Set<string>();\n this.addExtension(extensions, options.file_extension);\n\n if (isBlob(source)) {\n this.addExtension(extensions, extensionFromMime(source.type));\n if (\"name\" in source && typeof source.name === \"string\") {\n this.addExtension(extensions, extensionFromPathname(source.name));\n }\n }\n\n if (extensions.size === 0) {\n throw new Error(\n \"Could not determine the file type. Provide `file_extension` when converting bytes.\"\n );\n }\n\n return this.convertBytes(await toUint8Array(source), extensions, options);\n }\n\n /**\n * @deprecated Pass the byte source directly to `convert`.\n */\n async convertBuffer(\n source: ByteSource,\n options: ConverterOptions & { file_extension: string }\n ): Promise<ConverterResult> {\n return this.convert(source, options);\n }\n\n private async convertUrl(\n source: string,\n { fetch: fetchImplementation = globalThis.fetch, ...options }: ConverterOptions\n ): Promise<ConverterResult> {\n const url = new URL(source);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n throw new Error(`Unsupported URL protocol: ${url.protocol}`);\n }\n if (!fetchImplementation) {\n throw new Error(\"No fetch implementation is available.\");\n }\n\n const response = await fetchImplementation(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch URL: ${url}, status: ${response.status}`);\n }\n\n return this.convertResponse(response, { ...options, url: url.toString() });\n }\n\n private async convertResponse(\n response: Response,\n options: ConverterOptions\n ): Promise<ConverterResult> {\n const extensions = new Set<string>();\n this.addExtension(extensions, options.file_extension);\n this.addExtension(extensions, extensionFromMime(response.headers.get(\"content-type\")));\n\n const disposition = response.headers.get(\"content-disposition\") ?? \"\";\n const filename = disposition.match(/filename\\*?=(?:UTF-8''|[\"']?)([^;\"']+)/i)?.[1];\n if (filename) {\n this.addExtension(extensions, extensionFromPathname(decodeURIComponent(filename.trim())));\n }\n\n const responseUrl = options.url || response.url;\n if (responseUrl) {\n this.addExtension(extensions, extensionFromPathname(new URL(responseUrl).pathname));\n }\n\n if (extensions.size === 0) {\n throw new Error(\n \"Could not determine the file type. Provide `file_extension` or a Content-Type header.\"\n );\n }\n\n return this.convertBytes(new Uint8Array(await response.arrayBuffer()), extensions, {\n ...options,\n url: responseUrl\n });\n }\n\n private async convertBytes(\n source: Uint8Array,\n extensions: Set<string>,\n options: ConverterOptions\n ): Promise<ConverterResult> {\n let lastError: unknown;\n\n for (const extension of extensions) {\n for (const converter of this.converters) {\n try {\n const result = await converter.convert(source, {\n ...options,\n file_extension: extension,\n _parent_converters: this.converters\n });\n if (result) {\n result.markdown = result.markdown\n .replace(/\\r\\n|\\r|\\n/g, \"\\n\")\n .trim()\n .replace(/\\n{3,}/g, \"\\n\\n\");\n result.text_content = result.markdown;\n return result;\n }\n } catch (error) {\n lastError = error;\n }\n }\n }\n\n const formats = [...extensions].join(\", \");\n if (lastError) {\n throw new Error(`Could not convert ${formats} to Markdown: ${String(lastError)}`);\n }\n throw new Error(`Unsupported file type: ${formats}.`);\n }\n\n private addExtension(extensions: Set<string>, extension: string | null | undefined): void {\n if (!extension) {\n return;\n }\n extensions.add(\n extension.startsWith(\".\") ? extension.toLowerCase() : `.${extension.toLowerCase()}`\n );\n }\n\n private registerConverter(converter: DocumentConverter): void {\n this.converters.unshift(converter);\n }\n}\n\nfunction isResponse(value: unknown): value is Response {\n return typeof Response !== \"undefined\" && value instanceof Response;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["TurndownService","turndownPluginGfm","parseHTML","getDocumentProxy","extractText","getMeta","XLSX","DOMParser","unzipSync"],"sources":["../src/bytes.ts","../src/custom-turndown.ts","../src/html-document.ts","../src/converters/bingserp.ts","../src/converters/html.ts","../src/converters/docx.ts","../src/converters/ipynb.ts","../src/converters/pdf.ts","../src/mime.ts","../src/converters/plain-text.ts","../src/converters/wikipedia.ts","../src/converters/xlsx.ts","../src/converters/xml-rss-atom.ts","../src/converters/youtube.ts","../src/converters/zip.ts","../src/markitdown.ts"],"sourcesContent":["import type { ByteSource } from \"./types\";\n\nexport async function toUint8Array(source: ByteSource): Promise<Uint8Array> {\n if (source instanceof Uint8Array) {\n return source;\n }\n\n if (isBlob(source)) {\n return new Uint8Array(await source.arrayBuffer());\n }\n\n if (ArrayBuffer.isView(source)) {\n return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);\n }\n\n return new Uint8Array(source);\n}\n\nexport function toArrayBuffer(source: Uint8Array): ArrayBuffer {\n return source.slice().buffer;\n}\n\nexport function decodeText(source: Uint8Array): string {\n return new TextDecoder().decode(source);\n}\n\nexport function isBlob(value: unknown): value is Blob {\n return typeof Blob !== \"undefined\" && value instanceof Blob;\n}\n\nexport function normalizeExtension(extension: string): string {\n if (!extension) {\n return \"\";\n }\n\n const normalized = extension.toLowerCase();\n return normalized.startsWith(\".\") ? normalized : `.${normalized}`;\n}\n","import turndownPluginGfm from \"@joplin/turndown-plugin-gfm\";\nimport TurndownService from \"turndown\";\n\nexport class CustomTurnDown {\n convertSoup(document: string | Node): string {\n const service = new TurndownService({ headingStyle: \"atx\" });\n service.use(turndownPluginGfm.gfm);\n\n service.addRule(\"anchor tags\", {\n filter: [\"a\"],\n replacement(content, node) {\n if (!content) return \"\";\n\n const prefix = content.startsWith(\" \") ? \" \" : \"\";\n const suffix = content.endsWith(\" \") ? \" \" : \"\";\n const text = content.trim().replace(/\\n\\n.*/g, \"\");\n if (!text) return \"\";\n\n const element = node as unknown as Element;\n const href = element.getAttribute(\"href\");\n let title = element.getAttribute(\"title\") ?? \"\";\n if (!href) return `${prefix}${text}${suffix}`;\n\n try {\n const url = new URL(href);\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n return `${prefix}${text}${suffix}`;\n }\n } catch {\n if (\n !href.startsWith(\"/\") &&\n !href.startsWith(\"#\") &&\n !href.startsWith(\"./\") &&\n !href.startsWith(\"../\")\n ) {\n return `${prefix}${text}${suffix}`;\n }\n }\n\n if (text.replace(/\\\\_/g, \"_\") === href && !title) {\n return `<${href}>`;\n }\n if (!title) title = href;\n return `${prefix}[${text}](${href}${title ? ` \"${title}\"` : \"\"})${suffix}`;\n }\n });\n\n service.addRule(\"img tags\", {\n filter: [\"img\"],\n replacement(_content, node) {\n const element = node as unknown as Element;\n const alt = element.getAttribute(\"alt\") ?? \"\";\n let source = element.getAttribute(\"src\") ?? \"\";\n const title = element.getAttribute(\"title\");\n if (source.startsWith(\"data:\")) {\n source = `${source.split(\",\", 1)[0]}...`;\n }\n return `![${alt}](${source}${title ? ` \"${title}\"` : \"\"})`;\n }\n });\n\n return service.turndown(document as TurndownService.Node);\n }\n}\n","import { parseHTML } from \"linkedom\";\n\nexport function parseHtmlDocument(html: string): Document {\n return parseHTML(html).document as unknown as Document;\n}\n","import { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nconst BING_SEARCH_URL = /^https:\\/\\/www\\.bing\\.com\\/search\\?q=/i;\nconst BASE64_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\nexport class BingSerpConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n const url = options.url ?? \"\";\n if ((extension !== \".html\" && extension !== \".htm\") || !BING_SEARCH_URL.test(url)) {\n return null;\n }\n\n const document = parseHtmlDocument(decodeText(source));\n const query = new URL(url).searchParams.get(\"q\") ?? \"\";\n\n document.querySelectorAll(\".tptt\").forEach((element) => {\n if (element.textContent) {\n element.textContent += \" \";\n }\n });\n document.querySelectorAll(\".algoSlug_icon\").forEach((element) => {\n element.remove();\n });\n\n const turndown = new CustomTurnDown();\n const results = [...document.querySelectorAll(\".b_algo\")].map((result) => {\n result.querySelectorAll(\"a[href]\").forEach((anchor) => {\n const href = anchor.getAttribute(\"href\");\n if (!href) {\n return;\n }\n try {\n const encoded = new URL(href, url).searchParams.get(\"u\");\n if (encoded) {\n anchor.setAttribute(\"href\", decodeBingUrl(encoded));\n }\n } catch {\n // Preserve malformed links as they appeared in the source document.\n }\n });\n\n return turndown\n .convertSoup(result)\n .split(/\\n+/)\n .map((line) => line.trim())\n .filter(Boolean)\n .join(\"\\n\");\n });\n\n const markdown = `## A Bing search for '${query}' found the following results:\\n\\n${results.join(\"\\n\\n\")}`;\n return { title: document.title || null, markdown, text_content: markdown };\n }\n}\n\nfunction decodeBingUrl(encoded: string): string {\n const input = encoded.slice(2).replace(/-/g, \"+\").replace(/_/g, \"/\").replace(/=+$/, \"\");\n const bytes: number[] = [];\n let bits = 0;\n let bitCount = 0;\n\n for (const character of input) {\n const value = BASE64_ALPHABET.indexOf(character);\n if (value < 0) {\n return encoded;\n }\n bits = (bits << 6) | value;\n bitCount += 6;\n if (bitCount >= 8) {\n bitCount -= 8;\n bytes.push((bits >> bitCount) & 0xff);\n }\n }\n\n return new TextDecoder().decode(new Uint8Array(bytes));\n}\n","import { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class HtmlConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if (extension !== \".html\" && extension !== \".htm\") {\n return null;\n }\n\n return this.convertHtml(decodeText(source));\n }\n\n async convertHtml(html: string): Promise<ConverterResult> {\n const document = parseHtmlDocument(html);\n document.querySelectorAll(\"script, style\").forEach((element) => {\n element.remove();\n });\n\n const markdown = new CustomTurnDown().convertSoup(document.body ?? document);\n return {\n title: document.title || null,\n markdown,\n text_content: markdown\n };\n }\n}\n","import mammoth from \"mammoth\";\nimport { toArrayBuffer } from \"../bytes\";\nimport type { ConverterOptions, ConverterResult } from \"../types\";\nimport { HtmlConverter } from \"./html\";\n\nexport class DocxConverter extends HtmlConverter {\n async convert(source: Uint8Array, options: ConverterOptions): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".docx\") {\n return null;\n }\n\n const html = await mammoth.convertToHtml(\n { arrayBuffer: toArrayBuffer(source) },\n {\n styleMap: options.styleMap,\n includeEmbeddedStyleMap: options.includeEmbeddedStyleMap,\n includeDefaultStyleMap: options.includeDefaultStyleMap,\n ignoreEmptyParagraphs: options.ignoreEmptyParagraphs,\n idPrefix: options.idPrefix,\n transformDocument: options.transformDocument\n }\n );\n return this.convertHtml(html.value);\n }\n}\n","import { decodeText } from \"../bytes\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\ntype NotebookCell = {\n cell_type?: string;\n source?: string[];\n};\n\ntype Notebook = {\n cells?: NotebookCell[];\n metadata?: { title?: string };\n};\n\nexport class IpynbConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".ipynb\") {\n return null;\n }\n\n const notebook = JSON.parse(decodeText(source)) as Notebook;\n const output: string[] = [];\n let title: string | null = notebook.metadata?.title ?? null;\n\n for (const cell of notebook.cells ?? []) {\n const lines = cell.source ?? [];\n if (cell.cell_type === \"markdown\") {\n output.push(lines.join(\"\"));\n title ??=\n lines\n .find((line) => line.startsWith(\"# \"))\n ?.slice(2)\n .trim() ?? null;\n } else if (cell.cell_type === \"code\") {\n output.push(`\\`\\`\\`python\\n${lines.join(\"\")}\\n\\`\\`\\``);\n } else if (cell.cell_type === \"raw\") {\n output.push(`\\`\\`\\`\\n${lines.join(\"\")}\\n\\`\\`\\``);\n }\n }\n\n const markdown = output.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n}\n","import { extractText, getDocumentProxy, getMeta } from \"unpdf\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class PdfConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".pdf\") {\n return null;\n }\n\n const pdf = await getDocumentProxy(source.slice());\n try {\n const [{ text }, { info }] = await Promise.all([\n extractText(pdf, { mergePages: true }),\n getMeta(pdf)\n ]);\n const title = typeof info.Title === \"string\" && info.Title.trim() ? info.Title : null;\n\n return { title, markdown: text, text_content: text };\n } finally {\n await pdf.loadingTask.destroy();\n }\n }\n}\n","const MIME_EXTENSIONS: Record<string, string> = {\n \"application/atom+xml\": \".atom\",\n \"application/json\": \".json\",\n \"application/pdf\": \".pdf\",\n \"application/zip\": \".zip\",\n \"application/rss+xml\": \".rss\",\n \"application/x-pdf\": \".pdf\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\": \".xlsx\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\": \".docx\",\n \"application/xml\": \".xml\",\n \"text/csv\": \".csv\",\n \"text/html\": \".html\",\n \"text/markdown\": \".md\",\n \"text/plain\": \".txt\",\n \"text/xml\": \".xml\"\n};\n\nconst TEXT_EXTENSIONS = new Set([\".csv\", \".json\", \".log\", \".markdown\", \".md\", \".text\", \".txt\"]);\n\nexport function extensionFromMime(contentType: string | null | undefined): string | null {\n if (!contentType) {\n return null;\n }\n\n const mime = contentType.split(\";\", 1)[0]?.trim().toLowerCase() ?? \"\";\n return MIME_EXTENSIONS[mime] ?? (mime.startsWith(\"text/\") ? \".txt\" : null);\n}\n\nexport function isTextExtension(extension: string): boolean {\n return TEXT_EXTENSIONS.has(extension.toLowerCase());\n}\n\nexport function extensionFromPathname(pathname: string): string | null {\n const filename = pathname.split(\"/\").pop() ?? \"\";\n const dot = filename.lastIndexOf(\".\");\n return dot > 0 ? filename.slice(dot).toLowerCase() : null;\n}\n","import { decodeText } from \"../bytes\";\nimport { isTextExtension } from \"../mime\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class PlainTextConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n if (!isTextExtension(options.file_extension ?? \"\")) {\n return null;\n }\n\n const content = decodeText(source);\n return { title: null, markdown: content, text_content: content };\n }\n}\n","import { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nconst WIKIPEDIA_URL = /^https?:\\/\\/[a-z]{2,3}\\.wikipedia\\.org\\//i;\n\nexport class WikipediaConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if ((extension !== \".html\" && extension !== \".htm\") || !WIKIPEDIA_URL.test(options.url ?? \"\")) {\n return null;\n }\n\n const document = parseHtmlDocument(decodeText(source));\n document.querySelectorAll(\"script, style\").forEach((element) => {\n element.remove();\n });\n\n const body = document.querySelector(\"div#mw-content-text\");\n const pageTitle = document.querySelector(\"span.mw-page-title-main\")?.textContent?.trim();\n const title = pageTitle || document.title || null;\n const markdown = body\n ? `# ${title ?? \"Wikipedia\"}\\n\\n${new CustomTurnDown().convertSoup(body)}`\n : new CustomTurnDown().convertSoup(document);\n\n return { title, markdown, text_content: markdown };\n }\n}\n","import * as XLSX from \"xlsx\";\nimport type { ConverterOptions, ConverterResult } from \"../types\";\nimport { HtmlConverter } from \"./html\";\n\nexport class XlsxConverter extends HtmlConverter {\n async convert(source: Uint8Array, options: ConverterOptions): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".xlsx\") {\n return null;\n }\n\n const workbook = XLSX.read(source, { type: \"array\" });\n const sections: string[] = [];\n\n for (const sheetName of workbook.SheetNames) {\n const sheet = workbook.Sheets[sheetName];\n if (sheet?.[\"!ref\"]) {\n const result = await this.convertHtml(XLSX.utils.sheet_to_html(sheet));\n sections.push(`## ${sheetName}\\n${result?.markdown.trim() ?? \"\"}`);\n }\n }\n\n const markdown = sections.join(\"\\n\\n\");\n return {\n title: workbook.Props?.Title || \"Untitled\",\n markdown,\n text_content: markdown\n };\n }\n}\n","import type { Document, Element } from \"@xmldom/xmldom\";\nimport { DOMParser } from \"@xmldom/xmldom\";\nimport { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class RSSConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if (![\".xml\", \".rss\", \".atom\"].includes(extension)) {\n return null;\n }\n\n const document = new DOMParser().parseFromString(decodeText(source), \"text/xml\");\n if (document.getElementsByTagName(\"rss\").length > 0) {\n return this.parseRss(document);\n }\n if (document.getElementsByTagName(\"feed\")[0]?.getElementsByTagName(\"entry\").length) {\n return this.parseAtom(document);\n }\n return null;\n }\n\n private parseAtom(document: Document): ConverterResult {\n const root = document.getElementsByTagName(\"feed\")[0];\n if (!root) return null;\n\n const title = getText(root, \"title\");\n const subtitle = getText(root, \"subtitle\");\n const sections = [`# ${title ?? \"Feed\"}`];\n if (subtitle) sections.push(subtitle);\n\n for (const entry of [...root.getElementsByTagName(\"entry\")]) {\n const entryTitle = getText(entry, \"title\");\n const updated = getText(entry, \"updated\");\n const summary = getText(entry, \"summary\");\n const content = getText(entry, \"content\");\n const lines: string[] = [];\n if (entryTitle) lines.push(`## ${entryTitle}`);\n if (updated) lines.push(`Updated on: ${updated}`);\n if (summary) lines.push(parseContent(summary));\n if (content) lines.push(parseContent(content));\n sections.push(lines.join(\"\\n\"));\n }\n\n const markdown = sections.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n\n private parseRss(document: Document): ConverterResult {\n const channel = document.getElementsByTagName(\"rss\")[0]?.getElementsByTagName(\"channel\")[0];\n if (!channel) return null;\n\n const title = getText(channel, \"title\");\n const description = getText(channel, \"description\");\n const sections: string[] = title ? [`# ${title}`] : [];\n if (description) sections.push(description);\n\n for (const item of [...channel.getElementsByTagName(\"item\")]) {\n const itemTitle = getText(item, \"title\");\n const published = getText(item, \"pubDate\");\n const itemDescription = getText(item, \"description\");\n const content = getText(item, \"content:encoded\");\n const lines: string[] = [];\n if (itemTitle) lines.push(`## ${itemTitle}`);\n if (published) lines.push(`Published on: ${published}`);\n if (itemDescription) lines.push(parseContent(itemDescription));\n if (content) lines.push(parseContent(content));\n sections.push(lines.join(\"\\n\"));\n }\n\n const markdown = sections.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n}\n\nfunction parseContent(content: string): string {\n return new CustomTurnDown().convertSoup(parseHtmlDocument(content).documentElement);\n}\n\nfunction getText(element: Element, tagName: string): string | null {\n const node = element.getElementsByTagName(tagName)[0];\n return node?.textContent?.trim() || null;\n}\n","import { decodeText } from \"../bytes\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class YouTubeConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if (\n (extension !== \".html\" && extension !== \".htm\") ||\n !options.url?.startsWith(\"https://www.youtube.com/watch?\")\n ) {\n return null;\n }\n\n const document = parseHtmlDocument(decodeText(source));\n const metadata: Record<string, string> = { title: document.title };\n\n document.querySelectorAll(\"meta\").forEach((meta) => {\n const content = meta.getAttribute(\"content\");\n const key =\n meta.getAttribute(\"itemprop\") ?? meta.getAttribute(\"property\") ?? meta.getAttribute(\"name\");\n if (key && content) {\n metadata[key] = content;\n }\n });\n\n try {\n for (const script of document.querySelectorAll(\"script\")) {\n const content = script.textContent ?? \"\";\n if (!content.includes(\"ytInitialData\")) {\n continue;\n }\n const start = content.indexOf(\"{\");\n const end = content.lastIndexOf(\"}\");\n if (start >= 0 && end > start) {\n const description = findKey(\n JSON.parse(content.slice(start, end + 1)),\n \"attributedDescriptionBodyText\"\n );\n if (isRecord(description) && typeof description.content === \"string\") {\n metadata.description = description.content;\n }\n }\n break;\n }\n } catch {\n // Meta description remains available when the page implementation changes.\n }\n\n const title = first(metadata, [\"title\", \"og:title\", \"name\"]) || document.title || null;\n const lines = [\"# YouTube\"];\n if (title) {\n lines.push(`## ${title}`);\n }\n\n const stats: string[] = [];\n const views = first(metadata, [\"interactionCount\"]);\n const keywords = first(metadata, [\"keywords\"]);\n const runtime = first(metadata, [\"duration\"]);\n if (views) stats.push(`- **Views:** ${views}`);\n if (keywords) stats.push(`- **Keywords:** ${keywords}`);\n if (runtime) stats.push(`- **Runtime:** ${runtime}`);\n if (stats.length > 0) {\n lines.push(`### Video Metadata\\n${stats.join(\"\\n\")}`);\n }\n\n const description = first(metadata, [\"description\", \"og:description\"]);\n if (description) {\n lines.push(`### Description\\n${description}`);\n }\n\n const markdown = lines.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n}\n\nfunction first(metadata: Record<string, string>, keys: string[]): string | null {\n for (const key of keys) {\n if (metadata[key]) return metadata[key];\n }\n return null;\n}\n\nfunction findKey(value: unknown, key: string): unknown {\n if (Array.isArray(value)) {\n for (const item of value) {\n const match = findKey(item, key);\n if (match !== undefined) return match;\n }\n } else if (isRecord(value)) {\n if (key in value) return value[key];\n for (const item of Object.values(value)) {\n const match = findKey(item, key);\n if (match !== undefined) return match;\n }\n }\n return undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n","import { unzipSync } from \"fflate\";\nimport { extensionFromPathname } from \"../mime\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class ZipConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".zip\") {\n return null;\n }\n\n const files = unzipSync(source, {\n filter: (file) => !file.name.endsWith(\"/\")\n });\n const converters = options._parent_converters ?? [];\n const zipName = options.url ?? \"archive.zip\";\n const sections = [`Content from the zip file \\`${zipName}\\`:`];\n\n for (const [name, bytes] of Object.entries(files)) {\n const result = await convertEntry(bytes, name, converters, options);\n if (result) {\n sections.push(`## File: ${name}\\n\\n${result.markdown}`);\n }\n }\n\n const markdown = sections.join(\"\\n\\n\");\n return { title: null, markdown, text_content: markdown };\n }\n}\n\nasync function convertEntry(\n source: Uint8Array,\n name: string,\n converters: DocumentConverter[],\n options: ConverterOptions\n): Promise<ConverterResult> {\n const extension = extensionFromPathname(name);\n if (!extension) {\n return null;\n }\n\n const entryOptions: ConverterOptions = {\n ...options,\n file_extension: extension,\n url: undefined,\n _parent_converters: converters\n };\n\n for (const converter of converters) {\n try {\n const result = await converter.convert(source, entryOptions);\n if (result) {\n return result;\n }\n } catch {\n // Match the original ZipConverter: skip entries that fail conversion.\n }\n }\n\n return null;\n}\n","import { isBlob, toUint8Array } from \"./bytes\";\nimport { BingSerpConverter } from \"./converters/bingserp\";\nimport { DocxConverter } from \"./converters/docx\";\nimport { HtmlConverter } from \"./converters/html\";\nimport { IpynbConverter } from \"./converters/ipynb\";\nimport { PdfConverter } from \"./converters/pdf\";\nimport { PlainTextConverter } from \"./converters/plain-text\";\nimport { WikipediaConverter } from \"./converters/wikipedia\";\nimport { XlsxConverter } from \"./converters/xlsx\";\nimport { RSSConverter } from \"./converters/xml-rss-atom\";\nimport { YouTubeConverter } from \"./converters/youtube\";\nimport { ZipConverter } from \"./converters/zip\";\nimport { extensionFromMime, extensionFromPathname } from \"./mime\";\nimport type { ByteSource, ConverterOptions, ConverterResult, DocumentConverter } from \"./types\";\n\nexport type ConversionSource = ByteSource | Response | URL | string;\n\nexport class MarkItDown {\n private readonly converters: DocumentConverter[] = [];\n\n constructor() {\n this.registerConverter(new PlainTextConverter());\n this.registerConverter(new HtmlConverter());\n this.registerConverter(new ZipConverter());\n this.registerConverter(new RSSConverter());\n this.registerConverter(new WikipediaConverter());\n this.registerConverter(new YouTubeConverter());\n this.registerConverter(new BingSerpConverter());\n this.registerConverter(new DocxConverter());\n this.registerConverter(new XlsxConverter());\n this.registerConverter(new PdfConverter());\n this.registerConverter(new IpynbConverter());\n }\n\n /** Convert a URL, response, blob, array buffer, data view, or typed array. */\n async convert(\n source: ConversionSource,\n options: ConverterOptions = {}\n ): Promise<ConverterResult> {\n if (typeof source === \"string\" || source instanceof URL) {\n return this.convertUrl(source.toString(), options);\n }\n\n if (isResponse(source)) {\n return this.convertResponse(source, options);\n }\n\n const extensions = new Set<string>();\n this.addExtension(extensions, options.file_extension);\n\n if (isBlob(source)) {\n this.addExtension(extensions, extensionFromMime(source.type));\n if (\"name\" in source && typeof source.name === \"string\") {\n this.addExtension(extensions, extensionFromPathname(source.name));\n }\n }\n\n if (extensions.size === 0) {\n throw new Error(\n \"Could not determine the file type. Provide `file_extension` when converting bytes.\"\n );\n }\n\n return this.convertBytes(await toUint8Array(source), extensions, options);\n }\n\n /**\n * @deprecated Pass the byte source directly to `convert`.\n */\n async convertBuffer(\n source: ByteSource,\n options: ConverterOptions & { file_extension: string }\n ): Promise<ConverterResult> {\n return this.convert(source, options);\n }\n\n private async convertUrl(\n source: string,\n { fetch: fetchImplementation = globalThis.fetch, ...options }: ConverterOptions\n ): Promise<ConverterResult> {\n const url = new URL(source);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n throw new Error(`Unsupported URL protocol: ${url.protocol}`);\n }\n if (!fetchImplementation) {\n throw new Error(\"No fetch implementation is available.\");\n }\n\n const response = await fetchImplementation(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch URL: ${url}, status: ${response.status}`);\n }\n\n return this.convertResponse(response, { ...options, url: url.toString() });\n }\n\n private async convertResponse(\n response: Response,\n options: ConverterOptions\n ): Promise<ConverterResult> {\n const extensions = new Set<string>();\n this.addExtension(extensions, options.file_extension);\n this.addExtension(extensions, extensionFromMime(response.headers.get(\"content-type\")));\n\n const disposition = response.headers.get(\"content-disposition\") ?? \"\";\n const filename = disposition.match(/filename\\*?=(?:UTF-8''|[\"']?)([^;\"']+)/i)?.[1];\n if (filename) {\n this.addExtension(extensions, extensionFromPathname(decodeURIComponent(filename.trim())));\n }\n\n const responseUrl = options.url || response.url;\n if (responseUrl) {\n this.addExtension(extensions, extensionFromPathname(new URL(responseUrl).pathname));\n }\n\n if (extensions.size === 0) {\n throw new Error(\n \"Could not determine the file type. Provide `file_extension` or a Content-Type header.\"\n );\n }\n\n return this.convertBytes(new Uint8Array(await response.arrayBuffer()), extensions, {\n ...options,\n url: responseUrl\n });\n }\n\n private async convertBytes(\n source: Uint8Array,\n extensions: Set<string>,\n options: ConverterOptions\n ): Promise<ConverterResult> {\n let lastError: unknown;\n\n for (const extension of extensions) {\n for (const converter of this.converters) {\n try {\n const result = await converter.convert(source, {\n ...options,\n file_extension: extension,\n _parent_converters: this.converters\n });\n if (result) {\n result.markdown = result.markdown\n .replace(/\\r\\n|\\r|\\n/g, \"\\n\")\n .trim()\n .replace(/\\n{3,}/g, \"\\n\\n\");\n result.text_content = result.markdown;\n return result;\n }\n } catch (error) {\n lastError = error;\n }\n }\n }\n\n const formats = [...extensions].join(\", \");\n if (lastError) {\n throw new Error(`Could not convert ${formats} to Markdown: ${String(lastError)}`);\n }\n throw new Error(`Unsupported file type: ${formats}.`);\n }\n\n private addExtension(extensions: Set<string>, extension: string | null | undefined): void {\n if (!extension) {\n return;\n }\n extensions.add(\n extension.startsWith(\".\") ? extension.toLowerCase() : `.${extension.toLowerCase()}`\n );\n }\n\n private registerConverter(converter: DocumentConverter): void {\n this.converters.unshift(converter);\n }\n}\n\nfunction isResponse(value: unknown): value is Response {\n return typeof Response !== \"undefined\" && value instanceof Response;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/markitdown.ts"],"mappings":";KAAY;EACV;EACA;;EAEA;;;;;;;;KASU,aAAa,aAAa,kBAAkB,kBAAkB;KAE9D;;EAEV;;EAEA;;EAEA,eAAe;;EAEf;EACA;EACA;EACA;EACA;EACA,qBAAqB;EACrB,qBAAqB;;UAGN;EACf,QAAQ,QAAQ,YAAY,SAAS,mBAAmB,QAAQ;;;;KCpBtD,mBAAmB,aAAa,WAAW;cAE1C;mBACM;EAEjB;;EAaM,QACJ,QAAQ,kBACR,UAAS,mBACR,QAAQ;;;;EA+BL,cACJ,QAAQ,YACR,SAAS;IAAqB;MAC7B,QAAQ;UAIG;UAoBA;UA+BA;UAoCN;UASA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/markitdown.ts"],"mappings":";KAAY;EACV;EACA;;EAEA;;;;;;;;KASU,aAAa,aAAa,kBAAkB,kBAAkB;KAE9D;;EAEV;;EAEA;;EAEA,eAAe;;EAEf;EACA;EACA;EACA;EACA;EACA,qBAAqB;EACrB,qBAAqB;;UAGN;EACf,QAAQ,QAAQ,YAAY,SAAS,mBAAmB,QAAQ;;;;KClBtD,mBAAmB,aAAa,WAAW;cAE1C;mBACM;EAEjB;;EAeM,QACJ,QAAQ,kBACR,UAAS,mBACR,QAAQ;;;;EA+BL,cACJ,QAAQ,YACR,SAAS;IAAqB;MAC7B,QAAQ;UAIG;UAoBA;UA+BA;UAoCN;UASA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/markitdown.ts"],"mappings":";KAAY;EACV;EACA;;EAEA;;;;;;;;KASU,aAAa,aAAa,kBAAkB,kBAAkB;KAE9D;;EAEV;;EAEA;;EAEA,eAAe;;EAEf;EACA;EACA;EACA;EACA;EACA,qBAAqB;EACrB,qBAAqB;;UAGN;EACf,QAAQ,QAAQ,YAAY,SAAS,mBAAmB,QAAQ;;;;KCpBtD,mBAAmB,aAAa,WAAW;cAE1C;mBACM;EAEjB;;EAaM,QACJ,QAAQ,kBACR,UAAS,mBACR,QAAQ;;;;EA+BL,cACJ,QAAQ,YACR,SAAS;IAAqB;MAC7B,QAAQ;UAIG;UAoBA;UA+BA;UAoCN;UASA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/markitdown.ts"],"mappings":";KAAY;EACV;EACA;;EAEA;;;;;;;;KASU,aAAa,aAAa,kBAAkB,kBAAkB;KAE9D;;EAEV;;EAEA;;EAEA,eAAe;;EAEf;EACA;EACA;EACA;EACA;EACA,qBAAqB;EACrB,qBAAqB;;UAGN;EACf,QAAQ,QAAQ,YAAY,SAAS,mBAAmB,QAAQ;;;;KClBtD,mBAAmB,aAAa,WAAW;cAE1C;mBACM;EAEjB;;EAeM,QACJ,QAAQ,kBACR,UAAS,mBACR,QAAQ;;;;EA+BL,cACJ,QAAQ,YACR,SAAS;IAAqB;MAC7B,QAAQ;UAIG;UAoBA;UA+BA;UAoCN;UASA"}
package/dist/index.js CHANGED
@@ -2,8 +2,10 @@ import turndownPluginGfm from "@joplin/turndown-plugin-gfm";
2
2
  import TurndownService from "turndown";
3
3
  import { parseHTML } from "linkedom";
4
4
  import mammoth from "mammoth";
5
+ import { extractText, getDocumentProxy, getMeta } from "unpdf";
5
6
  import * as XLSX from "xlsx";
6
7
  import { DOMParser } from "@xmldom/xmldom";
8
+ import { unzipSync } from "fflate";
7
9
  //#region src/bytes.ts
8
10
  async function toUint8Array(source) {
9
11
  if (source instanceof Uint8Array) return source;
@@ -183,11 +185,32 @@ var IpynbConverter = class {
183
185
  }
184
186
  };
185
187
  //#endregion
188
+ //#region src/converters/pdf.ts
189
+ var PdfConverter = class {
190
+ async convert(source, options) {
191
+ if (options.file_extension?.toLowerCase() !== ".pdf") return null;
192
+ const pdf = await getDocumentProxy(source.slice());
193
+ try {
194
+ const [{ text }, { info }] = await Promise.all([extractText(pdf, { mergePages: true }), getMeta(pdf)]);
195
+ return {
196
+ title: typeof info.Title === "string" && info.Title.trim() ? info.Title : null,
197
+ markdown: text,
198
+ text_content: text
199
+ };
200
+ } finally {
201
+ await pdf.loadingTask.destroy();
202
+ }
203
+ }
204
+ };
205
+ //#endregion
186
206
  //#region src/mime.ts
187
207
  const MIME_EXTENSIONS = {
188
208
  "application/atom+xml": ".atom",
189
209
  "application/json": ".json",
210
+ "application/pdf": ".pdf",
211
+ "application/zip": ".zip",
190
212
  "application/rss+xml": ".rss",
213
+ "application/x-pdf": ".pdf",
191
214
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ".xlsx",
192
215
  "application/vnd.openxmlformats-officedocument.wordprocessingml.document": ".docx",
193
216
  "application/xml": ".xml",
@@ -421,18 +444,55 @@ function isRecord(value) {
421
444
  return typeof value === "object" && value !== null;
422
445
  }
423
446
  //#endregion
447
+ //#region src/converters/zip.ts
448
+ var ZipConverter = class {
449
+ async convert(source, options = {}) {
450
+ if (options.file_extension?.toLowerCase() !== ".zip") return null;
451
+ const files = unzipSync(source, { filter: (file) => !file.name.endsWith("/") });
452
+ const converters = options._parent_converters ?? [];
453
+ const sections = [`Content from the zip file \`${options.url ?? "archive.zip"}\`:`];
454
+ for (const [name, bytes] of Object.entries(files)) {
455
+ const result = await convertEntry(bytes, name, converters, options);
456
+ if (result) sections.push(`## File: ${name}\n\n${result.markdown}`);
457
+ }
458
+ const markdown = sections.join("\n\n");
459
+ return {
460
+ title: null,
461
+ markdown,
462
+ text_content: markdown
463
+ };
464
+ }
465
+ };
466
+ async function convertEntry(source, name, converters, options) {
467
+ const extension = extensionFromPathname(name);
468
+ if (!extension) return null;
469
+ const entryOptions = {
470
+ ...options,
471
+ file_extension: extension,
472
+ url: void 0,
473
+ _parent_converters: converters
474
+ };
475
+ for (const converter of converters) try {
476
+ const result = await converter.convert(source, entryOptions);
477
+ if (result) return result;
478
+ } catch {}
479
+ return null;
480
+ }
481
+ //#endregion
424
482
  //#region src/markitdown.ts
425
483
  var MarkItDown = class {
426
484
  constructor() {
427
485
  this.converters = [];
428
486
  this.registerConverter(new PlainTextConverter());
429
487
  this.registerConverter(new HtmlConverter());
488
+ this.registerConverter(new ZipConverter());
430
489
  this.registerConverter(new RSSConverter());
431
490
  this.registerConverter(new WikipediaConverter());
432
491
  this.registerConverter(new YouTubeConverter());
433
492
  this.registerConverter(new BingSerpConverter());
434
493
  this.registerConverter(new DocxConverter());
435
494
  this.registerConverter(new XlsxConverter());
495
+ this.registerConverter(new PdfConverter());
436
496
  this.registerConverter(new IpynbConverter());
437
497
  }
438
498
  /** Convert a URL, response, blob, array buffer, data view, or typed array. */
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/bytes.ts","../src/custom-turndown.ts","../src/html-document.ts","../src/converters/bingserp.ts","../src/converters/html.ts","../src/converters/docx.ts","../src/converters/ipynb.ts","../src/mime.ts","../src/converters/plain-text.ts","../src/converters/wikipedia.ts","../src/converters/xlsx.ts","../src/converters/xml-rss-atom.ts","../src/converters/youtube.ts","../src/markitdown.ts"],"sourcesContent":["import type { ByteSource } from \"./types\";\n\nexport async function toUint8Array(source: ByteSource): Promise<Uint8Array> {\n if (source instanceof Uint8Array) {\n return source;\n }\n\n if (isBlob(source)) {\n return new Uint8Array(await source.arrayBuffer());\n }\n\n if (ArrayBuffer.isView(source)) {\n return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);\n }\n\n return new Uint8Array(source);\n}\n\nexport function toArrayBuffer(source: Uint8Array): ArrayBuffer {\n return source.slice().buffer;\n}\n\nexport function decodeText(source: Uint8Array): string {\n return new TextDecoder().decode(source);\n}\n\nexport function isBlob(value: unknown): value is Blob {\n return typeof Blob !== \"undefined\" && value instanceof Blob;\n}\n\nexport function normalizeExtension(extension: string): string {\n if (!extension) {\n return \"\";\n }\n\n const normalized = extension.toLowerCase();\n return normalized.startsWith(\".\") ? normalized : `.${normalized}`;\n}\n","import turndownPluginGfm from \"@joplin/turndown-plugin-gfm\";\nimport TurndownService from \"turndown\";\n\nexport class CustomTurnDown {\n convertSoup(document: string | Node): string {\n const service = new TurndownService({ headingStyle: \"atx\" });\n service.use(turndownPluginGfm.gfm);\n\n service.addRule(\"anchor tags\", {\n filter: [\"a\"],\n replacement(content, node) {\n if (!content) return \"\";\n\n const prefix = content.startsWith(\" \") ? \" \" : \"\";\n const suffix = content.endsWith(\" \") ? \" \" : \"\";\n const text = content.trim().replace(/\\n\\n.*/g, \"\");\n if (!text) return \"\";\n\n const element = node as unknown as Element;\n const href = element.getAttribute(\"href\");\n let title = element.getAttribute(\"title\") ?? \"\";\n if (!href) return `${prefix}${text}${suffix}`;\n\n try {\n const url = new URL(href);\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n return `${prefix}${text}${suffix}`;\n }\n } catch {\n if (\n !href.startsWith(\"/\") &&\n !href.startsWith(\"#\") &&\n !href.startsWith(\"./\") &&\n !href.startsWith(\"../\")\n ) {\n return `${prefix}${text}${suffix}`;\n }\n }\n\n if (text.replace(/\\\\_/g, \"_\") === href && !title) {\n return `<${href}>`;\n }\n if (!title) title = href;\n return `${prefix}[${text}](${href}${title ? ` \"${title}\"` : \"\"})${suffix}`;\n }\n });\n\n service.addRule(\"img tags\", {\n filter: [\"img\"],\n replacement(_content, node) {\n const element = node as unknown as Element;\n const alt = element.getAttribute(\"alt\") ?? \"\";\n let source = element.getAttribute(\"src\") ?? \"\";\n const title = element.getAttribute(\"title\");\n if (source.startsWith(\"data:\")) {\n source = `${source.split(\",\", 1)[0]}...`;\n }\n return `![${alt}](${source}${title ? ` \"${title}\"` : \"\"})`;\n }\n });\n\n return service.turndown(document as TurndownService.Node);\n }\n}\n","import { parseHTML } from \"linkedom\";\n\nexport function parseHtmlDocument(html: string): Document {\n return parseHTML(html).document as unknown as Document;\n}\n","import { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nconst BING_SEARCH_URL = /^https:\\/\\/www\\.bing\\.com\\/search\\?q=/i;\nconst BASE64_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\nexport class BingSerpConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n const url = options.url ?? \"\";\n if ((extension !== \".html\" && extension !== \".htm\") || !BING_SEARCH_URL.test(url)) {\n return null;\n }\n\n const document = parseHtmlDocument(decodeText(source));\n const query = new URL(url).searchParams.get(\"q\") ?? \"\";\n\n document.querySelectorAll(\".tptt\").forEach((element) => {\n if (element.textContent) {\n element.textContent += \" \";\n }\n });\n document.querySelectorAll(\".algoSlug_icon\").forEach((element) => {\n element.remove();\n });\n\n const turndown = new CustomTurnDown();\n const results = [...document.querySelectorAll(\".b_algo\")].map((result) => {\n result.querySelectorAll(\"a[href]\").forEach((anchor) => {\n const href = anchor.getAttribute(\"href\");\n if (!href) {\n return;\n }\n try {\n const encoded = new URL(href, url).searchParams.get(\"u\");\n if (encoded) {\n anchor.setAttribute(\"href\", decodeBingUrl(encoded));\n }\n } catch {\n // Preserve malformed links as they appeared in the source document.\n }\n });\n\n return turndown\n .convertSoup(result)\n .split(/\\n+/)\n .map((line) => line.trim())\n .filter(Boolean)\n .join(\"\\n\");\n });\n\n const markdown = `## A Bing search for '${query}' found the following results:\\n\\n${results.join(\"\\n\\n\")}`;\n return { title: document.title || null, markdown, text_content: markdown };\n }\n}\n\nfunction decodeBingUrl(encoded: string): string {\n const input = encoded.slice(2).replace(/-/g, \"+\").replace(/_/g, \"/\").replace(/=+$/, \"\");\n const bytes: number[] = [];\n let bits = 0;\n let bitCount = 0;\n\n for (const character of input) {\n const value = BASE64_ALPHABET.indexOf(character);\n if (value < 0) {\n return encoded;\n }\n bits = (bits << 6) | value;\n bitCount += 6;\n if (bitCount >= 8) {\n bitCount -= 8;\n bytes.push((bits >> bitCount) & 0xff);\n }\n }\n\n return new TextDecoder().decode(new Uint8Array(bytes));\n}\n","import { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class HtmlConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if (extension !== \".html\" && extension !== \".htm\") {\n return null;\n }\n\n return this.convertHtml(decodeText(source));\n }\n\n async convertHtml(html: string): Promise<ConverterResult> {\n const document = parseHtmlDocument(html);\n document.querySelectorAll(\"script, style\").forEach((element) => {\n element.remove();\n });\n\n const markdown = new CustomTurnDown().convertSoup(document.body ?? document);\n return {\n title: document.title || null,\n markdown,\n text_content: markdown\n };\n }\n}\n","import mammoth from \"mammoth\";\nimport { toArrayBuffer } from \"../bytes\";\nimport type { ConverterOptions, ConverterResult } from \"../types\";\nimport { HtmlConverter } from \"./html\";\n\nexport class DocxConverter extends HtmlConverter {\n async convert(source: Uint8Array, options: ConverterOptions): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".docx\") {\n return null;\n }\n\n const html = await mammoth.convertToHtml(\n { arrayBuffer: toArrayBuffer(source) },\n {\n styleMap: options.styleMap,\n includeEmbeddedStyleMap: options.includeEmbeddedStyleMap,\n includeDefaultStyleMap: options.includeDefaultStyleMap,\n ignoreEmptyParagraphs: options.ignoreEmptyParagraphs,\n idPrefix: options.idPrefix,\n transformDocument: options.transformDocument\n }\n );\n return this.convertHtml(html.value);\n }\n}\n","import { decodeText } from \"../bytes\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\ntype NotebookCell = {\n cell_type?: string;\n source?: string[];\n};\n\ntype Notebook = {\n cells?: NotebookCell[];\n metadata?: { title?: string };\n};\n\nexport class IpynbConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".ipynb\") {\n return null;\n }\n\n const notebook = JSON.parse(decodeText(source)) as Notebook;\n const output: string[] = [];\n let title: string | null = notebook.metadata?.title ?? null;\n\n for (const cell of notebook.cells ?? []) {\n const lines = cell.source ?? [];\n if (cell.cell_type === \"markdown\") {\n output.push(lines.join(\"\"));\n title ??=\n lines\n .find((line) => line.startsWith(\"# \"))\n ?.slice(2)\n .trim() ?? null;\n } else if (cell.cell_type === \"code\") {\n output.push(`\\`\\`\\`python\\n${lines.join(\"\")}\\n\\`\\`\\``);\n } else if (cell.cell_type === \"raw\") {\n output.push(`\\`\\`\\`\\n${lines.join(\"\")}\\n\\`\\`\\``);\n }\n }\n\n const markdown = output.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n}\n","const MIME_EXTENSIONS: Record<string, string> = {\n \"application/atom+xml\": \".atom\",\n \"application/json\": \".json\",\n \"application/rss+xml\": \".rss\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\": \".xlsx\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\": \".docx\",\n \"application/xml\": \".xml\",\n \"text/csv\": \".csv\",\n \"text/html\": \".html\",\n \"text/markdown\": \".md\",\n \"text/plain\": \".txt\",\n \"text/xml\": \".xml\"\n};\n\nconst TEXT_EXTENSIONS = new Set([\".csv\", \".json\", \".log\", \".markdown\", \".md\", \".text\", \".txt\"]);\n\nexport function extensionFromMime(contentType: string | null | undefined): string | null {\n if (!contentType) {\n return null;\n }\n\n const mime = contentType.split(\";\", 1)[0]?.trim().toLowerCase() ?? \"\";\n return MIME_EXTENSIONS[mime] ?? (mime.startsWith(\"text/\") ? \".txt\" : null);\n}\n\nexport function isTextExtension(extension: string): boolean {\n return TEXT_EXTENSIONS.has(extension.toLowerCase());\n}\n\nexport function extensionFromPathname(pathname: string): string | null {\n const filename = pathname.split(\"/\").pop() ?? \"\";\n const dot = filename.lastIndexOf(\".\");\n return dot > 0 ? filename.slice(dot).toLowerCase() : null;\n}\n","import { decodeText } from \"../bytes\";\nimport { isTextExtension } from \"../mime\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class PlainTextConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n if (!isTextExtension(options.file_extension ?? \"\")) {\n return null;\n }\n\n const content = decodeText(source);\n return { title: null, markdown: content, text_content: content };\n }\n}\n","import { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nconst WIKIPEDIA_URL = /^https?:\\/\\/[a-z]{2,3}\\.wikipedia\\.org\\//i;\n\nexport class WikipediaConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if ((extension !== \".html\" && extension !== \".htm\") || !WIKIPEDIA_URL.test(options.url ?? \"\")) {\n return null;\n }\n\n const document = parseHtmlDocument(decodeText(source));\n document.querySelectorAll(\"script, style\").forEach((element) => {\n element.remove();\n });\n\n const body = document.querySelector(\"div#mw-content-text\");\n const pageTitle = document.querySelector(\"span.mw-page-title-main\")?.textContent?.trim();\n const title = pageTitle || document.title || null;\n const markdown = body\n ? `# ${title ?? \"Wikipedia\"}\\n\\n${new CustomTurnDown().convertSoup(body)}`\n : new CustomTurnDown().convertSoup(document);\n\n return { title, markdown, text_content: markdown };\n }\n}\n","import * as XLSX from \"xlsx\";\nimport type { ConverterOptions, ConverterResult } from \"../types\";\nimport { HtmlConverter } from \"./html\";\n\nexport class XlsxConverter extends HtmlConverter {\n async convert(source: Uint8Array, options: ConverterOptions): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".xlsx\") {\n return null;\n }\n\n const workbook = XLSX.read(source, { type: \"array\" });\n const sections: string[] = [];\n\n for (const sheetName of workbook.SheetNames) {\n const sheet = workbook.Sheets[sheetName];\n if (sheet?.[\"!ref\"]) {\n const result = await this.convertHtml(XLSX.utils.sheet_to_html(sheet));\n sections.push(`## ${sheetName}\\n${result?.markdown.trim() ?? \"\"}`);\n }\n }\n\n const markdown = sections.join(\"\\n\\n\");\n return {\n title: workbook.Props?.Title || \"Untitled\",\n markdown,\n text_content: markdown\n };\n }\n}\n","import type { Document, Element } from \"@xmldom/xmldom\";\nimport { DOMParser } from \"@xmldom/xmldom\";\nimport { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class RSSConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if (![\".xml\", \".rss\", \".atom\"].includes(extension)) {\n return null;\n }\n\n const document = new DOMParser().parseFromString(decodeText(source), \"text/xml\");\n if (document.getElementsByTagName(\"rss\").length > 0) {\n return this.parseRss(document);\n }\n if (document.getElementsByTagName(\"feed\")[0]?.getElementsByTagName(\"entry\").length) {\n return this.parseAtom(document);\n }\n return null;\n }\n\n private parseAtom(document: Document): ConverterResult {\n const root = document.getElementsByTagName(\"feed\")[0];\n if (!root) return null;\n\n const title = getText(root, \"title\");\n const subtitle = getText(root, \"subtitle\");\n const sections = [`# ${title ?? \"Feed\"}`];\n if (subtitle) sections.push(subtitle);\n\n for (const entry of [...root.getElementsByTagName(\"entry\")]) {\n const entryTitle = getText(entry, \"title\");\n const updated = getText(entry, \"updated\");\n const summary = getText(entry, \"summary\");\n const content = getText(entry, \"content\");\n const lines: string[] = [];\n if (entryTitle) lines.push(`## ${entryTitle}`);\n if (updated) lines.push(`Updated on: ${updated}`);\n if (summary) lines.push(parseContent(summary));\n if (content) lines.push(parseContent(content));\n sections.push(lines.join(\"\\n\"));\n }\n\n const markdown = sections.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n\n private parseRss(document: Document): ConverterResult {\n const channel = document.getElementsByTagName(\"rss\")[0]?.getElementsByTagName(\"channel\")[0];\n if (!channel) return null;\n\n const title = getText(channel, \"title\");\n const description = getText(channel, \"description\");\n const sections: string[] = title ? [`# ${title}`] : [];\n if (description) sections.push(description);\n\n for (const item of [...channel.getElementsByTagName(\"item\")]) {\n const itemTitle = getText(item, \"title\");\n const published = getText(item, \"pubDate\");\n const itemDescription = getText(item, \"description\");\n const content = getText(item, \"content:encoded\");\n const lines: string[] = [];\n if (itemTitle) lines.push(`## ${itemTitle}`);\n if (published) lines.push(`Published on: ${published}`);\n if (itemDescription) lines.push(parseContent(itemDescription));\n if (content) lines.push(parseContent(content));\n sections.push(lines.join(\"\\n\"));\n }\n\n const markdown = sections.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n}\n\nfunction parseContent(content: string): string {\n return new CustomTurnDown().convertSoup(parseHtmlDocument(content).documentElement);\n}\n\nfunction getText(element: Element, tagName: string): string | null {\n const node = element.getElementsByTagName(tagName)[0];\n return node?.textContent?.trim() || null;\n}\n","import { decodeText } from \"../bytes\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class YouTubeConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if (\n (extension !== \".html\" && extension !== \".htm\") ||\n !options.url?.startsWith(\"https://www.youtube.com/watch?\")\n ) {\n return null;\n }\n\n const document = parseHtmlDocument(decodeText(source));\n const metadata: Record<string, string> = { title: document.title };\n\n document.querySelectorAll(\"meta\").forEach((meta) => {\n const content = meta.getAttribute(\"content\");\n const key =\n meta.getAttribute(\"itemprop\") ?? meta.getAttribute(\"property\") ?? meta.getAttribute(\"name\");\n if (key && content) {\n metadata[key] = content;\n }\n });\n\n try {\n for (const script of document.querySelectorAll(\"script\")) {\n const content = script.textContent ?? \"\";\n if (!content.includes(\"ytInitialData\")) {\n continue;\n }\n const start = content.indexOf(\"{\");\n const end = content.lastIndexOf(\"}\");\n if (start >= 0 && end > start) {\n const description = findKey(\n JSON.parse(content.slice(start, end + 1)),\n \"attributedDescriptionBodyText\"\n );\n if (isRecord(description) && typeof description.content === \"string\") {\n metadata.description = description.content;\n }\n }\n break;\n }\n } catch {\n // Meta description remains available when the page implementation changes.\n }\n\n const title = first(metadata, [\"title\", \"og:title\", \"name\"]) || document.title || null;\n const lines = [\"# YouTube\"];\n if (title) {\n lines.push(`## ${title}`);\n }\n\n const stats: string[] = [];\n const views = first(metadata, [\"interactionCount\"]);\n const keywords = first(metadata, [\"keywords\"]);\n const runtime = first(metadata, [\"duration\"]);\n if (views) stats.push(`- **Views:** ${views}`);\n if (keywords) stats.push(`- **Keywords:** ${keywords}`);\n if (runtime) stats.push(`- **Runtime:** ${runtime}`);\n if (stats.length > 0) {\n lines.push(`### Video Metadata\\n${stats.join(\"\\n\")}`);\n }\n\n const description = first(metadata, [\"description\", \"og:description\"]);\n if (description) {\n lines.push(`### Description\\n${description}`);\n }\n\n const markdown = lines.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n}\n\nfunction first(metadata: Record<string, string>, keys: string[]): string | null {\n for (const key of keys) {\n if (metadata[key]) return metadata[key];\n }\n return null;\n}\n\nfunction findKey(value: unknown, key: string): unknown {\n if (Array.isArray(value)) {\n for (const item of value) {\n const match = findKey(item, key);\n if (match !== undefined) return match;\n }\n } else if (isRecord(value)) {\n if (key in value) return value[key];\n for (const item of Object.values(value)) {\n const match = findKey(item, key);\n if (match !== undefined) return match;\n }\n }\n return undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n","import { isBlob, toUint8Array } from \"./bytes\";\nimport { BingSerpConverter } from \"./converters/bingserp\";\nimport { DocxConverter } from \"./converters/docx\";\nimport { HtmlConverter } from \"./converters/html\";\nimport { IpynbConverter } from \"./converters/ipynb\";\nimport { PlainTextConverter } from \"./converters/plain-text\";\nimport { WikipediaConverter } from \"./converters/wikipedia\";\nimport { XlsxConverter } from \"./converters/xlsx\";\nimport { RSSConverter } from \"./converters/xml-rss-atom\";\nimport { YouTubeConverter } from \"./converters/youtube\";\nimport { extensionFromMime, extensionFromPathname } from \"./mime\";\nimport type { ByteSource, ConverterOptions, ConverterResult, DocumentConverter } from \"./types\";\n\nexport type ConversionSource = ByteSource | Response | URL | string;\n\nexport class MarkItDown {\n private readonly converters: DocumentConverter[] = [];\n\n constructor() {\n this.registerConverter(new PlainTextConverter());\n this.registerConverter(new HtmlConverter());\n this.registerConverter(new RSSConverter());\n this.registerConverter(new WikipediaConverter());\n this.registerConverter(new YouTubeConverter());\n this.registerConverter(new BingSerpConverter());\n this.registerConverter(new DocxConverter());\n this.registerConverter(new XlsxConverter());\n this.registerConverter(new IpynbConverter());\n }\n\n /** Convert a URL, response, blob, array buffer, data view, or typed array. */\n async convert(\n source: ConversionSource,\n options: ConverterOptions = {}\n ): Promise<ConverterResult> {\n if (typeof source === \"string\" || source instanceof URL) {\n return this.convertUrl(source.toString(), options);\n }\n\n if (isResponse(source)) {\n return this.convertResponse(source, options);\n }\n\n const extensions = new Set<string>();\n this.addExtension(extensions, options.file_extension);\n\n if (isBlob(source)) {\n this.addExtension(extensions, extensionFromMime(source.type));\n if (\"name\" in source && typeof source.name === \"string\") {\n this.addExtension(extensions, extensionFromPathname(source.name));\n }\n }\n\n if (extensions.size === 0) {\n throw new Error(\n \"Could not determine the file type. Provide `file_extension` when converting bytes.\"\n );\n }\n\n return this.convertBytes(await toUint8Array(source), extensions, options);\n }\n\n /**\n * @deprecated Pass the byte source directly to `convert`.\n */\n async convertBuffer(\n source: ByteSource,\n options: ConverterOptions & { file_extension: string }\n ): Promise<ConverterResult> {\n return this.convert(source, options);\n }\n\n private async convertUrl(\n source: string,\n { fetch: fetchImplementation = globalThis.fetch, ...options }: ConverterOptions\n ): Promise<ConverterResult> {\n const url = new URL(source);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n throw new Error(`Unsupported URL protocol: ${url.protocol}`);\n }\n if (!fetchImplementation) {\n throw new Error(\"No fetch implementation is available.\");\n }\n\n const response = await fetchImplementation(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch URL: ${url}, status: ${response.status}`);\n }\n\n return this.convertResponse(response, { ...options, url: url.toString() });\n }\n\n private async convertResponse(\n response: Response,\n options: ConverterOptions\n ): Promise<ConverterResult> {\n const extensions = new Set<string>();\n this.addExtension(extensions, options.file_extension);\n this.addExtension(extensions, extensionFromMime(response.headers.get(\"content-type\")));\n\n const disposition = response.headers.get(\"content-disposition\") ?? \"\";\n const filename = disposition.match(/filename\\*?=(?:UTF-8''|[\"']?)([^;\"']+)/i)?.[1];\n if (filename) {\n this.addExtension(extensions, extensionFromPathname(decodeURIComponent(filename.trim())));\n }\n\n const responseUrl = options.url || response.url;\n if (responseUrl) {\n this.addExtension(extensions, extensionFromPathname(new URL(responseUrl).pathname));\n }\n\n if (extensions.size === 0) {\n throw new Error(\n \"Could not determine the file type. Provide `file_extension` or a Content-Type header.\"\n );\n }\n\n return this.convertBytes(new Uint8Array(await response.arrayBuffer()), extensions, {\n ...options,\n url: responseUrl\n });\n }\n\n private async convertBytes(\n source: Uint8Array,\n extensions: Set<string>,\n options: ConverterOptions\n ): Promise<ConverterResult> {\n let lastError: unknown;\n\n for (const extension of extensions) {\n for (const converter of this.converters) {\n try {\n const result = await converter.convert(source, {\n ...options,\n file_extension: extension,\n _parent_converters: this.converters\n });\n if (result) {\n result.markdown = result.markdown\n .replace(/\\r\\n|\\r|\\n/g, \"\\n\")\n .trim()\n .replace(/\\n{3,}/g, \"\\n\\n\");\n result.text_content = result.markdown;\n return result;\n }\n } catch (error) {\n lastError = error;\n }\n }\n }\n\n const formats = [...extensions].join(\", \");\n if (lastError) {\n throw new Error(`Could not convert ${formats} to Markdown: ${String(lastError)}`);\n }\n throw new Error(`Unsupported file type: ${formats}.`);\n }\n\n private addExtension(extensions: Set<string>, extension: string | null | undefined): void {\n if (!extension) {\n return;\n }\n extensions.add(\n extension.startsWith(\".\") ? extension.toLowerCase() : `.${extension.toLowerCase()}`\n );\n }\n\n private registerConverter(converter: DocumentConverter): void {\n this.converters.unshift(converter);\n }\n}\n\nfunction isResponse(value: unknown): value is Response {\n return typeof Response !== \"undefined\" && value instanceof Response;\n}\n"],"mappings":";;;;;;;AAEA,eAAsB,aAAa,QAAyC;CAC1E,IAAI,kBAAkB,YACpB,OAAO;CAGT,IAAI,OAAO,MAAM,GACf,OAAO,IAAI,WAAW,MAAM,OAAO,YAAY,CAAC;CAGlD,IAAI,YAAY,OAAO,MAAM,GAC3B,OAAO,IAAI,WAAW,OAAO,QAAQ,OAAO,YAAY,OAAO,UAAU;CAG3E,OAAO,IAAI,WAAW,MAAM;AAC9B;AAEA,SAAgB,cAAc,QAAiC;CAC7D,OAAO,OAAO,MAAM,CAAC,CAAC;AACxB;AAEA,SAAgB,WAAW,QAA4B;CACrD,OAAO,IAAI,YAAY,CAAC,CAAC,OAAO,MAAM;AACxC;AAEA,SAAgB,OAAO,OAA+B;CACpD,OAAO,OAAO,SAAS,eAAe,iBAAiB;AACzD;;;ACzBA,IAAa,iBAAb,MAA4B;CAC1B,YAAY,UAAiC;EAC3C,MAAM,UAAU,IAAI,gBAAgB,EAAE,cAAc,MAAM,CAAC;EAC3D,QAAQ,IAAI,kBAAkB,GAAG;EAEjC,QAAQ,QAAQ,eAAe;GAC7B,QAAQ,CAAC,GAAG;GACZ,YAAY,SAAS,MAAM;IACzB,IAAI,CAAC,SAAS,OAAO;IAErB,MAAM,SAAS,QAAQ,WAAW,GAAG,IAAI,MAAM;IAC/C,MAAM,SAAS,QAAQ,SAAS,GAAG,IAAI,MAAM;IAC7C,MAAM,OAAO,QAAQ,KAAK,CAAC,CAAC,QAAQ,WAAW,EAAE;IACjD,IAAI,CAAC,MAAM,OAAO;IAElB,MAAM,UAAU;IAChB,MAAM,OAAO,QAAQ,aAAa,MAAM;IACxC,IAAI,QAAQ,QAAQ,aAAa,OAAO,KAAK;IAC7C,IAAI,CAAC,MAAM,OAAO,GAAG,SAAS,OAAO;IAErC,IAAI;KACF,MAAM,MAAM,IAAI,IAAI,IAAI;KACxB,IAAI,IAAI,aAAa,YAAY,IAAI,aAAa,SAChD,OAAO,GAAG,SAAS,OAAO;IAE9B,QAAQ;KACN,IACE,CAAC,KAAK,WAAW,GAAG,KACpB,CAAC,KAAK,WAAW,GAAG,KACpB,CAAC,KAAK,WAAW,IAAI,KACrB,CAAC,KAAK,WAAW,KAAK,GAEtB,OAAO,GAAG,SAAS,OAAO;IAE9B;IAEA,IAAI,KAAK,QAAQ,QAAQ,GAAG,MAAM,QAAQ,CAAC,OACzC,OAAO,IAAI,KAAK;IAElB,IAAI,CAAC,OAAO,QAAQ;IACpB,OAAO,GAAG,OAAO,GAAG,KAAK,IAAI,OAAO,QAAQ,KAAK,MAAM,KAAK,GAAG,GAAG;GACpE;EACF,CAAC;EAED,QAAQ,QAAQ,YAAY;GAC1B,QAAQ,CAAC,KAAK;GACd,YAAY,UAAU,MAAM;IAC1B,MAAM,UAAU;IAChB,MAAM,MAAM,QAAQ,aAAa,KAAK,KAAK;IAC3C,IAAI,SAAS,QAAQ,aAAa,KAAK,KAAK;IAC5C,MAAM,QAAQ,QAAQ,aAAa,OAAO;IAC1C,IAAI,OAAO,WAAW,OAAO,GAC3B,SAAS,GAAG,OAAO,MAAM,KAAK,CAAC,CAAC,CAAC,GAAG;IAEtC,OAAO,KAAK,IAAI,IAAI,SAAS,QAAQ,KAAK,MAAM,KAAK,GAAG;GAC1D;EACF,CAAC;EAED,OAAO,QAAQ,SAAS,QAAgC;CAC1D;AACF;;;AC7DA,SAAgB,kBAAkB,MAAwB;CACxD,OAAO,UAAU,IAAI,CAAC,CAAC;AACzB;;;ACCA,MAAM,kBAAkB;AACxB,MAAM,kBAAkB;AAExB,IAAa,oBAAb,MAA4D;CAC1D,MAAM,QAAQ,QAAoB,UAA4B,CAAC,GAA6B;EAC1F,MAAM,YAAY,QAAQ,gBAAgB,YAAY,KAAK;EAC3D,MAAM,MAAM,QAAQ,OAAO;EAC3B,IAAK,cAAc,WAAW,cAAc,UAAW,CAAC,gBAAgB,KAAK,GAAG,GAC9E,OAAO;EAGT,MAAM,WAAW,kBAAkB,WAAW,MAAM,CAAC;EACrD,MAAM,QAAQ,IAAI,IAAI,GAAG,CAAC,CAAC,aAAa,IAAI,GAAG,KAAK;EAEpD,SAAS,iBAAiB,OAAO,CAAC,CAAC,SAAS,YAAY;GACtD,IAAI,QAAQ,aACV,QAAQ,eAAe;EAE3B,CAAC;EACD,SAAS,iBAAiB,gBAAgB,CAAC,CAAC,SAAS,YAAY;GAC/D,QAAQ,OAAO;EACjB,CAAC;EAED,MAAM,WAAW,IAAI,eAAe;EAyBpC,MAAM,WAAW,yBAAyB,MAAM,oCAxBhC,CAAC,GAAG,SAAS,iBAAiB,SAAS,CAAC,CAAC,CAAC,KAAK,WAAW;GACxE,OAAO,iBAAiB,SAAS,CAAC,CAAC,SAAS,WAAW;IACrD,MAAM,OAAO,OAAO,aAAa,MAAM;IACvC,IAAI,CAAC,MACH;IAEF,IAAI;KACF,MAAM,UAAU,IAAI,IAAI,MAAM,GAAG,CAAC,CAAC,aAAa,IAAI,GAAG;KACvD,IAAI,SACF,OAAO,aAAa,QAAQ,cAAc,OAAO,CAAC;IAEtD,QAAQ,CAER;GACF,CAAC;GAED,OAAO,SACJ,YAAY,MAAM,CAAC,CACnB,MAAM,KAAK,CAAC,CACZ,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,OAAO,OAAO,CAAC,CACf,KAAK,IAAI;EACd,CAE0F,CAAC,CAAC,KAAK,MAAM;EACvG,OAAO;GAAE,OAAO,SAAS,SAAS;GAAM;GAAU,cAAc;EAAS;CAC3E;AACF;AAEA,SAAS,cAAc,SAAyB;CAC9C,MAAM,QAAQ,QAAQ,MAAM,CAAC,CAAC,CAAC,QAAQ,MAAM,GAAG,CAAC,CAAC,QAAQ,MAAM,GAAG,CAAC,CAAC,QAAQ,OAAO,EAAE;CACtF,MAAM,QAAkB,CAAC;CACzB,IAAI,OAAO;CACX,IAAI,WAAW;CAEf,KAAK,MAAM,aAAa,OAAO;EAC7B,MAAM,QAAQ,gBAAgB,QAAQ,SAAS;EAC/C,IAAI,QAAQ,GACV,OAAO;EAET,OAAQ,QAAQ,IAAK;EACrB,YAAY;EACZ,IAAI,YAAY,GAAG;GACjB,YAAY;GACZ,MAAM,KAAM,QAAQ,WAAY,GAAI;EACtC;CACF;CAEA,OAAO,IAAI,YAAY,CAAC,CAAC,OAAO,IAAI,WAAW,KAAK,CAAC;AACvD;;;ACzEA,IAAa,gBAAb,MAAwD;CACtD,MAAM,QAAQ,QAAoB,SAAqD;EACrF,MAAM,YAAY,QAAQ,gBAAgB,YAAY,KAAK;EAC3D,IAAI,cAAc,WAAW,cAAc,QACzC,OAAO;EAGT,OAAO,KAAK,YAAY,WAAW,MAAM,CAAC;CAC5C;CAEA,MAAM,YAAY,MAAwC;EACxD,MAAM,WAAW,kBAAkB,IAAI;EACvC,SAAS,iBAAiB,eAAe,CAAC,CAAC,SAAS,YAAY;GAC9D,QAAQ,OAAO;EACjB,CAAC;EAED,MAAM,WAAW,IAAI,eAAe,CAAC,CAAC,YAAY,SAAS,QAAQ,QAAQ;EAC3E,OAAO;GACL,OAAO,SAAS,SAAS;GACzB;GACA,cAAc;EAChB;CACF;AACF;;;ACvBA,IAAa,gBAAb,cAAmC,cAAc;CAC/C,MAAM,QAAQ,QAAoB,SAAqD;EACrF,IAAI,QAAQ,gBAAgB,YAAY,MAAM,SAC5C,OAAO;EAGT,MAAM,OAAO,MAAM,QAAQ,cACzB,EAAE,aAAa,cAAc,MAAM,EAAE,GACrC;GACE,UAAU,QAAQ;GAClB,yBAAyB,QAAQ;GACjC,wBAAwB,QAAQ;GAChC,uBAAuB,QAAQ;GAC/B,UAAU,QAAQ;GAClB,mBAAmB,QAAQ;EAC7B,CACF;EACA,OAAO,KAAK,YAAY,KAAK,KAAK;CACpC;AACF;;;ACXA,IAAa,iBAAb,MAAyD;CACvD,MAAM,QAAQ,QAAoB,UAA4B,CAAC,GAA6B;EAC1F,IAAI,QAAQ,gBAAgB,YAAY,MAAM,UAC5C,OAAO;EAGT,MAAM,WAAW,KAAK,MAAM,WAAW,MAAM,CAAC;EAC9C,MAAM,SAAmB,CAAC;EAC1B,IAAI,QAAuB,SAAS,UAAU,SAAS;EAEvD,KAAK,MAAM,QAAQ,SAAS,SAAS,CAAC,GAAG;GACvC,MAAM,QAAQ,KAAK,UAAU,CAAC;GAC9B,IAAI,KAAK,cAAc,YAAY;IACjC,OAAO,KAAK,MAAM,KAAK,EAAE,CAAC;IAC1B,UAAA,QACE,MACG,MAAM,SAAS,KAAK,WAAW,IAAI,CAAC,CAAC,EACpC,MAAM,CAAC,CAAC,CACT,KAAK,KAAK;GACjB,OAAO,IAAI,KAAK,cAAc,QAC5B,OAAO,KAAK,iBAAiB,MAAM,KAAK,EAAE,EAAE,SAAS;QAChD,IAAI,KAAK,cAAc,OAC5B,OAAO,KAAK,WAAW,MAAM,KAAK,EAAE,EAAE,SAAS;EAEnD;EAEA,MAAM,WAAW,OAAO,KAAK,MAAM;EACnC,OAAO;GAAE;GAAO;GAAU,cAAc;EAAS;CACnD;AACF;;;AC1CA,MAAM,kBAA0C;CAC9C,wBAAwB;CACxB,oBAAoB;CACpB,uBAAuB;CACvB,qEAAqE;CACrE,2EAA2E;CAC3E,mBAAmB;CACnB,YAAY;CACZ,aAAa;CACb,iBAAiB;CACjB,cAAc;CACd,YAAY;AACd;AAEA,MAAM,kCAAkB,IAAI,IAAI;CAAC;CAAQ;CAAS;CAAQ;CAAa;CAAO;CAAS;AAAM,CAAC;AAE9F,SAAgB,kBAAkB,aAAuD;CACvF,IAAI,CAAC,aACH,OAAO;CAGT,MAAM,OAAO,YAAY,MAAM,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,YAAY,KAAK;CACnE,OAAO,gBAAgB,UAAU,KAAK,WAAW,OAAO,IAAI,SAAS;AACvE;AAEA,SAAgB,gBAAgB,WAA4B;CAC1D,OAAO,gBAAgB,IAAI,UAAU,YAAY,CAAC;AACpD;AAEA,SAAgB,sBAAsB,UAAiC;CACrE,MAAM,WAAW,SAAS,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK;CAC9C,MAAM,MAAM,SAAS,YAAY,GAAG;CACpC,OAAO,MAAM,IAAI,SAAS,MAAM,GAAG,CAAC,CAAC,YAAY,IAAI;AACvD;;;AC7BA,IAAa,qBAAb,MAA6D;CAC3D,MAAM,QAAQ,QAAoB,UAA4B,CAAC,GAA6B;EAC1F,IAAI,CAAC,gBAAgB,QAAQ,kBAAkB,EAAE,GAC/C,OAAO;EAGT,MAAM,UAAU,WAAW,MAAM;EACjC,OAAO;GAAE,OAAO;GAAM,UAAU;GAAS,cAAc;EAAQ;CACjE;AACF;;;ACRA,MAAM,gBAAgB;AAEtB,IAAa,qBAAb,MAA6D;CAC3D,MAAM,QAAQ,QAAoB,UAA4B,CAAC,GAA6B;EAC1F,MAAM,YAAY,QAAQ,gBAAgB,YAAY,KAAK;EAC3D,IAAK,cAAc,WAAW,cAAc,UAAW,CAAC,cAAc,KAAK,QAAQ,OAAO,EAAE,GAC1F,OAAO;EAGT,MAAM,WAAW,kBAAkB,WAAW,MAAM,CAAC;EACrD,SAAS,iBAAiB,eAAe,CAAC,CAAC,SAAS,YAAY;GAC9D,QAAQ,OAAO;EACjB,CAAC;EAED,MAAM,OAAO,SAAS,cAAc,qBAAqB;EAEzD,MAAM,QADY,SAAS,cAAc,yBAAyB,CAAC,EAAE,aAAa,KAAK,KAC5D,SAAS,SAAS;EAC7C,MAAM,WAAW,OACb,KAAK,SAAS,YAAY,MAAM,IAAI,eAAe,CAAC,CAAC,YAAY,IAAI,MACrE,IAAI,eAAe,CAAC,CAAC,YAAY,QAAQ;EAE7C,OAAO;GAAE;GAAO;GAAU,cAAc;EAAS;CACnD;AACF;;;ACxBA,IAAa,gBAAb,cAAmC,cAAc;CAC/C,MAAM,QAAQ,QAAoB,SAAqD;EACrF,IAAI,QAAQ,gBAAgB,YAAY,MAAM,SAC5C,OAAO;EAGT,MAAM,WAAW,KAAK,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAC;EACpD,MAAM,WAAqB,CAAC;EAE5B,KAAK,MAAM,aAAa,SAAS,YAAY;GAC3C,MAAM,QAAQ,SAAS,OAAO;GAC9B,IAAI,QAAQ,SAAS;IACnB,MAAM,SAAS,MAAM,KAAK,YAAY,KAAK,MAAM,cAAc,KAAK,CAAC;IACrE,SAAS,KAAK,MAAM,UAAU,IAAI,QAAQ,SAAS,KAAK,KAAK,IAAI;GACnE;EACF;EAEA,MAAM,WAAW,SAAS,KAAK,MAAM;EACrC,OAAO;GACL,OAAO,SAAS,OAAO,SAAS;GAChC;GACA,cAAc;EAChB;CACF;AACF;;;ACrBA,IAAa,eAAb,MAAuD;CACrD,MAAM,QAAQ,QAAoB,UAA4B,CAAC,GAA6B;EAC1F,MAAM,YAAY,QAAQ,gBAAgB,YAAY,KAAK;EAC3D,IAAI,CAAC;GAAC;GAAQ;GAAQ;EAAO,CAAC,CAAC,SAAS,SAAS,GAC/C,OAAO;EAGT,MAAM,WAAW,IAAI,UAAU,CAAC,CAAC,gBAAgB,WAAW,MAAM,GAAG,UAAU;EAC/E,IAAI,SAAS,qBAAqB,KAAK,CAAC,CAAC,SAAS,GAChD,OAAO,KAAK,SAAS,QAAQ;EAE/B,IAAI,SAAS,qBAAqB,MAAM,CAAC,CAAC,EAAE,EAAE,qBAAqB,OAAO,CAAC,CAAC,QAC1E,OAAO,KAAK,UAAU,QAAQ;EAEhC,OAAO;CACT;CAEA,UAAkB,UAAqC;EACrD,MAAM,OAAO,SAAS,qBAAqB,MAAM,CAAC,CAAC;EACnD,IAAI,CAAC,MAAM,OAAO;EAElB,MAAM,QAAQ,QAAQ,MAAM,OAAO;EACnC,MAAM,WAAW,QAAQ,MAAM,UAAU;EACzC,MAAM,WAAW,CAAC,KAAK,SAAS,QAAQ;EACxC,IAAI,UAAU,SAAS,KAAK,QAAQ;EAEpC,KAAK,MAAM,SAAS,CAAC,GAAG,KAAK,qBAAqB,OAAO,CAAC,GAAG;GAC3D,MAAM,aAAa,QAAQ,OAAO,OAAO;GACzC,MAAM,UAAU,QAAQ,OAAO,SAAS;GACxC,MAAM,UAAU,QAAQ,OAAO,SAAS;GACxC,MAAM,UAAU,QAAQ,OAAO,SAAS;GACxC,MAAM,QAAkB,CAAC;GACzB,IAAI,YAAY,MAAM,KAAK,MAAM,YAAY;GAC7C,IAAI,SAAS,MAAM,KAAK,eAAe,SAAS;GAChD,IAAI,SAAS,MAAM,KAAK,aAAa,OAAO,CAAC;GAC7C,IAAI,SAAS,MAAM,KAAK,aAAa,OAAO,CAAC;GAC7C,SAAS,KAAK,MAAM,KAAK,IAAI,CAAC;EAChC;EAEA,MAAM,WAAW,SAAS,KAAK,MAAM;EACrC,OAAO;GAAE;GAAO;GAAU,cAAc;EAAS;CACnD;CAEA,SAAiB,UAAqC;EACpD,MAAM,UAAU,SAAS,qBAAqB,KAAK,CAAC,CAAC,EAAE,EAAE,qBAAqB,SAAS,CAAC,CAAC;EACzF,IAAI,CAAC,SAAS,OAAO;EAErB,MAAM,QAAQ,QAAQ,SAAS,OAAO;EACtC,MAAM,cAAc,QAAQ,SAAS,aAAa;EAClD,MAAM,WAAqB,QAAQ,CAAC,KAAK,OAAO,IAAI,CAAC;EACrD,IAAI,aAAa,SAAS,KAAK,WAAW;EAE1C,KAAK,MAAM,QAAQ,CAAC,GAAG,QAAQ,qBAAqB,MAAM,CAAC,GAAG;GAC5D,MAAM,YAAY,QAAQ,MAAM,OAAO;GACvC,MAAM,YAAY,QAAQ,MAAM,SAAS;GACzC,MAAM,kBAAkB,QAAQ,MAAM,aAAa;GACnD,MAAM,UAAU,QAAQ,MAAM,iBAAiB;GAC/C,MAAM,QAAkB,CAAC;GACzB,IAAI,WAAW,MAAM,KAAK,MAAM,WAAW;GAC3C,IAAI,WAAW,MAAM,KAAK,iBAAiB,WAAW;GACtD,IAAI,iBAAiB,MAAM,KAAK,aAAa,eAAe,CAAC;GAC7D,IAAI,SAAS,MAAM,KAAK,aAAa,OAAO,CAAC;GAC7C,SAAS,KAAK,MAAM,KAAK,IAAI,CAAC;EAChC;EAEA,MAAM,WAAW,SAAS,KAAK,MAAM;EACrC,OAAO;GAAE;GAAO;GAAU,cAAc;EAAS;CACnD;AACF;AAEA,SAAS,aAAa,SAAyB;CAC7C,OAAO,IAAI,eAAe,CAAC,CAAC,YAAY,kBAAkB,OAAO,CAAC,CAAC,eAAe;AACpF;AAEA,SAAS,QAAQ,SAAkB,SAAgC;CAEjE,OADa,QAAQ,qBAAqB,OAAO,CAAC,CAAC,EACxC,EAAE,aAAa,KAAK,KAAK;AACtC;;;AChFA,IAAa,mBAAb,MAA2D;CACzD,MAAM,QAAQ,QAAoB,UAA4B,CAAC,GAA6B;EAC1F,MAAM,YAAY,QAAQ,gBAAgB,YAAY,KAAK;EAC3D,IACG,cAAc,WAAW,cAAc,UACxC,CAAC,QAAQ,KAAK,WAAW,gCAAgC,GAEzD,OAAO;EAGT,MAAM,WAAW,kBAAkB,WAAW,MAAM,CAAC;EACrD,MAAM,WAAmC,EAAE,OAAO,SAAS,MAAM;EAEjE,SAAS,iBAAiB,MAAM,CAAC,CAAC,SAAS,SAAS;GAClD,MAAM,UAAU,KAAK,aAAa,SAAS;GAC3C,MAAM,MACJ,KAAK,aAAa,UAAU,KAAK,KAAK,aAAa,UAAU,KAAK,KAAK,aAAa,MAAM;GAC5F,IAAI,OAAO,SACT,SAAS,OAAO;EAEpB,CAAC;EAED,IAAI;GACF,KAAK,MAAM,UAAU,SAAS,iBAAiB,QAAQ,GAAG;IACxD,MAAM,UAAU,OAAO,eAAe;IACtC,IAAI,CAAC,QAAQ,SAAS,eAAe,GACnC;IAEF,MAAM,QAAQ,QAAQ,QAAQ,GAAG;IACjC,MAAM,MAAM,QAAQ,YAAY,GAAG;IACnC,IAAI,SAAS,KAAK,MAAM,OAAO;KAC7B,MAAM,cAAc,QAClB,KAAK,MAAM,QAAQ,MAAM,OAAO,MAAM,CAAC,CAAC,GACxC,+BACF;KACA,IAAI,SAAS,WAAW,KAAK,OAAO,YAAY,YAAY,UAC1D,SAAS,cAAc,YAAY;IAEvC;IACA;GACF;EACF,QAAQ,CAER;EAEA,MAAM,QAAQ,MAAM,UAAU;GAAC;GAAS;GAAY;EAAM,CAAC,KAAK,SAAS,SAAS;EAClF,MAAM,QAAQ,CAAC,WAAW;EAC1B,IAAI,OACF,MAAM,KAAK,MAAM,OAAO;EAG1B,MAAM,QAAkB,CAAC;EACzB,MAAM,QAAQ,MAAM,UAAU,CAAC,kBAAkB,CAAC;EAClD,MAAM,WAAW,MAAM,UAAU,CAAC,UAAU,CAAC;EAC7C,MAAM,UAAU,MAAM,UAAU,CAAC,UAAU,CAAC;EAC5C,IAAI,OAAO,MAAM,KAAK,gBAAgB,OAAO;EAC7C,IAAI,UAAU,MAAM,KAAK,mBAAmB,UAAU;EACtD,IAAI,SAAS,MAAM,KAAK,kBAAkB,SAAS;EACnD,IAAI,MAAM,SAAS,GACjB,MAAM,KAAK,uBAAuB,MAAM,KAAK,IAAI,GAAG;EAGtD,MAAM,cAAc,MAAM,UAAU,CAAC,eAAe,gBAAgB,CAAC;EACrE,IAAI,aACF,MAAM,KAAK,oBAAoB,aAAa;EAG9C,MAAM,WAAW,MAAM,KAAK,MAAM;EAClC,OAAO;GAAE;GAAO;GAAU,cAAc;EAAS;CACnD;AACF;AAEA,SAAS,MAAM,UAAkC,MAA+B;CAC9E,KAAK,MAAM,OAAO,MAChB,IAAI,SAAS,MAAM,OAAO,SAAS;CAErC,OAAO;AACT;AAEA,SAAS,QAAQ,OAAgB,KAAsB;CACrD,IAAI,MAAM,QAAQ,KAAK,GACrB,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,QAAQ,QAAQ,MAAM,GAAG;EAC/B,IAAI,UAAU,KAAA,GAAW,OAAO;CAClC;MACK,IAAI,SAAS,KAAK,GAAG;EAC1B,IAAI,OAAO,OAAO,OAAO,MAAM;EAC/B,KAAK,MAAM,QAAQ,OAAO,OAAO,KAAK,GAAG;GACvC,MAAM,QAAQ,QAAQ,MAAM,GAAG;GAC/B,IAAI,UAAU,KAAA,GAAW,OAAO;EAClC;CACF;AAEF;AAEA,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU;AAChD;;;ACtFA,IAAa,aAAb,MAAwB;CAGtB,cAAc;EAFd,KAAiB,aAAkC,CAAC;EAGlD,KAAK,kBAAkB,IAAI,mBAAmB,CAAC;EAC/C,KAAK,kBAAkB,IAAI,cAAc,CAAC;EAC1C,KAAK,kBAAkB,IAAI,aAAa,CAAC;EACzC,KAAK,kBAAkB,IAAI,mBAAmB,CAAC;EAC/C,KAAK,kBAAkB,IAAI,iBAAiB,CAAC;EAC7C,KAAK,kBAAkB,IAAI,kBAAkB,CAAC;EAC9C,KAAK,kBAAkB,IAAI,cAAc,CAAC;EAC1C,KAAK,kBAAkB,IAAI,cAAc,CAAC;EAC1C,KAAK,kBAAkB,IAAI,eAAe,CAAC;CAC7C;;CAGA,MAAM,QACJ,QACA,UAA4B,CAAC,GACH;EAC1B,IAAI,OAAO,WAAW,YAAY,kBAAkB,KAClD,OAAO,KAAK,WAAW,OAAO,SAAS,GAAG,OAAO;EAGnD,IAAI,WAAW,MAAM,GACnB,OAAO,KAAK,gBAAgB,QAAQ,OAAO;EAG7C,MAAM,6BAAa,IAAI,IAAY;EACnC,KAAK,aAAa,YAAY,QAAQ,cAAc;EAEpD,IAAI,OAAO,MAAM,GAAG;GAClB,KAAK,aAAa,YAAY,kBAAkB,OAAO,IAAI,CAAC;GAC5D,IAAI,UAAU,UAAU,OAAO,OAAO,SAAS,UAC7C,KAAK,aAAa,YAAY,sBAAsB,OAAO,IAAI,CAAC;EAEpE;EAEA,IAAI,WAAW,SAAS,GACtB,MAAM,IAAI,MACR,oFACF;EAGF,OAAO,KAAK,aAAa,MAAM,aAAa,MAAM,GAAG,YAAY,OAAO;CAC1E;;;;CAKA,MAAM,cACJ,QACA,SAC0B;EAC1B,OAAO,KAAK,QAAQ,QAAQ,OAAO;CACrC;CAEA,MAAc,WACZ,QACA,EAAE,OAAO,sBAAsB,WAAW,OAAO,GAAG,WAC1B;EAC1B,MAAM,MAAM,IAAI,IAAI,MAAM;EAC1B,IAAI,IAAI,aAAa,WAAW,IAAI,aAAa,UAC/C,MAAM,IAAI,MAAM,6BAA6B,IAAI,UAAU;EAE7D,IAAI,CAAC,qBACH,MAAM,IAAI,MAAM,uCAAuC;EAGzD,MAAM,WAAW,MAAM,oBAAoB,GAAG;EAC9C,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,wBAAwB,IAAI,YAAY,SAAS,QAAQ;EAG3E,OAAO,KAAK,gBAAgB,UAAU;GAAE,GAAG;GAAS,KAAK,IAAI,SAAS;EAAE,CAAC;CAC3E;CAEA,MAAc,gBACZ,UACA,SAC0B;EAC1B,MAAM,6BAAa,IAAI,IAAY;EACnC,KAAK,aAAa,YAAY,QAAQ,cAAc;EACpD,KAAK,aAAa,YAAY,kBAAkB,SAAS,QAAQ,IAAI,cAAc,CAAC,CAAC;EAGrF,MAAM,YADc,SAAS,QAAQ,IAAI,qBAAqB,KAAK,GAAA,CACtC,MAAM,yCAAyC,CAAC,GAAG;EAChF,IAAI,UACF,KAAK,aAAa,YAAY,sBAAsB,mBAAmB,SAAS,KAAK,CAAC,CAAC,CAAC;EAG1F,MAAM,cAAc,QAAQ,OAAO,SAAS;EAC5C,IAAI,aACF,KAAK,aAAa,YAAY,sBAAsB,IAAI,IAAI,WAAW,CAAC,CAAC,QAAQ,CAAC;EAGpF,IAAI,WAAW,SAAS,GACtB,MAAM,IAAI,MACR,uFACF;EAGF,OAAO,KAAK,aAAa,IAAI,WAAW,MAAM,SAAS,YAAY,CAAC,GAAG,YAAY;GACjF,GAAG;GACH,KAAK;EACP,CAAC;CACH;CAEA,MAAc,aACZ,QACA,YACA,SAC0B;EAC1B,IAAI;EAEJ,KAAK,MAAM,aAAa,YACtB,KAAK,MAAM,aAAa,KAAK,YAC3B,IAAI;GACF,MAAM,SAAS,MAAM,UAAU,QAAQ,QAAQ;IAC7C,GAAG;IACH,gBAAgB;IAChB,oBAAoB,KAAK;GAC3B,CAAC;GACD,IAAI,QAAQ;IACV,OAAO,WAAW,OAAO,SACtB,QAAQ,eAAe,IAAI,CAAC,CAC5B,KAAK,CAAC,CACN,QAAQ,WAAW,MAAM;IAC5B,OAAO,eAAe,OAAO;IAC7B,OAAO;GACT;EACF,SAAS,OAAO;GACd,YAAY;EACd;EAIJ,MAAM,UAAU,CAAC,GAAG,UAAU,CAAC,CAAC,KAAK,IAAI;EACzC,IAAI,WACF,MAAM,IAAI,MAAM,qBAAqB,QAAQ,gBAAgB,OAAO,SAAS,GAAG;EAElF,MAAM,IAAI,MAAM,0BAA0B,QAAQ,EAAE;CACtD;CAEA,aAAqB,YAAyB,WAA4C;EACxF,IAAI,CAAC,WACH;EAEF,WAAW,IACT,UAAU,WAAW,GAAG,IAAI,UAAU,YAAY,IAAI,IAAI,UAAU,YAAY,GAClF;CACF;CAEA,kBAA0B,WAAoC;EAC5D,KAAK,WAAW,QAAQ,SAAS;CACnC;AACF;AAEA,SAAS,WAAW,OAAmC;CACrD,OAAO,OAAO,aAAa,eAAe,iBAAiB;AAC7D"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/bytes.ts","../src/custom-turndown.ts","../src/html-document.ts","../src/converters/bingserp.ts","../src/converters/html.ts","../src/converters/docx.ts","../src/converters/ipynb.ts","../src/converters/pdf.ts","../src/mime.ts","../src/converters/plain-text.ts","../src/converters/wikipedia.ts","../src/converters/xlsx.ts","../src/converters/xml-rss-atom.ts","../src/converters/youtube.ts","../src/converters/zip.ts","../src/markitdown.ts"],"sourcesContent":["import type { ByteSource } from \"./types\";\n\nexport async function toUint8Array(source: ByteSource): Promise<Uint8Array> {\n if (source instanceof Uint8Array) {\n return source;\n }\n\n if (isBlob(source)) {\n return new Uint8Array(await source.arrayBuffer());\n }\n\n if (ArrayBuffer.isView(source)) {\n return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);\n }\n\n return new Uint8Array(source);\n}\n\nexport function toArrayBuffer(source: Uint8Array): ArrayBuffer {\n return source.slice().buffer;\n}\n\nexport function decodeText(source: Uint8Array): string {\n return new TextDecoder().decode(source);\n}\n\nexport function isBlob(value: unknown): value is Blob {\n return typeof Blob !== \"undefined\" && value instanceof Blob;\n}\n\nexport function normalizeExtension(extension: string): string {\n if (!extension) {\n return \"\";\n }\n\n const normalized = extension.toLowerCase();\n return normalized.startsWith(\".\") ? normalized : `.${normalized}`;\n}\n","import turndownPluginGfm from \"@joplin/turndown-plugin-gfm\";\nimport TurndownService from \"turndown\";\n\nexport class CustomTurnDown {\n convertSoup(document: string | Node): string {\n const service = new TurndownService({ headingStyle: \"atx\" });\n service.use(turndownPluginGfm.gfm);\n\n service.addRule(\"anchor tags\", {\n filter: [\"a\"],\n replacement(content, node) {\n if (!content) return \"\";\n\n const prefix = content.startsWith(\" \") ? \" \" : \"\";\n const suffix = content.endsWith(\" \") ? \" \" : \"\";\n const text = content.trim().replace(/\\n\\n.*/g, \"\");\n if (!text) return \"\";\n\n const element = node as unknown as Element;\n const href = element.getAttribute(\"href\");\n let title = element.getAttribute(\"title\") ?? \"\";\n if (!href) return `${prefix}${text}${suffix}`;\n\n try {\n const url = new URL(href);\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n return `${prefix}${text}${suffix}`;\n }\n } catch {\n if (\n !href.startsWith(\"/\") &&\n !href.startsWith(\"#\") &&\n !href.startsWith(\"./\") &&\n !href.startsWith(\"../\")\n ) {\n return `${prefix}${text}${suffix}`;\n }\n }\n\n if (text.replace(/\\\\_/g, \"_\") === href && !title) {\n return `<${href}>`;\n }\n if (!title) title = href;\n return `${prefix}[${text}](${href}${title ? ` \"${title}\"` : \"\"})${suffix}`;\n }\n });\n\n service.addRule(\"img tags\", {\n filter: [\"img\"],\n replacement(_content, node) {\n const element = node as unknown as Element;\n const alt = element.getAttribute(\"alt\") ?? \"\";\n let source = element.getAttribute(\"src\") ?? \"\";\n const title = element.getAttribute(\"title\");\n if (source.startsWith(\"data:\")) {\n source = `${source.split(\",\", 1)[0]}...`;\n }\n return `![${alt}](${source}${title ? ` \"${title}\"` : \"\"})`;\n }\n });\n\n return service.turndown(document as TurndownService.Node);\n }\n}\n","import { parseHTML } from \"linkedom\";\n\nexport function parseHtmlDocument(html: string): Document {\n return parseHTML(html).document as unknown as Document;\n}\n","import { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nconst BING_SEARCH_URL = /^https:\\/\\/www\\.bing\\.com\\/search\\?q=/i;\nconst BASE64_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\nexport class BingSerpConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n const url = options.url ?? \"\";\n if ((extension !== \".html\" && extension !== \".htm\") || !BING_SEARCH_URL.test(url)) {\n return null;\n }\n\n const document = parseHtmlDocument(decodeText(source));\n const query = new URL(url).searchParams.get(\"q\") ?? \"\";\n\n document.querySelectorAll(\".tptt\").forEach((element) => {\n if (element.textContent) {\n element.textContent += \" \";\n }\n });\n document.querySelectorAll(\".algoSlug_icon\").forEach((element) => {\n element.remove();\n });\n\n const turndown = new CustomTurnDown();\n const results = [...document.querySelectorAll(\".b_algo\")].map((result) => {\n result.querySelectorAll(\"a[href]\").forEach((anchor) => {\n const href = anchor.getAttribute(\"href\");\n if (!href) {\n return;\n }\n try {\n const encoded = new URL(href, url).searchParams.get(\"u\");\n if (encoded) {\n anchor.setAttribute(\"href\", decodeBingUrl(encoded));\n }\n } catch {\n // Preserve malformed links as they appeared in the source document.\n }\n });\n\n return turndown\n .convertSoup(result)\n .split(/\\n+/)\n .map((line) => line.trim())\n .filter(Boolean)\n .join(\"\\n\");\n });\n\n const markdown = `## A Bing search for '${query}' found the following results:\\n\\n${results.join(\"\\n\\n\")}`;\n return { title: document.title || null, markdown, text_content: markdown };\n }\n}\n\nfunction decodeBingUrl(encoded: string): string {\n const input = encoded.slice(2).replace(/-/g, \"+\").replace(/_/g, \"/\").replace(/=+$/, \"\");\n const bytes: number[] = [];\n let bits = 0;\n let bitCount = 0;\n\n for (const character of input) {\n const value = BASE64_ALPHABET.indexOf(character);\n if (value < 0) {\n return encoded;\n }\n bits = (bits << 6) | value;\n bitCount += 6;\n if (bitCount >= 8) {\n bitCount -= 8;\n bytes.push((bits >> bitCount) & 0xff);\n }\n }\n\n return new TextDecoder().decode(new Uint8Array(bytes));\n}\n","import { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class HtmlConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if (extension !== \".html\" && extension !== \".htm\") {\n return null;\n }\n\n return this.convertHtml(decodeText(source));\n }\n\n async convertHtml(html: string): Promise<ConverterResult> {\n const document = parseHtmlDocument(html);\n document.querySelectorAll(\"script, style\").forEach((element) => {\n element.remove();\n });\n\n const markdown = new CustomTurnDown().convertSoup(document.body ?? document);\n return {\n title: document.title || null,\n markdown,\n text_content: markdown\n };\n }\n}\n","import mammoth from \"mammoth\";\nimport { toArrayBuffer } from \"../bytes\";\nimport type { ConverterOptions, ConverterResult } from \"../types\";\nimport { HtmlConverter } from \"./html\";\n\nexport class DocxConverter extends HtmlConverter {\n async convert(source: Uint8Array, options: ConverterOptions): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".docx\") {\n return null;\n }\n\n const html = await mammoth.convertToHtml(\n { arrayBuffer: toArrayBuffer(source) },\n {\n styleMap: options.styleMap,\n includeEmbeddedStyleMap: options.includeEmbeddedStyleMap,\n includeDefaultStyleMap: options.includeDefaultStyleMap,\n ignoreEmptyParagraphs: options.ignoreEmptyParagraphs,\n idPrefix: options.idPrefix,\n transformDocument: options.transformDocument\n }\n );\n return this.convertHtml(html.value);\n }\n}\n","import { decodeText } from \"../bytes\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\ntype NotebookCell = {\n cell_type?: string;\n source?: string[];\n};\n\ntype Notebook = {\n cells?: NotebookCell[];\n metadata?: { title?: string };\n};\n\nexport class IpynbConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".ipynb\") {\n return null;\n }\n\n const notebook = JSON.parse(decodeText(source)) as Notebook;\n const output: string[] = [];\n let title: string | null = notebook.metadata?.title ?? null;\n\n for (const cell of notebook.cells ?? []) {\n const lines = cell.source ?? [];\n if (cell.cell_type === \"markdown\") {\n output.push(lines.join(\"\"));\n title ??=\n lines\n .find((line) => line.startsWith(\"# \"))\n ?.slice(2)\n .trim() ?? null;\n } else if (cell.cell_type === \"code\") {\n output.push(`\\`\\`\\`python\\n${lines.join(\"\")}\\n\\`\\`\\``);\n } else if (cell.cell_type === \"raw\") {\n output.push(`\\`\\`\\`\\n${lines.join(\"\")}\\n\\`\\`\\``);\n }\n }\n\n const markdown = output.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n}\n","import { extractText, getDocumentProxy, getMeta } from \"unpdf\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class PdfConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".pdf\") {\n return null;\n }\n\n const pdf = await getDocumentProxy(source.slice());\n try {\n const [{ text }, { info }] = await Promise.all([\n extractText(pdf, { mergePages: true }),\n getMeta(pdf)\n ]);\n const title = typeof info.Title === \"string\" && info.Title.trim() ? info.Title : null;\n\n return { title, markdown: text, text_content: text };\n } finally {\n await pdf.loadingTask.destroy();\n }\n }\n}\n","const MIME_EXTENSIONS: Record<string, string> = {\n \"application/atom+xml\": \".atom\",\n \"application/json\": \".json\",\n \"application/pdf\": \".pdf\",\n \"application/zip\": \".zip\",\n \"application/rss+xml\": \".rss\",\n \"application/x-pdf\": \".pdf\",\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\": \".xlsx\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\": \".docx\",\n \"application/xml\": \".xml\",\n \"text/csv\": \".csv\",\n \"text/html\": \".html\",\n \"text/markdown\": \".md\",\n \"text/plain\": \".txt\",\n \"text/xml\": \".xml\"\n};\n\nconst TEXT_EXTENSIONS = new Set([\".csv\", \".json\", \".log\", \".markdown\", \".md\", \".text\", \".txt\"]);\n\nexport function extensionFromMime(contentType: string | null | undefined): string | null {\n if (!contentType) {\n return null;\n }\n\n const mime = contentType.split(\";\", 1)[0]?.trim().toLowerCase() ?? \"\";\n return MIME_EXTENSIONS[mime] ?? (mime.startsWith(\"text/\") ? \".txt\" : null);\n}\n\nexport function isTextExtension(extension: string): boolean {\n return TEXT_EXTENSIONS.has(extension.toLowerCase());\n}\n\nexport function extensionFromPathname(pathname: string): string | null {\n const filename = pathname.split(\"/\").pop() ?? \"\";\n const dot = filename.lastIndexOf(\".\");\n return dot > 0 ? filename.slice(dot).toLowerCase() : null;\n}\n","import { decodeText } from \"../bytes\";\nimport { isTextExtension } from \"../mime\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class PlainTextConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n if (!isTextExtension(options.file_extension ?? \"\")) {\n return null;\n }\n\n const content = decodeText(source);\n return { title: null, markdown: content, text_content: content };\n }\n}\n","import { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nconst WIKIPEDIA_URL = /^https?:\\/\\/[a-z]{2,3}\\.wikipedia\\.org\\//i;\n\nexport class WikipediaConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if ((extension !== \".html\" && extension !== \".htm\") || !WIKIPEDIA_URL.test(options.url ?? \"\")) {\n return null;\n }\n\n const document = parseHtmlDocument(decodeText(source));\n document.querySelectorAll(\"script, style\").forEach((element) => {\n element.remove();\n });\n\n const body = document.querySelector(\"div#mw-content-text\");\n const pageTitle = document.querySelector(\"span.mw-page-title-main\")?.textContent?.trim();\n const title = pageTitle || document.title || null;\n const markdown = body\n ? `# ${title ?? \"Wikipedia\"}\\n\\n${new CustomTurnDown().convertSoup(body)}`\n : new CustomTurnDown().convertSoup(document);\n\n return { title, markdown, text_content: markdown };\n }\n}\n","import * as XLSX from \"xlsx\";\nimport type { ConverterOptions, ConverterResult } from \"../types\";\nimport { HtmlConverter } from \"./html\";\n\nexport class XlsxConverter extends HtmlConverter {\n async convert(source: Uint8Array, options: ConverterOptions): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".xlsx\") {\n return null;\n }\n\n const workbook = XLSX.read(source, { type: \"array\" });\n const sections: string[] = [];\n\n for (const sheetName of workbook.SheetNames) {\n const sheet = workbook.Sheets[sheetName];\n if (sheet?.[\"!ref\"]) {\n const result = await this.convertHtml(XLSX.utils.sheet_to_html(sheet));\n sections.push(`## ${sheetName}\\n${result?.markdown.trim() ?? \"\"}`);\n }\n }\n\n const markdown = sections.join(\"\\n\\n\");\n return {\n title: workbook.Props?.Title || \"Untitled\",\n markdown,\n text_content: markdown\n };\n }\n}\n","import type { Document, Element } from \"@xmldom/xmldom\";\nimport { DOMParser } from \"@xmldom/xmldom\";\nimport { decodeText } from \"../bytes\";\nimport { CustomTurnDown } from \"../custom-turndown\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class RSSConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if (![\".xml\", \".rss\", \".atom\"].includes(extension)) {\n return null;\n }\n\n const document = new DOMParser().parseFromString(decodeText(source), \"text/xml\");\n if (document.getElementsByTagName(\"rss\").length > 0) {\n return this.parseRss(document);\n }\n if (document.getElementsByTagName(\"feed\")[0]?.getElementsByTagName(\"entry\").length) {\n return this.parseAtom(document);\n }\n return null;\n }\n\n private parseAtom(document: Document): ConverterResult {\n const root = document.getElementsByTagName(\"feed\")[0];\n if (!root) return null;\n\n const title = getText(root, \"title\");\n const subtitle = getText(root, \"subtitle\");\n const sections = [`# ${title ?? \"Feed\"}`];\n if (subtitle) sections.push(subtitle);\n\n for (const entry of [...root.getElementsByTagName(\"entry\")]) {\n const entryTitle = getText(entry, \"title\");\n const updated = getText(entry, \"updated\");\n const summary = getText(entry, \"summary\");\n const content = getText(entry, \"content\");\n const lines: string[] = [];\n if (entryTitle) lines.push(`## ${entryTitle}`);\n if (updated) lines.push(`Updated on: ${updated}`);\n if (summary) lines.push(parseContent(summary));\n if (content) lines.push(parseContent(content));\n sections.push(lines.join(\"\\n\"));\n }\n\n const markdown = sections.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n\n private parseRss(document: Document): ConverterResult {\n const channel = document.getElementsByTagName(\"rss\")[0]?.getElementsByTagName(\"channel\")[0];\n if (!channel) return null;\n\n const title = getText(channel, \"title\");\n const description = getText(channel, \"description\");\n const sections: string[] = title ? [`# ${title}`] : [];\n if (description) sections.push(description);\n\n for (const item of [...channel.getElementsByTagName(\"item\")]) {\n const itemTitle = getText(item, \"title\");\n const published = getText(item, \"pubDate\");\n const itemDescription = getText(item, \"description\");\n const content = getText(item, \"content:encoded\");\n const lines: string[] = [];\n if (itemTitle) lines.push(`## ${itemTitle}`);\n if (published) lines.push(`Published on: ${published}`);\n if (itemDescription) lines.push(parseContent(itemDescription));\n if (content) lines.push(parseContent(content));\n sections.push(lines.join(\"\\n\"));\n }\n\n const markdown = sections.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n}\n\nfunction parseContent(content: string): string {\n return new CustomTurnDown().convertSoup(parseHtmlDocument(content).documentElement);\n}\n\nfunction getText(element: Element, tagName: string): string | null {\n const node = element.getElementsByTagName(tagName)[0];\n return node?.textContent?.trim() || null;\n}\n","import { decodeText } from \"../bytes\";\nimport { parseHtmlDocument } from \"../html-document\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class YouTubeConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n const extension = options.file_extension?.toLowerCase() ?? \"\";\n if (\n (extension !== \".html\" && extension !== \".htm\") ||\n !options.url?.startsWith(\"https://www.youtube.com/watch?\")\n ) {\n return null;\n }\n\n const document = parseHtmlDocument(decodeText(source));\n const metadata: Record<string, string> = { title: document.title };\n\n document.querySelectorAll(\"meta\").forEach((meta) => {\n const content = meta.getAttribute(\"content\");\n const key =\n meta.getAttribute(\"itemprop\") ?? meta.getAttribute(\"property\") ?? meta.getAttribute(\"name\");\n if (key && content) {\n metadata[key] = content;\n }\n });\n\n try {\n for (const script of document.querySelectorAll(\"script\")) {\n const content = script.textContent ?? \"\";\n if (!content.includes(\"ytInitialData\")) {\n continue;\n }\n const start = content.indexOf(\"{\");\n const end = content.lastIndexOf(\"}\");\n if (start >= 0 && end > start) {\n const description = findKey(\n JSON.parse(content.slice(start, end + 1)),\n \"attributedDescriptionBodyText\"\n );\n if (isRecord(description) && typeof description.content === \"string\") {\n metadata.description = description.content;\n }\n }\n break;\n }\n } catch {\n // Meta description remains available when the page implementation changes.\n }\n\n const title = first(metadata, [\"title\", \"og:title\", \"name\"]) || document.title || null;\n const lines = [\"# YouTube\"];\n if (title) {\n lines.push(`## ${title}`);\n }\n\n const stats: string[] = [];\n const views = first(metadata, [\"interactionCount\"]);\n const keywords = first(metadata, [\"keywords\"]);\n const runtime = first(metadata, [\"duration\"]);\n if (views) stats.push(`- **Views:** ${views}`);\n if (keywords) stats.push(`- **Keywords:** ${keywords}`);\n if (runtime) stats.push(`- **Runtime:** ${runtime}`);\n if (stats.length > 0) {\n lines.push(`### Video Metadata\\n${stats.join(\"\\n\")}`);\n }\n\n const description = first(metadata, [\"description\", \"og:description\"]);\n if (description) {\n lines.push(`### Description\\n${description}`);\n }\n\n const markdown = lines.join(\"\\n\\n\");\n return { title, markdown, text_content: markdown };\n }\n}\n\nfunction first(metadata: Record<string, string>, keys: string[]): string | null {\n for (const key of keys) {\n if (metadata[key]) return metadata[key];\n }\n return null;\n}\n\nfunction findKey(value: unknown, key: string): unknown {\n if (Array.isArray(value)) {\n for (const item of value) {\n const match = findKey(item, key);\n if (match !== undefined) return match;\n }\n } else if (isRecord(value)) {\n if (key in value) return value[key];\n for (const item of Object.values(value)) {\n const match = findKey(item, key);\n if (match !== undefined) return match;\n }\n }\n return undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n","import { unzipSync } from \"fflate\";\nimport { extensionFromPathname } from \"../mime\";\nimport type { ConverterOptions, ConverterResult, DocumentConverter } from \"../types\";\n\nexport class ZipConverter implements DocumentConverter {\n async convert(source: Uint8Array, options: ConverterOptions = {}): Promise<ConverterResult> {\n if (options.file_extension?.toLowerCase() !== \".zip\") {\n return null;\n }\n\n const files = unzipSync(source, {\n filter: (file) => !file.name.endsWith(\"/\")\n });\n const converters = options._parent_converters ?? [];\n const zipName = options.url ?? \"archive.zip\";\n const sections = [`Content from the zip file \\`${zipName}\\`:`];\n\n for (const [name, bytes] of Object.entries(files)) {\n const result = await convertEntry(bytes, name, converters, options);\n if (result) {\n sections.push(`## File: ${name}\\n\\n${result.markdown}`);\n }\n }\n\n const markdown = sections.join(\"\\n\\n\");\n return { title: null, markdown, text_content: markdown };\n }\n}\n\nasync function convertEntry(\n source: Uint8Array,\n name: string,\n converters: DocumentConverter[],\n options: ConverterOptions\n): Promise<ConverterResult> {\n const extension = extensionFromPathname(name);\n if (!extension) {\n return null;\n }\n\n const entryOptions: ConverterOptions = {\n ...options,\n file_extension: extension,\n url: undefined,\n _parent_converters: converters\n };\n\n for (const converter of converters) {\n try {\n const result = await converter.convert(source, entryOptions);\n if (result) {\n return result;\n }\n } catch {\n // Match the original ZipConverter: skip entries that fail conversion.\n }\n }\n\n return null;\n}\n","import { isBlob, toUint8Array } from \"./bytes\";\nimport { BingSerpConverter } from \"./converters/bingserp\";\nimport { DocxConverter } from \"./converters/docx\";\nimport { HtmlConverter } from \"./converters/html\";\nimport { IpynbConverter } from \"./converters/ipynb\";\nimport { PdfConverter } from \"./converters/pdf\";\nimport { PlainTextConverter } from \"./converters/plain-text\";\nimport { WikipediaConverter } from \"./converters/wikipedia\";\nimport { XlsxConverter } from \"./converters/xlsx\";\nimport { RSSConverter } from \"./converters/xml-rss-atom\";\nimport { YouTubeConverter } from \"./converters/youtube\";\nimport { ZipConverter } from \"./converters/zip\";\nimport { extensionFromMime, extensionFromPathname } from \"./mime\";\nimport type { ByteSource, ConverterOptions, ConverterResult, DocumentConverter } from \"./types\";\n\nexport type ConversionSource = ByteSource | Response | URL | string;\n\nexport class MarkItDown {\n private readonly converters: DocumentConverter[] = [];\n\n constructor() {\n this.registerConverter(new PlainTextConverter());\n this.registerConverter(new HtmlConverter());\n this.registerConverter(new ZipConverter());\n this.registerConverter(new RSSConverter());\n this.registerConverter(new WikipediaConverter());\n this.registerConverter(new YouTubeConverter());\n this.registerConverter(new BingSerpConverter());\n this.registerConverter(new DocxConverter());\n this.registerConverter(new XlsxConverter());\n this.registerConverter(new PdfConverter());\n this.registerConverter(new IpynbConverter());\n }\n\n /** Convert a URL, response, blob, array buffer, data view, or typed array. */\n async convert(\n source: ConversionSource,\n options: ConverterOptions = {}\n ): Promise<ConverterResult> {\n if (typeof source === \"string\" || source instanceof URL) {\n return this.convertUrl(source.toString(), options);\n }\n\n if (isResponse(source)) {\n return this.convertResponse(source, options);\n }\n\n const extensions = new Set<string>();\n this.addExtension(extensions, options.file_extension);\n\n if (isBlob(source)) {\n this.addExtension(extensions, extensionFromMime(source.type));\n if (\"name\" in source && typeof source.name === \"string\") {\n this.addExtension(extensions, extensionFromPathname(source.name));\n }\n }\n\n if (extensions.size === 0) {\n throw new Error(\n \"Could not determine the file type. Provide `file_extension` when converting bytes.\"\n );\n }\n\n return this.convertBytes(await toUint8Array(source), extensions, options);\n }\n\n /**\n * @deprecated Pass the byte source directly to `convert`.\n */\n async convertBuffer(\n source: ByteSource,\n options: ConverterOptions & { file_extension: string }\n ): Promise<ConverterResult> {\n return this.convert(source, options);\n }\n\n private async convertUrl(\n source: string,\n { fetch: fetchImplementation = globalThis.fetch, ...options }: ConverterOptions\n ): Promise<ConverterResult> {\n const url = new URL(source);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n throw new Error(`Unsupported URL protocol: ${url.protocol}`);\n }\n if (!fetchImplementation) {\n throw new Error(\"No fetch implementation is available.\");\n }\n\n const response = await fetchImplementation(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch URL: ${url}, status: ${response.status}`);\n }\n\n return this.convertResponse(response, { ...options, url: url.toString() });\n }\n\n private async convertResponse(\n response: Response,\n options: ConverterOptions\n ): Promise<ConverterResult> {\n const extensions = new Set<string>();\n this.addExtension(extensions, options.file_extension);\n this.addExtension(extensions, extensionFromMime(response.headers.get(\"content-type\")));\n\n const disposition = response.headers.get(\"content-disposition\") ?? \"\";\n const filename = disposition.match(/filename\\*?=(?:UTF-8''|[\"']?)([^;\"']+)/i)?.[1];\n if (filename) {\n this.addExtension(extensions, extensionFromPathname(decodeURIComponent(filename.trim())));\n }\n\n const responseUrl = options.url || response.url;\n if (responseUrl) {\n this.addExtension(extensions, extensionFromPathname(new URL(responseUrl).pathname));\n }\n\n if (extensions.size === 0) {\n throw new Error(\n \"Could not determine the file type. Provide `file_extension` or a Content-Type header.\"\n );\n }\n\n return this.convertBytes(new Uint8Array(await response.arrayBuffer()), extensions, {\n ...options,\n url: responseUrl\n });\n }\n\n private async convertBytes(\n source: Uint8Array,\n extensions: Set<string>,\n options: ConverterOptions\n ): Promise<ConverterResult> {\n let lastError: unknown;\n\n for (const extension of extensions) {\n for (const converter of this.converters) {\n try {\n const result = await converter.convert(source, {\n ...options,\n file_extension: extension,\n _parent_converters: this.converters\n });\n if (result) {\n result.markdown = result.markdown\n .replace(/\\r\\n|\\r|\\n/g, \"\\n\")\n .trim()\n .replace(/\\n{3,}/g, \"\\n\\n\");\n result.text_content = result.markdown;\n return result;\n }\n } catch (error) {\n lastError = error;\n }\n }\n }\n\n const formats = [...extensions].join(\", \");\n if (lastError) {\n throw new Error(`Could not convert ${formats} to Markdown: ${String(lastError)}`);\n }\n throw new Error(`Unsupported file type: ${formats}.`);\n }\n\n private addExtension(extensions: Set<string>, extension: string | null | undefined): void {\n if (!extension) {\n return;\n }\n extensions.add(\n extension.startsWith(\".\") ? extension.toLowerCase() : `.${extension.toLowerCase()}`\n );\n }\n\n private registerConverter(converter: DocumentConverter): void {\n this.converters.unshift(converter);\n }\n}\n\nfunction isResponse(value: unknown): value is Response {\n return typeof Response !== \"undefined\" && value instanceof Response;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ryangarber/markitdown-ts",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Convert various file formats to Markdown for indexing, text analysis, and other applications that benefit from structured text. Node-free fork of the TypeScript fork of the original Python library.",
5
5
  "keywords": [
6
6
  "markdown",
@@ -8,7 +8,9 @@
8
8
  "browser",
9
9
  "uint8array",
10
10
  "docx",
11
- "xlsx"
11
+ "pdf",
12
+ "xlsx",
13
+ "zip"
12
14
  ],
13
15
  "homepage": "https://github.com/ryangarber/markitdown-ts#readme",
14
16
  "bugs": {
@@ -51,9 +53,11 @@
51
53
  "dependencies": {
52
54
  "@joplin/turndown-plugin-gfm": "^1.0.67",
53
55
  "@xmldom/xmldom": "^0.9.11",
56
+ "fflate": "^0.8.3",
54
57
  "linkedom": "^0.18.13",
55
58
  "mammoth": "^1.12.1",
56
59
  "turndown": "^7.2.4",
60
+ "unpdf": "^1.8.1",
57
61
  "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
58
62
  },
59
63
  "devDependencies": {