boox-note-parser
WARNING: This crate is still work in progress.
A Rust library for parsing
.notefiles from Onyx Boox e-ink devices.
boox-note-parser provides a pure Rust implementation for reading and interpreting handwritten note data stored in .note files on Boox devices.
The format is undocumented and reverse-engineered from real note exports.
What Works Today
- Open single-note and multi-note
.notearchives. - Read note metadata (
note_tree/note_infoprotobuf payloads). - Parse page models and virtual page/document metadata.
- Parse shape groups and custom points stroke files.
- Parse
extra/pb/extrametadata. - Parse templates from
template/json/*.template_jsonand.template_json(including mirroreddocument/<note_id>/...paths). - Surface
resource/pb/*records, including explicit handling for empty payload files. - Surface TOC and preview PNG asset metadata.
- Render page strokes to PNG using style-aware color/width/line-style mapping.
Quick Start
use ;
use NoteFile;
You can also run the example inspector:
Or the bundled render CLI binary, which writes one PNG per page without
the inspector's metadata dump:
Try It Out
CLI Track (Inspector Example)
Run the built-in inspector:
Expected behavior:
- Prints note metadata (IDs, names, timestamps, pen settings).
- Prints template/resource/extra/asset metadata (
Templates:,Resources:,TOC exists:,Preview:). - Renders pages and writes PNG files to the current directory.
- Skips pages with no shapes (logs a
WARNand prints(empty page — skipped render)). - Skips detached page entries that have no page model (prints
(no page model — detached/orphan)).
Quick verification checks:
- Confirm output includes lines for template/resource/assets.
- Confirm generated PNGs are present in your working directory.
CLI Track (render Binary)
For batch rendering without inspection output:
Writes <note_name>_<note_id>_<page_id>.png for every active, reserved, and
detached page. The output directory defaults to the current working directory
and is created if missing.
Library Track (Use the Crate in Your Own Binary)
Minimal example:
use ;
use NoteFile;
Compile/run guidance:
Add this dependency in Cargo.toml:
[]
= { = "../boox-note-parser" }
Then run:
Troubleshooting
- If you forget the note-file path, inspector exits with a usage line.
- If a note is unsupported/corrupt, parsing returns an error instead of panicking.
- Corpus integration tests are skipped unless enabled with:
BOOX_NOTE_PARSER_RUN_CORPUS_TESTS=1
Fixture Contribution Guide
This project prefers extracted-minimal fixtures over full .note files.
Guidelines:
- Do not commit personal/raw full exports by default.
- Contribute only the smallest extracted blobs needed to prove parser behavior under
tests/fixtures/<topic>/. - Remove or anonymize sensitive names/text/identifiers in fixture content before submission.
- Add a short note in the test describing which behavior the fixture validates.
Expected wiring:
- Fixture files live under
tests/fixtures/<topic>/. - In-memory archive assembly and reuse helpers live in
tests/common/mod.rs. - Behavior-focused integration tests follow the pattern in
tests/p2_fixture_coverage.rs.
Quality Checks
Baseline required checks:
Optional local corpus validation (requires local sample .note files):
BOOX_NOTE_PARSER_RUN_CORPUS_TESTS=1
Optional stricter static analysis (non-gating for now):
Corpus Notes (Current Reverse Engineering Basis)
The code and format notes are currently validated against Boox Notes App exports from a Boox Note Air 4 C (Notes app build 42842 - 0760e1b1dad).
Observed in that corpus:
- Both single-note and multi-note layouts are present.
- UUIDs appear in both simple (32 hex chars) and hyphenated forms.
template/json/.template_jsonappears as a per-note default template/background descriptor.resource/pbfiles may exist but can be empty (0 bytes).toc/directories may exist and be empty.- Multi-note exports include note preview PNG thumbnails (
499x666) at note-root level.
Current Gaps
- Unknown protobuf fields and some metadata semantics still need broader cross-device validation.
resource/pb/*andtoc/pb/*payload internals are still treated as opaque/partially modeled.- More cross-device corpus coverage is needed to confirm behavior outside current observed exports.