Skip to contentSkip to Braille Studio
ALB Wiki

Diff — albBRAILLE

Comparing rev 1 → rev 2

{{infobox
| title = albBRAILLE
| form = Braille transcription engine — two engines, one envelope
| written_in = AdaLogic BASIC (ueb.albi, nemeth.albi, braille.alb)
| compiled_by = ALBW — emits TypeScript/JavaScript (flat script)
| engines = UEB Grade 2 contracted · UEB Grade 1 uncontracted · Nemeth math
| output = BRF/ASCII · Unicode braille · raw 6-bit cell arrays · error ledger
| live_at = alb-lang.org — POST /api/braille (open anonymous tier, free keys)
| validation = UEB G2 matches liblouis en-ueb-g2.ctb cell-for-cell on 25,836 tested words
| gaps = No typeforms/foreign markup · no Nemeth array colspecs or display environments
}}
**albBRAILLE** is the site's braille transcription engine — a two-engine transcriber written in AdaLogic BASIC and compiled to JavaScript by the ALBW backend. It turns literary text into real UEB contracted braille and math notation into real Nemeth code, and it runs the public API at `/api/braille`. The second engine, **albNEMETH**, handles mathematics — the part of braille that almost nothing on the open web can produce on demand.
## Why it exists
The site was built eyes-free first — the Linux handbook is written for blind readers, the library publishes braille-ready editions, and the wiki carries the [[Braille]], [[Nemeth Braille Code]], and [[Eyes-Free Linux]] trail as flagship content. A library of braille needs a transcriber, so one was written — in ALB, which turned out to be the right tool for it: deterministic rules, bounded tables, no hidden state.
The public API answers a gap that is easy to miss. Braille translation *does* exist elsewhere — liblouis transcribes UEB text, and commercial services embed Nemeth inside document workflows. But a free, public endpoint that turns an arbitrary math string into Nemeth braille is a different thing, and there essentially isn't one. That gap has gotten sharper with AI: a tutoring agent can write the words "factor x squared plus three x minus ten," but it cannot produce the braille. `POST /api/braille` with `{"sys":"nemeth","txt":"x^2+3x-10=0"}` closes that last inch — the envelope it returns (`brf`, `uni`, `cells`) drives an embosser, a screen, or a refreshable display from one call.
## The two engines
| Engine | Input | Output |
| --- | --- | --- |
| **UEB Grade 2** | literary text | contracted braille — the shortforms and groupsigns real braille readers expect (`the`, `quick`, `brown` all contract) |
| **UEB Grade 1** | literary text | uncontracted letter-for-cell — for learners and precise spellings |
| **albNEMETH** | latex-ish / asciimath math | Nemeth code — linear and spatial: matrices, cases, binomials, stacked arithmetic, long division |
### The UEB pipeline
The literary engine runs text through five stages — a tokenizer, a shortform dictionary, a context-legality pass (a contraction is only legal in the positions UEB allows), a greedy longest-match selector, and finally a 6-bit cell stream. The legality stage is where real transcription happens — UEB is a context-sensitive code, not a lookup table, and whether `st` may contract depends on morpheme boundaries the engine has to reason about rather than memorize. Capitals get letter, word, and passage modes; numbers get the numeric indicator and numeric-space rules; errors land in a ledger rather than disappearing.
### The Nemeth engine
albNEMETH takes the ascii/latex-ish grammar — `x^2`, `sqrt(16)`, fractions, matrices — and emits Nemeth with proper indicators: the superscript and subscript marks, grouping symbols, the numeric indicator's level shifts. Beyond linear math it does **spatial** Nemeth: matrices laid out as braille tables, `cases` constructions, binomial coefficients, stacked arithmetic, and long division in its traditional carried layout. That matters because Nemeth is how blind STEM students actually read math — linear text is not a substitute.
+
Live Nemeth, inline: [[math:x^2+3x-10=0]] factors as [[math:(x+5)(x-2)=0]], and the quadratic formula sets as [[math:x=(-b+-sqrt(b^2-4ac))/(2a)]]. Those cells are not an image or a font trick — they are the engine's real output, transcribed server-side at render time, readable on a refreshable braille display or embossed straight from the page's own braille edition.
+
## Validation
The UEB engine was checked the honest way — against **liblouis**, the reference open-source braille translator. On a **25,836-word corpus** (a 13,747-word stratified sample, a 12,000-word `a`-initial slice, and 89 curated edge cases) the output matched `en-ueb-g2.ctb` **cell-for-cell**. That is the claim a transcription engine is entitled to make.
## The API
| Endpoint | Purpose |
| --- | --- |
| `POST /api/braille` | `{sys, txt}` → the envelope — `sys` is `ueb`, `ueb-g1`, or `nemeth` |
| `GET /api/braille` | self-describing docs: systems, formats, limits, examples |
| `GET /api/braille/status` | capability report |
| `POST /api/braille/keys` | mint a free API key (raises the rate limit) |
No key is needed to try it — anonymous callers get a per-IP budget; a free key raises it. Keys arrive via `X-API-Key` or `Authorization: Bearer`. Underneath, the same engine also speaks JSON-RPC tools (`br_ueb`, `br_ueb_g1`, `br_nemeth`, `br_translate`) — the REST surface mirrors them.
+
+
## In the wiki and across the site
+
+
The same engine serves three reading surfaces on top of the API:
+
+
* **`[[math:expr]]`** — wiki markup that transcribes `expr` to Nemeth inline, as used above. Spatial input (matrices, cases) renders as a braille cell block.
+
* **Braille editions** — every public wiki article carries a *⠃ Braille* tab next to Edit and History, linking `/braille/wiki/<slug>` — a UEB Grade 2 edition with Nemeth math — plus a `.brf` download paged for embossers. `?grade=1` switches to uncontracted. Static site pages have the same treatment under `/braille/site/<path>`.
+
* **[The Braille Studio](/braille/)** — a browser workbench: type text or math, get Unicode braille, the BRF stream, the raw cell masks, and a dot-grid — plus live `curl` examples for the API.
+
+
Editions are generated on demand and cached against the article's revision — an edit produces a new braille edition on the next read, not a stale one.
## The honest gaps
No typeform, foreign-language, or italic markup; Nemeth arrays don't take colspecs and display environments aren't emitted; `cells[]` caps at 256 so long documents page per-paragraph. The Nemeth input is the engine's own ascii/latex-ish grammar, not full LaTeX `\commands`.
## See also
* [[Braille]] · [[Nemeth Braille Code]] · [[Abraham Nemeth]] · [[Louis Braille]]
* [[Eyes-Free Linux]] · [[Speakup]] · [[BRLTTY]]
* [[ALB TypeScript backend]] — the ALBW backend that compiles the engine
* [/library/](/library/) — the braille editions this engine exists for
* `GET /api/braille` — the live API's own documentation
[[Category:AdaLogic BASIC]]
[[Category:Accessibility]]
[[Category:Software]]