summaryrefslogtreecommitdiff
path: root/support/texlab/src/citeproc/name/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/src/citeproc/name/mod.rs')
-rw-r--r--support/texlab/src/citeproc/name/mod.rs275
1 files changed, 275 insertions, 0 deletions
diff --git a/support/texlab/src/citeproc/name/mod.rs b/support/texlab/src/citeproc/name/mod.rs
new file mode 100644
index 0000000000..7668d0fff8
--- /dev/null
+++ b/support/texlab/src/citeproc/name/mod.rs
@@ -0,0 +1,275 @@
+// Ported from: https://github.com/michel-kraemer/citeproc-java/blob/master/citeproc-java/grammars/InternalName.g4
+// Michel Kraemer
+// Apache License 2.0
+mod parser;
+
+use self::parser::NamesParser;
+use citeproc_io::Name;
+
+pub fn parse(input: &str) -> Vec<Name> {
+ let parser = NamesParser::new();
+ parser.parse(input).unwrap_or_else(|_| {
+ vec![Name::Literal {
+ literal: input.into(),
+ }]
+ })
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use citeproc_io::PersonName;
+
+ #[test]
+ fn test_family_only() {
+ let name = Name::Person(PersonName {
+ family: Some("Thompson".into()),
+ given: None,
+ non_dropping_particle: None,
+ dropping_particle: None,
+ suffix: None,
+ });
+ assert_eq!(parse("Thompson"), vec![name]);
+ }
+
+ #[test]
+ fn test_simple() {
+ let name = Name::Person(PersonName {
+ family: Some("Thompson".into()),
+ given: Some("Ken".into()),
+ non_dropping_particle: None,
+ dropping_particle: None,
+ suffix: None,
+ });
+ assert_eq!(parse("Ken Thompson"), vec![name]);
+ }
+
+ #[test]
+ fn test_middle_name() {
+ let name = Name::Person(PersonName {
+ family: Some("Ritchie".into()),
+ given: Some("Dennis M.".into()),
+ non_dropping_particle: None,
+ dropping_particle: None,
+ suffix: None,
+ });
+ assert_eq!(parse("Dennis M. Ritchie"), vec![name]);
+ }
+
+ #[test]
+ fn test_initials() {
+ let name = Name::Person(PersonName {
+ family: Some("Johnson".into()),
+ given: Some("S. C.".into()),
+ non_dropping_particle: None,
+ dropping_particle: None,
+ suffix: None,
+ });
+ assert_eq!(parse("S. C. Johnson"), vec![name]);
+ }
+
+ #[test]
+ fn test_non_dropping_particle() {
+ let name = Name::Person(PersonName {
+ family: Some("Gerwen".into()),
+ given: Some("Michael".into()),
+ non_dropping_particle: Some("van".into()),
+ dropping_particle: None,
+ suffix: None,
+ });
+ assert_eq!(parse("Michael van Gerwen"), vec![name]);
+ }
+
+ #[test]
+ fn test_non_dropping_particle_family_only() {
+ let name = Name::Person(PersonName {
+ family: Some("Gerwen".into()),
+ given: None,
+ non_dropping_particle: Some("van".into()),
+ dropping_particle: None,
+ suffix: None,
+ });
+ assert_eq!(parse("van Gerwen"), vec![name]);
+ }
+
+ #[test]
+ fn test_comma() {
+ let name = Name::Person(PersonName {
+ family: Some("Thompson".into()),
+ given: Some("Ken".into()),
+ non_dropping_particle: None,
+ dropping_particle: None,
+ suffix: None,
+ });
+ assert_eq!(parse("Thompson, Ken"), vec![name]);
+ }
+
+ #[test]
+ fn test_comma_junior() {
+ let name = Name::Person(PersonName {
+ family: Some("Friedman".into()),
+ given: Some("George".into()),
+ non_dropping_particle: None,
+ dropping_particle: None,
+ suffix: Some("Jr.".into()),
+ });
+ assert_eq!(parse("Friedman, Jr., George"), vec![name]);
+ }
+
+ #[test]
+ fn test_comma_no_junior() {
+ let name = Name::Person(PersonName {
+ family: Some("Familya Familyb".into()),
+ given: Some("Given".into()),
+ non_dropping_particle: None,
+ dropping_particle: None,
+ suffix: None,
+ });
+ assert_eq!(parse("Familya Familyb, Given"), vec![name]);
+ }
+
+ #[test]
+ fn test_comma_initials() {
+ let name = Name::Person(PersonName {
+ family: Some("Ritchie".into()),
+ given: Some("Dennis M.".into()),
+ non_dropping_particle: None,
+ dropping_particle: None,
+ suffix: None,
+ });
+ assert_eq!(parse("Ritchie, Dennis M."), vec![name]);
+ }
+
+ #[test]
+ fn test_comma_non_dropping_particle() {
+ let name = Name::Person(PersonName {
+ family: Some("Gerwen".into()),
+ given: Some("Michael".into()),
+ non_dropping_particle: Some("van".into()),
+ dropping_particle: None,
+ suffix: None,
+ });
+ assert_eq!(parse("van Gerwen, Michael"), vec![name]);
+ }
+
+ #[test]
+ fn test_comma_non_dropping_particles() {
+ let name = Name::Person(PersonName {
+ family: Some("Voort".into()),
+ given: Some("Vincent".into()),
+ non_dropping_particle: Some("Van der".into()),
+ dropping_particle: None,
+ suffix: None,
+ });
+ assert_eq!(parse("Van der Voort, Vincent"), vec![name]);
+ }
+
+ #[test]
+ fn test_and() {
+ let name1 = Name::Person(PersonName {
+ family: Some("Gerwen".into()),
+ given: Some("Michael".into()),
+ non_dropping_particle: Some("van".into()),
+ dropping_particle: None,
+ suffix: None,
+ });
+ let name2 = Name::Person(PersonName {
+ family: Some("Voort".into()),
+ given: Some("Vincent".into()),
+ non_dropping_particle: Some("van der".into()),
+ dropping_particle: None,
+ suffix: None,
+ });
+ assert_eq!(
+ parse("Michael van Gerwen and Vincent van der Voort"),
+ vec![name1, name2]
+ );
+ }
+
+ #[test]
+ fn test_and_comma1() {
+ let name1 = Name::Person(PersonName {
+ family: Some("Gerwen".into()),
+ given: Some("Michael".into()),
+ non_dropping_particle: Some("van".into()),
+ dropping_particle: None,
+ suffix: None,
+ });
+ let name2 = Name::Person(PersonName {
+ family: Some("Voort".into()),
+ given: Some("Vincent".into()),
+ non_dropping_particle: Some("Van der".into()),
+ dropping_particle: None,
+ suffix: None,
+ });
+ assert_eq!(
+ parse("van Gerwen, Michael and Van der Voort, Vincent"),
+ vec![name1, name2]
+ );
+ }
+
+ #[test]
+ fn test_and_comma2() {
+ let name1 = Name::Person(PersonName {
+ family: Some("Gerwen".into()),
+ given: Some("Michael".into()),
+ non_dropping_particle: Some("van".into()),
+ dropping_particle: None,
+ suffix: None,
+ });
+ let name2 = Name::Person(PersonName {
+ family: Some("Voort".into()),
+ given: Some("Vincent".into()),
+ non_dropping_particle: Some("van der".into()),
+ dropping_particle: None,
+ suffix: None,
+ });
+ assert_eq!(
+ parse("van Gerwen, Michael and van der Voort, Vincent"),
+ vec![name1, name2]
+ );
+ }
+
+ #[test]
+ fn test_and_comma_mix() {
+ let name1 = Name::Person(PersonName {
+ family: Some("Gerwen".into()),
+ given: Some("Michael".into()),
+ non_dropping_particle: Some("van".into()),
+ dropping_particle: None,
+ suffix: None,
+ });
+ let name2 = Name::Person(PersonName {
+ family: Some("Voort".into()),
+ given: Some("Vincent".into()),
+ non_dropping_particle: Some("van der".into()),
+ dropping_particle: None,
+ suffix: None,
+ });
+ assert_eq!(
+ parse("van Gerwen, Michael and Vincent van der Voort"),
+ vec![name1, name2]
+ );
+ }
+
+ #[test]
+ fn test_junior() {
+ let name = Name::Person(PersonName {
+ family: Some("Friedman".into()),
+ given: Some("George".into()),
+ non_dropping_particle: None,
+ dropping_particle: None,
+ suffix: Some("Jr.".into()),
+ });
+ assert_eq!(parse("George Friedman, Jr."), vec![name]);
+ }
+
+ #[test]
+ fn test_non_parseable() {
+ let literal = "Jerry Peek and Tim O'Reilly and Mike Loukides and other authors of the Nutshell handbooks";
+ let name = Name::Literal {
+ literal: literal.into(),
+ };
+ assert_eq!(parse(literal), vec![name]);
+ }
+}