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. Field values are stored verbatim,
14//! including their outer `{}` or `""` delimiters. A duplicate citation key
15//! is a [`BibParseErrorKind::DuplicateKey`] error; a repeated field name
16//! within one entry keeps the last value. Entries and fields live in
17//! [`BTreeMap`](std::collections::BTreeMap)s, so iteration is deterministic
18//! and sorted.
19//!
20//! Bibliography features beyond record parsing are separate concerns and
21//! live elsewhere when they land: CSL / `BibLaTeX` styling, `@string` /
22//! `@preamble` / `@comment` and `#` concatenation, `TeX` decoding, name
23//! parsing, reading `.bib` files from disk, citation-key resolution, and
24//! citation or bibliography rendering. This crate does none of those and has
25//! no `mos-eval` / layout / PDF wiring.
26//!
27//! # Examples
28//!
29//! ```
30//! use mos_bib::parse_bibtex;
31//!
32//! # fn main() -> Result<(), mos_bib::BibParseError> {
33//! let bib = parse_bibtex("@article{knuth1984, title = {Literate Programming}, year = 1984}")?;
34//! let entry = &bib.entries["knuth1984"];
35//! assert_eq!(entry.entry_type, "article");
36//! assert_eq!(entry.fields["title"], "{Literate Programming}");
37//! assert_eq!(entry.fields["year"], "1984");
38//! # Ok(())
39//! # }
40//! ```
41
42#![doc(
43 html_logo_url = "https://mosaiclang.dev/assets/A4.svg",
44 html_favicon_url = "https://mosaiclang.dev/assets/A4.svg"
45)]
46
47mod content;
48mod error;
49mod parser;
50mod record;
51
52pub use content::bibliography_content_hash;
53pub use error::{BibParseError, BibParseErrorKind};
54pub use parser::parse_bibtex;
55pub use record::{BibEntry, Bibliography, Citation, unwrap_value};