html2text Rust Crate

repository·main·Indexed 42 days ago

https://github.com/jugglerchris/rust-html2text

A Rust library and CLI tool for rendering HTML as plain text or rich terminal output. It utilizes the html5ever parser and supports CSS rule processing, ANSI colors, and syntax highlighting via the syntect engine. Key features include a configurable Config struct for text wrapping and table rendering, a StyleData system for managing agent, user, and author CSS rules, and a CLI for converting HTML files or stdin to formatted text.

Tokens
10.8K
Snippets
41
Records
60
Agent score
53%

What's inside html2text

  1. Configure CSS and color support

    main

    When the css feature is enabled, html2text can handle basic CSS selectors and colors.

    Style Sources

    Style rules are sourced from:

    • Document <style> elements
    • Inline style attributes
    • <font color=...> tags
    • Custom rules added via Config::add_css(...) (available regardless of use_doc_css() setting).

    Accessing Colors

    To utilize CSS colors in your output, you have two options:

    1. Rich Annotations: Use from_read_rich() or its variants. This returns a tree containing Colour(..) annotations.
    2. Direct Coloring: Use from_read_coloured(). This function accepts a closure that allows you to map RichAnnotations directly to terminal styling (e.g., using termion).
    // Example concept: using from_read_rich to get annotations
    // let rich_text = from_read_rich(&html[..], 80);
    // // rich_text will contain nodes like Colour(..)
  2. Enable advanced terminal output with colors and syntax highlighting

    main

    You can generate enhanced terminal output using specific flags. Note that syntax highlighting requires the css_ext Cargo feature to be enabled in the underlying library.

    Available advanced options:

    • --colour: Enables ANSI colors in the output.
    • --css: Enables CSS rule processing.
    • --syntax: Enables syntax highlighting using syntect.
    • --agent-css '<selector> { <rule>; }': Allows passing custom CSS rules to the agent.
    html2text --colour --css --syntax --agent-css 'pre.rust { x-syntax: rs; }' < file_with_rust_code.html
  3. Use the html2text CLI to convert HTML to text

    main

    The html2text command-line tool converts HTML into text formats. By default, it produces text with ASCII annotations (similar to Markdown) for elements like <strong> and lists, and includes table formatting. It reads from standard input and writes to standard output by default.

    html2text foo.html
  4. Enable XML/XHTML support via `xml` feature

    main

    By default, html2text parses documents as HTML. If the xml feature is enabled, the parser will automatically switch to XHTML mode if the document begins with an <?xml?> declaration.

    You can manually control this behavior using Config::xml_mode().

  5. How TextDecorator annotations work

    main

    The TextDecorator trait uses an associated type Annotation to allow renderers to pass metadata to the final output stage.

    1. When a decorator method like decorate_em_start is called, it returns a (String, Self::Annotation) tuple. The String is the literal text decoration (e.g., *), and the Annotation is the metadata.
    2. This Annotation is then attached to the TaggedString via the TaggedLineElement structure.
    3. A consumer of the rendered TaggedLine<Annotation> can iterate through the elements and use the Annotation to apply environment-specific styling (like ANSI escape codes for terminal colors) to the corresponding text spans.
  6. How the rendering pipeline works

    main

    The conversion process follows a two-phase pipeline:

    1. Tree Construction: HTML is parsed into a RenderNode tree. During this phase, styles are computed and elements are categorized into RenderNodeInfo variants.
    2. Rendering: The render_tree_to_string function processes the tree in two sub-steps:
      • Phase 1 (Size Estimation): A tree_map_reduce pass calculates size estimates (like min_width and prefix_size) for nodes to ensure proper layout (especially for tables and lists).
      • Phase 2 (Actual Rendering): A TextRenderer traverses the tree. It uses a TextDecorator to handle text styling and manages a stack of SubRenderer instances to handle indentation and nested structures (like blockquotes or list items).
  7. Supported CSS property parsing behaviors

    main

    The parser handles several specific CSS properties and formats:

    • Colors: Supports hex codes (#123, #abcdef), named colors (white), and functional notation (rgb(1, 2, 3)).
    • Backgrounds: The background shorthand can be parsed into BackgroundColor if it contains a color (e.g., background: white or background: url('...'), white). If it contains complex values like URLs without a fallback color, it may result in Decl::Unknown.
    • Dimensions: Supports height and max-height with various units like px and cm (e.g., height: 0; max-height: 100cm).
    • Overflow: Supports overflow and overflow-y with values like hidden and scroll.
    • Content: Supports the content property for pseudo-elements (e.g., content: "blah*#";).
    • Importance: Supports the !important flag to set the importance field of a Declaration to Importance::Important.
  8. Understand NodeData types

    main

    The NodeData enum defines the specific type of information stored in a Node. When processing the DOM, you will typically match on these variants:

    • Document: The root node.
    • Doctype: Contains name, public_id, and system_id (as StrTendril).
    • Text: Contains the text content in a RefCell<StrTendril>.
    • Comment: Contains the comment text as a StrTendril.
    • Element: Contains the name (QualName), attrs (RefCell<Vec<Attribute>>), template_contents (RefCell<Option<Handle>>), and mathml_annotation_xml_integration_point (bool).
    • ProcessingInstruction: Contains a target and contents (both StrTendril).
  9. How HTML elements are mapped to RenderNodes

    main

    The library converts HTML elements into a tree of RenderNode objects. Each HTML tag is mapped to a specific RenderNodeInfo variant which dictates how it will be rendered into text.

    Key mappings include:

    • Structural/Block elements: <div>, <p>, <ul>, <ol>, <li>, <h1>-<h6>, <blockquote>, <table>, <tr>, <td>, <th>, <thead>, <tbody>.
    • Inline/Text styling: <a> (Link), <em>/<i>/<ins> (Em), <strong>/<b> (Strong), <s>/<del> (Strikeout), <code> (Code), <sup> (Sup).
    • Media/Special: <img> (Img), <svg> (Svg), <br> (Break).
    • Lists: <ul> (Ul), <ol> (Ol), <dl> (Dl), <dt> (Dt), <dd> (Dd).

    Some elements like <span> or <div> act as containers without adding specific text decorations, while others like <a> extract attributes (e.g., href) to create functional text nodes.

  10. How CSS styles are applied to text

    main

    When the css_ext feature is enabled, the library can apply styles to specific text segments within a node.

    During the conversion of markup5ever_rcdom::NodeData::Text, the library checks for extra_styles. If present, it splits the text into multiple RenderNode segments: some plain Text nodes and some Text nodes with a ComputedStyle (containing fg_colour and bg_colour). This allows for inline styling within a single text block.

  11. Reference types: Handle and WeakHandle

    main

    The DOM uses reference counting to manage memory and allow nodes to exist independently of the document.

    • Handle: A type alias for Rc<Node>. This is the standard way to hold a reference to a node.
    • WeakHandle: A type alias for Weak<Node>. Used for parent pointers to prevent reference cycles that would cause memory leaks.