commit 47c94c3afcf7d2384d38aec4908be92939251a0d
parent a8dec74ffaa73f26b289736529fcdc63999a1027
Author: Georges Dupéron <jahvascriptmaniac+github@gmail.com>
Date: Fri, 19 May 2017 22:42:48 +0200
Last,First format for names in bibtex
Handle comma-separated Last,First and Last,Jr,First format for names in bibtex, as well as "von", "de la", "van de", and other separators that start with lowercase letters
Diffstat:
1 file changed, 172 insertions(+), 14 deletions(-)
diff --git a/scribble-lib/scriblib/bibtex.rkt b/scribble-lib/scriblib/bibtex.rkt
@@ -1,7 +1,8 @@
#lang at-exp racket/base
(require racket/function
racket/match
- racket/list)
+ racket/list
+ racket/string)
(struct bibdb (raw bibs))
@@ -208,7 +209,7 @@
(λ (key)
(and (not (string=? "\n" key))
(generate-bib bibtex-db key)))
- (append-map (curry regexp-split #rx" +")
+ (append-map (curry regexp-split #px"\\s+")
(cons f r)))))
(define ~cite-id (make-citer autobib-cite))
(define citet-id (make-citer autobib-citet))))
@@ -216,14 +217,25 @@
(define (parse-author as)
(and as
(apply authors
- (for/list ([a (in-list (regexp-split #rx" +and *" as))])
- (match (regexp-split #rx" +" a)
- [(list one) (org-author-name one)]
- [(list one two) (author-name one two)]
- [(list-rest first rest)
- (author-name (apply string-append (add-between (cons first (drop-right rest 1))
- " "))
- (last rest))])))))
+ (for/list ([a (in-list (regexp-split #px"\\s+and\\s+" as))])
+ (define (trim s)
+ (string-trim (regexp-replace #px"\\s+" s " ")))
+ (match a
+ [(pregexp #px"^(.*),(.*),(.*)$" (list _ two suffix one))
+ (author-name (trim one) (trim two) #:suffix (trim suffix))]
+ [(pregexp #px"^(.*),(.*)$" (list _ two one))
+ (author-name (string-trim one) (string-trim two))]
+ [(pregexp #px"^(.*?)\\s+(\\p{Ll}[^\\s]*(\\s+\\p{Ll}[^\\s]*)*)\\s+(.*)$" (list _ one von-like _ two))
+ (author-name (string-trim one)
+ (string-append (string-trim von-like) " " (string-trim two)))]
+ [space-separated
+ (match (regexp-split #px"\\s+" space-separated)
+ [(list one) (org-author-name one)]
+ [(list one two) (author-name one two)]
+ [(list-rest first rest)
+ (author-name (apply string-append (add-between (cons first (drop-right rest 1))
+ " "))
+ (last rest))])])))))
(module+ test
(require rackunit)
@@ -235,8 +247,8 @@
(equal? (format "~s" a)
(format "~s" b)))
- (check
- print-as-equal-string?
+ (check
+ print-as-equal-string?
(parse-author "James Earl Jones")
(authors
(author-name "James Earl" "Jones")))
@@ -248,12 +260,158 @@
(author-name "Morgan" "Freeman")))
(check
- print-as-equal-string?
+ print-as-equal-string?
(parse-author "Edward L. Deci and Robert J. Vallerand and Luc G. Pelletier and Richard M. Ryan")
(authors (author-name "Edward L." "Deci")
(author-name "Robert J." "Vallerand")
(author-name "Luc G." "Pelletier")
- (author-name "Richard M." "Ryan"))))
+ (author-name "Richard M." "Ryan")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "Lst, Fst")
+ (authors
+ (author-name "Fst" "Lst")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "Lst,Fst")
+ (authors
+ (author-name "Fst" "Lst")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "James, Earl Jones")
+ (authors
+ (author-name "Earl Jones" "James")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "James,Earl Jones")
+ (authors
+ (author-name "Earl Jones" "James")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "LstA LstB, Fst")
+ (authors
+ (author-name "Fst" "LstA LstB")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "LstA LstB,Fst")
+ (authors
+ (author-name "Fst" "LstA LstB")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "LstA LstB, FstA FstB")
+ (authors
+ (author-name "FstA FstB" "LstA LstB")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "LstA LstB,FstA FstB")
+ (authors
+ (author-name "FstA FstB" "LstA LstB")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "James, Jr, Earl Jones")
+ (authors
+ (author-name "Earl Jones" "James" #:suffix "Jr")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "James,Jr, Earl Jones")
+ (authors
+ (author-name "Earl Jones" "James" #:suffix "Jr")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "James, Jr,Earl Jones")
+ (authors
+ (author-name "Earl Jones" "James" #:suffix "Jr")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "James,Jr,Earl Jones")
+ (authors
+ (author-name "Earl Jones" "James" #:suffix "Jr")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "James, III, Earl Jones")
+ (authors
+ (author-name "Earl Jones" "James" #:suffix "III")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "James,III, Earl Jones")
+ (authors
+ (author-name "Earl Jones" "James" #:suffix "III")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "James, III,Earl Jones")
+ (authors
+ (author-name "Earl Jones" "James" #:suffix "III")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "James,III,Earl Jones")
+ (authors
+ (author-name "Earl Jones" "James" #:suffix "III")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "James Jack von Earl Jones")
+ (authors
+ (author-name "James Jack" "von Earl Jones")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "James Jack de la Earl Jones")
+ (authors
+ (author-name "James Jack" "de la Earl Jones")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "James Jack van der Earl Jones")
+ (authors
+ (author-name "James Jack" "van der Earl Jones")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "James Jack von de la Earl Jones")
+ (authors
+ (author-name "James Jack" "von de la Earl Jones")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "James Jack di Earl Jones")
+ (authors
+ (author-name "James Jack" "di Earl Jones")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "First fOn bER Last")
+ (authors
+ (author-name "First" "fOn bER Last")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "Deci, Edward L. and Robert J. Vallerand and Pelletier, Luc G. and Ryan, Jr, Richard M.")
+ (authors (author-name "Edward L." "Deci")
+ (author-name "Robert J." "Vallerand")
+ (author-name "Luc G." "Pelletier")
+ (author-name "Richard M." "Ryan" #:suffix "Jr")))
+
+ (check
+ print-as-equal-string?
+ (parse-author "Foo anderson") ;; Should not be parsed as the two authors "Foo" & "erson"
+ (authors
+ (author-name "Foo" "anderson"))))
(define (parse-pages ps)
(match ps