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
This commit is contained in:
Matthew Flatt 2012-07-09 22:14:09 -06:00
parent d23768ba32
commit 83e4a20c8e
6 changed files with 146 additions and 59 deletions

View File

@ -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)

View File

@ -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?]{

View File

@ -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.

View File

@ -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[]

View File

@ -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.

View File

@ -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.