
necessary modules are now "all.rkt"s; "shard.rkt"s turn to "resources.rkt". Also, "navbar.rkt" changes to "all.rkt", since it was doing the same thing (in addition to setting the navbar).
157 lines
6.0 KiB
Racket
157 lines
6.0 KiB
Racket
#lang meta/web
|
|
|
|
(require "resources.rkt")
|
|
|
|
;; bib values are hash tables mapping field names (symbols) to strings.
|
|
;; Keywords can also be used for the field names, which makes them meta-fields
|
|
;; that are not included in the usual bib printout. Two of them are required:
|
|
;; - #:type the type of the entry (a symbol: 'article, 'techreport, etc)
|
|
;; - #:key the label for the entry
|
|
|
|
(define bib-fields
|
|
'(author editor title booktitle journal
|
|
edition volume number series
|
|
chapter pages
|
|
type
|
|
school institution organization
|
|
publisher howpublished
|
|
address
|
|
month year
|
|
key
|
|
crossref
|
|
url
|
|
note
|
|
eprint))
|
|
|
|
(define meta-field? keyword?)
|
|
|
|
(define key->number
|
|
(let ([t (for/hash ([k bib-fields] [i (in-naturals)]) (values k i))])
|
|
(lambda (key)
|
|
(hash-ref t key (lambda ()
|
|
(error 'key->number "unknown field name: ~e" key))))))
|
|
|
|
;; converts the hash to an alist with the order specified by bib-fields
|
|
(define (bib->alist bib)
|
|
(sort (filter-not (compose meta-field? car) (hash-map bib cons))
|
|
< #:key (compose key->number car) #:cache-keys? #t))
|
|
|
|
(define (display* . xs)
|
|
(for-each display xs))
|
|
|
|
(define (display-attr attr)
|
|
(let* ([prefix (format " ~a = {" (car attr))]
|
|
[sep (delay (string-append "\n" (make-string (string-length prefix)
|
|
#\space)))])
|
|
(display* prefix
|
|
(if (regexp-match? #rx"\n" (cdr attr))
|
|
(regexp-replace* #rx"\n" (cdr attr) (force sep))
|
|
(cdr attr))
|
|
"}")))
|
|
|
|
(provide display-bib)
|
|
(define (display-bib bib)
|
|
(display* "@" (hash-ref bib '#:type) "{" (hash-ref bib '#:key))
|
|
(for ([attr (bib->alist bib)]) (display* ",\n") (display-attr attr))
|
|
(display* "\n}\n"))
|
|
|
|
(provide with-braces without-braces)
|
|
(define (with-braces str) (regexp-replace* #px"\\b\\w+[A-Z]\\w*" str "{\\0}"))
|
|
(define (without-braces str) (regexp-replace* #rx"[{}]+" str ""))
|
|
|
|
(provide bib-author)
|
|
(define (bib-author bib)
|
|
(let ([authors (regexp-split #rx"[ \t\n]+and[ \t\n]+"
|
|
(hash-ref bib 'author))])
|
|
(case (length authors)
|
|
[(0) "???"]
|
|
[(1) (car authors)]
|
|
[(2) (apply format "~a and ~a" authors)]
|
|
[(3) (apply format "~a, ~a, and ~a" authors)]
|
|
[else (format "~a et al" (car authors))])))
|
|
|
|
;; ----------------------------------------------------------------------------
|
|
|
|
;; processes the (key val ...) alist to a hash of (key . val) by combining the
|
|
;; possibly multiple values for each key (each value becomes a line)
|
|
(provide bib)
|
|
(define (bib type key attrs)
|
|
(define t (make-hasheq))
|
|
(hash-set! t '#:type type)
|
|
(hash-set! t '#:key key)
|
|
(for ([a attrs])
|
|
(define (err) (error 'make-bib "bad attribute: ~e" a))
|
|
(unless (and (pair? a) (pair? (cdr a)) (list? (cdr a))) (err))
|
|
(let ([key (car a)])
|
|
(unless (hash-ref t key #f) ; previous keys take precedence
|
|
(cond [(symbol? key)
|
|
;; turn non-strings to strings, join multiple strings, normalize
|
|
;; spaces
|
|
(let* ([val (cdr a)]
|
|
[val (map (lambda (x) (if (string? x) x (format "~a" x)))
|
|
val)]
|
|
[val (string-append* (add-between val "\n"))]
|
|
[val (regexp-replace* #rx"\t" val " ")]
|
|
[val (regexp-replace* #rx" +" val " ")]
|
|
[val (regexp-replace #rx"^ +" val "")]
|
|
[val (regexp-replace #rx" +$" val "")]
|
|
[val (regexp-replace* #rx"(?: *\r?\n *)+" val "\n")])
|
|
(hash-set! t key val))]
|
|
[(and (meta-field? key) (null? (cddr a)))
|
|
(hash-set! t key (cadr a))]
|
|
[else (err)]))))
|
|
t)
|
|
|
|
;; ----------------------------------------------------------------------------
|
|
|
|
#|
|
|
In the future, it might be good to do some field verification, etc. From the
|
|
bibtext thing:
|
|
article: An article from a journal or magazine.
|
|
req: author, title, journal, year
|
|
opt: volume, number, pages, month, note
|
|
book: A book with an explicit publisher.
|
|
req: author or editor, title, publisher, year
|
|
opt: volume or number, series, address, edition, month, note
|
|
booklet: A work that is printed and bound, but without a named publisher or
|
|
sponsoring institution.
|
|
req: title
|
|
opt: author, howpublished, address, month, year, note
|
|
conference: The same as `inproceedings', included for Scribe compatibility.
|
|
inbook: A part of a book, which may be a chapter (or section or whatever)
|
|
and/or a range of pages.
|
|
req: author or editor, title, chapter and/or pages, publisher, year
|
|
opt: volume or number, series, type, address, edition, month, note
|
|
incollection: A part of a book having its own title.
|
|
req: author, title, booktitle, publisher, year
|
|
opt: editor, volume or number, series, type, chapter, pages, address,
|
|
edition, month, note
|
|
inproceedings: An article in a conference proceedings.
|
|
req: author, title, booktitle, year
|
|
opt: editor, volume or number, series, pages, address, month, organization,
|
|
publisher, note
|
|
manual: Technical documentation.
|
|
req: title
|
|
opt: author, organization, address, edition, month, year, note
|
|
mastersthesis: A Master's thesis.
|
|
req: author, title, school, year
|
|
opt: type, address, month, note
|
|
misc: Use this type when nothing else fits.
|
|
opt: author, title, howpublished, month, year, note
|
|
phdthesis: A PhD thesis.
|
|
req: author, title, school, year
|
|
opt: type, address, month, note
|
|
proceedings: The proceedings of a conference.
|
|
req: title, year
|
|
opt: editor, volume or number, series, address, month, organization,
|
|
publisher, note
|
|
techreport: A report published by a school or other institution, usually
|
|
numbered within a series.
|
|
req: author, title, institution, year
|
|
opt: type, number, address, month, note
|
|
unpublished: A document having an author and title, but not formally
|
|
published.
|
|
req: author, title, note
|
|
opt: month, year
|
|
|#
|