Skip to main content

mos_bib/
lib.rs

1//! Bibliography records for Mosaic (manifest ยง12).
2//!
3//! [`parse_bibtex`] reads a BibTeX string into typed [`BibEntry`] records,
4//! keyed by citation key inside a [`Bibliography`]. The grammar is a
5//! deliberately small, well-defined BibTeX subset: entry type, citation
6//! key, and `{braced}` / `"quoted"` / bare string fields: chosen to give a
7//! later citation resolver a stable, ordered record model to build on.
8//!
9//! Within that subset the parser is complete: it accepts any
10//! `@type{key, field = value, ...}` entry, lowercases the (case-insensitive)
11//! entry type and field names while keeping citation keys verbatim, balances
12//! nested braces, and reports malformed input as a [`BibParseError`] with a
13//! byte offset instead of panicking. Entries and fields live in
14//! [`BTreeMap`](std::collections::BTreeMap)s, so iteration is deterministic
15//! and sorted.
16//!
17//! Bibliography features beyond record parsing are separate concerns and
18//! live elsewhere when they land: CSL / `BibLaTeX` styling, `@string` /
19//! `@preamble` / `@comment` and `#` concatenation, `TeX` decoding, name
20//! parsing, reading `.bib` files from disk, citation-key resolution, and
21//! citation or bibliography rendering. This crate does none of those and has
22//! no `mos-eval` / layout / PDF wiring.
23//!
24//! # Examples
25//!
26//! ```
27//! use mos_bib::parse_bibtex;
28//!
29//! # fn main() -> Result<(), mos_bib::BibParseError> {
30//! let bib = parse_bibtex("@article{knuth1984, title = {Literate Programming}, year = 1984}")?;
31//! let entry = &bib.entries["knuth1984"];
32//! assert_eq!(entry.entry_type, "article");
33//! assert_eq!(entry.fields["title"], "Literate Programming");
34//! assert_eq!(entry.fields["year"], "1984");
35//! # Ok(())
36//! # }
37//! ```
38
39#![doc(
40    html_logo_url = "https://mosaic.kjanat.dev/assets/A4.svg",
41    html_favicon_url = "https://mosaic.kjanat.dev/assets/A4.svg"
42)]
43
44mod content;
45mod error;
46mod parser;
47mod record;
48
49pub use content::bibliography_content_hash;
50pub use error::{BibParseError, BibParseErrorKind};
51pub use parser::parse_bibtex;
52pub use record::{BibEntry, Bibliography, Citation};