Skip to content

Commit 1f2753e

Browse files
authored
Implement extended support for comments in bib source files (#80)
1 parent 96751bf commit 1f2753e

File tree

3 files changed

+114
-1
lines changed

3 files changed

+114
-1
lines changed

src/lib.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,33 @@ mod tests {
10531053
dump_author_title("tests/polaritons.bib");
10541054
}
10551055

1056+
#[test]
1057+
fn test_comments() {
1058+
let contents = fs::read_to_string("tests/comments.bib").unwrap();
1059+
1060+
let bibliography = Bibliography::parse(&contents).unwrap();
1061+
1062+
assert_eq!(
1063+
bibliography.keys().collect::<Vec<_>>(),
1064+
&[
1065+
"mcelreath2007mathematical",
1066+
"fischer2022equivalence",
1067+
"roes2003belief",
1068+
"wong2016null",
1069+
]
1070+
);
1071+
1072+
assert_eq!(
1073+
bibliography
1074+
.get("wong2016null")
1075+
.unwrap()
1076+
.title()
1077+
.unwrap()
1078+
.format_verbatim(),
1079+
"Null hypothesis testing (I)-5% significance level"
1080+
);
1081+
}
1082+
10561083
#[test]
10571084
fn test_extended_name_format() {
10581085
dump_author_title("tests/extended_name_format.bib");

src/raw.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,11 @@ impl<'s> BiblatexParser<'s> {
167167
pub fn parse(mut self) -> Result<RawBibliography<'s>, ParseError> {
168168
while !self.s.done() {
169169
self.s.eat_whitespace();
170+
170171
match self.s.peek() {
171172
Some('@') => self.entry()?,
173+
// Handle comments outside of entry
174+
Some('%') => self.comment()?,
172175
Some(_) => {
173176
self.s.eat();
174177
}
@@ -360,7 +363,13 @@ impl<'s> BiblatexParser<'s> {
360363

361364
let value = self.abbr_field()?;
362365

366+
// Handle inline comments before closing brace at end of entry:
367+
// @article{foo,
368+
// title={bar},
369+
// year={2025} % A comment
370+
// }
363371
self.s.eat_whitespace();
372+
self.comment()?;
364373

365374
Ok((key, value))
366375
}
@@ -393,7 +402,17 @@ impl<'s> BiblatexParser<'s> {
393402
fields.push(Pair::new(key, value));
394403

395404
match self.s.peek() {
396-
Some(',') => self.comma()?,
405+
Some(',') => {
406+
self.comma()?;
407+
408+
// Handle inline comments after comma at end of field
409+
// @article{foo,
410+
// title={bar}, % A comment
411+
// year={2025}
412+
// }
413+
self.s.eat_whitespace();
414+
self.comment()?;
415+
}
397416
Some('}') => {
398417
return Ok(fields);
399418
}
@@ -486,6 +505,14 @@ impl<'s> BiblatexParser<'s> {
486505
self.s.eat_whitespace();
487506
self.comma()?;
488507

508+
// Handle inline comments after entry key
509+
// @article{foo, % A comment
510+
// title={bar},
511+
// year={2025}
512+
// }
513+
self.s.eat_whitespace();
514+
self.comment()?;
515+
489516
self.s.eat_whitespace();
490517
let fields = self.fields()?;
491518

@@ -495,6 +522,14 @@ impl<'s> BiblatexParser<'s> {
495522
Ok(())
496523
}
497524

525+
/// Eat an inline comment.
526+
fn comment(&mut self) -> Result<(), ParseError> {
527+
if self.s.eat_if('%') {
528+
self.s.eat_until('\n');
529+
}
530+
Ok(())
531+
}
532+
498533
fn here(&self) -> Span {
499534
self.s.cursor()..self.s.cursor()
500535
}

tests/comments.bib

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
% Comments before the entry works
2+
@book{mcelreath2007mathematical,
3+
title={Mathematical models of social evolution: A guide for the perplexed},
4+
author={McElreath, Richard and Boyd, Robert},
5+
year={2007},
6+
publisher={University of Chicago Press},
7+
address={Chicago}
8+
}
9+
10+
@article{fischer2022equivalence,
11+
title={Why equivalence and invariance are both different and essential for scientific studies of culture: A discussion of mapping processes and theoretical implications},
12+
author={Fischer, Ronald and Karl, Johannes and Luczak-Roesch, Markus},
13+
year={2022}, % An inline comment should also work
14+
publisher={PsyArXiv},
15+
% A comment on a new line of the entry
16+
url={https://files.osf.io/v1/resources/fst9k/providers/osfstorage/6312eb42e7f1b7082aaae63c}
17+
}
18+
19+
% Commented-out blocks should also work
20+
% @manual{rlang,
21+
% title={R: A Language and Environment for Statistical Computing},
22+
% author={{R Core Team}},
23+
% organization={R Foundation for Statistical Computing},
24+
% address={Vienna, Austria},
25+
% year={2024},
26+
% url={https://www.R-project.org/}
27+
% }
28+
29+
@article{roes2003belief, % A comment after the entry key
30+
title={Belief in moralizing gods},
31+
author={Roes, Frans L and Raymond, Michel},
32+
journal={Evolution and human behavior},
33+
volume={24},
34+
number={2},
35+
pages={126--135},
36+
year={2003},
37+
publisher={Elsevier},
38+
doi={10.1016/S1090-5138(02)00134-4}
39+
} % A comment after the entry
40+
41+
% This is an example of a percent symbol in the content of the entry, so we must ignore after the % too eagerly
42+
@article{wong2016null,
43+
title={Null hypothesis testing ({I})-5\% significance level},
44+
author={Wong, Kai-Choi},
45+
journal={East Asian Archives of Psychiatry},
46+
volume={26},
47+
number={3},
48+
pages={112--113},
49+
year={2016},
50+
publisher={Hong Kong College of Psychiatrists} % A comment at the end of the entry
51+
}

0 commit comments

Comments
 (0)