caj2pdf-rust
Convert CNKI CAJ-family documents (CAJ, KDH, HN, C8) to PDF from the command
line, Node.js or the browser. MIT-licensed Rust with a WebAssembly build.
Memory stays bounded: input is read by range and output is written as a stream.
Releases are v0.x: CLI behavior and APIs may still change, and HN/C8 support
is experimental.
Quick start
Download the CLI archive for your platform from GitHub Releases, extract it, and run:
Or install it from crates.io with Rust 1.88 or newer and curl:
Releases also carry a container image (Docker usage) and a JavaScript tarball for Node.js 22+ and browsers (JS API). The JavaScript package is also on npm:
Supported operating systems and CPUs are listed in the platform matrix.
The JavaScript API runs each conversion in a Worker. It reads a browser
File, Blob or OPFS file handle, or a Node.js path, descriptor or Blob,
and writes to a stream:
import from "caj2pdf-rust";
const writer = .;
await ;
await writer.;
What converts
| Input | Status |
|---|---|
| Supported: copied, with documented repairs. The TTKN server profile requires an explicit response. | |
| CAJ | Supported, with its bookmarks. |
| KDH | Supported for embedded PDFs. |
| HN-A | Experimental: scanned page images and bookmarks; no text layer. |
| C8, HN-B | Experimental: image pages, and native text pages with automatic bundled fonts (below). No bookmarks yet. |
| CAA | Recognized target descriptor: inspection only; obtain the referenced document to convert it. |
| TEB | Recognized, conversion not implemented; detection does not establish encryption or recoverability. |
The support matrix is the source of truth, with the verified profiles and remaining differences. Unsupported content fails with a located error instead of dropping pages.
Extensions do not determine the format: the measured .nh sample contains
HN-A bytes and converts through that path (433 pages, 365 bookmarks;
validation). Historical
CAJViewer documentation also names CAS, but no authentic sample has been found;
CAS research remains open.
The measured C8 subset includes the NJU title, resource-control and line-segment profiles documented in provenance. Other record/style combinations can still be refused.
Fonts for C8 and HN-B text pages
CLI and JavaScript conversions automatically use the measured CAJViewer font preset, including mode-specific parameters. No font installation or extra conversion arguments are needed. Native binaries work offline; Node reads fonts from the package, and the browser downloads and caches them on first use.
The resource pack adds about 58.6 MiB before compression. It stays outside the
core/WASM module, and ranged reads keep it outside the WASM heap. Complete
original font programs also increase the size of native-text PDFs.
See bundled fonts for browser hosting, offline source
builds and custom-font overrides. Explicit fonts remain available through
--fonts DIR or JavaScript hnc8.fonts.
Limits
- C8/HN-B outlines are not verified, so those PDFs have no outline and the CLI
prints a warning.
--no-bookmarkssilences it. - HN-A pages are images. Run an OCR tool such as
ocrmypdffor search. - Substitute fonts do not reproduce the CAJViewer typography pixel for pixel. A measured HN-B private-use glyph may use a visual approximation with an explicit warning; its private-use code is retained in PDF ActualText.
- TEB files cannot be converted.
Library
Add the Rust library with cargo add caj2pdf-core.
The caj2pdf-core crate is the engine behind the CLI and the WASM build. It
reads any RangedSource (SeekableSource over a File, or a byte slice)
and writes any std::io::Write:
use ;
use ;
let mut input = new?;
let mut output = new;
let report = convert?;
convert detects the format and converts it; inspect returns the format,
page count, outline and structure. ConversionOptions selects bookmarks,
damaged-CAJ substitution and C8/HN-B fonts; a Progress receives the
detected format and read progress and can cancel. The
I/O architecture describes the contract.
More
- CLI reference: every command, option, exit status and the
inspectJSON schema. - I/O architecture and JS validation.
- Release policy and build provenance for verifying downloads.
- Research notes: the format investigations behind the decoders, kept with the oracles and conformance harnesses in caj2pdf-samples.
Contributing, provenance and license
Source code is MIT. Code must be original: do not copy from the Python or Go converters or from decoders under other licenses. The provenance record lists format references, the external test corpus rules and the dependency review. Sample documents are not part of this repository; the separate CAJSamples collection is an optional compatibility corpus. See CONTRIBUTING.md for checks, commit style and the merge gate, and CHANGELOG.md for changes. The project's public language is English.