|
| 1 | +#lang racket |
| 2 | +(provide (all-defined-out)) |
| 3 | + |
| 4 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 5 | +;;;;; Principal data structure for describing pretty-printed things |
| 6 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 7 | + |
| 8 | +(struct str (s) #:transparent) |
| 9 | +(struct nil () #:transparent) |
| 10 | +(struct nl () #:transparent) |
| 11 | +(struct indent (s) #:transparent) |
| 12 | +(struct ++ (s1 s2) #:transparent) |
| 13 | + |
| 14 | +; Efficiently converting that data structure into a string, avoiding the |
| 15 | +; n^2 append when dealing with left-nested appends |
| 16 | +(define (flatten col ss) |
| 17 | + (match ss |
| 18 | + ['() ""] |
| 19 | + [(cons (cons (indent s) i) rest) (flatten col `((,s . ,col) ,@rest))] |
| 20 | + [(cons (cons (nil) i) rest) (flatten col rest)] |
| 21 | + [(cons (cons (str s) i) rest) (string-append s |
| 22 | + (flatten (+ (string-length s) i) rest))] |
| 23 | + [(cons (cons (++ s1 s2) i) rest) (flatten col `(,(cons s1 i) |
| 24 | + ,(cons s2 i) |
| 25 | + ,@rest))] |
| 26 | + [(cons (cons (nl) i) rest) (string-append |
| 27 | + "\n" |
| 28 | + (make-string i #\ ) |
| 29 | + (flatten i rest))])) |
| 30 | + |
| 31 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 32 | +;;;;; Pretty-printing API |
| 33 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 34 | + |
| 35 | +; Top-level pretty-print, |
| 36 | +(define (seq->string seq) |
| 37 | + (flatten 0 (list (cons seq 0)))) |
| 38 | + |
| 39 | +;;;;; Appending Things |
| 40 | + |
| 41 | +; Append two things with a space in between |
| 42 | +(define (+++ s1 s2) |
| 43 | + (++ s1 (++ ss s2))) |
| 44 | + |
| 45 | +; Append two things with an arrow in between |
| 46 | +(define (+-> s1 s2) |
| 47 | + (+++ s1 (+++ (str "->") s2))) |
| 48 | + |
| 49 | +; Append two things with an equals in between |
| 50 | +(define (+= s1 s2) |
| 51 | + (+++ s1 (+++ (str "=") s2))) |
| 52 | + |
| 53 | +;;;;; List of sequences |
| 54 | +;;;;; * no separation |
| 55 | +;;;;; * space separated |
| 56 | +;;;;; * Comma separated |
| 57 | +;;;;; * semi-colon separated |
| 58 | + |
| 59 | +(define (lst seqs sep) |
| 60 | + (match seqs |
| 61 | + ['() (nil)] |
| 62 | + [(cons s '()) s] |
| 63 | + [(cons s ss) (++ s (++ sep (lst ss sep)))])) |
| 64 | + |
| 65 | +(define (no-sep seqs) |
| 66 | + (lst seqs (nil))) |
| 67 | + |
| 68 | +(define (sp-sep seqs) |
| 69 | + (lst seqs ss)) |
| 70 | + |
| 71 | +(define (comma-sep seqs) |
| 72 | + (lst seqs com)) |
| 73 | + |
| 74 | +(define (semi-sep seqs) |
| 75 | + (lst seqs sem)) |
| 76 | + |
| 77 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 78 | +;;;;; Enclosing things |
| 79 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 80 | + |
| 81 | +; Enclose a sequence with the given open and close sequences |
| 82 | +(define (enc open close seq) |
| 83 | + (+++ open (+++ seq close))) |
| 84 | + |
| 85 | +; Enclose the given sequence with curly braces |
| 86 | +(define (curly seq) |
| 87 | + (enc (str "{") (str "}") seq)) |
| 88 | + |
| 89 | +; Enclose the given sequence with square braces |
| 90 | +(define (sqr seq) |
| 91 | + (enc (str "[") (str "]") seq)) |
| 92 | + |
| 93 | +; Enclose the given sequence with parentheses |
| 94 | +(define (par seq) |
| 95 | + (enc (str "(") (str ")") seq)) |
| 96 | + |
| 97 | +;; Same as above but with an indented sequence |
| 98 | + |
| 99 | +; This is ugly: TODO: Think of a better way |
| 100 | +(define (enc-ind open close seq) |
| 101 | + (++ open (++ (nl) |
| 102 | + (++ (space 2) |
| 103 | + (++ (indent seq) |
| 104 | + (++ (nl) close)))))) |
| 105 | + |
| 106 | +; Enclose and indent with curly braces |
| 107 | +(define (curl-ind seq) |
| 108 | + (enc-ind (str "{") (str "}") seq)) |
| 109 | + |
| 110 | +; Enclose and indent with square braces |
| 111 | +(define (sqr-ind seq) |
| 112 | + (enc-ind (str "[") (str "]") seq)) |
| 113 | + |
| 114 | +; Enclose and indent with parantheses |
| 115 | +(define (par-ind seq) |
| 116 | + (enc-ind (str "(") (str ")") seq)) |
| 117 | + |
| 118 | + |
| 119 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 120 | +;;;;; End line with various things |
| 121 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 122 | + |
| 123 | +(define (end-semi seq) |
| 124 | + (++ seq (++ sem (nl)))) |
| 125 | + |
| 126 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 127 | +;;;;; Miscelanious Characters or Symbols |
| 128 | +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 129 | + |
| 130 | +; A set number of spaces |
| 131 | +(define (space i) |
| 132 | + (str (make-string i #\ ))) |
| 133 | + |
| 134 | +; A single space |
| 135 | +(define ss (str " ")) ; single space |
| 136 | + |
| 137 | +;;; Comma, semi-colons, and colons |
| 138 | +(define com (str ",")) |
| 139 | +(define sem (str ";")) |
| 140 | +(define col (str ":")) |
0 commit comments