/
citations.rkt
64 lines (50 loc) 路 2.14 KB
/
citations.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#lang racket
(require txexpr
pollen/decode
"tooltips.rkt")
(provide (all-defined-out))
;; The tag functions used in Pollen sources
;; Insert a citation: actually just leaves behind an empty marker in the doc for later processing
;; by `citations-root-handler`
(define (cite key)
`(cite [[ref ,(format "~a" key)]]))
;; Define a citation
(define (define-citation key . elems)
`(cite-def [[ref ,(format "~a" key)]] ,@elems))
;; Insert the bibliography: All sources cited in this chapter
(define (insert-bibliography)
`(bib))
(define (make-bibliography ctable)
; Get a list of the keys, ensure it is sorted alphabetically
; I had originally converted them to strings before sorting.
; But, turns out Racket has a function I can use with symbols directly
(define keys-srt (sort (hash-keys ctable) string<?))
(define list-items
(for/list ([item (in-list keys-srt)])
`(li ,@(hash-ref ctable item))))
`(@ (h3 "Bibliography") (ol ,@list-items)))
;; Called from `root` in pollen.rkt -- see that function for more context
(define (citations-root-handler doc)
;; Local helper function: returns #true if a tag is a citation definition
(define (is-citedef? tx)
(and (txexpr? tx)
(equal? (get-tag tx) 'cite-def)))
;; Split the citation definitions out of the main doc
(define-values (boiled-tx citedefs) (splitf-txexpr doc is-citedef?))
;; Build a hash table out of the list of cite-def txexprs
(define cite-table
(for/hash ([c (in-list citedefs)])
(values (attr-ref c 'ref) (get-elements c))))
;; Local helper function: if a txexpr is a citation, replace it with a tooltip; if it鈥檚 a
;; bibliography tag, replace it with the bibliography
(define (replace-cites tx)
(cond
[(equal? 'bib (get-tag tx))
(make-bibliography cite-table)]
[(equal? 'cite (get-tag tx))
(apply tooltip (hash-ref cite-table
(attr-ref tx 'ref)
(list (format "No def for ~a" (attr-ref tx 'ref)))))]
[else tx]))
;; Run the doc through decode, applying replace-cites to every txexpr
(decode boiled-tx #:txexpr-proc replace-cites))