SPB Git

spb/tendril Public

Tendril — web ingestion platform (scrape/crawl/map/search) on macOS Apple Silicon: WebKit fidelity, authenticated pages, deterministic testable extraction. A self-hosted Firecrawl alternative.

JavaScript 82.6% TypeScript 11.8% HTML 5.3%
2.1 KB · 58 lines typescript
Raw Blame History
1// author: simon-pierre boucher <contact@spboucher.ai>2import { describe, expect, it } from "vitest";3import { htmlToMarkdown } from "./markdown.js";45describe("htmlToMarkdown", () => {6  it("uses ATX headings and dash bullets", () => {7    const md = htmlToMarkdown("<h1>Title</h1><ul><li>a</li><li>b</li></ul>");8    expect(md).toContain("# Title");9    expect(md).toContain("- a");10    expect(md).toContain("- b");11  });1213  it("emits fenced code blocks with a language tag", () => {14    const md = htmlToMarkdown('<pre><code class="language-ts">const x = 1;</code></pre>');15    expect(md).toContain("```ts");16    expect(md).toContain("const x = 1;");17  });1819  it("converts tables to GFM with a header separator", () => {20    const md = htmlToMarkdown(21      "<table><thead><tr><th>Name</th><th>Age</th></tr></thead><tbody><tr><td>Ada</td><td>36</td></tr></tbody></table>",22    );23    expect(md).toContain("| Name | Age |");24    expect(md).toContain("| --- | --- |");25    expect(md).toContain("| Ada | 36 |");26  });2728  it("escapes pipes inside table cells", () => {29    const md = htmlToMarkdown("<table><tr><th>a|b</th></tr><tr><td>c|d</td></tr></table>");30    expect(md).toContain("a\\|b");31    expect(md).toContain("c\\|d");32  });3334  it("renders figure + figcaption as image plus italic caption", () => {35    const md = htmlToMarkdown('<figure><img src="https://x/y.png" alt="chart"><figcaption>Fig 1</figcaption></figure>');36    expect(md).toContain("![chart](https://x/y.png)");37    expect(md).toContain("_Fig 1_");38  });3940  it("removes heading anchor links", () => {41    const md = htmlToMarkdown('<h2>Sec <a class="headerlink" href="#sec">¶</a></h2>');42    expect(md).toContain("## Sec");43    expect(md).not.toContain("¶");44    expect(md).not.toContain("#sec");45  });4647  it("renders definition lists", () => {48    const md = htmlToMarkdown("<dl><dt>Term</dt><dd>Meaning</dd></dl>");49    expect(md).toContain("**Term**");50    expect(md).toContain(": Meaning");51  });5253  it("collapses 3+ blank lines to 2", () => {54    const md = htmlToMarkdown("<p>a</p><br><br><br><p>b</p>");55    expect(md).not.toMatch(/\n{3,}/);56  });57});58