(module file mzscheme
(require (lib "file.ss")
(lib "plt-match.ss")
(lib "port.ss")
(lib "string.ss" "srfi" "13")
(planet "read.ss" ("ryanc" "scripting.plt" 1)))
(provide (all-defined))
(define (make-directory-tree tree)
(define (tree-fold seed tree)
(define (list->path head rest)
(apply build-path (reverse (cons head rest))))
(match tree
[(? string? here)
(make-directory* (list->path here seed))]
[(list) (void)]
[`(,(? string? head) (,children ...) . ,rest)
(make-directory* (list->path head seed))
(tree-fold (cons head seed) children)
(tree-fold seed rest)]
[`(,(? string? here) . ,rest)
(make-directory* (list->path here seed))
(tree-fold seed rest)]))
(tree-fold null tree))
(define (make-non-conflicting-path path filename)
(build-path path (make-non-conflicting-filename path filename)))
(define (make-non-conflicting-filename path filename)
(define (stem->stem-and-index stem)
(let loop ([stem stem] [index-string ""])
(if (char-numeric? (string-ref stem (sub1 (string-length stem))))
(loop (string-drop-right stem 1)
(string-append index-string (string-take-right stem 1)))
(values stem
(if (= (string-length index-string) 0)
1
(string->number index-string))))))
(if (file-exists? (build-path path filename))
(let* ([pos (string-index-right filename #\.)]
[stem (if pos (string-take filename pos) filename)]
[extension (if pos (string-drop filename pos) "")])
(let-values ([(stem index)
(stem->stem-and-index stem)])
(let loop ([index index])
(let ([filename
(string-append
stem
(number->string index)
extension)])
(if (file-exists? (build-path path filename))
(loop (add1 index))
filename)))))
filename))
(define (read-file->string path)
(let ([in (open-input-file path)]
[out (open-output-string)])
(let loop ()
(let ([buf (read-string 1024 in)])
(unless (eof-object? buf)
(display buf out)
(loop))))
(close-input-port in)
(get-output-string out)))
(define (concatenate-files des src)
(with-output-to-file des
(lambda ()
(copy-port (apply input-port-append
#t
(map open-input-file src))
(current-output-port)))))
)