Python bindings for the Wasot markup language compiler
Project description
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.
.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.
.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.
.image "hero.jpg" alt="A sunset" width=800 :img-001
"hero.jpg"— positional argumentalt="A sunset"— keyword argumentwidth=800— another keyword argument:img-001— block ID for linking
Headings
Headings use # and are self-closing (no content lines).
.# Main Title
.## Section
.### Subsection
Inline Text
Use .. to put text on the same line as the block.
.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.
.sidebar
Some sidebar content.
./
Back to the main flow.
Quoted Types
Block types with spaces need quotes.
."code block" language=python
print("hello")
."my custom type" foo=bar
Content here.
Complete Example
.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.
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:
wasot --select "code" doc.wasot
wasot --select "section > p" doc.wasot -t jsonl
Validate and inspect:
wasot tools check *.wasot # validate syntax
wasot tools info doc.wasot # block counts, depth, size
wasot tools pretty docs/ # reformat in place
SQLite roundtrip:
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 for complete CLI reference.
Installation
git clone https://github.com/anthropics/wasot.git
cd wasot
cargo build --release
./target/release/wasot --help
Shell completions:
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
cd wasot
maturin develop --features 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 for details.
Documentation
- CLI Reference — Complete command-line documentation
- Syntax Reference — Language specification
- Architecture — Event-driven streaming design
- Selectors — CSS-like query syntax
- Python Bindings — Python integration
- Contributor Guide — 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 for development workflow, testing patterns, and scripts. Run ./scripts/dev/pre-commit.sh before committing.
cargo test # fast tests (~7 seconds)
./scripts/verify.sh # full verification suite
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file pywasot-0.1.1.tar.gz.
File metadata
- Download URL: pywasot-0.1.1.tar.gz
- Upload date:
- Size: 5.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"TUXEDO OS","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ccc6bc6cef23177fe015d0daf3b71175c1bb4b6dacaca43af8641dd2b6c27f3e
|
|
| MD5 |
01ca79a39d85d0c90477560f5c6795b6
|
|
| BLAKE2b-256 |
0f5dc9f50e23f6d1120f1042e180eeb17019cc8471b69891efde76c844d95849
|