diff --git a/scribble-lib/scriblib/autobib.rkt b/scribble-lib/scriblib/autobib.rkt index 92674a2315..ec31e78859 100644 --- a/scribble-lib/scriblib/autobib.rkt +++ b/scribble-lib/scriblib/autobib.rkt @@ -421,7 +421,7 @@ ".") null) (if (and (not doi) url) `(" " ,[(url-rendering) url]) null) - (if doi `(" " ,[(doi-rendering) doi]) null) + (if doi `(" " ,[(doi-rendering) doi] ,(if note "." null)) null) (if note `(" " ,note) null)))) (define-syntax (define-cite stx) @@ -540,11 +540,60 @@ (define (given-names->initials str) (regexp-replace* #rx"(.)[^ ]*( |$)" str "\\1. ")) +;; return content for v, preserve false +(define (contentify v) + (if (or (not v) (content? v) (string? v)) + v + (format "~a" v))) +;; return string for v, preserve false +(define (stringify v) + (and v (content->string v))) + (module+ test (require rackunit) (check-equal? (given-names->initials "Matthew") "M. ") (check-equal? (given-names->initials "Matthew R.") "M. R. ") - (check-equal? (given-names->initials "Matthew Raymond") "M. R. ")) + (check-equal? (given-names->initials "Matthew Raymond") "M. R. ") + (check-equal? (content->string (journal-location (bold "Journal of Things"))) "Journal of Things") + (check-equal? (content->string (author-name (italic "Ada") "Lovelace")) "Ada Lovelace") + + (check-false (contentify #f)) + (check-false (stringify #f)) + (check-equal? (contentify 42) "42") + (check-equal? (stringify 42) "42") + (define emphasized (italic "foo")) + (check-eq? (contentify emphasized) emphasized) + (check-equal? (stringify emphasized) "foo") + + (define no-note + (make-bib #:title "Title" #:doi "10.1234/foo")) + (define with-note + (make-bib #:title "Title" + #:doi "10.1234/foo" + #:note "A note")) + (check-equal? + (content->string + (bib->entry no-note author+date-style #f + default-render-date-bib 1)) + "Title. doi:10.1234/foo") + (check-equal? + (content->string + (bib->entry with-note author+date-style #f + default-render-date-bib 1)) + "Title. doi:10.1234/foo. A note") + + (check-equal? + (content->string + (book-location + #:edition "second" + #:chapter 3 + #:series "LNCS" + #:volume 42 + #:number 7 + #:pages '(10 20) + #:publisher "Springer" + #:address "Berlin")) + "Second edition, 3, LNCS, 42(7), pp. 10--20. Springer, Berlin")) (define (proceedings-location #:editor [editor_ #f] @@ -562,7 +611,7 @@ (concatenate-elements #:separator ", " (and editor_ (editor editor_)) - @italic{@elem{Proc. @to-string[location]}} + (and location @italic{@elem{Proc. @contentify[location]}}) (series-volume-number-pages-element series volume number pages))) #:separator ". " (organization-publisher-address-element organization publisher address))) @@ -573,7 +622,7 @@ #:number [number #f] #:pages [pages #f]) (concatenate-elements - @italic{@to-string[location]} + (and location @italic{@contentify[location]}) #:separator " " (series-volume-number-pages-element #f volume number pages))) @@ -582,7 +631,7 @@ (concatenate-elements (and url ((url-rendering) url)) #:separator " " - (and accessed @elem{(accessed @to-string[accessed])}))) + (and accessed @elem{(accessed @contentify[accessed])}))) (define (string-capitalize str) (if (non-empty-string? str) @@ -611,7 +660,7 @@ (concatenate-elements #:separator ", " (edition-element edition) - (to-string* chapter) + (contentify chapter) (and editor_ (editor editor_)) (series-volume-number-pages-element series volume number pages)) #:separator ". " @@ -621,12 +670,12 @@ #:howpublished [howpublished #f] #:address [address #f]) (concatenate-elements #:separator ". " - (to-string* howpublished) - (to-string* address))) + (contentify howpublished) + (contentify address))) (define (misc-location #:howpublished [howpublished #f]) - (and howpublished (elem (to-string howpublished)))) + (and howpublished (elem (contentify howpublished)))) (define (manual-location #:organization [organization #f] @@ -634,7 +683,7 @@ (concatenate-elements (edition-element edition) #:separator ", " - (to-string* organization))) + (contentify organization))) (define (techrpt-location #:institution institution @@ -642,7 +691,7 @@ #:number [number #f] #:address [address #f]) (concatenate-elements #:separator ", " - (to-string* institution) (to-string* type) (to-string* number) (to-string* address))) + (contentify institution) (contentify type) (contentify number) (contentify address))) (define (dissertation-location #:institution institution @@ -650,10 +699,10 @@ #:type [type #f] #:address [address #f]) (concatenate-elements #:separator ", " - @elem{@to-string[degree] dissertation} - (to-string institution) - (to-string* type) - (to-string* address))) + @elem{@contentify[degree] dissertation} + (contentify institution) + (contentify type) + (contentify address))) (define (book-chapter-location location @@ -667,7 +716,7 @@ #:publisher [publisher #f] #:address [address #f]) (concatenate-elements #:separator " " - @elem{In @italic{@elem{@to-string[location]}}} + (and location @elem{In @italic{@elem{@contentify[location]}}}) (book-location #:edition edition #:chapter chapter #:editor editor_ #:series series #:volume volume #:number number #:pages pages #:publisher publisher #:address address))) @@ -675,21 +724,25 @@ ;; ---------------------------------------- (define (author-name first last #:suffix [suffix #f]) + (define first* (contentify first)) + (define last* (contentify last)) + (define suffix* (contentify suffix)) + + ;; Plain-text projections are needed for sorting. + (define first-string (stringify first)) + (define last-string (stringify last)) + (define suffix-string (stringify suffix)) (make-author-element #f - (list - (format "~a ~a~a" - (if (abbreviate-given-names) - (given-names->initials first) - first) - last - (if suffix - (format " ~a" suffix) - ""))) - (format "~a ~a~a" last first (if suffix - (format " ~a" suffix) - "")) - last)) + (concatenate-elements #:separator " " + (if (abbreviate-given-names) + (given-names->initials first-string) + first*) + last* + suffix*) + (format "~a ~a~a" last-string first-string + (if suffix-string (format " ~a" suffix-string) "")) + last*)) (define (org-author-name org) (make-author-element @@ -749,25 +802,24 @@ (author-element-names name) (author-element-cite name)))) -(define (to-string v) (format "~a" v)) -(define (to-string* v) (and v (to-string v))) (define (edition-element edition) - (and edition @elem{@(string-capitalize (to-string edition)) edition})) + (and edition + @elem{@(string-capitalize (stringify edition)) edition})) (define (pages-element pages) - (and pages @elem{pp. @(to-string (car pages))--@(to-string (cadr pages))})) + (and pages @elem{pp. @(contentify (car pages))--@(contentify (cadr pages))})) (define (series-volume-number-pages-element series volume number pages) (concatenate-elements - (to-string* series) + (contentify series) #:separator ", " (concatenate-elements - (to-string* volume) - (and number @elem{(@to-string[number])})) + (contentify volume) + (and number @elem{(@contentify[number])})) (pages-element pages))) (define (organization-publisher-address-element organization publisher address) (concatenate-elements - (to-string* organization) + (contentify organization) #:separator ". " (concatenate-elements - (to-string* publisher) + (contentify publisher) #:separator ", " - (to-string* address)))) + (contentify address)))) diff --git a/scribble-lib/scriblib/autobib.tex b/scribble-lib/scriblib/autobib.tex index 8e95ce9711..9d692141cd 100644 --- a/scribble-lib/scriblib/autobib.tex +++ b/scribble-lib/scriblib/autobib.tex @@ -1,15 +1,62 @@ +\usepackage{needspace} -\newenvironment{AutoBibliography}{\begin{small}}{\end{small}} -\newcommand{\Autobibentry}[1]{\hspace{0.05\linewidth}\parbox[t]{0.95\linewidth}{\parindent=-0.05\linewidth#1\vspace{1.0ex}}} -\newcommand{\Autobibtarget}[1]{\phantomsection#1} +\newenvironment{AutoBibliography} + {\begin{small}} + {\end{small}} -\usepackage{calc} -\newlength{\ABcollength} -\newcommand{\Autocolbibnumber}[1]{\parbox[t]{5ex}{\hfill#1~~\vspace{1.0ex}}} -\newcommand{\Autocolbibentry}[1]{\setlength{\ABcollength}{\linewidth-5ex}\parbox[t]{\ABcollength}{#1\vspace{1.0ex}}} +% Minimum number of lines that must remain before starting an entry. +\newcount\AutobibNeedlines +\AutobibNeedlines=5 -\newcommand{\Autobibref}[1]{#1} +% Hanging indentation of ordinary bibliography entries. +\newlength{\ABindent} +\setlength{\ABindent}{0.05\linewidth} + +% Additional indentation of subsequent paragraph first lines. +\newlength{\AutobibParindent} +\setlength{\AutobibParindent}{1.5em} + +% Width reserved for the number in a numbered bibliography. +\newlength{\AutobibNumberWidth} +\setlength{\AutobibNumberWidth}{5ex} +\newcommand{\Autobibentry}[1]{% + \par + \Needspace{\AutobibNeedlines\baselineskip}% + \begingroup + \emergencystretch=2em + \tolerance=1000 + \leftskip=\ABindent + \parindent=\AutobibParindent + \noindent + \hspace*{-\ABindent}% + #1% + \par + \endgroup + \addvspace{1.0ex}% +} + +\newcommand{\Autobibtarget}[1]{\phantomsection#1} +\newcommand{\Autocolbibnumber}[1]{% + \par + \Needspace{\AutobibNeedlines\baselineskip}% + \begingroup + \emergencystretch=2em + \tolerance=1000 + \leftskip=\AutobibNumberWidth + \parindent=\AutobibParindent + \noindent + \hspace*{-\AutobibNumberWidth}% + \makebox[\AutobibNumberWidth][r]{#1~~}% + \ignorespaces +} +\newcommand{\Autocolbibentry}[1]{% + #1% + \par + \endgroup + \addvspace{1.0ex}% +} +\newcommand{\Autobibref}[1]{#1} \providecommand{\AutobibLink}[1]{#1} \newcommand{\pseudodoi}[1]{#1} diff --git a/scribble-lib/scriblib/bibtex.rkt b/scribble-lib/scriblib/bibtex.rkt index 7bedc96f69..9d44217bdf 100644 --- a/scribble-lib/scriblib/bibtex.rkt +++ b/scribble-lib/scriblib/bibtex.rkt @@ -540,7 +540,7 @@ #:title (support-escapes (raw-attr "title")) #:date (raw-attr "year") ;; TODO: optional month #:location (proceedings-location - (raw-attr "booktitle") + (raw-attr* "booktitle") ;; optional: #:editor (parse-author (raw-attr "editor")) #:series (raw-attr "series") @@ -680,7 +680,7 @@ #:date (raw-attr "year") ;; TODO: optional month ;; optional: #:location (proceedings-location - (raw-attr "booktitle") + (raw-attr* "booktitle") ;; optional: #:editor (parse-author (raw-attr "editor")) #:volume (raw-attr "volume") ;; volume OR number