|
4 | 4 | net/uri-codec |
5 | 5 | net/url |
6 | 6 | racket/string |
7 | | - setup/dirs) |
8 | | -(provide perform-search send-main-page) |
| 7 | + setup/dirs |
| 8 | + racket/contract |
| 9 | + racket/list) |
| 10 | + |
| 11 | +(provide |
| 12 | + (contract-out |
| 13 | + [perform-search |
| 14 | + (->* (any/c) |
| 15 | + (any/c #:query-table (hash/c symbol? string? #:immutable #t)) |
| 16 | + void?)] |
| 17 | + [send-main-page |
| 18 | + (->* () |
| 19 | + (#:sub string? |
| 20 | + #:fragment (or/c string? #f) |
| 21 | + #:query (or/c string? #f) |
| 22 | + #:notify (-> (or/c string? path?) any) |
| 23 | + #:query-table (hash/c symbol? string? #:immutable #t)) |
| 24 | + void?)])) |
9 | 25 |
|
10 | 26 | (define search-dir "search/") |
11 | 27 |
|
|
14 | 30 |
|
15 | 31 | (define (send-main-page #:sub [sub "index.html"] |
16 | 32 | #:fragment [fragment #f] #:query [query #f] |
17 | | - #:notify [notify void]) |
| 33 | + #:notify [notify void] |
| 34 | + #:query-table [query-table (hash)]) |
| 35 | + (define query-table-list-of-pairs |
| 36 | + (for/list ([k (in-list (sort (hash-keys query-table) symbol<?))]) |
| 37 | + (cons k (hash-ref query-table k)))) |
18 | 38 | (define open-url (get-doc-open-url)) |
19 | 39 | (cond |
20 | 40 | [open-url |
|
35 | 55 | (url-query |
36 | 56 | (string->url |
37 | 57 | (format "q?~a" query))) |
38 | | - null))])))] |
| 58 | + null) |
| 59 | + query-table-list-of-pairs)])))] |
39 | 60 | [else |
40 | 61 | (define path (or (for/or ([dir (in-list (get-doc-search-dirs))]) |
41 | 62 | (define path (build-path dir sub)) |
|
44 | 65 | ;; Doesn't exist, but notify and then fall back below: |
45 | 66 | (build-path (find-doc-dir) sub))) |
46 | 67 | (notify path) |
| 68 | + (define parsed-query-table |
| 69 | + (if (null? query-table-list-of-pairs) |
| 70 | + #f |
| 71 | + (substring (url->string (url #f #f #f #f #f (list) query-table-list-of-pairs #f)) |
| 72 | + 1))) |
| 73 | + (define combined-query |
| 74 | + (cond |
| 75 | + [(and query parsed-query-table) |
| 76 | + (string-append query "&" parsed-query-table)] |
| 77 | + [else |
| 78 | + (or query parsed-query-table)])) |
47 | 79 | (cond |
48 | | - [(file-exists? path) (send-url/file path #:fragment fragment #:query query)] |
| 80 | + [(file-exists? path) (send-url/file path #:fragment fragment #:query combined-query)] |
49 | 81 | [else |
50 | 82 | (define (part pfx x) |
51 | 83 | (if x (string-append pfx x) "")) |
52 | 84 | (send-url |
53 | | - (string-append "https://docs.racket-lang.org/" sub (part "#" fragment) (part "?" query)))])])) |
| 85 | + (string-append "https://docs.racket-lang.org/" sub |
| 86 | + (part "#" fragment) |
| 87 | + (part "?" combined-query)))])])) |
54 | 88 |
|
55 | 89 | ;; This is an example of changing this code to use the online manuals. |
56 | 90 | ;; Normally, it's better to set `doc-open-url` in "etc/config.rktd", |
|
67 | 101 | ;; "http://download.racket-lang.org/docs/" (version) "/html/" |
68 | 102 | ;; sub (part "#" fragment) (part "?" query)))) |
69 | 103 |
|
70 | | -(define (perform-search str [context #f]) |
| 104 | +(define (perform-search str [context #f] |
| 105 | + #:query-table [query-table (hash)]) |
71 | 106 | ;; `context' can be a pre-filter query string to use for a context, |
72 | 107 | ;; optionally a list of one and a label to display for that context. |
73 | 108 | ;; In any case, when a context is specified, the search actually |
|
85 | 120 | (format "&label=~a" (uri-encode label)) |
86 | 121 | "")) |
87 | 122 | query)]) |
88 | | - (send-main-page #:sub (string-append search-dir page) #:query query))) |
| 123 | + (send-main-page #:sub (string-append search-dir page) #:query query |
| 124 | + #:query-table query-table))) |
0 commit comments