commit 83e4a20c8e2962dee5dc37c8e04560b8ce265b65
parent d23768ba32806161e309be1ac756948a7e1c212b
Author: Matthew Flatt <mflatt@racket-lang.org>
Date: Mon, 9 Jul 2012 22:14:09 -0600
scriblib/autobib: fixes in docs and related to disambiguation
Fixed problems related to sorting, more than two references for
one citation, and "specific" additions like page numbers.
Also, removed a set of parentheses around disambiguated dates
in the bibliography, because I don't think they belong there.
The doc format was confused; for example, square brackets don't mean
optional in a syntactic form documentation, but instead mean square
brackets.
original commit: 71fe28e5dcf33f33a1afbb810b0cf6cc439e6629
Diffstat:
6 files changed, 146 insertions(+), 59 deletions(-)
diff --git a/collects/scriblib/autobib.rkt b/collects/scriblib/autobib.rkt
@@ -48,25 +48,25 @@
(lambda (renderer part ri)
;; (list which key) should be mapped to the bibliography element.
(define s (resolve-get part ri `(,which ,key)))
- (cons (make-link-element #f
- (list (or s "???")
- (if with-specific?
- (auto-bib-specific bib-entry)
- ""))
- `(autobib ,(auto-bib-key bib-entry)))
- (cond [disambiguation ;; should be a list of bib-entries with same author/date
- (define disambiguation*
- (add-between (for/list ([bib (in-list disambiguation)])
- (define key (auto-bib-key bib))
- (define maybe-disambiguation
- (resolve-get part ri `(autobib-disambiguation ,key)))
- (case maybe-disambiguation
- [(unambiguous) #f]
- [else (make-link-element #f maybe-disambiguation `(autobib ,key))]))
- ","))
- (cond [(not (car disambiguation*)) '()] ;; the bib was unambiguous
- [else disambiguation*])]
- [else '()])))
+ (make-link-element #f
+ (list (or s "???")
+ (cond [disambiguation ;; should be a list of bib-entries with same author/date
+ (define disambiguation*
+ (add-between (for/list ([bib (in-list disambiguation)])
+ (define key (auto-bib-key bib))
+ (define maybe-disambiguation
+ (resolve-get part ri `(autobib-disambiguation ,key)))
+ (case maybe-disambiguation
+ [(unambiguous) #f]
+ [else (make-link-element #f maybe-disambiguation `(autobib ,key))]))
+ ","))
+ (cond [(not (car disambiguation*)) '()] ;; the bib was unambiguous
+ [else disambiguation*])]
+ [else '()])
+ (if with-specific?
+ (auto-bib-specific bib-entry)
+ ""))
+ `(autobib ,(auto-bib-key bib-entry))))
(lambda () "(???)")
(lambda () "(???)"))))
@@ -80,13 +80,16 @@
[currently-ambiguous '()]
[partition '()])
([bib (reverse sorted-by-date)])
- (cond [(and last (date=? last bib)) ;; ambiguous! group.
+ (cond [(and last (date=? last bib)
+ (equal? (auto-bib-specific bib) "")
+ (equal? (auto-bib-specific last) ""))
+ ;; can group
(values bib (cons bib currently-ambiguous) partition)]
;; first element.
[(not last) (values bib (list bib) partition)]
;; not ambiguous. Start next group.
[else (values bib (list bib) (cons currently-ambiguous partition))]))])
- (reverse (cons last-ambiguous-list partition))))
+ (cons last-ambiguous-list partition)))
(cond [(null? bib-entries) '()]
[else
(add-between
@@ -94,11 +97,17 @@
(add-cite group (car part) 'autobib-date #t part))
delimiter)]))
+(define all-equal?
+ (case-lambda
+ [(a) #t]
+ [(a b) (equal? a b)]
+ [(a . bs) (andmap (lambda (v) (equal? a v)) bs)]))
+
(define (add-inline-cite group bib-entries bib-date<? bib-date=?)
(for ([i bib-entries])
(hash-set! (bib-group-ht group) (auto-bib-key i) i))
(when (and (pair? (cdr bib-entries))
- (not (apply equal? (map (compose author-element-names* auto-bib-author) bib-entries))))
+ (not (apply all-equal? (map (compose author-element-names* auto-bib-author) bib-entries))))
(error 'citet "citet must be used with identical authors, given ~a"
(map (compose author-element-names* auto-bib-author) bib-entries)))
(make-element
@@ -161,16 +170,18 @@
(define render-date-bib (or maybe-render-date-bib default-render-date-bib))
(define render-date-cite (or maybe-render-date-cite default-render-date-cite))
(define (author/date<? a b)
- ;; comparing just the authors causes non-deterministic render order.
- ;; We still have to use the authors first in order for last name order.
- ;; If there is a collision for names, then disambiguate with the keys and then the date.
+ ;; Compare author names, then date, then full key
(or (string-ci<? (extract-bib-key a) (extract-bib-key b))
(and (string-ci=? (extract-bib-key a) (extract-bib-key b))
- (or (string-ci<? (auto-bib-key a) (auto-bib-key b))
- (and (string-ci=? (auto-bib-key a) (auto-bib-key b))
- (auto-bib-date a)
- (auto-bib-date b)
- (date<? a b))))))
+ (cond
+ [(not (auto-bib-date a))
+ (if (auto-bib-date b)
+ #f
+ (string-ci<? (auto-bib-key a) (auto-bib-key b)))]
+ [(not (auto-bib-date b)) #t]
+ [(date<? a b) #t]
+ [(date<? b a) #f]
+ [else (string-ci<? (auto-bib-key a) (auto-bib-key b))]))))
(define (ambiguous? a b)
(and (string-ci=? (extract-bib-key a) (extract-bib-key b))
(auto-bib-date a)
@@ -261,7 +272,7 @@
null)
(if date `(" "
,@(if disambiguation
- `("(" ,@(decode-content (list (render-date-bib date))) ,disambiguation ")")
+ `(,@(decode-content (list (render-date-bib date))) ,disambiguation)
(decode-content (list (render-date-bib date))))
".")
null)
diff --git a/collects/scriblib/scribblings/autobib.scrbl b/collects/scriblib/scribblings/autobib.scrbl
@@ -28,7 +28,8 @@ function. See below for an example.
#:title "Reference: Racket"
#:author (authors "Matthew Flatt" "PLT")
#:date "2010"
- #:location (techrpt-location #:institution "PLT Inc." #:number "PLT-TR-2010-1")
+ #:location (techrpt-location #:institution "PLT Inc."
+ #:number "PLT-TR-2010-1")
#:url "http://racket-lang.org/tr1/"))
Racket is fun@~cite[plt-tr1].
@@ -36,30 +37,20 @@ function. See below for an example.
@(generate-bibliography)
}|
-@defform[(define-cite ~cite-id citet-id generate-bibliography-id
- [#:disambiguate disambiguator]
- [#:render-date-bib render-date]
- [#:render-date-cite render-date]
- [#:date<? date-compare]
- [#:date=? date-compare])]{
+@defform/subs[(define-cite ~cite-id citet-id generate-bibliography-id
+ option ...)
+ ([option (code:line #:disambiguate disambiguator-expr)
+ (code:line #:render-date-bib render-date-expr)
+ (code:line #:render-date-cite render-date-expr)
+ (code:line #:date<? date-compare-expr)
+ (code:line #:date=? date-compare-expr)])
+ #:contracts ([disambiguator-expr (-> exact-nonnegative-integer? element?)]
+ [render-date-expr (-> date? element?)]
+ [date-compare-expr (-> date? date? boolean?)])]{
Binds @racket[~cite-id], @racket[citet-id], and
-@racket[generate-bibliography-id], which share state to accumulate and render
-citations. If two citations' references would render the same (as judged by equal authors and dates are @racket[date=?]) but are
-different, the optionally provided disambiguation function is used to add an
-extra element after the date. The default disambiguator will add "a", "b", etc
-until "z". Anything more ambiguous will throw an error. It has the contract
-
-@racketblock[(-> exact-nonnegative-integer? element?)]
-
-Dates in citations and dates in the bibliography may be rendered differently,
-as specified by the optionally given @racket[render-date] functions, which have the contract
-
-@racketblock[(-> date? element?)]
-
-The dates of citations are stored as @racket[date] values, and the granularity in which they are compared and rendered are, by default, by year. The comparison functions have contract
-
-@racketblock[(-> date? date? boolean?)]
+@racket[generate-bibliography-id], which share state to accumulate and
+render citations.
The function bound to @racket[~cite-id] produces a citation referring
to one or more bibliography entries with a preceding non-breaking
@@ -87,7 +78,16 @@ section for the bibliography. It has the contract
The default value for the @racket[#:tag] argument is @racket["doc-bibliography"]
and for @racket[#:sec-title] is @racket["Bibliography"].
-}
+
+If two citations' references would render the same (as judged by equal
+authors and dates that are considered the same) but are different, the
+optionally provided function from @racket[disambiguator-expr] is used
+to add an extra element after the date; the default disambiguator adds
+@litchar{a}, @litchar{b}, @etc until @litchar{z}, and anything more
+ambiguous raises an exception. Date comparison is controlled by
+@racket[date-compare-expr]s. Dates in citations and dates in the
+bibliography may be rendered differently, as specified by the
+optionally given @racket[render-date-expr] functions.}
@defproc[(bib? [v any/c]) boolean?]{
diff --git a/collects/tests/scribble/docs/autobib-disambiguation-corner.txt b/collects/tests/scribble/docs/autobib-disambiguation-corner.txt
@@ -2,5 +2,5 @@
Bibliography
-Little, Bo, and Peep. Diss A. PhD dissertation, NEU, (2012a).
-Little, Bo, and Peep. Diss B. PhD dissertation, NEU, (2012b).
+Little, Bo, and Peep. Diss A. PhD dissertation, NEU, 2012a.
+Little, Bo, and Peep. Diss B. PhD dissertation, NEU, 2012b.
diff --git a/collects/tests/scribble/docs/autobib-disambiguation-more.scrbl b/collects/tests/scribble/docs/autobib-disambiguation-more.scrbl
@@ -0,0 +1,56 @@
+#lang scribble/manual
+@(require scriblib/autobib)
+
+@(define-cite ~cite citet generate-bibliography)
+
+@(define a1
+ (make-bib
+ #:title "One"
+ #:author "A"
+ #:date "2012"
+ #:location "There"))
+
+@(define a2
+ (make-bib
+ #:title "Two"
+ #:author "A"
+ #:date "2012"
+ #:location "Here"))
+
+@(define a2x
+ (make-bib
+ #:title "Twoish"
+ #:author "A"
+ #:date "2012"
+ #:location "HereX"))
+
+@(define a3
+ (make-bib
+ #:title "Three"
+ #:author "A"
+ #:date "2013"
+ #:location "Where?"))
+
+@(define b1
+ (make-bib
+ #:title "Uno"
+ #:author "B"
+ #:date "2012"
+ #:location "Ici"))
+
+A1@~cite[a1 a2 b1].
+
+A1@~cite[a1 a2 a3].
+
+@citet[a1 a2 a3].
+
+In A2@~cite[(in-bib a2 " p. 17")]
+
+In A2 and A3@~cite[(in-bib a2 " p. 17") a3]
+
+In A1 and more@~cite[a1 (in-bib a2 " p. 17") a3]
+
+B&B@~cite[b1 a1].
+
+
+@generate-bibliography[]
diff --git a/collects/tests/scribble/docs/autobib-disambiguation-more.txt b/collects/tests/scribble/docs/autobib-disambiguation-more.txt
@@ -0,0 +1,20 @@
+A1 (A 2012a,b; B 2012).
+
+A1 (A 2012a,b, 2013).
+
+A (2012a,b; 2013).
+
+In A2 (A 2012b p. 17)
+
+In A2 and A3 (A 2012b p. 17, 2013)
+
+In A1 and more (A 2012a, 2012b p. 17, 2013)
+
+B&B (A 2012a; B 2012).
+
+Bibliography
+
+A. One. There, 2012a.
+A. Two. Here, 2012b.
+A. Three. Where?, 2013.
+B. Uno. Ici, 2012.
diff --git a/collects/tests/scribble/docs/autobib-disambiguation.txt b/collects/tests/scribble/docs/autobib-disambiguation.txt
@@ -5,5 +5,5 @@ al. (2012b,a)
Bibliography
-Little, Bo, and Peep. Diss 1. PhD dissertation, NEU, (2012a).
-Little, Bo, and Peep. Diss 2. PhD dissertation, NEU, (2012b).
+Little, Bo, and Peep. Diss 1. PhD dissertation, NEU, 2012a.
+Little, Bo, and Peep. Diss 2. PhD dissertation, NEU, 2012b.