• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import { type ParserOptions, type TreeAdapterTypeMap, html } from 'parse5';
2import { ParserStream } from 'parse5-parser-stream';
3
4const { TAG_ID: $, TAG_NAMES: TN } = html;
5
6/**
7 * Converts plain text files into HTML document as required by [HTML specification](https://html.spec.whatwg.org/#read-text).
8 * A [writable stream](https://nodejs.org/api/stream.html#stream_class_stream_writable).
9 *
10 * @example
11 *
12 * ```js
13 * const PlainTextConversionStream = require('parse5-plain-text-conversion-stream');
14 * const fs = require('fs');
15 * const { finished } = require('node:stream');
16 *
17 * const file = fs.createReadStream('war_and_peace.txt');
18 * const converter = new PlainTextConversionStream();
19 *
20 * finished(converter, () => {
21 *     console.log(converter.document.childNodes[1].childNodes[0].tagName); //> 'head'
22 * });
23 *
24 * file.pipe(converter);
25 * ```
26 */
27export class PlainTextConversionStream<T extends TreeAdapterTypeMap> extends ParserStream<T> {
28    constructor(options?: ParserOptions<T>) {
29        super(options);
30
31        // NOTE: see https://html.spec.whatwg.org/#read-text
32        this.parser._insertFakeElement(TN.HTML, $.HTML);
33        this.parser._insertFakeElement(TN.HEAD, $.HEAD);
34        this.parser.openElements.pop();
35        this.parser._insertFakeElement(TN.BODY, $.BODY);
36        this.parser._insertFakeElement(TN.PRE, $.PRE);
37        this.parser.treeAdapter.insertText(this.parser.openElements.current, '\n');
38        this.parser.switchToPlaintextParsing();
39    }
40}
41