diff --git a/beautiful-racket-lib/br/indent.rkt b/beautiful-racket-lib/br/indent.rkt index 518cd2d..7f6ae29 100644 --- a/beautiful-racket-lib/br/indent.rkt +++ b/beautiful-racket-lib/br/indent.rkt @@ -1,5 +1,5 @@ #lang racket/base -(require racket/class) +(require racket/class racket/gui/base racket/list) (provide (all-defined-out)) (module+ test @@ -10,7 +10,7 @@ (define indent-width 2) (define (char text pos) - (send text get-character pos)) + (and pos (send text get-character pos))) (module+ test (check-equal? (char t 0) #\f) @@ -29,6 +29,19 @@ (check-equal? (line t 10) 2) (check-equal? (line t 11) 2)) +(define (line-chars text line) + (and + (valid-line? text line) + (for/list ([pos (in-range (line-start text line) (add1 (line-end text line)))]) + (char text pos)))) + +(module+ test + (check-equal? (line-chars t 0) '(#\f #\o #\o #\newline)) + (check-equal? (line-chars t 1) '(#\space #\a #\r #\newline)) + (check-equal? (line-chars t 2) '(#\space #\space #\m #\nul)) + (check-equal? (line-chars t 3) #f)) + + (define (previous-line text pos) (define this-line (line text pos)) (and (this-line . > . 0) (sub1 this-line))) @@ -126,4 +139,25 @@ (check-equal? (count-char t #\f) 1) (check-equal? (count-char t #\o) 2) (check-equal? (count-char t #\o 0 1) 1) - (check-equal? (count-char t #\newline) 2)) \ No newline at end of file + (check-equal? (count-char t #\newline) 2)) + + +(define (str->text str) + (define t (new text%)) + (send t insert-port (open-input-string str)) + t) + +(define (map-indenter indenter t) + (for/list ([line-idx (in-range (add1 (send t last-line)))]) + (indenter t (line-start t line-idx)))) + +(define (test-indenter indenter t-or-str) + (define t (if (string? t-or-str) (str->text t-or-str) t-or-str)) + (list->string + (append* + (for/list ([line-idx (in-range (add1 (send t last-line)))] + [indent (in-list (map-indenter indenter t))]) + ;; simulate DrR indentation + ;; by dropping leading spaces and applying new indent. + (append (make-list (or indent 0) #\space) + (dropf (line-chars t line-idx) (λ(x) (x . char=? . #\space)))))))) \ No newline at end of file diff --git a/beautiful-racket/br/demo/jsonic/indenter.rkt b/beautiful-racket/br/demo/jsonic/indenter.rkt index 4a045b1..daa56d0 100644 --- a/beautiful-racket/br/demo/jsonic/indenter.rkt +++ b/beautiful-racket/br/demo/jsonic/indenter.rkt @@ -1,9 +1,9 @@ -#lang br -(require br/indent) +#lang at-exp br +(require br/indent sugar/debug) (provide indenter) (define indent-width 2) -(define (indenter text this-pos) +(define (indenter text [this-pos 0]) ;; if line begins with }: ;; outdent to the matching { ;; indent to match the previous line @@ -14,7 +14,7 @@ (count-char text #\} 0 this-line-end))) (and (positive? open-braces) (* indent-width - (if ((char text (line-start text this-line)) . char=? . #\{) + (if ((char text (line-start-visible text this-line)) . char=? . #\{) (sub1 open-braces) open-braces)))) @@ -27,4 +27,24 @@ [((char text (line-start text prev-line)) . char=? . #\{) (+ (or prev-indent 0) indent-width)] [else prev-indent])) -|# \ No newline at end of file +|# + +(module+ test + (require rackunit) + (define test-str @string-append|{ +#lang br/demo/jsonic +{ +"string": @$(string-append "foo" "bar")$@, +{ +"array": @$(range 5)$@, +"object": @$(hash "k1" "valstring" (format "~a" 42) (hash "k1" (range 10) "k2" 42))$@ +} +// "bar" : +}}|) + (displayln test-str) + (define indented-str (test-indenter indenter test-str)) + (displayln indented-str) + (define indented-str2 (test-indenter indenter indented-str)) + (displayln indented-str2) + (define indented-str3 (test-indenter indenter indented-str2)) + (displayln indented-str3)) \ No newline at end of file