← Runnable Projects

阅读中文版本

HTML to Plain Text CLI

A dependency-free Node CLI that converts a small HTML document to readable plain text, honoring block breaks and decoding common entities.

intermediatejavascriptunverified

Project

node-html-to-text

Entry point: html-to-text.mjs

Install

node --version

Run

node html-to-text.mjs page.html

Test

node --test html-to-text.test.mjs

Expected output

Prints the visible text with block elements on separate lines and HTML entities decoded, and strips script and style contents.

Dependencies

  • node >=20

What it does

Removes script and style blocks, replaces block-level tags with newlines, strips remaining tags, and decodes a set of named and numeric entities. It is intentionally a small, predictable converter rather than a full parser.

const ENTITIES = { amp: '&', lt: '<', gt: '>', quot: '"', apos: "'", nbsp: ' ' };
const BLOCK = /<\/?(p|div|h[1-6]|li|tr|br|section|article)[^>]*>/gi;

export function htmlToText(html) {
  return html
    .replace(/<(script|style)[\s\S]*?<\/\1>/gi, ' ')
    .replace(BLOCK, '\n')
    .replace(/<[^>]+>/g, '')
    .replace(/&#(\d+);/g, (_, d) => String.fromCodePoint(Number(d)))
    .replace(/&(\w+);/g, (m, name) => ENTITIES[name] ?? m)
    .split('\n').map((l) => l.trim()).filter(Boolean).join('\n');
}

import { readFileSync } from 'node:fs';
const file = process.argv[2];
const input = file ? readFileSync(file, 'utf8') : readFileSync(0, 'utf8');
console.log(htmlToText(input));

Run and verify

node html-to-text.mjs page.html

Run the test command to check the implementation: node --test html-to-text.test.mjs.

Expected Output

For a document containing <h1>Title</h1><p>A &amp; B</p>, script and style are dropped and entities decoded:

Title
A & B

Limitations

Not a spec-compliant parser: malformed markup, entity edge cases, and nested tables may not convert as a browser would render them.