{"id":29012175,"url":"https://github.com/liblouis/louis-rs","last_synced_at":"2025-09-17T15:34:54.372Z","repository":{"id":147567134,"uuid":"426565973","full_name":"liblouis/louis-rs","owner":"liblouis","description":"An experiment at re-writing liblouis in Rust","archived":false,"fork":false,"pushed_at":"2024-04-12T15:16:21.000Z","size":349,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-04-12T23:34:08.143Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/liblouis.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2021-11-10T09:47:37.000Z","updated_at":"2024-04-15T12:26:42.671Z","dependencies_parsed_at":"2024-04-02T10:28:16.746Z","dependency_job_id":"c5d61194-a691-47b7-8d4d-cc28f8efbada","html_url":"https://github.com/liblouis/louis-rs","commit_stats":null,"previous_names":["liblouis/louis-rs"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/liblouis/louis-rs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liblouis%2Flouis-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liblouis%2Flouis-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liblouis%2Flouis-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liblouis%2Flouis-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/liblouis","download_url":"https://codeload.github.com/liblouis/louis-rs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liblouis%2Flouis-rs/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261927691,"owners_count":23231383,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-25T18:15:19.212Z","updated_at":"2025-09-17T15:34:54.366Z","avatar_url":"https://github.com/liblouis.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"#+title: louis-rs: a liblouis re-implementation in Rust\n\nThis is the reduced-to-the-max re-write of liblouis in Rust.\n\n* Rationale\nMany if not most of the CVEs of liblouis are rooted in the manual\nmemory management in the C version of liblouis.\n\nMoving to Rust is of tremendous help not only for the solid memory\nmanagement to avoid buffer overflow problems, but also to bring joy\nback into liblouis maintenance.\n\n* Status\nWith the some small exceptions the parser is complete. Translation\nusing only character and most translation opcodes basically works.\n\nThe original YAML test suite is supported and can be used to test the\nre-implementation.\n\nCurrently, the re-implementation passes 68% of the liblouis test suite\nsuccessfully.\n\n* Relation to liblouis\n\nlouis-rs is *not* a direct port of the liblouis C code to Rust. It\nuses the same tables and the same YAML tests but other than that it is\na complete rewrite. It uses different data structures and does the\ntranslation using a different algorithm.\n\nThe goal is to be as compatible as possible with liblouis, when it\nmakes sense.\n\n* Usage\n\nGet help:\n\n#+BEGIN_SRC shell\n  $ cargo run -- help\n#+END_SRC\n\nTranslate some text:\n\n#+BEGIN_SRC shell\n  $ cargo run -- translate ~/src/liblouis/tables/de-comp6.utb \n  \u003e Guten Tag\n  ⠈⠛⠥⠞⠑⠝⠀⠈⠞⠁⠛⠀\n#+END_SRC\n\nTest the parser:\n\n#+BEGIN_SRC shell\n  $ cargo run -- parse\n  \u003e nofor letter e 123-1\n  Letter { character: 'e', dots: Explicit([{Dot2, Dot1, Dot3}, {Dot1}]), constraints: EnumSet(Nofor) }\n#+END_SRC\n\nBuild a release version:\n\n#+BEGIN_SRC shell\n  $ cargo build --release\n#+END_SRC\n\nRun the tests in a YAML file:\n\n#+begin_src shell\n  $ LOUIS_TABLE_PATH=~/src/liblouis/tables cargo run -- check ~/src/liblouis/tests/braille-specs/de-de-comp8.yaml 2\u003e /dev/null\n  ================================================================================\n  8 tests run:\n  8 successes [100%]\n  0 failures [0%]\n  0 expected failures [0%]\n  0 unexpected successes [0%]\n#+end_src\n\nRun all YAML tests:\n\n#+BEGIN_SRC shell\n  $ LOUIS_TABLE_PATH=~/src/liblouis/tables:~/src/liblouis ./target/release/louis check --summary ~/src/liblouis/tests/braille-specs/*.yaml ~/src/liblouis/tests/yaml/*.yaml 2\u003e /dev/null \n  ================================================================================\n  473240 tests run:\n  324695 successes [68.6%]\n  137803 failures [29.1%]\n  10319 expected failures [2.2%]\n  423 unexpected successes [0.1%]\n#+END_SRC\n\nTest the table query functionality:\n\n#+BEGIN_SRC shell\n  $ LOUIS_TABLE_PATH=~/src/liblouis/tables cargo run -- query language=de,contraction=full\n  {\"[...]/liblouis/tables/de-g2-detailed.ctb\", \"[...]/liblouis/tables/de-g2.ctb\"}\n#+END_SRC\n\n* Prerequisites\n\n- You need the [[https://www.rust-lang.org/][Rust tool chain]].\n\n* Contributing\nIf you have any improvements or comments please feel free to file a\npull request or an issue.\n\n* Acknowledgments\n\nA lot of inspiration for the hand-rolled parser comes from the\nabsolutely fantastic book [[https://craftinginterpreters.com/][Crafting Interpreters]] by Robert Nystrom.\nSurely [[http://mitpress.mit.edu/9780262510875/structure-and-interpretation-of-computer-programs/][Structure and Interpretation of Computer Programs]] has had some\ninfluence as must have the [[https://people.inf.ethz.ch/wirth/CompilerConstruction/CompilerConstruction1.pdf][Compiler Construction]] classes with Niklaus\nWirth (\"as simple as possible but not simpler\").\n\nThe parser is built from the grammar used in [[https://github.com/liblouis/tree-sitter-liblouis][tree-sitter-liblouis]],\nwhich is a port of the [[https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form][EBNF grammar]] in [[https://github.com/liblouis/rewrite-louis][rewrite-louis]], which in turn is\na just port of the [[https://en.wikipedia.org/wiki/Parsing_expression_grammar][Parsing expression grammar]] from [[https://github.com/liblouis/louis-parser][louis-parser]].\n\n* Todo [6/15]\n- [ ] Parse with context\n  - currently tables are parsed line by line. Opcodes have no idea\n    whether a character or a class has been defined before\n  - Probably need to pass some context to the rule parser where\n    character definitions and class names are kept\n  - this is solved with a two-pass compilation now. The first pass\n    collects all relevant information and the second pass consequently\n    uses that.\n- [ ] (Emphasis and Caps) Indication\n  - presumably this could be done independently of translation, i.e.\n    find indication locations and put them in the typeform array\n    before even translating.\n- [X] Add support for virtual dots\n  - Virtual dots are supported and are converted to Unicode Supplementary Private Use Area-A\n- [ ] The correct, multipass and match opcodes\n- [X] Currently the matching of input text against the rules is case\n  sensitive.\n  - [X] Make it case insensitive.\n  - [X] Now everything is case insensitive, even character\n    definitions. This is probably not what we want. We might have to\n    move the character definitions out of the trie into a separate\n    structure.\n- [X] Word boundaries so we could support beg- and endword.\n  - the [[https://docs.rs/unicode-segmentation/latest/unicode_segmentation/][unicode_segmentation]] crate would probably help. It has\n    functions like [[https://docs.rs/unicode-segmentation/latest/unicode_segmentation/trait.UnicodeSegmentation.html#tymethod.split_word_bound_indices][split_word_bound_indices]], that give you word bounds\n    based on the Unicode standard.\n- [X] Handle implicit braille definitions, i.e. '='\n- [ ] Typeforms\n- [ ] Cursor handling\n- [ ] Hyphenation\n  - will probably be delegated to the [[https://docs.rs/hyphenation/latest/hyphenation/][hyphenation crate]]\n- [ ] Add an API so that the functionality can be used as a library\n  - end expose it as a C ABI so that it can be used from other\n    languages (see also [[https://github.com/mozilla/cbindgen][cbindgen]] or even better [[https://github.com/rust-diplomat/diplomat][Diplomat]])\n- [X] Table resolution based on metadata\n- [ ] Display tables\n  - When testing the YAML files the display tables are used.\n  - However normal translation has currently no way to specify a\n    display table\n- [X] Handle undefined characters similarly to liblouis\n- [ ] Use a well established FST or graph library as a bases\n  - currently regular expressions are implemented using a simple\n    directed acyclic graph. It would surely be better to use a well\n    established library for that task such as [[https://github.com/garvys-org/rustfst][rustfst]], [[https://crates.io/crates/petgraph][petgraph]] or\n    [[https://github.com/neo4j-labs/graph][graph]].\n\n* License\n\nCopyright (C) 2023-2024 Swiss Library for the Blind, Visually Impaired\nand Print Disabled\n\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program.  If not, see\n\u003chttps://www.gnu.org/licenses/\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliblouis%2Flouis-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fliblouis%2Flouis-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliblouis%2Flouis-rs/lists"}