How well does this actually work?

Every translation tool claims it preserves your formatting. Almost none of them show you the test that proves it. These are ours, across 7 file formats: what each harness checks, what it found, and what we still do not cover.

118/118
checks and fixtures passing
7
formats with a harness
August 1, 2026
most recent run

These are not marketing numbers. Each one is regenerated from a harness in backend/eval/ that runs against the same engine this site uses. The unit differs by format, which the table below labels: some harnesses report one result per named check, others one per test file, where a single file has to clear several checks at once.

The scorecard

Format Result What it proves Last run
Word (.docx) 13/13 fixtures Only the text changed. Every other byte of the document is provably untouched. July 2, 2026
Excel (.xlsx) 35/35 checks Selected cells translate. Formulas, numbers and unselected sheets come back byte-identical. July 25, 2026
EPUB 56/56 checks The book still opens in a strict reader, with both tables of contents translated and images untouched. July 29, 2026
JSON / i18n 3/3 fixtures Values translate, keys never do, and placeholders like {{name}} come back intact. August 1, 2026
CSV 4/4 fixtures The exact frame of the file survives: delimiters, quoting, ragged rows and all. August 1, 2026
YAML 3/3 fixtures Comments, anchors and indentation survive, because the file is edited in place rather than rebuilt. August 1, 2026
Plain text (.txt) 4/4 fixtures The line skeleton is preserved exactly: line count, blank lines, indentation, BOM and line endings. July 23, 2026

How these are measured

There are two kinds of run here, and the difference matters when you read a number.

Offline gates

The engine runs against fake translators instead of a real model: one that returns the text unchanged, one that rewrites the words but keeps the formatting markers, and one that deliberately destroys them. Free, deterministic, and it isolates the part we control. This proves the engine cannot corrupt your file.

Live gates

The same fixtures go through the real Gemini pipeline this site uses, and the output is scored for coverage, source-language leakage and protected tokens. Slower and it costs money to run, so it is run less often. This proves the whole path works, not just our half of it.

The central idea in all of it is the no-op gate: translate a file with a pass-through that changes nothing, and require the output to be byte-for-byte identical to the input. It sounds trivial. It is the single most revealing test we run, because most tools that "lose your formatting" lose it here, in the rebuild, before a model has said a word.

What these numbers do not claim

None of this measures whether a translation reads well. There is no LLM judge and no COMET-style quality score here. What is measured is fidelity: that your file comes back structurally intact, that the right parts were translated and the rest was left alone, and that URLs, emails, placeholders and formulas survived. Translation quality is a separate problem and we would rather publish nothing about it than publish something unverified.

Format by format

Word (.docx)

13/13 fixtures · live run into French · July 2, 2026
Text units translated
67
Coverage
100.0%
Source text left untranslated
0.0%
URLs and emails altered
0

What the harness checks

  • No-op gate. Translate with a pass-through that returns each string unchanged, then compare the two .docx packages part by part at the XML level. Each part is compared as a canonicalized tree, so attribute order and whitespace noise do not count as changes, only real structural differences do. The result must be identical.
  • Formatting gate. Translate for real, then run the same comparison with every text node blanked first. This answers the question that matters: did anything other than the words change? Styles, tables, numbering, headers, footers, colours and page breaks all have to survive it.
  • Coverage and leakage. Read the output back and language-detect every text unit. Coverage is how much the engine reported translating; leakage is output text still detected as the source language. A tool can translate 100% of units and still leave source text sitting in the file, so these are measured separately.
  • Do-not-translate gate. Harvest every URL and email address from the source and require each one to appear verbatim in the output. These have no valid localized form, so any change is a real defect rather than a judgement call.
  • Opens cleanly. The translated file is opened with LibreOffice to confirm no repair prompt or load error.

Known limitations

  • The published live run targets French. Other languages are tested by hand, not by this harness.
  • Leakage is a review signal, not a hard gate. Short units are unreliable to language-detect, so the metric only judges units long enough to be confident and never fails one for uncertainty alone.
  • Numbers and dates are deliberately excluded from the do-not-translate check, because localizing "1,234.56" to "1 234,56" in French is correct behaviour, not a violation.
  • This measures fidelity, not fluency. There is no LLM-judge or COMET-style quality score here, so none of these numbers claim the translation reads well, only that the document survived it intact.
All 13 fixtures from the last run
  • passed adversarial.docx — 1 text unit, 100% translated
  • passed colored_fonts.docx — 1 text unit, 100% translated
  • passed headers_footers.docx — 3 text units, 100% translated
  • passed headings.docx — 5 text units, 100% translated
  • passed hyperlinks_dnt.docx — 4 text units, 100% translated
  • passed inline_formatting.docx — 2 text units, 100% translated
  • passed lists.docx — 8 text units, 100% translated
  • passed long_multipage.docx — 21 text units, 100% translated
  • passed mixed_everything.docx — 8 text units, 100% translated
  • passed page_breaks.docx — 2 text units, 100% translated
  • passed rtl_target.docx — 2 text units, 100% translated
  • passed styles.docx — 3 text units, 100% translated
  • passed tables.docx — 7 text units, 100% translated

Use the Word (.docx) translator → Harness: eval/run_eval.py

Excel (.xlsx)

35/35 checks · offline · July 25, 2026

What the harness checks

  • No-op gate. A full-scope identity translation must leave every zip entry byte-for-byte identical except the shared-string table and the recalculation flag. This proves the engine never re-serializes what it did not translate.
  • Scope gate. Translate one sheet and two columns with the header row skipped, then check the four promises the scope panel makes: only the selected cells changed, formulas and numbers and SKUs in other columns are untouched, unselected sheets round-trip byte-identical, and a string shared between an in-scope and an out-of-scope cell is split so the out-of-scope copy keeps its original text.
  • Rich text and inline gate. When the model reorders the formatting markers inside a cell, the bold or italic run has to rebuild onto the right word. When the model drops a marker instead, the cell falls back to its original text, so the output is never worse than the source.
  • Scope validation. Malformed scope input is rejected rather than silently interpreted as "translate everything".

Known limitations

  • Every gate is offline, driven by fake and identity translators. It proves the engine cannot corrupt a workbook; it says nothing about how well Gemini translates one.
  • Chart titles and cell comments are not translated, and so are not evaluated.
All 35 checks from the last run
  • passed EVERY entry byte-identical on identity translation
  • passed all cell values identical
  • passed units found
  • passed identity counts as covered
  • passed header row untouched
  • passed scoped cells translated
  • passed same word on unscoped sheet untouched
  • passed unscoped column untouched
  • passed recalc flag set (formulas + real changes)
  • passed pure-URL cell skipped by engine
  • passed numbers untouched
  • passed formulas untouched
  • passed unscoped sheet values untouched
  • passed unscoped sheet XMLs byte-identical
  • passed split created one new entry
  • passed original shared entry untouched
  • passed appended copy translated
  • passed exclusive entry translated in place
  • passed uniqueCount updated
  • passed in-scope cell retargeted to the copy
  • passed out-of-scope sheet byte-identical
  • passed no recalc flag without formulas
  • passed rebuild used for reorder
  • passed reordered text correct
  • passed bold formatting followed its run
  • passed inline string translated
  • passed numeric cell untouched
  • passed marker-drop keeps original text
  • passed marker mismatches counted
  • passed empty -> full workbook
  • passed columns normalized
  • passed rejects '{"sheets":[]}'
  • passed rejects '{"sheets":[{"columns":[]}]}'
  • passed rejects 'not json'
  • passed rejects '{"sheets":[{"name":"S","columns":["A1B"]}]}'

Use the Excel (.xlsx) translator → Harness: eval/run_xlsx_eval.py

EPUB

56/56 checks · offline · July 29, 2026

What the harness checks

  • No-op gate. Translate nothing. Every zip entry must be byte-identical and the mimetype entry must still be first and stored uncompressed, which is what strict readers check before anything else.
  • Identity gate. Echo every unit back unchanged. The chapter documents genuinely get re-parsed and re-written here, so this is the round-trip test: text, tag structure and attributes have to survive it, the output must still be well-formed XML, and every stylesheet, image and font must still be byte-identical.
  • Structure gate. Translate the whole book and check what the tool page promises: chapter text, the book title and both tables of contents are translated, the spine and manifest are unchanged so reading order survives, the language tag is rewritten to the target, the author and identifier are left alone, and links, image sources and stylesheet references are untouched.
  • Marker gate. Inline emphasis is tracked with markers, and models mangle them. Reordered markers must rebuild as real tags on the right word. Dropped markers must keep the text and be counted rather than hidden. Even deliberately corrupted markers must still produce a valid document.

Known limitations

  • Every gate is offline. It proves the book survives the engine, not that the prose reads well.
  • DRM-protected books are not supported and are not tested.
All 56 checks from the last run
  • passed same entry set
  • passed every entry byte-identical
  • passed mimetype first and STORED
  • passed units were found at all
  • passed standalone URL is not a translation unit
  • passed a sentence containing a URL IS a unit
  • passed OEBPS/images/cover.png byte-identical
  • passed OEBPS/style.css byte-identical
  • passed OEBPS/ch1.xhtml still valid XML
  • passed OEBPS/ch1.xhtml text preserved
  • passed OEBPS/ch1.xhtml tag structure preserved
  • passed OEBPS/ch2.xhtml still valid XML
  • passed OEBPS/ch2.xhtml text preserved
  • passed OEBPS/ch2.xhtml tag structure preserved
  • passed OEBPS/nav.xhtml still valid XML
  • passed OEBPS/nav.xhtml text preserved
  • passed OEBPS/nav.xhtml tag structure preserved
  • passed no invalid documents
  • passed OEBPS/images/cover.png byte-identical
  • passed OEBPS/style.css byte-identical
  • passed OEBPS/ch1.xhtml still valid XML
  • passed OEBPS/ch2.xhtml still valid XML
  • passed OEBPS/nav.xhtml still valid XML
  • passed chapter body translated
  • passed inline <em> survived
  • passed list items translated
  • passed URL untouched
  • passed email untouched
  • passed image src untouched
  • passed stylesheet link untouched
  • passed NCX navLabels translated
  • passed NCX docTitle translated
  • passed EPUB3 nav links translated
  • passed nav hrefs untouched
  • passed dc:title translated
  • passed dc:description translated
  • passed dc:creator untouched
  • passed dc:identifier untouched
  • passed dc:language rewritten to es
  • passed language_tag_set reported
  • passed OEBPS/ch1.xhtml html lang retagged
  • passed OEBPS/ch2.xhtml html lang retagged
  • passed OEBPS/nav.xhtml html lang retagged
  • passed spine order unchanged
  • passed manifest unchanged
  • passed mimetype still first and STORED
  • passed no invalid documents
  • passed stats count all 3 documents
  • passed found a marked unit to reorder
  • passed reordered marker rebuilt as a real tag
  • passed moved emphasis lands after the noun
  • passed dropped marker keeps the text
  • passed dropped marker is counted, not hidden
  • passed document still valid XML after degrade
  • passed garbage markers still produce valid XML
  • passed garbage marker text survives

Use the EPUB translator → Harness: eval/run_epub_eval.py

JSON / i18n

3/3 fixtures · offline · August 1, 2026
Strings seen
56
Selected for translation
38
Deliberately skipped
18
Placeholders protected
32

What the harness checks

  • No-op gate. An identity translation must re-serialize byte-for-byte identical, including indent width, tabs, unicode escaping, key order and the trailing newline.
  • Placeholder gate. A translator that rewrites the words but keeps the markers must return every original placeholder verbatim, once, in the right string.
  • Hostile gate. A translator that drops the markers is the realistic model failure. Those strings must fall back to the original value rather than ship a locale file containing a dead variable.
  • Structure gate. Keys, key order, nesting and non-string types are unchanged throughout all of the above.

Known limitations

  • Every gate is offline, so these numbers are about the engine, not the model.
  • ICU plural categories are not restructured. Each plural string is translated on its own, but a language whose plural rules differ from the source may need categories added or removed by hand.
All 3 fixtures from the last run
  • passed i18next.json — 16 translatable, 7 left alone, 12 placeholders
  • passed icu_react.json — 9 translatable, 3 left alone, 9 placeholders
  • passed printf_tabs.json — 13 translatable, 8 left alone, 11 placeholders

Use the JSON / i18n translator → Harness: eval/run_json_eval.py

CSV

4/4 fixtures · offline · August 1, 2026
Strings seen
80
Selected for translation
42
Deliberately skipped
38
Placeholders protected
5

What the harness checks

  • No-op gate. An identity translation must come back byte-for-byte identical, run three ways: default scope, a column subset, and with the header row skipped. The frame under test is the real one, meaning delimiters, quoting style, line endings, ragged rows and the trailing newline.
  • Placeholder and hostile gates. Placeholders must return verbatim with the right multiplicity and no marker leaks. A model that drops them falls back to the original field bytes.
  • Scope gate. With a single column selected and the header skipped, every field outside that scope must be byte-identical, and no unit may even be collected from outside it.
  • Quoting gate. A translation that contains the delimiter or a quote character must be re-quoted correctly rather than allowed to split a row and corrupt the file.

Known limitations

  • Every gate is offline.
  • Comma, semicolon and pipe delimited files are covered by the fixtures. Other delimiters use the same code path but are not separately gated.
All 4 fixtures from the last run
  • passed app-strings.csv — 9 translatable, 7 left alone, 5 placeholders
  • passed edge-cases.csv — 12 translatable, 2 left alone
  • passed product-catalog.csv — 14 translatable, 16 left alone
  • passed survey-pipe.csv — 7 translatable, 13 left alone

Use the CSV translator → Harness: eval/run_csv_eval.py

YAML

3/3 fixtures · offline · August 1, 2026
Strings seen
36
Selected for translation
27
Deliberately skipped
9
Placeholders protected
5
Comments preserved
9

What the harness checks

  • No-op gate. An identity translation must come back byte-for-byte identical, including every comment, the indentation, the quoting style, anchors, block scalars and document markers. This is the gate that matters most for YAML, because a naive load-then-dump silently destroys all of that.
  • Placeholder and hostile gates. Placeholders return verbatim with the right multiplicity, the output still parses as YAML, and a marker-dropping model falls back to the original value.
  • Structure gate. Keys, key order, nesting, non-string types, block-scalar bytes and every comment are unchanged.
  • Quoting gate. A translation containing a colon-space, a trailing comment marker or a comma must still parse and round-trip exactly. Unsafe plain scalars get wrapped in quotes rather than being allowed to corrupt the document.

Known limitations

  • Every gate is offline.
  • Block scalars are skipped by design. They are preserved byte-exact rather than translated, because re-wrapping them safely is not something we are willing to guess at.
All 3 fixtures from the last run
  • passed app_config.yaml — 8 translatable, 2 left alone
  • passed edge_cases.yaml — 10 translatable, 2 left alone
  • passed rails_locale.yaml — 9 translatable, 5 left alone, 5 placeholders

Use the YAML translator → Harness: eval/run_yaml_eval.py

Plain text (.txt)

4/4 fixtures · live run into French · July 23, 2026
Text units translated
31
Coverage
100.0%
URLs and emails altered
0

What the harness checks

  • No-op gate. An identity translation must be byte-for-byte identical, including line endings, the byte-order mark, blank lines and indentation.
  • Skeleton gate. After a real translation the line count, the position of every blank line, and the leading and trailing whitespace of every line must be unchanged. A translated file has to paste back into whatever produced it.
  • Coverage and do-not-translate. At least 99% of text lines must come back translated, and every URL, email address and file path must survive verbatim.

Known limitations

  • The published live run targets French.
  • As with Word, this measures fidelity rather than fluency.
All 4 fixtures from the last run
  • passed crlf_bom.txt — 5 text units, 100% translated
  • passed dnt_mixed.txt — 5 text units, 100% translated
  • passed list_indent.txt — 16 text units, 100% translated
  • passed prose.txt — 5 text units, 100% translated

Use the Plain text (.txt) translator → Harness: eval/run_txt_eval.py

Tools with no published scorecard yet

These work and people use them daily, but they have no harness, so there is nothing here we can honestly show you. Listing them is the point: a scorecard that only covers the formats we happen to do well is a sales page, not an eval.

  • PowerPoint (.pptx) — Has unit tests and was checked by hand against a real deck, including the text-overflow auto-fit, but there is no scorecard harness yet. SmartArt is not translated.
  • HTML — No automated harness yet.
  • PDF — No automated harness yet.
  • Subtitles (SRT, VTT) — No automated harness yet. It is the oldest engine on the site and predates this eval work, so it is the next one to get a scorecard.

Found something these tests missed?

That is the most useful thing you can send us. If a file came back wrong, tell us which tool and which languages and send the input, and it usually becomes a new gate on this page.

Report a problem

Page data generated August 17, 2026 from the harness runs dated above. Each format is re-scored when its engine changes, and this page is regenerated from those results rather than written by hand.