Method

How this site is checked

Seven scripts read every page and all five translators before anything is published, and fail when a page says something the code does not do. They are here to be read, and to be run.

A reference site is only as good as its last unchecked sentence. The pages here say thousands of small things — this word is written with these cells, this letter is in so many of the commonest words, these two marks differ by one dot — and each of those is either true of the translator or it is not. So the pages are read by a program that asks.

The checks have found faults in this site more often than anywhere else. Each one is listed, with its date, in the corrections log.

What each check asserts

verify-ueb.js
The English translator against the reference. Writes 5,000 common English words and the UEB Shortforms List in Grade 2 and compares every cell with liblouis 3.39.0. It reads the figure the accuracy study prints and fails if the translator cannot meet it, so the page and the code cannot drift apart.
verify-rulebook.js
The rulebook's own examples. Writes each worked example it holds from the Rules of Unified English Braille, and every entry of the rulebook's Word List, and fails unless the entries that differ are exactly the ones recorded in expected-word-list-differences.tsv.
verify-wider.js
A wider and harder word list. The same comparison over 46,717 words taken from film and television subtitles. The words that differ from the reference must be exactly those in expected-wider-differences.tsv. Then three novels are translated whole, in running text, by both — 223,107 words with their capitals, punctuation and quotation marks — and the 22 words that differ must be exactly the lines of expected-context-differences.tsv.
verify-defects.js
The published faults in the reference tables. For each fault listed on the defects page, checks both ends: that liblouis still does what the page says, and that this site does otherwise. A fault fixed upstream fails the check, so the page cannot go on reporting it.
verify-dropped.js
Nothing left out in silence. The translators name every character they cannot write. This checks that the notice never fires on text they can write, and that it does fire on what they skip.
verify-pages.js
The English pages against the translator. Every braille example on an English page is what the translator writes for that print. The counts in the two studies of a whole book are counted again. So are the places and counts the contraction pages give from the 5,000-word list, the sentences on the letter and punctuation pages that follow from the cells, and the explanation the contraction finder gives for 47,659 words. The figures the signs pages take from the 2010 ADA Standards are not computed; they are held to what the standard prints, so that one changed by accident fails. And what the tool pages say the translator does — capitals, numbers, decoding, the page estimator's figures — is tried on the translator. What a screen reader is given is read too: the label of every drawn cell against the dots drawn, the dot code and the image text of each letter, digit, mark and contraction page against the engine of its language, and each engine's own drawing of all 63 cells against the way the pages draw one. What the tools write into a page while they run cannot be read from the page; it was measured in a browser on 11 October 2026, and what that found is held here in the scripts and described in the README. The picture on each of those pages is read from its pixels — a filled disc is a raised dot, a ring an unraised one — and must show the page's cells; the four charts are read the same way. llms.txt, the summary written for programs, is held to the pages it speaks of, and the privacy page to the scripts it describes: which events are sent and with what, what is stored, that nothing is loaded from elsewhere but the analytics script, and that a browser which has asked not to be counted never loads even that. The first screen of the practice drill is on its page before the drill's script arrives, so that nothing moves when it does; build-practice-skeleton.js draws it with the drill's own code, and the page must hold what it draws. Every page is asked what a screen reader asks of it — its language, its headings, a name for every control, a caption and scopes for every table, every reference by id — and the stylesheet's own colours are measured pair by pair for contrast, the outline of an unraised dot among them. The printable charts are read from the PDF files themselves, dot by dot. Every link, script, stylesheet and image a page names is followed to a file that is there, the markup of every page is parsed, and the files written for programs — the catalogue of data files, the agent skill and the tools offered to an agent in the page — are held to the data files and the engine they describe. What the pages say with a background alone — a raised dot above all — must also be said to a browser that drops backgrounds: one that prints without them, and one showing a contrast theme, where every cell was once drawn as its own complement. And a run of dot numbers in a table, a list of cells or a label is marked to stay on one line, since some browsers will cut 1-2-4-5 in two. A table has one scrolling box, and a number field is wide enough for the largest number it takes. Words in another language are marked with it, so that a screen reader changes its voice for them, and what the other four codes' pages say a cell means in English braille is what the English page says. The dates a page states about itself are the day its words last changed. A long text is read back in time that keeps step with its length. Last, every number a reader is given on any page — seen or read out — is held in page-numbers.tsv, written by build-number-ledger.js: a number that changes without the ledger changing with it fails, whether or not a check can rebuild it. The ledger does not show that a number is true, only that none has changed unnoticed.
verify-languages.js
Spanish, Portuguese, Arabic and Hindi. Each translator against its published word list in /data/ and against liblouis on numbers and punctuation in context, and the Spanish and Portuguese ones against the examples in their own standards; every difference must be one recorded, with its reason, in expected-pattern-differences.tsv. Then every example on those pages that names its print, every table row that holds braille, and the 63 cells of the cell tables. Last, what the home page says the Spanish and Portuguese codes do differently from English, and what five pages say about the letter w. And one whole book in each of the four languages is translated by this site and by liblouis in running text; the words that differ must be exactly the lines of expected-running-text-differences.tsv. The 23 data files under /api/ are read in all five codes: every cell against the dots given for it, every entry against what the engine writes, and every figure against the measurement it reports. The English file must hold all 182 contractions, each under the family the rulebook gives it. And the two sections of the Arabic punctuation page drawn from Mada's fifth lesson of eight-dot braille are written again by build-ar-punctuation.js: its sentences by this site's engine, read back, and its eight-dot cells by liblouis's computer table, which must first write the lesson's own seven examples as the lesson prints them. What the Hindi phrase page says each phrase shows is written again by build-hi-phrases.js, which first asks the Hindi engine for every order it describes.

Two more files do the counting for the book studies — measure-usage.js and measure-letters.js — and seven hold what is expected to differ from the reference, each line with its reason: expected-differences.tsv, expected-shortform-differences.tsv, expected-wider-differences.tsv, expected-word-list-differences.tsv, expected-pattern-differences.tsv, expected-context-differences.tsv, expected-running-text-differences.tsv. A line there that stops being true fails the check, and so does a difference that is not there. README.md is the working record: what each check was written after, and what it found.

What is not here, and why

Five files the checks read are not republished, because they are other people's work under terms that do not allow it. Each can be rebuilt from its source.

The files left out, and where they come from
FileWhat it isWhy it is not here
corpus.txtThe first 5,000 lines of google-10000-english, one word to a line.Its licence permits educational and research use, and advises against commercial use without a licence from the Linguistic Data Consortium.
wider-list.txtEvery token made only of letters in the first 50,000 lines of content/2018/en/en_50k.txt from hermitdave/FrequencyWords, in the order they come: 46,717 words.It is raw subtitle vocabulary, under CC BY-SA 4.0; the source is one download away.
ueb-rulebook-examples.tsv
ueb-word-list.tsv
ueb-shortforms-list.tsv
1,898 worked examples, the 1,043 entries of the Word List and the 612 entries of the Shortforms List, taken from the Rules of Unified English Braille.The rulebook is published under a Creative Commons licence that allows neither commercial use nor derived works.

To know a rebuilt word list is the same file, join its lines with a single line feed and take the SHA-256:

corpus.txt
07ffadeaf0de99199de61137589aab0b65977385c92cf9606165ecc258a49d93
wider-list.txt
7fcc536378022ef20972c06342bdffabffcc898b0a69d3bd277c5f4fb7e64857

verify-defects.js and verify-languages.js need none of the five. verify-dropped.js needs the first. The other four need the files drawn from the rulebook.

Running them

  1. Put a copy of this site in a folder: its pages, /tools/ and /data/. The checks read the pages as they are published.
  2. Put the files from /checks/verify/ in a folder named verify inside it, with any of the five files above that you have rebuilt.
  3. Fetch the reference. On Windows, get-liblouis.ps1 downloads liblouis 3.39.0 and checks its hash. Elsewhere, build that release and put lou_translate in verify/liblouis/bin/ and its tables in verify/liblouis/share/liblouis/tables/.
  4. Run a check with Node.js: node verify/verify-languages.js. It prints what it counted and ends with PASS, or with the lines that failed.

The version of liblouis matters. The tables change between releases, so another build gives other figures; moving to a new release is a decision this site makes and dates on the accuracy study.

What a check cannot do

It can tell whether a page agrees with the translator, and whether the translator agrees with the reference and with the rulebook's examples. It cannot tell whether a sentence about history or about readers is true: those are held to a different rule, a named source or nothing, and are read by hand. And agreement with a reference is not certification. Anything to be embossed for someone to rely on should be read by a qualified transcriber.