123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- (define-module (scripts read-text-outline)
- :export (read-text-outline
- read-text-outline-silently
- make-text-outline-reader)
- :use-module (ice-9 regex)
- :autoload (ice-9 rdelim) (read-line)
- :autoload (ice-9 getopt-long) (getopt-long))
- (define %include-in-guild-list #f)
- (define %summary "Convert textual outlines to s-expressions.")
- (define (?? symbol)
- (let ((name (symbol->string symbol)))
- (string=? "?" (substring name (1- (string-length name))))))
- (define (msub n)
- (lambda (m)
- (match:substring m n)))
- (define (??-predicates pair)
- (cons (car pair)
- (if (?? (car pair))
- (lambda (m)
- (not (string=? "" (match:substring m (cdr pair)))))
- (msub (cdr pair)))))
- (define (make-line-parser re specs)
- (let* ((rx (let ((fc (substring re 0 1)))
- (make-regexp (if (string=? "^" fc)
- re
- (string-append "^" re)))))
- (check (lambda (key)
- (assq-ref specs key)))
- (level-substring (msub (or (check 'level-submatch-number) 1)))
- (extract-level (cond ((check 'compute-level)
- => (lambda (proc)
- (lambda (m)
- (proc m))))
- ((check 'level-substring-divisor)
- => (lambda (n)
- (lambda (m)
- (/ (string-length (level-substring m))
- n))))
- (else
- (lambda (m)
- (string-length (level-substring m))))))
- (extract-body (cond ((check 'body-submatch-number)
- => msub)
- (else
- (lambda (m) (match:suffix m)))))
- (misc-props! (cond ((check 'extra-fields)
- => (lambda (alist)
- (let ((new (map ??-predicates alist)))
- (lambda (obj m)
- (for-each
- (lambda (pair)
- (set-object-property!
- obj (car pair)
- ((cdr pair) m)))
- new)))))
- (else
- (lambda (obj m) #t)))))
-
- (lambda (line)
- (cond ((regexp-exec rx line)
- => (lambda (m)
- (let ((level (extract-level m))
- (body (extract-body m)))
- (set-object-property! body 'level level)
- (misc-props! body m)
- body)))
- (else #f)))))
- (define (make-text-outline-reader re specs)
- (let ((parse-line (make-line-parser re specs)))
-
- (lambda (port)
- (let* ((all '(start))
- (pchain (list)))
- (let loop ((line (read-line port))
- (prev-level -1)
-
-
-
-
-
-
- (tp all))
- (or (eof-object? line)
- (cond ((parse-line line)
- => (lambda (w)
- (let* ((words (list w))
- (level (object-property w 'level))
- (diff (- level prev-level)))
- (cond
-
- ((zero? diff)
-
- (set-cdr! tp words))
-
- ((positive? diff)
- (or (= 1 diff)
- (error "unhandled diff not 1:" diff line))
-
-
- (set-object-property! tp 'level prev-level)
- (set! pchain (cons tp pchain))
-
- (set-car! tp (cons (car tp) words)))
-
- ((negative? diff)
-
- (do ((p pchain (cdr p)))
- ((= level (object-property (car p) 'level))
- (set! pchain p)))
-
- (set-cdr! (car pchain) words)
- (set! pchain (cdr pchain))))
- (loop (read-line port) level words))))
- (else (loop (read-line port) prev-level tp)))))
- (set! all (car all))
- (if (eq? 'start all)
- '()
- (cdr all))))))
- (define read-text-outline-silently
- (make-text-outline-reader "(([ ][ ])*)- *"
- '((level-substring-divisor . 2))))
- (define (read-text-outline . args)
- (write (read-text-outline-silently (open-file (car args) "r")))
- (newline)
- #t)
- (define main read-text-outline)
|