Skip to main content

Formats

A format in neokapi is a paired reader and writer for a document type. The reader turns a file into a stream of Parts — the content blocks and the surrounding structure — and the writer turns that stream back into a file. This read/process/write symmetry is what lets the same tools and flows operate on any format: by the time a tool sees a Block, it no longer matters whether it came from JSON, HTML, or DOCX.

See the skeleton preserved

Reading a file splits it into content blocks and a non-translatable skeleton — every tag, key, attribute, and delimiter the writer needs to reproduce the original structure. Run a file through pseudo-translate below and compare the source with the round-tripped output: only the leaf text changes, while the skeleton comes back byte-for-byte. This runs the real kapi reader and writer in your browser via WebAssembly.

Loading the interactive lab…

neokapi ships built-in readers and writers spanning several families:

  • Software i18n catalogs — JSON (including i18next, ARB, and design tokens), YAML, Java properties, Android strings.xml, Apple .strings/.xcstrings, RESX, Qt TS, gettext PO/MO, ICU MessageFormat.
  • Documents & markup — Markdown and MDX, HTML, AsciiDoc, XML (with configurable translatable elements), plain text.
  • Office & publishing — Office Open XML (.docx, .xlsx, .pptx), OpenDocument, EPUB, PDF.
  • Data — CSV/TSV, with column-role configuration.
  • Subtitles & media — SubRip (SRT), WebVTT; images, audio, and video as per-locale assets.
  • Bilingual interchange — XLIFF 1.2 and 2.x, PO, TMX, and the native Kapi format family — the translator-handoff layer.
  • Containers & archives — ZIP, TAR, and gzip-compressed TAR, treated as a folder of sub-documents (see below).

An image is read as an asset in its own right: the picture itself is the unit a workflow can replace with a per-locale variant. With the kapi-vision plugin installed (and the ocr/layout options on), the reader also extracts in-image text and document layout — regions, reading order, tables — turning a screenshot or scanned page into structured, translatable content. The design, and the full set of image-adaptation modes, are described in AD-029.

PDF is read by Google's PDFium rather than a built-in reader: on the desktop and CLI through the kapi-pdfium plugin, and in the browser through PDFium compiled to WebAssembly. Beyond text, it recovers each fragment's position on the page (geometry) and the document's structure — headings, paragraphs, and tables — from the PDF's own tags where present and by geometric inference otherwise. You can try it on your own files in the Structure & Layout lab; the design is described in AD-028.

An archive — a ZIP, TAR, or gzip-compressed TAR — is a namespace of inner documents rather than one document, so it is handled as a container binding (AD-026) rather than a format with a writer. Pointed at an output-producing command, each entry is processed as its own file run — through that entry's normal reader and writer with full skeleton round-trip — and the results are repacked over the original container, copying every other member byte-for-byte. Because each entry is a real, standalone file run, a packaged format such as a DOCX or EPUB inside the archive round-trips faithfully, and each entry resolves its own format configuration. Binary assets, nested containers, and bilingual interchange files pass through unchanged. So kapi pseudo-translate bundle.zip -o out.zip pseudo-translates every recognised file inside it — including nested Office documents — in one pass. For inspection, a read-only archive reader surfaces each entry's content so kapi inspect bundle.zip shows what is inside.

Each format exposes its own configuration (extraction rules, segmentation, inline-code handling). Rather than maintain a list by hand, the Format Reference is generated directly from the format registry — it always reflects the formats and parameters in the current build.

How kapi reads a file

The clearest way to see what a format reader does is to watch it parse a file. Below, kapi reads an Android strings.xml resource and produces the content model — the translatable blocks, their identifiers, and their source text. This is the reader stage of the pipeline, with no transformation applied:

The same parser, pointed at a different format, produces blocks of the same shape. Here an XLIFF bilingual file resolves to the same kind of block stream:

The block shape is the same, but bilingual formats carry more. A monolingual format (JSON, YAML, properties) produces whole-block source content with no internal segment structure. A bilingual format (XLIFF, TMX) additionally populates stand-off segmentation and alignment overlays: the file's existing segment boundaries and source↔target pairings are recorded as overlays over the runs rather than baked into structure, so they survive a round-trip when present and are simply absent when a format doesn't define them. Tools and writers read those overlays; a format that emits none works at whole-block granularity.

Content fidelity: context for ingestion

The split above — translatable blocks plus an inert skeleton — is not the whole story. A document carries text that should not be translated but is still meaningful: code listings, image captions and alt-text, formulas, strings explicitly marked do-not-translate, and values a config rule excluded from translation. For a translation run this is noise; for feeding a document to an LLM or a retrieval index, it is exactly the context you want to keep.

By default, neokapi readers surface this contextual content as non-translatable blocks rather than hiding it in the skeleton. Such a block is visible to anything that reads the Part stream — the editor, an export to Markdown, an ingestion pipeline — and is tagged with a role (code, formula, caption, …) so consumers know what it is, but machine translation skips it and the round-trip is unaffected (its original bytes are still replayed verbatim). Comments and similar metadata surface as data or notes alongside the content.

Each reader that supports this exposes an extractNonTranslatableContent option (on by default) in the Format Reference; set it false to restore the older skeleton-only behavior. The design — and why it leaves translation output and the round-trip guarantee unchanged — is described in AD-031. Equations are a notable case: Word/OMML formulas are converted to LaTeX/MathML and rendered on cross-format export, and the natural-language prose inside an equation is translatable — see kconv and AD-032.

Plugin formats

Plugins can register additional readers and writers alongside the built-in set — the kapi-pdfium plugin adds the PDF reader, for example. Once installed, a plugin's formats participate in detection, kapi formats list, and flows exactly like the built-in ones.

Format Detection

neokapi automatically detects formats using a cascade strategy:

  1. Explicit MIME type (if provided)
  2. File extension mapping
  3. Magic bytes / content sniffing

You can override detection with the --format flag on any command.

Listing Formats

kapi formats

Use --mime or --ext to filter:

kapi formats --mime text/html
kapi formats --ext .docx

Interactive Format Reference

See the Format Reference page for interactive documentation of all formats with configurable parameters.