1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//! # bibtex-parser
//!
//! Fast BibTeX parsing with a Rust-first [`Library`] API.
//!
//! `bibtex-parser` is built for applications that need both throughput and a
//! practical user-facing API: strict parsing by default, explicit tolerant
//! recovery when a corpus is messy, string and month expansion, comments and
//! preambles, validation, query/edit helpers, and configurable writing.
//!
//! ## Features
//!
//! - Borrowed values where possible for low-allocation parsing.
//! - String variables, concatenation, and standard month constants.
//! - Entries, strings, preambles, comments, and tolerant failures in source order.
//! - Opt-in source-span capture.
//! - DOI normalization, duplicate detection, validation, sorting, and field normalization.
//! - Configurable writer for formatting and file output.
//! - Optional `parallel` feature for parsing multiple files concurrently.
//! - Optional `latex_to_unicode` feature for LaTeX accent conversion helpers.
//!
//! ## Parse
//!
//! ```
//! use bibtex_parser::Library;
//!
//! let input = r#"
//! @string{venue = "VLDB"}
//! @article{paper,
//! author = "Jane Doe and John Smith",
//! title = "Fast BibTeX",
//! journal = venue,
//! year = 2026
//! }
//! "#;
//!
//! let library = Library::parse(input)?;
//! let entry = library.find_by_key("paper").unwrap();
//!
//! assert_eq!(entry.get("journal"), Some("VLDB"));
//! assert_eq!(entry.year(), Some("2026".to_string()));
//! assert_eq!(entry.authors().len(), 2);
//! # Ok::<(), bibtex_parser::Error>(())
//! ```
//!
//! ## Tolerant Recovery
//!
//! ```
//! use bibtex_parser::{Block, Library};
//!
//! let library = Library::parser()
//! .tolerant()
//! .capture_source()
//! .parse(r#"
//! @article{ok, title = "Good"}
//! @article{bad, title = "Missing close"
//! @book{recovered, title = "Recovered"}
//! "#)?;
//!
//! assert_eq!(library.entries().len(), 2);
//! assert_eq!(library.failed_blocks().len(), 1);
//!
//! let has_failure_span = library.blocks().iter().any(|block| {
//! matches!(block, Block::Failed(failed) if failed.source.is_some())
//! });
//! assert!(has_failure_span);
//! # Ok::<(), bibtex_parser::Error>(())
//! ```
//!
//! ## Write
//!
//! ```
//! use bibtex_parser::{Library, Writer, WriterConfig};
//!
//! let library = Library::parse(r#"@article{paper, title = "Fast BibTeX"}"#)?;
//! let mut output = Vec::new();
//! let config = WriterConfig {
//! align_values: true,
//! ..Default::default()
//! };
//!
//! Writer::with_config(&mut output, config).write_library(&library)?;
//! assert!(String::from_utf8(output).unwrap().contains("@article{paper"));
//! # Ok::<(), bibtex_parser::Error>(())
//! ```
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
/// Re-export of common parser functions
/// Parse a BibTeX library from a string.
/// Parse a BibTeX library from a file.