Expand description
logoxide: Bibles, commentaries, lexicons, books, and media as versioned packages.
A package is a git repository (or a registry’s archive) with a logoxide.toml (manifest) and
its text in one or more formats. Bibles are read as verses from USX, USFM (through usfm3), USJ,
OSIS, and ThML (by the logoxide-text crate, behind the read feature: a book a file, or a whole Bible
in one file); books are kept as EPUBs, whose Bible references topos finds (references);
versification maps are Paratext .vrs lines (logoxide-text’s versification); audio and video
are listed by URL and hash, never stored (media).
Package::openreads a package from anyStorage(a folder, memory, or a host’s files in WebAssembly), choosing the best readable format its features turn on;Cachekeeps its parsed books, andCachedPackage::add_togives topos the translation’s name, aliases, and verse counts, soJohn 3:16 KJVis checked against that translationProjectis a folder with alogoxide.toml(a vault’s has no[package]) and itslogoxide.lock(lock):Project::installresolves its dependencies (git, registry archives, or paths) into theLibrary, pinned by commit and checksumcatalogsearches catalogs (catalog.toml; other publishers’ lists, read by thelogoxide-importcrate, which turns their downloads into packages)summarysays what a version holds (verse counts, a hash of every verse) and how much a new version changed, whichreleasechecks against its version number
use std::sync::Arc;
use logoxide::{
Cache, Features, FsStorage, Package, reader::DefaultReader,
topos_bible::data::translations::Translations,
};
fn main() -> logoxide::Result<()> {
// A package's folder: its logoxide.toml and its text
let package = Package::open(Arc::new(FsStorage::new("bibles/kjv")), Features::default())?;
let info = package.info();
println!("{} {}: {}", info.short_name(), info.version, package.checksum()?);
// Parsed books and verse counts are kept in a cache folder, by version and checksum
let cache = Cache::new(Arc::new(FsStorage::new("cache")));
let kjv = cache.open(package, &DefaultReader)?;
if let Some(john) = logoxide::bible_data().books().search_usfm("JHN") {
println!("John has {} chapters", kjv.book(john)?.chapter_verses().len());
}
// topos checks references naming the translation against its own verse counts
let _translations = kjv.add_to(Translations::default());
Ok(())
}A vault’s Bibles, installed as its lock file says (fetching runs the git command):
use logoxide::{Library, Project, git::GitCli, reader::DefaultReader, resolve::Update};
fn main() -> logoxide::Result<()> {
let mut project = Project::open("notes")?;
let library = Library::new("library", "cache");
project.install(&library, &GitCli::default(), Update::Nothing)?;
let _translations = project.translations(&library, &DefaultReader)?;
Ok(())
}The file formats (logoxide.toml, catalog.toml, logoxide.lock, summaries) and the trust
model are specified in the repository’s doc/ folder, for other implementations.
Re-exports§
pub use cache::Cache;pub use cache::CachedPackage;pub use error::LogoxideError;pub use error::Result;pub use library::Library;pub use lock::LockedPackage;pub use lock::Lockfile;pub use manifest::Manifest;pub use package::Features;pub use package::Package;pub use project::Project;pub use reader::TextReader;pub use storage::FsStorage;pub use storage::MemoryStorage;pub use storage::Storage;pub use topos_bible;
Modules§
- books
- The book numbers in logoxide’s files (
logoxide.verses.bin), which logoxide owns so they never change with topos’s data: 1 to 66 forGENtoREVin the Protestant canon’s order, 67 to 90 as topos 0.6 numbers its deuterocanonical and other books (70 and 78, which have no USFM code, are reserved), 91 to 103 the books after them, 104 to 199 reserved, and 200 to 214 the peripherals (front matter, glossaries, indexes). 0 is never a book. - cache
- Parsed books and verse counts, kept per package version so a book loads without parsing its source again. A cache is per device and never synced: it can always be built again.
- catalog
- Catalogs: lists of packages to search, so a Bible can be found by its name or language instead of
its URL. A catalog holds what each package is and where it comes from, never its text, so anyone
can host one (a file in a git repository is enough). This module reads logoxide catalogs
(
catalog.toml): packages published as git repositories or as a registry’s archives, each as itslogoxide.tomldescribes it (lx catalog entry <url>writes an entry). Other publishers’ own lists (eBible.org’stranslations.csv,EBIBLE_CATALOG; fetch.bible’smanifest.json,FETCH_BIBLE_CATALOG; CCEL’s page of its Bibles,CCEL_CATALOG; a SWORD repository’smods.d.tar.gz,SWORD_CATALOGCrossWire’s) are read by thelogoxide-importcrate into the sameCatalog, each entry anCatalogSource::Externalthat says what to download; the package manager knows no publisher, only what an entry says of itself. - config
- logoxide’s own config,
~/.config/logoxide/config.toml($XDG_CONFIG_HOME/logoxide, or the fileLOGOXIDE_CONFIGnames): this machine’s defaults forlxand logoxide-lsp. Every key is optional; without the file nothing changes. topos’s settings (book data, formats) stay in topos’s ownconfig.toml. - create
- Making a new package from a single file (
lx new --from book.epub): the file in its format’s folder, with alogoxide.tomlaround it. What the file says about itself fills in the manifest, and anything given (NewPackage) wins over it: - error
- What goes wrong, as one error type with a
kindfor callers that act on it rather than read it. - git
- Fetching packages from git repositories.
Fetcheris what resolving and installing need (a repository’s tags, and its files at a commit);GitClidoes it with thegitcommand, which reads any URL git does (https://,ssh://,file://, a local path). - language
- Languages, scripts, and which way a text runs.
- library
- The library: installed package versions, side by side, as plain files.
- license
- Licenses and what they allow. Licenses are shown, never enforced: this says what a package’s
license and rights are, and what a user should know before redistributing it (
assess). - lock
logoxide.lock: the exact text a vault (or a machine’s library) uses, likeCargo.lock. Each package’s version, commit, and checksum, so every device installs the same text and links mean the same thing everywhere.- locking
- Exclusive advisory locks on the library and on a project, so two
lxprocesses (an install and a clean, two installs from two vaults sharing one library) don’t write over each other. - manifest
logoxide.toml: a package’s manifest, or a vault’s (a manifest without[package]), likeCargo.toml.- media
- Audio and video: listed in a package’s
logoxide.tomlby URL, size, and SHA-256, never stored in it, so a package stays a small git repository and the media stays wherever its owner serves it. A host downloads a file when it’s first played, fromurlor else each of itsmirrorsin turn (MediaFile::urls), checks it (verify), and keeps it by its hash (store_path), so versions that list the same file share it. The hash makes every copy as good as the first, so anyone may serve one. - net
- Reaching repositories over plain HTTP, for hosts without
git(WebAssembly, the bindings, a machine without it):archivereads git’s smart-HTTP ref listing and unpacks a commit’s.tar.gz - package
- A package: a
logoxide.tomlwith[package], and its text in one or more formats. Opening one picks the best format its enabled features turn on (USX, then USFM, OSIS, ThML, and GBF; a dictionary’s entries or cross-references, which hold no verses, are read the same way). - project
- A project: a folder with a
logoxide.tomlthat asks for packages (a vault, or the library’s own for apps without one) and itslogoxide.lock. Adding and removing dependencies edits the manifest in place, keeping its comments and layout. - publish
- Publishing releases as archives, for registries: a package’s declared files as a
.tar.gzthat the same files always make byte for byte (sorted, with no times or owners), its SHA-256, and its entry in a registry’scatalog.toml. A project names such a package withregistry(the catalog’s URL) and a version, and installing downloads only that release’s archive, so a registry of thousands of books needs no repository per book, and any static host can serve one. - reader
- What the package manager asks of a package’s text, and nothing more: the facts a summary
records (
TextFacts), each book’s verse counts, and whether its media timings fit. It never reads the text itself: aTextReaderdoes, given by whoever runs it (lx, the bindings, the language server), so the package manager builds without a parser (--no-default-features) and is tested with facts made up. Thereadfeature’sDefaultReaderreads through logoxide-text, the crate that knows what’s in a Bible or a book and nothing of packages. - references
- The Bible references in a package’s books, found by topos in each EPUB its enabled formats hold,
and in a book’s ThML (
book_files). - release
- Releasing a package version: its summary is written, compared with the previous release’s, and
the version number checked against what changed, so a version always says what it can break (see
Change). Then the repository is committed and taggedv{version}. - resolve
- Resolving a manifest’s dependencies into a lock file, and installing what it names: each git dependency’s version (the newest tag matching its requirement, or the tag, branch, or revision it names), each registry dependency’s release (the newest matching archive its catalog lists), its files in the library, and its own dependencies, with the features asked for.
- roots
- The projects that use a library (
<library>/roots/<hash>.toml), solx cleankeeps what each of them locks: a vault elsewhere on this machine, or on another sharing the library through a sync service, would otherwise lose its versions to a clean run from here. - storage
- Where packages and caches are read from and written to: a folder on disk (
FsStorage), memory (MemoryStorage), or whatever a host provides (an Obsidian vault, IndexedDB), so the same code runs natively and in WebAssembly. - summary
- What a package version holds, published with it so it can be known without downloading the text:
logoxide.summary.toml(its books’ verse counts, how big each format is, how many of each element),logoxide.verses.bin(a short hash of every verse’s text), for books,logoxide.references.bin(the passages they cite,crate::references), and for dictionaries and cross-references,logoxide.entries.bin(a hash of every entry’s key and text).lx releasewrites them,lx verifybuilds them again and compares, and two versions’ summaries say what changed between them (diff,diff_entries), which says how the version number must change (Change). - text
- Text from elsewhere made safe to show in a terminal. A catalog’s, manifest’s, or git’s text could
hold escape sequences that move the cursor, rewrite what was printed, set the window’s title, or
make a link, and bidirectional controls that show text in another order than it’s read
(Trojan Source).
printabledrops them all, keeping the words. - titles
- Each file’s title: what a reader sees for a Bible book or a book (
John,The Dorean Principle), apart from its file name (usx/JHN.usx). Hosts name what they show by it (the Obsidian plugin’s stubs,Logoxide/bsb/John.bible), so a package’s titles are part of what it publishes: its summary lists them, and a changed title is a minor change (a host may rename what it shows, but nothing it points at is gone). - topos_
config - The book data topos’s own config gives (
~/.config/topos/config.toml:data,merge-data, andremove-data, as thetoposCLI and logoxide-lsp read them), so custom genres and books mean the same everywhere; and filters over books like topos’s (testaments, genres, books), for choosing packages by the books they’re about. - works
- Works and editions. A work is a text whatever its editions, formats, and publishers (the King
James Version); a package says which it is with
work = "kjv", and which edition withedition(1769-oxford) andedition-year. logoxide’s table of works (data/works.toml, the owner’s D9) gives each work’s name, aliases, its Wikidata item when known, and the import names known to be it, so an import is given its work by its name (of_import), never by guessing from a title.
Functions§
- bible_
data - topos’s book names and versification, with the deuterocanon, so every book a translation can have is known