latex_rust/lib.rs
1//! LaTeX-Rust: a pure Rust LaTeX **math** renderer.
2//!
3//! Parse a math string to a typed AST, lay it out with a TeX-faithful box
4//! model whose dimensions are zenith-float [`Dim`] values (no hardware `f32` /
5//! `f64` in layout arithmetic), and render to SVG, PNG (`features = ["png"]`),
6//! or egui shapes (`features = ["egui"]`).
7//!
8//! Crate layout follows the build-sheet architecture: [`parser`],
9//! [`mod@layout`], [`font`], [`render`] (`svg` / `png` / `egui`).
10//!
11//! Unsupported constructs return [`Error`] — never a fake render.
12//!
13//! # Examples
14//!
15//! ```
16//! use latex_rust::{parse, layout, tokenize, lookup, MathFont, MathStyle, Dim, MathBox};
17//!
18//! let ast = parse(r"\frac{1}{2}").expect("parse");
19//! assert_eq!(ast.gold(), r#"(frac (atom Ord "1") (atom Ord "2"))"#);
20//!
21//! let tokens = tokenize(r"\frac{1}{2}").expect("tokens");
22//! assert!(!tokens.is_empty());
23//! assert_eq!(lookup(r"\alpha").unwrap().glyph, "α");
24//!
25//! let font = MathFont::stix_two_math().expect("STIX Two Math");
26//! assert_eq!(font.units_per_em(), 1000);
27//!
28//! let boxed = layout(&ast, &font, MathStyle::Text).expect("layout");
29//! assert!(!boxed.width.is_zero());
30//!
31//! let svg = latex_rust::latex_to_svg(r"x", &font, &latex_rust::SvgOptions::new()).expect("svg");
32//! assert!(svg.contains("<path"));
33//!
34//! let packed = MathBox::hpack(vec![
35//! MathBox::rule(Dim::one(), Dim::zero(), Dim::zero()),
36//! MathBox::rule(Dim::ratio(1, 2), Dim::zero(), Dim::zero()),
37//! ]);
38//! assert_eq!(packed.width, Dim::ratio(3, 2));
39//! ```
40
41#![deny(missing_docs)]
42#![deny(clippy::float_arithmetic)]
43#![deny(clippy::undocumented_unsafe_blocks)]
44#![cfg_attr(docsrs, feature(doc_cfg))]
45
46mod atoms;
47mod color;
48mod dim;
49mod error;
50mod style_map;
51mod symbols;
52
53/// OpenType MATH metrics and the embedded STIX Two Math face.
54pub mod font;
55/// AST → TeX-faithful [`MathBox`](layout::MathBox).
56pub mod layout;
57/// LaTeX math → [`MathNode`](parser::MathNode) AST.
58pub mod parser;
59/// Box model → SVG, PNG, or egui primitives.
60pub mod render;
61
62pub use atoms::symbol_atom_kind;
63pub use color::{named_color, parse_color_spec, Color, ColorTable};
64pub use dim::{Dim, DIM_PREC};
65pub use error::{Error, FontError, ParseError};
66pub use font::{
67 GlyphMetrics, MathFont, STIX_TWO_MATH_NAME, STIX_TWO_MATH_OTF, STIX_TWO_MATH_SHA256,
68};
69pub use layout::{
70 layout, layout_with_numbering, BoxContent, MathBox, MathParams, MathStyle, NumberFormat,
71 NumberStyle, NumberingConfig, NumberingState,
72};
73pub use parser::{
74 format_tokens, parse, parse_with_colors, preprocess, tokenize, AccentKind, AtomKind, ColSpec,
75 DelimSize, Delimiter, EnvRow, EqNumber, IntegralKind, MathNode, MatrixStyle, PhantomKind,
76 SpaceKind, TextStyle, Token,
77};
78#[cfg(feature = "egui")]
79pub use render::egui::{latex_to_shapes, paint_egui, shapes};
80pub use render::egui::{render_egui, EguiOptions};
81pub use render::png::{latex_to_png, render_png, PngBackground, PngOptions};
82pub use render::svg::{latex_to_svg, render_svg, SvgOptions};
83pub use style_map::styled_char;
84pub use symbols::{category_count, glyph_char, lookup, symbols, SymbolEntry, SymbolKind};