improve jsonic

dev-srcloc
Matthew Butterick 8 years ago
parent bb364013ce
commit b23b8ae957

@ -2,15 +2,19 @@
(require (for-syntax racket/base br/syntax) br/define) (require (for-syntax racket/base br/syntax) br/define)
(provide (except-out (all-defined-out) string->datum)) (provide (except-out (all-defined-out) string->datum))
(define (blank? str)
(or (zero? (string-length str))
(andmap char-blank? (string->list str))))
;; read "foo bar" the same way as "(foo bar)" ;; read "foo bar" the same way as "(foo bar)"
;; otherwise "bar" is dropped, which is too astonishing ;; otherwise "bar" is dropped, which is too astonishing
(define (string->datum str) (define (string->datum str)
(if (positive? (string-length str)) (if (blank? str)
(void)
(let ([result (read (open-input-string (format "(~a)" str)))]) (let ([result (read (open-input-string (format "(~a)" str)))])
(if (= (length result) 1) (if (= (length result) 1)
(car result) (car result)
result)) result))))
(void)))
(define (datum? x) (define (datum? x)
(or (list? x) (symbol? x))) (or (list? x) (symbol? x)))
@ -34,5 +38,7 @@
(check-equal? (format-datum '(~a-bar-~a) #'foo #'zam) '(foo-bar-zam)) (check-equal? (format-datum '(~a-bar-~a) #'foo #'zam) '(foo-bar-zam))
(check-equal? (format-datum (datum (~a-bar-~a)) "foo" "zam") '(foo-bar-zam)) (check-equal? (format-datum (datum (~a-bar-~a)) "foo" "zam") '(foo-bar-zam))
(check-equal? (format-datum '~a "foo") 'foo) (check-equal? (format-datum '~a "foo") 'foo)
(check-equal? (format-datum (datum ~a) "foo") 'foo) (check-equal? (format-datum '~a "foo") 'foo)
(check-equal? (format-datum '~a "") (void))
(check-equal? (format-datum '~a " ") (void))
(check-equal? (format-datums '(put ~a) '("foo" "zam")) '((put foo) (put zam)))) (check-equal? (format-datums '(put ~a) '("foo" "zam")) '((put foo) (put zam))))

@ -1,11 +1,16 @@
#lang racket/base #lang racket/base
(require racket/class racket/gui/base racket/list) (require racket/class
racket/gui/base
racket/list
racket/string)
(provide (all-defined-out)) (provide (all-defined-out))
(module+ test (module+ test
;; todo: fix this so it can be tested on travis
(require racket/gui/base rackunit) (require racket/gui/base rackunit)
(define t (new text%)) (define t (new text%))
(define result (send t insert-port (open-input-string "foo\n ar\n m")))) (define t-str "foo\n ar\n m")
(define result (send t insert-port (open-input-string t-str))))
(define indent-width 2) (define indent-width 2)
@ -147,17 +152,28 @@
(send t insert-port (open-input-string str)) (send t insert-port (open-input-string str))
t) t)
(define (map-indenter indenter t) (define space-char? (λ(x) (x . char=? . #\space)))
(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 (test-indenter indenter t-or-str)
(define t (if (string? t-or-str) (str->text t-or-str) t-or-str)) (define t (if (string? t-or-str) (str->text t-or-str) t-or-str))
(list->string (define indented-t
(append* (for/fold ([t-acc t])
(for/list ([line-idx (in-range (add1 (send t last-line)))] ([line-idx (in-range (add1 (send t last-line)))])
[indent (in-list (map-indenter indenter t))])
;; simulate DrR indentation ;; simulate DrR indentation
;; by dropping leading spaces and applying new indent. ;; by dropping leading spaces and applying new indent.
(append (make-list (or indent 0) #\space) (define line-start-pos (line-start t-acc line-idx))
(dropf (line-chars t line-idx) (λ(x) (x . char=? . #\space)))))))) (define new-indent (indenter t-acc line-start-pos))
(define new-line-str
(list->string (append (make-list (or new-indent 0) #\space)
(dropf (line-chars t-acc line-idx) space-char?))))
(send t-acc delete line-start-pos (add1 (line-end t-acc line-idx))) ; add1 to grab ending newline too
(send t-acc insert new-line-str line-start-pos)
t-acc))
(send indented-t get-text))
(define (str->indents str)
(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)))

@ -23,7 +23,8 @@
[(string? result) (format "~v" result)] [(string? result) (format "~v" result)]
[(list? result) (format "[~a]" (string-join (map stringify result) ", "))] [(list? result) (format "[~a]" (string-join (map stringify result) ", "))]
[(hash? result) (format "{~a}" (string-join (for/list ([(k v) (in-hash result)]) [(hash? result) (format "{~a}" (string-join (for/list ([(k v) (in-hash result)])
(format "~a: ~a" (stringify k) (stringify v))) ", "))])) (format "~a: ~a" (stringify k) (stringify v))) ", "))]
[else ""]))
(define-macro (s-val STR ...) (define-macro (s-val STR ...)
(define s-exp-string (define s-exp-string

@ -1,37 +1,28 @@
#lang at-exp br #lang at-exp br
(require br/indent sugar/debug) (require br/indent)
(provide indenter) (provide indenter)
(define indent-width 2)
(define (indenter text [this-pos 0]) (define indent-width 2)
;; if line begins with }:
;; outdent to the matching {
;; indent to match the previous line
(define this-line (line text this-pos))
(define this-line-end (line-end text this-line))
(define open-braces
(- (count-char text #\{ 0 this-line-end)
(count-char text #\} 0 this-line-end)))
(and (positive? open-braces)
(* indent-width
(if ((char text (line-start-visible text this-line)) . char=? . #\{)
(sub1 open-braces)
open-braces))))
#| (define (indenter tb [this-pos 0])
(define prev-line (previous-line text this-line)) (define this-line (line tb this-pos))
(define prev-indent (line-indent text prev-line)) (define prev-line (previous-line tb this-pos))
(define prev-indent (or (line-indent tb prev-line) 0))
(define this-indent
(cond (cond
[((char text (line-start text this-line)) . char=? . #\}) ;; if this line begins with }, outdent.
(and prev-indent (- prev-indent indent-width))] [((char tb (line-start-visible tb this-line)) . char=? . #\})
[((char text (line-start text prev-line)) . char=? . #\{) (- prev-indent indent-width)]
(+ (or prev-indent 0) indent-width)] ;; if last line begins with {, indent.
[((char tb (line-start-visible tb prev-line)) . char=? . #\{)
(+ prev-indent indent-width)]
;; otherwise use previous indent
[else prev-indent])) [else prev-indent]))
|# (and (exact-positive-integer? this-indent) this-indent))
(module+ test (module+ test
(require rackunit) (require rackunit)
(define test-str @string-append|{ (define test-str #<<here
#lang br/demo/jsonic #lang br/demo/jsonic
{ {
"string": @$(string-append "foo" "bar")$@, "string": @$(string-append "foo" "bar")$@,
@ -40,11 +31,9 @@
"object": @$(hash "k1" "valstring" (format "~a" 42) (hash "k1" (range 10) "k2" 42))$@ "object": @$(hash "k1" "valstring" (format "~a" 42) (hash "k1" (range 10) "k2" 42))$@
} }
// "bar" : // "bar" :
}}|) }
(displayln test-str) here
(define indented-str (test-indenter indenter test-str)) )
(displayln indented-str) (displayln (test-indenter indenter test-str))
(define indented-str2 (test-indenter indenter indented-str)) (check-equal? (str->indents (test-indenter indenter test-str))
(displayln indented-str2) (map (λ(x) (* x indent-width)) '(0 0 1 1 2 2 1 1 0))))
(define indented-str3 (test-indenter indenter indented-str2))
(displayln indented-str3))

@ -1,9 +1,2 @@
#lang br/demo/jsonic #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" :
}
Loading…
Cancel
Save