brl2stl
Turn braille into plastic. brl2stl converts BRF braille files — or plain text — into 3D-printable STL/3MF models: signs, labels, flashcards, book pages, even paper-embossing jigs. Cross-platform, zero required dependencies, with a desktop app, a CLI, and a web UI.
⠨⠃⠗⠇⠆⠎⠞⠇ → ▄▄▖▄▄▄▖▄ → 🖨️
Quick start
Pick whichever is easiest for you:
Desktop app (easiest)
# grab brl2stl-gui.exe / brl2stl-gui.dmg from the Releases page - no
# install needed. Or run from source:
git clone https://github.com/leavesofgrass/brl2stl
cd brl2stl
pip install .[gui]
brl2stl gui
(brl2stl is not on PyPI yet - install from a clone or use a release binary.)
Type your text (or drop a .brf file on the window), watch the live
preview, press Export model, slice, print. Standalone apps that need no
Python at all build with PyInstaller: scripts/build-exe.ps1 (Windows
exe, liblouis bundled from the official win64 release),
scripts/build-macos.sh (macOS .app + .dmg, liblouis bundled
from Homebrew), scripts/build-exe.sh (Linux binary; liblouis via your
package manager). A GitHub Actions workflow
(.github/workflows/build.yml) tests on all three OSes and builds
smoke-verified Windows + macOS artifacts, attaching both to a release on
every v* tag.
Command line
git clone https://github.com/leavesofgrass/brl2stl && cd brl2stl
pip install .
brl2stl document.brf # one STL per page
brl2stl --text "Room 12" -o sign.stl # quick label
brl2stl document.brf --info # sizes only, writes nothing
Docker (nothing to install but Docker)
docker build -t brl2stl .
docker compose up # web UI at http://localhost:8080
./scripts/brl2stl.sh document.brf # CLI (Windows: scripts\brl2stl.cmd)
Text input defaults to contracted UEB Grade 2 whenever liblouis is installed — it always is in the Docker image — and falls back to the built-in uncontracted Grade 1 translator (with a warning) otherwise. Dimensions default to the ADA 703.3 signage standard.
Documentation
Step-by-step guides live in docs/: getting started, the desktop app, the CLI reference, Docker & web UI, input formats & translation, the printing guide, the emboss jig guide, building the standalone app, and the developer guide.
Options
| Option | What it does |
|---|---|
--preset ada|marburg|nls|jumbo |
dimension standards (ADA 703.3 signage is the default; Marburg Medium is the worldwide embosser standard) |
--dot-height/-diameter/-spacing, --cell-spacing, --line-spacing, --plate-thickness, --margin |
override any dimension (mm) |
--dot-shape dome|cone|cylinder |
dome is the tactile standard; cones/cylinders can print crisper on some FDM machines |
--mirror |
mirror image, for embossing dies or printing braille on a model's back face |
--counter |
counter plate: dot-shaped recesses instead of raised dots — the female die of a paper-embossing jig (pair with a --mirror dot plate) |
--hole left|both, --hole-diameter |
keyring / jig-bolt holes in extended margins |
--corner-radius |
rounded plate corners |
--booklet |
joins a multi-page document into one print-in-place model with folding hinges |
--nameplate [TEXT], --letter-height |
nameplate mode: raised uppercase print letters above the braille — ADA signs require tactile characters and braille; defaults to the input text |
--pages 1,3-5 |
convert only some pages |
-f binary|ascii|3mf |
output format |
--resolution low|medium|high |
mesh density |
--text, --text-file, --wrap |
plain-text input instead of BRF |
--louis-table |
text translation table; default auto = UEB Grade 2 (en-ueb-g2.ctb) when liblouis is installed, built-in Grade 1 otherwise; none forces Grade 1 |
--preview |
print the braille as Unicode dots in the terminal |
8-dot (computer) braille is supported via Unicode braille input (U+2800–U+28FF); dots 7/8 get a fourth row automatically.
Printing tips
- Layer height 0.1–0.15 mm — dots are only ~0.8 mm tall.
- A 0.4 mm nozzle works; 0.25 mm renders domes noticeably better.
- Print dots facing up, no supports needed.
- PETG and PLA both work; PETG wears better for heavy use.
- If dots feel faint, raise
--dot-heightto 0.9 mm — plastic reads best slightly taller than the paper-embossing standards.
What's a BRF file?
The exchange format of braille embossers: plain ASCII where each character is one braille cell (Braille ASCII / NABCC), form-feed between pages. The content is already translated braille — usually contracted Grade 2 — which brl2stl renders verbatim. Get BRFs from your transcriber, NLS BARD, or make your own from text with liblouis.
Development
git clone https://github.com/leavesofgrass/brl2stl && cd brl2stl
PYTHONPATH=src python -m unittest discover -s tests # zero-dep test suite
The mesh generator is pure stdlib Python. Every generated solid is
verified watertight (each edge shared by exactly two opposite-wound
triangles) by the test suite, and the Docker build fails if any test
fails. See docs/PLAN.md for architecture.
License
MIT. Copyright (c) 2026 Jon Pielaet. See LICENSE.
Qt note: the desktop app uses PySide6 (LGPLv3), which permits MIT apps — the official binaries bundle Qt's shared libraries unmodified per the LGPL. If you build with the optional PyQt6 fallback instead, PyQt6's GPLv3 governs distribution of that combination. The bundled liblouis is LGPL-2.1+ and is invoked as a separate program.
Release files for brl2stl 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| brl2stl-0.1.0.tar.gz | 50.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| brl2stl-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 96.4 kB
Release files / brl2stl-0.1.0.tar.gz
| Download URL | brl2stl-0.1.0.tar.gz |
|---|---|
| Size | 50.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
316def251a75e7e3b86f41ef0dca2e6b0e49858c4c8393f75a32182e58ca1185
|
|
BLAKE2b-256 checksum How to use checksums |
4456bd24539afe27b45a12073b876c2cd8187f611de4825abb4ce2d6977f8ed1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 9, 2026.
Transparency logRelease files / brl2stl-0.1.0-py3-none-any.whl
| Download URL | brl2stl-0.1.0-py3-none-any.whl |
|---|---|
| Size | 46.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b8fe030d0ed9c503b288b8bbd08d70d2c8d5237453e6fbe4b799e40b8662c45e
|
|
BLAKE2b-256 checksum How to use checksums |
3e9316aa2b6cdbd14671a1971f7d4461dd07a0bcd48ab0d8f4187aecce3ff604
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 9, 2026.
Transparency log