Metadata-Version: 2.4
Name: palestine
Version: 0.2.3
Summary: A Python DOM and server-side HTML rendering library
Project-URL: Homepage, https://github.com/u84u/palestine
Project-URL: Documentation, https://github.com/u84u/palestine#readme
Project-URL: Repository, https://github.com/u84u/palestine
Project-URL: Issues, https://github.com/u84u/palestine/issues
Author: u84u
License: MIT
Keywords: dom,html,rendering,server-side,ssr,template
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
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: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# Palestine

A Python library for building and rendering HTML using a DOM and component model.

## Installation

```bash
pip install git+https://github.com/u84u/palestine.git
```

Or clone and install locally:

```bash
git clone https://github.com/u84u/palestine
cd palestine
pip install -e .
```

Requires Python 3.9+.

## Quick start

```python
from palestine import Document, Html, Body, Div, Text

doc = Document()
html = Html()
body = Body()
doc.append_child(html)
html.append_child(body)

page = Div(class_="container")
page.append_child(Text("Hello from Palestine"))
body.append_child(page)

print(doc)
```

Output:

```html
<!DOCTYPE html>
<html><body><div class="container">Hello from Palestine</div></body></html>
```

## What it looks like

### Build a DOM tree

```python
from palestine import Div, Text, Button

card = Div(class_="card")
card.append_child(Text("Title"))
card.append_child(Button(type="submit").append_child(Text("Click")))

# Move nodes between parents automatically
other = Div()
other.append_child(card)  # Detaches from previous parent
```

### Render HTML

```python
from palestine import Div, Text, RawText

# Text is escaped automatically
div = Div()
div.append_child(Text("<script>"))  # Renders as &lt;script&gt;

# RawText is for trusted markup
div.append_child(RawText("<svg>...</svg>"))  # Renders as-is
```

### Compose components

```python
from palestine import Div, H1, P, Text

def Card(title, content):
    card = Div(class_="card")
    card.append_child(H1().append_child(Text(title)))
    card.append_child(P().append_child(Text(content)))
    return card

page = Div()
page.append_child(Card("First", "Content here"))
page.append_child(Card("Second", "More content"))
```

### Parse and manipulate HTML

```python
from palestine import parse_html

doc = parse_html('<div class="box"><p>Hello</p></div>')
div = doc.query_selector(".box")
div.append_child(parse_html("<span>World</span>"))
```

### Templates

```python
from palestine import Template

tmpl = Template("<h1>{{ title }}</h1><p>{{ content }}</p>")
html = tmpl.render(title="My Page", content="Hello world")
```

### Forms and validation

```python
from palestine import FormBuilder, FormValidator, Required, Email

form = FormBuilder(action="/submit", method="post")
form.add_text("name", "Name", required=True)
form.add_email("email", "Email", required=True)
form.add_submit("Register")

validator = FormValidator({
    "name": [Required()],
    "email": [Required(), Email()],
})
errors = validator.validate({"name": "", "email": "invalid"})
```

## Features

- **DOM primitives**: Node, Element, Text, RawText, Comment, Document
- **HTML elements**: All standard HTML5 elements
- **Rendering**: HTML serialization, pretty printing, minification, streaming
- **Parsing**: HTML to DOM conversion
- **Templates**: Variable substitution and control flow
- **Components**: Reusable UI composition
- **Forms**: Form building and validation
- **Security**: HTML sanitization, escaping, URL validation
- **VDOM**: Virtual DOM with diff/patch

## Architecture

Palestine is built around a mutable DOM tree:

```
Node
  ├── Element (tag, attributes, children)
  ├── Text (escaped content)
  ├── RawText (trusted markup)
  ├── Comment
  └── Document (root node)
```

Components are functions that compose elements. The renderer serializes the tree to HTML.

## Performance

Palestine's renderer is optimized around direct DOM traversal, string accumulation, and bounded selector caching.

Reproducible benchmarks, profiling scripts, and historical baseline comparisons live in the GitHub repository under [`benchmarks/`](https://github.com/u84u/palestine/tree/master/benchmarks).

From a Git checkout:

```bash
python -m benchmarks.benchmark
python -m benchmarks.benchmark_memory
python benchmarks/profile_hotpaths.py
```

See [`benchmarks/REPORT.md`](https://github.com/u84u/palestine/blob/master/benchmarks/REPORT.md) for detailed results and methodology.

## Status

Early-stage project. The core DOM, rendering, and template engine are functional and tested.

The parser is built on Python's `html.parser` and does not implement the full WHATWG HTML parsing algorithm. It handles common cases but may differ from browser parsing on malformed input.

The API may change between versions.

## Why Palestine?

Most Python HTML generation falls into two camps: template languages (Jinja2, Mako) that treat HTML as strings, or minimal builder libraries (dominate, htpy) with a narrow API.

Palestine is different in that it gives you a mutable, traversable DOM tree — the same conceptual model as the browser — with `querySelector`, `classList`, event dispatch, `innerHTML`, `closest`, and `clone`. If you are building a server-side rendering pipeline, a static site generator, or an email renderer where you need to inspect and mutate the tree after construction (not just write it once), Palestine is designed for that.

It has no runtime dependencies and works on Python 3.9+.

## Examples

Two runnable examples are in the `examples/` directory:
- `hello_world.py` — minimal HTTP server
- `file_explorer.py` — file browser showing table building, conditional DOM construction, and safe path handling

Run either with: `python examples/file_explorer.py`
Then open http://localhost:8000

## License

MIT
