diff --git a/beautiful-racket-lib/br/indent.rkt b/beautiful-racket-lib/br/indent.rkt index 373acc9..54ae9a4 100644 --- a/beautiful-racket-lib/br/indent.rkt +++ b/beautiful-racket-lib/br/indent.rkt @@ -2,7 +2,8 @@ (require racket/class racket/gui/base racket/list - racket/string) + racket/string + racket/contract) (provide (all-defined-out)) (module+ test @@ -14,7 +15,8 @@ (define indent-width 2) -(define (char text pos) +(define/contract (char text pos) + ((is-a?/c text%) exact-nonnegative-integer? . -> . char?) (and pos (send text get-character pos))) (module+ test @@ -24,7 +26,8 @@ (check-equal? (char t 10) #\m) (check-equal? (char t 11) #\nul)) -(define (line text pos) +(define/contract (line text pos) + ((is-a?/c text%) exact-nonnegative-integer? . -> . exact-nonnegative-integer?) (send text position-line pos)) (module+ test @@ -34,7 +37,8 @@ (check-equal? (line t 10) 2) (check-equal? (line t 11) 2)) -(define (line-chars text line) +(define/contract (line-chars text line) + ((is-a?/c text%) exact-nonnegative-integer? . -> . (or/c (listof char?) #f)) (and (valid-line? text line) (for/list ([pos (in-range (line-start text line) (add1 (line-end text line)))]) @@ -47,7 +51,8 @@ (check-equal? (line-chars t 3) #f)) -(define (previous-line text pos) +(define/contract (previous-line text pos) + ((is-a?/c text%) exact-nonnegative-integer? . -> . (or/c exact-nonnegative-integer? #f)) (define this-line (line text pos)) (and (this-line . > . 0) (sub1 this-line))) @@ -58,7 +63,8 @@ (check-equal? (previous-line t 10) 1) (check-equal? (previous-line t 11) 1)) -(define (next-line text pos) +(define/contract (next-line text pos) + ((is-a?/c text%) exact-nonnegative-integer? . -> . (or/c exact-nonnegative-integer? #f)) (define last (send text last-line)) (define this-line (line text pos)) (and (this-line . < . last) (add1 this-line))) @@ -70,10 +76,12 @@ (check-equal? (next-line t 10) #f) (check-equal? (next-line t 11) #f)) -(define (valid-line? text line) +(define/contract (valid-line? text line) + ((is-a?/c text%) exact-nonnegative-integer? . -> . boolean?) (and line (<= 0 line (send text last-line)))) -(define (line-start text line) +(define/contract (line-start text line) + ((is-a?/c text%) exact-nonnegative-integer? . -> . (or/c exact-nonnegative-integer? #f)) (and (valid-line? text line) (send text line-start-position line))) @@ -83,7 +91,8 @@ (check-equal? (line-start t 2) 8) (check-equal? (line-start t 3) #f)) -(define (line-end text line) +(define/contract (line-end text line) + ((is-a?/c text%) exact-nonnegative-integer? . -> . (or/c exact-nonnegative-integer? #f)) (and (valid-line? text line) (send text line-end-position line))) @@ -100,7 +109,8 @@ #:when (not (char-blank? c))) pos)) -(define (line-start-visible text line) +(define/contract (line-start-visible text line) + ((is-a?/c text%) exact-nonnegative-integer? . -> . (or/c exact-nonnegative-integer? #f)) (define start (line-start text line)) (define end (line-end text line)) (and start end (first-visible-char-pos text start end))) @@ -111,7 +121,8 @@ (check-equal? (line-start-visible t 2) 10) (check-equal? (line-start-visible t 3) #f)) -(define (line-end-visible text line) +(define/contract (line-end-visible text line) + ((is-a?/c text%) exact-nonnegative-integer? . -> . (or/c exact-nonnegative-integer? #f)) (define start+1 (line-end text line)) ; start before newline (define end+1 (line-start text line)) (and start+1 end+1 (first-visible-char-pos text (sub1 start+1) (sub1 end+1)))) @@ -122,7 +133,8 @@ (check-equal? (line-end-visible t 2) 10) (check-equal? (line-end-visible t 3) #f)) -(define (line-indent text line) +(define/contract (line-indent text line) + ((is-a?/c text%) exact-nonnegative-integer? . -> . (or/c exact-nonnegative-integer? #f)) (and (valid-line? text line) (let ([lsv (line-start-visible text line)]) (and lsv ; could be #f @@ -152,9 +164,10 @@ (send t insert-port (open-input-string str)) t) -(define space-char? (λ(x) (x . char=? . #\space))) +(define (space-char? x) (char=? x #\space)) -(define (test-indenter indenter t-or-str) +(define/contract (apply-indenter indenter t-or-str) + (procedure? (or/c (is-a?/c text%) string?) . -> . string?) (define t (if (string? t-or-str) (str->text t-or-str) t-or-str)) (define indented-t (for/fold ([t-acc t]) @@ -171,9 +184,10 @@ t-acc)) (send indented-t get-text)) -(define (str->indents str) +(define/contract (string-indents str) + (string? . -> . (listof exact-nonnegative-integer?)) (for/list ([line (in-list (string-split str "\n"))]) (length (takef (string->list line) space-char?)))) (module+ test - (check-equal? (str->indents t-str) '(0 1 2))) \ No newline at end of file + (check-equal? (string-indents t-str) '(0 1 2))) \ No newline at end of file diff --git a/beautiful-racket/br/demo/jsonic-2/indenter.rkt b/beautiful-racket/br/demo/jsonic-2/indenter.rkt index f64542d..38b75ed 100644 --- a/beautiful-racket/br/demo/jsonic-2/indenter.rkt +++ b/beautiful-racket/br/demo/jsonic-2/indenter.rkt @@ -1,28 +1,25 @@ -#lang at-exp br +#lang br (require br/indent) (provide indent-jsonic) (define indent-width 2) -(define (left-bracket? c) - (and c (or (char=? c #\{) (char=? c #\[)))) +(define (left-bracket? c) (member c '(#\{ #\[))) +(define (right-bracket? c) (member c '(#\} #\]))) -(define (right-bracket? c) - (and c (or (char=? c #\}) (char=? c #\])))) - -(define (indent-jsonic tb [this-pos 0]) - (define this-line (line tb this-pos)) - (define prev-line (previous-line tb this-pos)) - (define prev-indent (or (line-indent tb prev-line) 0)) +;; if this line begins with } or ], outdent. +;; if last line begins with { or [, indent. +;; otherwise use previous indent +(define (indent-jsonic textbox [pos 0]) + (define this-line (line textbox pos)) + (define prev-line (previous-line textbox pos)) + (define prev-indent (or (line-indent textbox prev-line) 0)) (define this-indent (cond - ;; if this line begins with }, outdent. - [(right-bracket? (char tb (line-start-visible tb this-line))) - (- prev-indent indent-width)] - ;; if last line begins with {, indent. - [(left-bracket? (char tb (line-start-visible tb prev-line))) + [(left-bracket? (char textbox (line-start-visible textbox prev-line))) (+ prev-indent indent-width)] - ;; otherwise use previous indent + [(right-bracket? (char textbox (line-start-visible textbox this-line))) + (- prev-indent indent-width)] [else prev-indent])) (and (exact-positive-integer? this-indent) this-indent)) @@ -40,5 +37,5 @@ } here ) - (check-equal? (str->indents (test-indenter indent-jsonic test-str)) + (check-equal? (string-indents (apply-indenter indent-jsonic test-str)) (map (λ(x) (* x indent-width)) '(0 0 1 1 2 2 1 1 0))))