(module utils scheme/base (require scribble/struct scribble/manual (prefix-in scheme: scribble/scheme) (prefix-in scribble: scribble/reader)) (define-syntax bounce-for-label (syntax-rules (all-except) [(_ (all-except mod (id ...) (id2 ...))) (begin (require (for-label (except-in mod id ...))) (provide (for-label (except-out (all-from-out mod) id2 ...))))] [(_ mod) (begin (require (for-label mod)) (provide (for-label (all-from-out mod))))] [(_ mod ...) (begin (bounce-for-label mod) ...)])) (bounce-for-label (all-except scheme (link) ()) scribble/struct scribble/base-render scribble/decode scribble/manual scribble/scheme scribble/eval scribble/bnf) (provide scribble-examples litchar/lines) (define (litchar/lines . strs) (let ([strs (regexp-split #rx"\n" (apply string-append strs))]) (if (= 1 (length strs)) (litchar (car strs)) (make-table #f (map (lambda (s) (list (make-flow (list (make-paragraph (if (string=? s "") '(nbsp) ; needed for IE (list (litchar s)))))))) strs))))) (define (as-flow e) (make-flow (list (if (block? e) e (make-paragraph (list e)))))) (define spacer (hspace 2)) (define ((norm-spacing base) p) (cond [(and (syntax->list p) (not (null? (syntax-e p)))) (let loop ([e (syntax->list p)] [line (syntax-line (car (syntax-e p)))] [pos base] [second #f] [accum null]) (cond [(null? e) (datum->syntax p (reverse accum) (list (syntax-source p) (syntax-line p) base (add1 base) (- pos base)) p)] [else (let* ([v ((norm-spacing (if (= line (syntax-line (car e))) pos (or second pos))) (car e))] [next-pos (+ (syntax-column v) (syntax-span v) 1)]) (loop (cdr e) (syntax-line v) next-pos (or second next-pos) (cons v accum)))]))] [else (datum->syntax p (syntax-e p) (list (syntax-source p) (syntax-line p) base (add1 base) 1) p)])) (define (scribble-examples . lines) (define reads-as (make-paragraph (list spacer "reads as" spacer))) (let* ([lines (apply string-append lines)] [p (open-input-string lines)]) (port-count-lines! p) (let loop ([r '()] [newlines? #f]) (regexp-match? #px#"^[[:space:]]*" p) (let* ([p1 (file-position p)] [stx (scribble:read-syntax #f p)] [p2 (file-position p)]) (if (not (eof-object? stx)) (let ([str (substring lines p1 p2)]) (loop (cons (list str stx) r) (or newlines? (regexp-match? #rx#"\n" str)))) (let* ([r (reverse r)] [r (if newlines? (cdr (apply append (map (lambda (x) (list #f x)) r))) r)]) (make-table #f (map (lambda (x) (let ([@expr (if x (litchar/lines (car x)) "")] [sexpr (if x (scheme:to-paragraph ((norm-spacing 0) (cadr x))) "")] [reads-as (if x reads-as "")]) (map as-flow (list spacer @expr reads-as sexpr)))) r)))))))))