Den lør. 18. aug. 2018 kl. 03.31 skrev Andrew J <and...@alphajuliet.com>:

> Hi. In a little side project, I'm looking for an simple Racket-y way to
> transform a bulleted list into a tree structure, maybe like sxml.
>
> As an example, this...
>
> - a
>   - b c
>   - d e f
>     - g h
>
> would get transformed into something like this...
>
> '(a (b c) (d e f (g h)))
>
> I can see a few ways to do this, from recursively counting indents, right
> through to making a mini DSL (à la *Beautiful Racket*), but I'm wondering
> what a minimal idiomatic solution might look like?
>
>
>
Here is how I would write it.

#lang racket

(define (non-empty-string? s)
  (not (string=? s "")))

(define (string->lines s)
  (filter non-empty-string?
          (regexp-match* #rx"[^\n]*" s)))

(define (indentation-level s)
  (for/first ([c s] [i (in-naturals)] #:unless (char=? c #\space))
    i))

(define (string->symbols s)
  (for/list ([x (in-port read (open-input-string s))])
    x))

(define (strip-dash xs)
  (rest xs))

(define (bullet-string->nested-list s)
  (define lines   (string->lines s))
  (define levels  (map indentation-level lines))
  (define symbols (map strip-dash (map string->symbols (string->lines s))))
  (define (build js xss)
    (match* (js xss)
      [('() _)                         '()]
      [((list j)       (list xs))      xs]
      [((list* i j js) (list* xs xss)) (cond
                                         [(= i j) (cons xs   (list (build
(cons j js) xss)))]
                                         [(< i j) (append xs (list (build
(cons j js) xss)))]
                                         [else    (error 'build "not proper
nesting")])]))
  (build levels symbols))

(bullet-string->nested-list "
- g h")
(bullet-string->nested-list "
- g h
- i j")
(bullet-string->nested-list "
- d e f
  - g h")

(define example
"- a
   - b c
   - d e f
     - g h")


(bullet-string->nested-list example)

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to