diff --git a/collects/scriblib/autobib.rkt b/collects/scriblib/autobib.rkt index e307ef59..6a4ef11a 100644 --- 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 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 index 319a0225..c07dc3af 100644 --- 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 new file mode 100644 index 00000000..66772628 --- /dev/null +++ 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 new file mode 100644 index 00000000..e4d867df --- /dev/null +++ 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 index a2e61248..5b28a4ec 100644 --- 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.