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)
(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)"
;; otherwise "bar" is dropped, which is too astonishing
(define (string->datum str)
(if (positive? (string-length str))
(if (blank? str)
(void)
(let ([result (read (open-input-string (format "(~a)" str)))])
(if (= (length result) 1)
(car result)
result))
(void)))
result))))
(define (datum? 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 (datum (~a-bar-~a)) "foo" "zam") '(foo-bar-zam))
(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))))

@ -1,11 +1,16 @@
#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))
(module+ test
;; todo: fix this so it can be tested on travis
(require racket/gui/base rackunit)
(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)
@ -147,17 +152,28 @@
(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 space-char? (λ(x) (x . char=? . #\space)))
(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))))))))
(define indented-t
(for/fold ([t-acc t])
([line-idx (in-range (add1 (send t last-line)))])
;; simulate DrR indentation
;; by dropping leading spaces and applying new indent.
(define line-start-pos (line-start t-acc line-idx))
(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)]
[(list? result) (format "[~a]" (string-join (map stringify 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 s-exp-string

@ -1,37 +1,28 @@
#lang at-exp br
(require br/indent sugar/debug)
(require br/indent)
(provide indenter)
(define indent-width 2)
(define (indenter text [this-pos 0])
;; 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 indent-width 2)
#|
(define prev-line (previous-line text this-line))
(define prev-indent (line-indent text prev-line))
(cond
[((char text (line-start text this-line)) . char=? . #\})
(and prev-indent (- prev-indent indent-width))]
[((char text (line-start text prev-line)) . char=? . #\{)
(+ (or prev-indent 0) indent-width)]
[else prev-indent]))
|#
(define (indenter 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))
(define this-indent
(cond
;; if this line begins with }, outdent.
[((char tb (line-start-visible tb this-line)) . char=? . #\})
(- prev-indent 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]))
(and (exact-positive-integer? this-indent) this-indent))
(module+ test
(require rackunit)
(define test-str @string-append|{
(define test-str #<<here
#lang br/demo/jsonic
{
"string": @$(string-append "foo" "bar")$@,
@ -40,11 +31,9 @@
"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))
}
here
)
(displayln (test-indenter indenter test-str))
(check-equal? (str->indents (test-indenter indenter test-str))
(map (λ(x) (* x indent-width)) '(0 0 1 1 2 2 1 1 0))))

@ -1,9 +1,2 @@
#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