Metadata-Version: 2.5
Name: hyperscribe
Version: 0.2.0
Summary: A small, dependency-free HTML templating engine that writes markup with context managers.
Project-URL: Homepage, https://github.com/septatrix/hyperscribe
Project-URL: Repository, https://github.com/septatrix/hyperscribe
Project-URL: Issues, https://github.com/septatrix/hyperscribe/issues
Author-email: Septatrix <24257556+septatrix@users.noreply.github.com>
Keywords: context-manager,html,markup,template-engine,templating
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
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 :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Text Processing :: Markup :: HTML
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# hyperscribe

A small, dependency-free HTML templating engine for Python.
You write markup as ordinary Python code with context managers,
and hyperscribe streams escaped, indented HTML to any file-like object.

```python
from io import StringIO

from hyperscribe import DocWriter

output = StringIO()
doc = DocWriter(output)

with doc.html(lang="en"):
    with doc.body.main:
        doc.h1("Hello & welcome")
        with doc.ul:
            for name in ("one", "two"):
                doc.li(name)

print(output.getvalue())
```

```html
<html lang="en">
  <body>
    <main>
      <h1>Hello &amp; welcome</h1>
      <ul>
        <li>one</li>
        <li>two</li>
      </ul>
    </main>
  </body>
</html>
```

## Features

- Templates are plain Python: use loops, functions, and `@contextmanager` layouts.
- Text and attribute values are escaped by default.
- Output is streamed to anything with a `write(str)` method.
- No dependencies, fully typed, and supports Python 3.10 and newer.

## Installation

```sh
pip install hyperscribe
```

## Documentation

Full documentation is available at
<https://septatrix.github.io/hyperscribe/>.

## Development

```sh
make sync     # install dependencies
make check    # lint, type-check, check formatting, and test
make format   # format the code with ruff
make docs     # build the documentation
```

Run `make help` to list all targets.
Use `uv run sphinx-autobuild docs docs/_build/html` to preview the docs while editing.

The [benchmarks](benchmarks/README.md) compare hyperscribe with other Python HTML templating libraries
using pytest-benchmark.
Their dependencies live in the optional `benchmarks` dependency group
and need Python 3.14:

```sh
uv run --group benchmarks pytest benchmarks
```

## Releasing

The version is derived from git tags by `hatch-vcs`.
To release, publish a GitHub release whose tag is `v` plus the version, such as `v0.2.0`.
The `Publish` workflow builds the package
and uploads it to PyPI through
[trusted publishing](https://docs.pypi.org/trusted-publishers/).
Copy the files in `contrib/workflows/` to `.github/workflows/` once,
using a credential that may edit workflows.

## Roadmap

These gaps showed up
when porting real Jinja and bottle templates to hyperscribe.
Attribute handling, content conversion, comments,
`doc.void_tag` for void elements, and the guide's loop idioms
have been dealt with since.
Two larger items remain.

- **Element registry.**
  hyperscribe does not know anything about individual elements.
  A registry with metadata per element
  should cover the following:
  - Void elements such as `<br>` and `<img>` should be written
    without calling `doc.void_tag` explicitly.
  - Whitespace-sensitive elements such as `<pre>` and `<textarea>`
    should switch to inline mode automatically.
    Today the caller has to know to use `doc.inline()`.
  - The contents of `<style>` and `<script>` should be written verbatim.
  - The set of permitted attributes could be checked.
- **Trusted content.**
  Escaping text by default is intended.
  What is missing is a way to mark content as already safe
  other than `write_raw`,
  for example CSS, JavaScript or prepared markup.
  The idea is a safe string type,
  either MarkupSafe's `Markup` or a custom implementation,
  perhaps built on template strings (`t""`).

## Status

hyperscribe is in early development
and its API may change between minor releases.
