このページは FormatArc のブログ記事が引用している実測の生データです。検索結果には表示されません (noindex)。
| File | Size |
|---|---|
| README.md | 2.2 KB |
| measure.mjs | 5.5 KB |
| package-lock.json | 1.0 KB |
| package.json | 213 B |
| results.json | 5.9 KB |
| sample-content-block.html | 1.1 KB |
| sample-newsletter.html | 6.3 KB |
# html-email-to-markdown benchmark
Reproduces every number quoted in `content/blog/{ja,en,es,pt}/html-email-to-markdown.md`.
## What it measures
Two samples are converted with the exact Turndown configuration FormatArc's
html-to-markdown tool uses (`lib/tooling.ts` `getTurndown()`: `headingStyle: "atx"`,
`codeBlockStyle: "fenced"`, `bulletListMarker: "-"`, `emDelimiter: "_"` plus the
custom table rule that flattens `<table>` via `querySelectorAll("tr")` +
`renderMarkdownTable`):
1. `sample-newsletter.html` — a hand-built but representative full newsletter
source: XHTML doctype, 3 MSO conditional comments, 8 `<table>` elements
(nested layout tables), 33 inline `style` attributes, a `<style>` block,
a 1x1 tracking pixel, 4 ESP-wrapped (`click.example-esp.com`) links and
` ` spacers. 6,491 bytes UTF-8.
2. `sample-content-block.html` — only the main content block of the same email,
the way you would copy it from browser devtools ("Copy outerHTML" on the
content cell). 1,086 bytes UTF-8.
Recorded per sample (see `results.json`): input bytes / table count / style-attr
count / tracking artifacts, and output chars / lines / pipe-table rows /
surviving tracking URLs, plus the full converted Markdown.
## Key results (2026-07-17 run)
- Full newsletter source: 6,491 bytes in, converts to a flattened 12-column
pipe table (10 pipe rows) with heavily duplicated cell text, and the
`<title>` text plus the 380-byte `<style>` block CSS leak into the output as
plain text. The MSO conditional comments and inline `style` attributes are
stripped.
- Content block only: 1,086 bytes in, 477 chars of clean Markdown out
(heading, paragraphs, link preserved). The ESP-wrapped link URL survives
verbatim and still needs manual post-processing.
## Environment
- Node v26.3.1, darwin/arm64 (Apple M5 Pro), turndown 7.2.4 (same version as
the site: `package.json` pins `^7.2.4`)
- The production tool runs the identical Turndown config in the browser
(DOMParser instead of domino); the flatten-table rule and options are copied
verbatim from `lib/tooling.ts`.
## Run
```bash
npm install
node measure.mjs # rewrites results.json and prints both conversions
```
{
"generatedAt": "2026-08-01T01:43:42.786Z",
"environment": {
"node": "v26.3.1",
"platform": "darwin/arm64",
"dependencies": {
"turndown": "7.2.4"
},
"turndownConfig": "identical to lib/tooling.ts getTurndown(): headingStyle=atx, codeBlockStyle=fenced, bulletListMarker=-, emDelimiter=_, custom table rule (flatten via querySelectorAll('tr') + renderMarkdownTable)"
},
"samples": [
{
"sample": "sample-newsletter.html",
"input": {
"bytesUtf8": 6491,
"chars": 6491,
"tableElements": 8,
"styleAttributes": 33,
"inlineStyleBlockBytes": 380,
"msoConditionalComments": 3,
"trackingPixels": 1,
"espWrappedLinks": 4,
"nbspEntities": 4
},
"output": {
"bytesUtf8": 3805,
"chars": 3790,
"lines": 12,
"pipeTableRows": 10,
"pipeTableColumns": 12,
"survivingEspLinks": 1,
"containsMsoComment": false,
"containsStyleAttr": false,
"markdown": " Monthly Product Update body, table, td, a { -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } table, td { mso-table-lspace: 0pt; mso-table-rspace: 0pt; } img { -ms-interpolation-mode: bicubic; border: 0; height: auto; line-height: 100%; outline: none; text-decoration: none; } @media screen and (max-width: 600px) { .mobile-full { width: 100% !important; } } \n\n| Acme DevtoolsView in browserApril product updateThree new integrations shipped this month, and the CLI got a full rewrite. Here is everything that changed and what it means for your pipelines.New: Webhook relayForward events to any endpoint with retry and dead-letter queues built in. CLI 3.0Rewritten in Rust. Cold start is faster and the config format is unchanged.Read the full changelogYou are receiving this because you signed up at example.com.Acme Devtools, 100 Main St, SpringfieldUnsubscribe · Manage preferences | Acme DevtoolsView in browser | Acme Devtools | View in browser | April product updateThree new integrations shipped this month, and the CLI got a full rewrite. Here is everything that changed and what it means for your pipelines.New: Webhook relayForward events to any endpoint with retry and dead-letter queues built in. CLI 3.0Rewritten in Rust. Cold start is faster and the config format is unchanged.Read the full changelog | New: Webhook relayForward events to any endpoint with retry and dead-letter queues built in. | New: Webhook relayForward events to any endpoint with retry and dead-letter queues built in. | | CLI 3.0Rewritten in Rust. Cold start is faster and the config format is unchanged. | CLI 3.0Rewritten in Rust. Cold start is faster and the config format is unchanged. | Read the full changelog | You are receiving this because you signed up at example.com.Acme Devtools, 100 Main St, SpringfieldUnsubscribe · Manage preferences |\n| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |\n| Acme DevtoolsView in browser | Acme Devtools | View in browser | | | | | | | | | |\n| Acme Devtools | View in browser | | | | | | | | | | |\n| April product updateThree new integrations shipped this month, and the CLI got a full rewrite. Here is everything that changed and what it means for your pipelines.New: Webhook relayForward events to any endpoint with retry and dead-letter queues built in. CLI 3.0Rewritten in Rust. Cold start is faster and the config format is unchanged.Read the full changelog | New: Webhook relayForward events to any endpoint with retry and dead-letter queues built in. | New: Webhook relayForward events to any endpoint with retry and dead-letter queues built in. | | CLI 3.0Rewritten in Rust. Cold start is faster and the config format is unchanged. | CLI 3.0Rewritten in Rust. Cold start is faster and the config format is unchanged. | Read the full changelog | | | | | |\n| New: Webhook relayForward events to any endpoint with retry and dead-letter queues built in. | New: Webhook relayForward events to any endpoint with retry and dead-letter queues built in. | | CLI 3.0Rewritten in Rust. Cold start is faster and the config format is unchanged. | CLI 3.0Rewritten in Rust. Cold start is faster and the config format is unchanged. | | | | | | | |\n| New: Webhook relayForward events to any endpoint with retry and dead-letter queues built in. | | | | | | | | | | | |\n| CLI 3.0Rewritten in Rust. Cold start is faster and the config format is unchanged. | | | | | | | | | | | |\n| Read the full changelog | | | | | | | | | | | |\n| You are receiving this because you signed up at example.com.Acme Devtools, 100 Main St, SpringfieldUnsubscribe · Manage preferences | | | | | | | | | | | |"
}
},
{
"sample": "sample-content-block.html",
"input": {
"bytesUtf8": 1086,
"chars": 1086,
"tableElements": 0,
"styleAttributes": 8,
"inlineStyleBlockBytes": 0,
"msoConditionalComments": 0,
"trackingPixels": 0,
"espWrappedLinks": 1,
"nbspEntities": 1
},
"output": {
"bytesUtf8": 478,
"chars": 477,
"lines": 13,
"pipeTableRows": 0,
"pipeTableColumns": 0,
"survivingEspLinks": 1,
"containsMsoComment": false,
"containsStyleAttr": false,
"markdown": "# April product update\n\nThree new integrations shipped this month, and the CLI got a full rewrite. Here is everything that changed and what it means for your pipelines.\n\nNew: Webhook relay\n\nForward events to any endpoint with retry and dead-letter queues built in.\n\nCLI 3.0\n\nRewritten in Rust. Cold start is faster and the config format is unchanged.\n\n[Read the full changelog](https://click.example-esp.com/track?u=recipient-id-9981&dest=https%3A%2F%2Fexample.com%2Fchangelog)"
}
}
]
}