diff --git a/src/lib.rs b/src/lib.rs index 7142aa2..03d82aa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1053,6 +1053,33 @@ mod tests { dump_author_title("tests/polaritons.bib"); } + #[test] + fn test_comments() { + let contents = fs::read_to_string("tests/comments.bib").unwrap(); + + let bibliography = Bibliography::parse(&contents).unwrap(); + + assert_eq!( + bibliography.keys().collect::>(), + &[ + "mcelreath2007mathematical", + "fischer2022equivalence", + "roes2003belief", + "wong2016null", + ] + ); + + assert_eq!( + bibliography + .get("wong2016null") + .unwrap() + .title() + .unwrap() + .format_verbatim(), + "Null hypothesis testing (I)-5% significance level" + ); + } + #[test] fn test_extended_name_format() { dump_author_title("tests/extended_name_format.bib"); diff --git a/src/raw.rs b/src/raw.rs index cbbd87f..80f50e1 100644 --- a/src/raw.rs +++ b/src/raw.rs @@ -167,8 +167,11 @@ impl<'s> BiblatexParser<'s> { pub fn parse(mut self) -> Result, ParseError> { while !self.s.done() { self.s.eat_whitespace(); + match self.s.peek() { Some('@') => self.entry()?, + // Handle comments outside of entry + Some('%') => self.comment()?, Some(_) => { self.s.eat(); } @@ -360,7 +363,13 @@ impl<'s> BiblatexParser<'s> { let value = self.abbr_field()?; + // Handle inline comments before closing brace at end of entry: + // @article{foo, + // title={bar}, + // year={2025} % A comment + // } self.s.eat_whitespace(); + self.comment()?; Ok((key, value)) } @@ -393,7 +402,17 @@ impl<'s> BiblatexParser<'s> { fields.push(Pair::new(key, value)); match self.s.peek() { - Some(',') => self.comma()?, + Some(',') => { + self.comma()?; + + // Handle inline comments after comma at end of field + // @article{foo, + // title={bar}, % A comment + // year={2025} + // } + self.s.eat_whitespace(); + self.comment()?; + } Some('}') => { return Ok(fields); } @@ -486,6 +505,14 @@ impl<'s> BiblatexParser<'s> { self.s.eat_whitespace(); self.comma()?; + // Handle inline comments after entry key + // @article{foo, % A comment + // title={bar}, + // year={2025} + // } + self.s.eat_whitespace(); + self.comment()?; + self.s.eat_whitespace(); let fields = self.fields()?; @@ -495,6 +522,14 @@ impl<'s> BiblatexParser<'s> { Ok(()) } + /// Eat an inline comment. + fn comment(&mut self) -> Result<(), ParseError> { + if self.s.eat_if('%') { + self.s.eat_until('\n'); + } + Ok(()) + } + fn here(&self) -> Span { self.s.cursor()..self.s.cursor() } diff --git a/tests/comments.bib b/tests/comments.bib new file mode 100644 index 0000000..14027e4 --- /dev/null +++ b/tests/comments.bib @@ -0,0 +1,51 @@ +% Comments before the entry works +@book{mcelreath2007mathematical, + title={Mathematical models of social evolution: A guide for the perplexed}, + author={McElreath, Richard and Boyd, Robert}, + year={2007}, + publisher={University of Chicago Press}, + address={Chicago} +} + +@article{fischer2022equivalence, + title={Why equivalence and invariance are both different and essential for scientific studies of culture: A discussion of mapping processes and theoretical implications}, + author={Fischer, Ronald and Karl, Johannes and Luczak-Roesch, Markus}, + year={2022}, % An inline comment should also work + publisher={PsyArXiv}, + % A comment on a new line of the entry + url={https://files.osf.io/v1/resources/fst9k/providers/osfstorage/6312eb42e7f1b7082aaae63c} +} + +% Commented-out blocks should also work +% @manual{rlang, +% title={R: A Language and Environment for Statistical Computing}, +% author={{R Core Team}}, +% organization={R Foundation for Statistical Computing}, +% address={Vienna, Austria}, +% year={2024}, +% url={https://www.R-project.org/} +% } + +@article{roes2003belief, % A comment after the entry key + title={Belief in moralizing gods}, + author={Roes, Frans L and Raymond, Michel}, + journal={Evolution and human behavior}, + volume={24}, + number={2}, + pages={126--135}, + year={2003}, + publisher={Elsevier}, + doi={10.1016/S1090-5138(02)00134-4} +} % A comment after the entry + +% This is an example of a percent symbol in the content of the entry, so we must ignore after the % too eagerly +@article{wong2016null, + title={Null hypothesis testing ({I})-5\% significance level}, + author={Wong, Kai-Choi}, + journal={East Asian Archives of Psychiatry}, + volume={26}, + number={3}, + pages={112--113}, + year={2016}, + publisher={Hong Kong College of Psychiatrists} % A comment at the end of the entry +}