Metadata-Version: 2.4
Name: innertext
Version: 0.2.3
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing :: Markup :: HTML
Summary: Pure Rust WHATWG-compliant innerText, outerText, and textContent extraction
Author-email: Josh Fayer <josh@example.com>
License: MIT
Requires-Python: >=3.7
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/joshfayer/innertext
Project-URL: Repository, https://github.com/joshfayer/innertext

# innertext (Python)

Pure Rust WHATWG-compliant `innerText`, `outerText`, and `textContent` extraction from HTML.

## Installation

```bash
pip install innertext
```

## Quick Start

```python
import innertext

html = """
<div id="root">
    Hello <span style="display:none">hidden</span> World
    <script>console.log("not shown")</script>
</div>
"""

# Get rendered text (CSS-aware)
print(innertext.inner_text(html))  # "Hello World"

# Get structural text (CSS-blind)
print(innertext.text_content(html))  # "Hello hidden console.log("not shown")"
```

## Packaging Notes

The published Python package uses a two-layer layout:
- `innertext` is a regular Python package with a runtime `__init__.py`
- the compiled Rust extension is loaded as `innertext._innertext`

This avoids namespace-package import issues and ensures `import innertext`
always exposes `inner_text`, `outer_text`, and `text_content`.

## Type Hints

This package ships with PEP 561-compatible typing metadata:
- `innertext/__init__.pyi` defines the public API types
- `innertext/py.typed` marks the package as typed

Type checkers such as mypy and pyright can therefore infer:
- `inner_text(html: str) -> str`
- `outer_text(html: str) -> str`
- `text_content(html: str) -> str`

## API

### Functions

#### `inner_text(html: str) -> str`

Extract innerText from HTML string. Implements the [WHATWG innerText algorithm](https://html.spec.whatwg.org/multipage/dom.html#the-innertext-idl-attribute):
- Respects `display` CSS property (skips `display:none`)
- Respects `visibility` CSS property
- Respects `white-space` CSS property (normal, pre, pre-line, pre-wrap)
- Respects `text-transform` CSS property
- Handles replaced elements (textarea, input, img)
- Converts `<br>` tags to newlines

#### `outer_text(html: str) -> str`

Extract outerText from HTML string. Per WHATWG spec, outerText getter is identical to innerText getter.

#### `text_content(html: str) -> str`

Extract textContent from HTML string. Performs CSS-blind structural walk:
- Ignores all CSS properties
- Includes `display:none` content
- Includes `<script>` and `<style>` content

## Accuracy

100% Chromium parity on 36+ test cases covering:
- Display and visibility handling
- Whitespace normalization (normal, pre, pre-line)
- Block element newlines
- Table cell/row separators
- Replaced elements (textarea, input, img, button)
- Metadata elements (script, style)
- Unicode and entity handling

## Performance

- Pure Rust implementation
- Zero external runtime dependencies
- <1ms per document (parsing + extraction)
- Minimal memory overhead (O(n) DOM tree)

## License

MIT

