|
7 | 7 | racket/dict |
8 | 8 | setup/collects |
9 | 9 | racket/string |
10 | | - scribble/xref) |
| 10 | + scribble/xref |
| 11 | + net/url-string |
| 12 | + racket/format) |
11 | 13 |
|
12 | 14 | (define the-bluebox-cache (make-blueboxes-cache #t)) |
13 | 15 | (define pkg-cache (make-hash)) |
|
54 | 56 | [else (list strs #f)])] |
55 | 57 | [else (list #f #f)])) |
56 | 58 |
|
| 59 | +;; Examples: |
| 60 | +;; Input: "file:///C:/Program Files/Racket/doc/reference/module.html#(form._((quote._~23~25kernel)._module))" #f |
| 61 | +;; Output: https://docs.racket-lang.org/reference/module.html#%28form._%28%28quote._%7E23%7E25kernel%29._module%29%29 |
| 62 | +;; (i.e. https://docs.racket-lang.org/ + left trimmed `url`) |
| 63 | +;; Input: "pairs.html#(def._((lib._racket/list..rkt)._add-between))" "C:/Program Files/Racket/doc/reference/strings.html" |
| 64 | +;; Output: https://docs.racket-lang.org/reference/pairs.html#%28def._%28%28lib._racket%2Flist..rkt%29._add-between%29%29 |
| 65 | +;; (i.e. https://docs.racket-lang.org/ + /reference/ from `docs-path` + `url`) |
| 66 | +(define (make-proper-url-for-online-documentation url [docs-path #f]) |
| 67 | + (define online-docs-url "https://docs.racket-lang.org/") |
| 68 | + (define (absolute-web-url? url) (and (string-contains? url "://") (not (string-prefix? url "file")))) |
| 69 | + (define (get-relative-docs-url url) ;; e.g. "reference/module.html#(form._((quote._~23~25kernel)._module))" |
| 70 | + (last (string-split url #rx"/doc/(racket/)?"))) ; "(racket/)?" in case docs are installed in 'usr/share/doc/racket' on linux |
| 71 | + (define (strip-off-last-path-segment url) (string-join (drop-right (string-split url "/") 1) "/" #:after-last "/")) |
| 72 | + (define (encode-url url-string) |
| 73 | + (define url-struct (string->url url-string)) |
| 74 | + ;; particularly encode chars '(', ')' and '~' from Markdown. Both VSCode's and Atom's Md parsers don't like them in links. |
| 75 | + (current-url-encode-mode 'unreserved) |
| 76 | + (define encoded-url (string-replace (url->string url-struct) "~" "%7E")) |
| 77 | + ;; Rarely, there are `redirecting` links that require putting `&` back in query to work properly |
| 78 | + (string-replace encoded-url "&" "&")) |
| 79 | + |
| 80 | + (define encoded-url (encode-url url)) |
| 81 | + (cond |
| 82 | + [(absolute-web-url? encoded-url) encoded-url] |
| 83 | + [docs-path |
| 84 | + (define ending (get-relative-docs-url docs-path)) |
| 85 | + (~a online-docs-url |
| 86 | + (if (or (string-prefix? encoded-url "#") (zero? (string-length encoded-url))) |
| 87 | + ending |
| 88 | + (strip-off-last-path-segment ending)) |
| 89 | + encoded-url)] |
| 90 | + [else (~a online-docs-url (get-relative-docs-url encoded-url))])) |
| 91 | + |
| 92 | +;; Example: '(def ((quote #%kernel) hasheq)) => "(def._((quote._~23~25kernel)._hasheq))" |
| 93 | +;; mostly a copy of a closed function `anchor-name` in `scribble-lib/scribble/html-render.rkt` |
| 94 | +(define (def-tag->html-anchor-tag v) |
| 95 | + (define (encode-byte b) (string-append (if (< b 16) "~0" "~") (number->string b 16))) |
| 96 | + (define (encode-bytes str) (string->bytes/utf-8 (encode-byte (bytes-ref str 0)))) |
| 97 | + (let* ([v (string->bytes/utf-8 (format "~a" v))] |
| 98 | + [v (regexp-replace* #rx#"[A-Z.]" v #".&")] |
| 99 | + [v (regexp-replace* #rx#" " v #"._")] |
| 100 | + [v (regexp-replace* #rx#"\"" v #".'")] |
| 101 | + [v (regexp-replace* #rx#"[^-a-zA-Z0-9_!+*'()/.,]" v encode-bytes)]) |
| 102 | + (bytes->string/utf-8 v))) |
| 103 | + |
57 | 104 |
|
58 | 105 | (provide find-containing-paren |
59 | 106 | get-docs-for-tag |
60 | | - id-to-tag) |
| 107 | + id-to-tag |
| 108 | + make-proper-url-for-online-documentation |
| 109 | + def-tag->html-anchor-tag) |
0 commit comments