pywasot 0.1.1
Python bindings for the Wasot markup language compiler
License: MIT
Requires Python: >=3.8
Keywords: markup, parsing, wasot, compiler

# Wasot

A markup format for humans and tools working together.
Markdown is great for humans, but bad for tools. 
JSON (etc.) is great for tools, but bad for humans.
Wasot is good for both.


## Why Wasot?

Markup languages make you choose: readable (Markdown) or structured (XML/JSON). Wasot gives you both.

```wasot
.article "Building Better Tools"
Software should be simple.

..section "The Problem"
Most tools try to do too much.

..section "The Solution"
Do one thing well.

...code language=rust
fn main() {
    println!("Hello");
}
```

Wasot documents are:
- **Readable** — Clean syntax, no closing tags, nesting via dots
- **Structured** — Typed blocks, parameters, IDs for linking
- **Streamable** — Event-driven parsing, constant memory, handles files larger than RAM

## Syntax

### Blocks

Blocks start with dots. More dots = deeper nesting.

```wasot
.level-1
Content at level 1.

..level-2
Nested inside level-1.

...level-3
Even deeper.

.back-to-level-1
This closes all previous blocks and starts fresh.
```

### Parameters

Blocks can have positional args, keyword args, and IDs.

```wasot
.image "hero.jpg" alt="A sunset" width=800 :img-001
```

- `"hero.jpg"` — positional argument
- `alt="A sunset"` — keyword argument
- `width=800` — another keyword argument
- `:img-001` — block ID for linking

### Headings

Headings use `#` and are self-closing (no content lines).

```wasot
.# Main Title
.## Section
.### Subsection
```

### Inline Text

Use `..` to put text on the same line as the block.

```wasot
.note .. This text is inline with the block declaration.

.warning type=critical .. Do not delete this file!
```

### Explicit Close

Use `./` to close a block early.

```wasot
.sidebar
Some sidebar content.
./
Back to the main flow.
```

### Quoted Types

Block types with spaces need quotes.

```wasot
."code block" language=python
print("hello")

."my custom type" foo=bar
Content here.
```

### Complete Example

```wasot
.document "Project Proposal" version=2 :doc-main

.# Introduction

.p
This proposal outlines our approach to building
a next-generation document processing system.

.section "Technical Overview"

..p
The system uses an event-driven architecture.

..code language=rust
let emitter = WasotFileEmitter::from_file("doc.wasot");
for event in emitter.subscribe() {
    process(event);
}

..list
First item
Second item
Third item

.section "Timeline"

..table
| Phase | Duration |
| ----- | -------- |
| Design | 2 weeks |
| Build | 4 weeks |
| Test | 2 weeks |

.footer
Contact: team@example.com
```

## CLI

Wasot includes a command-line tool for converting and processing documents.

```bash
wasot doc.wasot                    # normalize/pretty-print
wasot doc.wasot -t xml             # convert to XML
wasot doc.wasot -t jsonl           # convert to JSON Lines
wasot doc.wasot -o doc.xml         # format from extension
cat doc.wasot | wasot -t xml       # pipe from stdin
```

Filter with CSS-like selectors:

```bash
wasot --select "code" doc.wasot
wasot --select "section > p" doc.wasot -t jsonl
```

Validate and inspect:

```bash
wasot tools check *.wasot          # validate syntax
wasot tools info doc.wasot         # block counts, depth, size
wasot tools pretty docs/           # reformat in place
```

SQLite roundtrip:

```bash
wasot to-sqlite doc.wasot -d doc.db
sqlite3 doc.db "SELECT type_name, COUNT(*) FROM blocks GROUP BY type_name"
wasot from-sqlite -d doc.db
```

See [docs/cli.md](docs/cli.md) for complete CLI reference.

## Installation

```bash
git clone https://github.com/anthropics/wasot.git
cd wasot
cargo build --release
./target/release/wasot --help
```

Shell completions:

```bash
wasot tools completions bash > ~/.local/share/bash-completion/completions/wasot
wasot tools completions zsh > ~/.zsh/completions/_wasot
wasot tools completions fish > ~/.config/fish/completions/wasot.fish
```

## Python

```bash
cd wasot
maturin develop --features python
```

```python
from pywasot import parse_wasot_file

for event in parse_wasot_file("doc.wasot"):
    if event.type == "BlockStarted":
        print(event.meta_line.type_name)
```

See [docs/python_bindings.md](docs/python_bindings.md) for details.

## Documentation

- [CLI Reference](docs/cli.md) — Complete command-line documentation
- [Syntax Reference](SYNTAX.md) — Language specification
- [Architecture](docs/architecture.md) — Event-driven streaming design
- [Selectors](docs/selectors.md) — CSS-like query syntax
- [Python Bindings](docs/python_bindings.md) — Python integration
- [Contributor Guide](docs/contributor_guide.md) — Development workflow and testing

## Performance

- Streaming architecture, constant memory regardless of file size
- ~2M events/second parsing speed
- 100M+ events with ~60MB RAM

## Contributing

See [Contributor Guide](docs/contributor_guide.md) for development workflow, testing patterns, and scripts. Run `./scripts/dev/pre-commit.sh` before committing.

```bash
cargo test                         # fast tests (~7 seconds)
./scripts/verify.sh                # full verification suite
```