parse5

repository·master·Indexed 26 days ago

https://github.com/inikulin/parse5

A high-performance, WHATWG HTML Living Standard compliant HTML parsing and serialization toolset for Node.js. Designed to mimic browser-level parsing behavior, it includes the core parser and serializer as well as specialized packages: parse5-html-rewriting-stream for streaming transformations, parse5-htmlparser2-tree-adapter for htmlparser2 compatibility, parse5-parser-stream for streaming parsing with scripting support, parse5-plain-text-conversion-stream for converting plain text to HTML, and parse5-sax-parser for event-based parsing.

Tokens
13.1K
Snippets
26
Records
64
Agent score
85%

What's inside parse5

  1. Overview of parse5

    master
    parse5 is a high-performance, WHATWG HTML Living Standard (HTML5) compliant HTML parsing and serialization toolset for Node.js. It is designed to parse HTML exactly as modern web browsers do and is used by major projects like jsdom, Angular, Lit, Cheerio, and rehype. The toolset includes various specialized packages for streaming, SAX parsing, and tree adaptation.
  2. Identify the correct parse5 package for your use case

    master

    The parse5 ecosystem consists of several specialized packages depending on your requirements for parsing, streaming, or rewriting HTML:

    • parse5: The core HTML parser and serializer.
    • parse5-htmlparser2-tree-adapter: Provides an adapter to use htmlparser2 tree structures with parse5.
    • parse5-parser-stream: A streaming HTML parser that includes scripting support.
    • parse5-plain-text-conversion-stream: A stream designed to convert plain text files into HTML documents.
    • parse5-sax-parser: A streaming SAX-style HTML parser.
    • parse5-html-rewriting-stream: A streaming HTML rewriter for modifying HTML content on the fly.
  3. Handle Adoption Agency Algorithm behavior

    master

    The parser implements the HTML 'Adoption Agency' algorithm. This algorithm is triggered when a formatting element (like <b> or <i>) is encountered while an existing formatting element of the same type is already in scope.

    When this occurs, the parser:

    1. Obtains the formatting element entry.
    2. Finds the furthest block in the stack.
    3. Performs an inner loop to move/recreate elements to ensure proper tree construction.
    4. Replaces the formatting element to maintain spec-compliant DOM structure.

    Developers using the parser can rely on this built-in behavior to ensure that malformed or highly nested formatting tags are parsed exactly as a web browser would handle them.

  4. Use RewritingStream for streaming HTML transformations

    master

    The RewritingStream class is a Node.js Transform stream that allows you to perform SAX-style HTML rewriting. It parses HTML and emits events for different token types, allowing you to intercept and modify them before pushing the results to the output stream. Because it is a Transform stream, you can pipe data through it (e.g., from an HTTP response to a file).

    To rewrite HTML, listen for events like startTag, endTag, or text, modify the token if necessary, and then call the corresponding emit* method to write the modified (or original) content to the stream.

    const RewritingStream = require('parse5-html-rewriting-stream');
    const http = require('http');
    const fs = require('fs');
    
    const file = fs.createWriteStream('/home/google.com.html');
    const rewriter = new RewritingStream();
    
    // Replace divs with spans
    rewriter.on('startTag', startTag => {
        if (startTag.tagName === 'span') {
            startTag.tagName = 'div';
        }
    
        rewriter.emitStartTag(startTag);
    });
    
    rewriter.on('endTag', endTag => {
        if (endTag.tagName === 'span') {
            endTag.tagName = 'div';
        }
    
        rewriter.emitEndTag(endTag);
    });
    
    // Wrap all text nodes with an <i> tag
    rewriter.on('text', (_, raw) => {
        // Use the raw representation of text without HTML entities decoding
        rewriter.emitRaw(`<i>${raw}</i>`);
    });
    
    http.get('http://google.com', res => {
       // Assumes response is UTF-8.
       res.setEncoding('utf8');
       // `RewritingStream` is a `Transform` stream, which means you can pipe
       // through it.
       res.pipe(rewriter).pipe(file);
    });