/racket-5-0-2-bin-i386-osx-mac-dmg/collects/scribble/decode.rkt
http://github.com/smorin/f4f.arc · Racket · 327 lines · 302 code · 21 blank · 4 comment · 50 complexity · 73f3590adf85ec2ef46d39c3c3ce4791 MD5 · raw file
- #lang scheme/base
- (require "core.ss"
- "private/provide-structs.ss"
- "decode-struct.ss"
- scheme/contract
- scheme/class
- scheme/list)
- (define (pre-content? i)
- (or (string? i)
- (and (content? i)
- (not (list? i)))
- (and (splice? i)
- (andmap pre-content? (splice-run i)))
- (void? i)))
- (define (pre-flow? i)
- (or (string? i)
- (and (content? i)
- (not (list? i)))
- (block? i)
- (and (splice? i)
- (andmap pre-flow? (splice-run i)))
- (void? i)))
- (define (pre-part? v)
- (or (pre-flow? v)
- (title-decl? v)
- (part-start? v)
- (part-index-decl? v)
- (part-collect-decl? v)
- (part-tag-decl? v)
- (part? v)
- (and (splice? v)
- (andmap pre-part? (splice-run v)))))
- (provide-structs
- [title-decl ([tag-prefix (or/c false/c string?)]
- [tags (listof tag?)]
- [version (or/c string? false/c)]
- [style style?]
- [content content?])]
- [part-start ([depth integer?]
- [tag-prefix (or/c false/c string?)]
- [tags (listof tag?)]
- [style style?]
- [title content?])]
- [splice ([run list?])]
- [part-index-decl ([plain-seq (listof string?)]
- [entry-seq list?])]
- [part-collect-decl ([element (or/c element? part-relative-element?)])]
- [part-tag-decl ([tag tag?])])
- (provide whitespace?
- pre-content?
- pre-flow?
- pre-part?)
- (provide/contract
- [decode (-> (listof pre-part?)
- part?)]
- [decode-part (-> (listof pre-part?)
- (listof string?)
- (or/c #f content?)
- exact-nonnegative-integer?
- part?)]
- [decode-flow (-> (listof pre-flow?)
- (listof block?))]
- [decode-paragraph (-> (listof pre-content?)
- paragraph?)]
- [decode-compound-paragraph (-> (listof pre-flow?)
- paragraph?)]
- [decode-content (-> (listof pre-content?)
- content?)]
- [rename decode-content decode-elements
- (-> (listof pre-content?)
- content?)]
- [decode-string (-> string? content?)]
- [clean-up-index-string (-> string? string?)])
- (define (clean-up-index-string s)
- ;; Collapse whitespace, and remove leading or trailing spaces, which
- ;; might appear there due to images or something else that gets
- ;; dropped in string form.
- (let* ([s (regexp-replace* #px"\\s+" s " ")]
- [s (regexp-replace* #rx"^ " s "")]
- [s (regexp-replace* #rx" $" s "")])
- s))
- (define (decode-string s)
- (let loop ([l '((#rx"---" mdash)
- (#rx"--" ndash)
- (#rx"``" ldquo)
- (#rx"''" rdquo)
- (#rx"'" rsquo))])
- (cond [(null? l) (list s)]
- [(regexp-match-positions (caar l) s)
- => (lambda (m)
- (append (decode-string (substring s 0 (caar m)))
- (cdar l)
- (decode-string (substring s (cdar m)))))]
- [else (loop (cdr l))])))
- (define (line-break? v)
- (equal? v "\n"))
- (define (whitespace? v)
- (and (string? v) (regexp-match? #px"^[\\s]*$" v)))
- (define (decode-accum-para accum)
- (if (andmap whitespace? accum)
- null
- (list (decode-compound-paragraph (reverse (skip-whitespace accum))))))
- (define (decode-flow* l keys colls tag-prefix tags vers style title part-depth)
- (let loop ([l l] [next? #f] [keys keys] [colls colls] [accum null]
- [title title] [tag-prefix tag-prefix] [tags tags] [vers vers]
- [style style])
- (cond
- [(null? l)
- (let ([k-tags (map (lambda (k) `(idx ,(make-generated-tag))) keys)]
- [tags (if (null? tags)
- (list `(part ,(make-generated-tag)))
- tags)])
- (make-part
- tag-prefix
- (append tags k-tags)
- title
- (if vers
- (make-style (style-name style)
- (cons (make-document-version vers)
- (style-properties style)))
- style)
- (let ([l (append
- (map (lambda (k tag)
- (make-index-element #f null tag
- (part-index-decl-plain-seq k)
- (part-index-decl-entry-seq k)
- #f))
- keys k-tags)
- colls)])
- (if (and title
- (not (memq 'hidden (style-properties style))))
- (cons (make-index-element
- #f null (car tags)
- (list (clean-up-index-string
- (regexp-replace #px"^\\s+(?:(?:A|An|The)\\s)?"
- (content->string title) "")))
- (list (make-element #f title))
- (make-part-index-desc))
- l)
- l))
- (decode-accum-para accum)
- null))]
- [(void? (car l))
- (loop (cdr l) next? keys colls accum title tag-prefix tags vers style)]
- [(title-decl? (car l))
- (cond [(not part-depth) (error 'decode "misplaced title: ~e" (car l))]
- [title (error 'decode "found extra title: ~v" (car l))]
- [else (loop (cdr l) next? keys colls accum
- (title-decl-content (car l))
- (title-decl-tag-prefix (car l))
- (title-decl-tags (car l))
- (title-decl-version (car l))
- (title-decl-style (car l)))])]
- #;
- ;; Blocks are now handled by decode-accum-para
- [(block? (car l))
- (let ([para (decode-accum-para accum)]
- [part (decode-flow* (cdr l) keys colls tag-prefix tags vers style
- title part-depth)])
- (make-part
- (part-tag-prefix part)
- (part-tags part)
- (part-title-content part)
- (part-style part)
- (part-to-collect part)
- (append para (list (car l)) (part-flow part))
- (part-parts part)))]
- [(part? (car l))
- (let ([para (decode-accum-para accum)]
- [part (decode-flow* (cdr l) keys colls tag-prefix tags vers style
- title part-depth)])
- (make-part
- (part-tag-prefix part)
- (part-tags part)
- (part-title-content part)
- (part-style part)
- (part-to-collect part)
- (append para (part-blocks part))
- (cons (car l) (part-parts part))))]
- [(and (part-start? (car l))
- (or (not part-depth)
- ((part-start-depth (car l)) . <= . part-depth)))
- (unless part-depth (error 'decode "misplaced part: ~e" (car l)))
- (let ([s (car l)])
- (let loop ([l (cdr l)] [s-accum null])
- (if (or (null? l)
- (and (part-start? (car l))
- ((part-start-depth (car l)) . <= . part-depth))
- (part? (car l)))
- (let ([para (decode-accum-para accum)]
- [s (decode-styled-part (reverse s-accum)
- (part-start-tag-prefix s)
- (part-start-tags s)
- (part-start-style s)
- (part-start-title s)
- (add1 part-depth))]
- [part (decode-flow* l keys colls tag-prefix tags vers style
- title part-depth)])
- (make-part (part-tag-prefix part)
- (part-tags part)
- (part-title-content part)
- (part-style part)
- (part-to-collect part)
- para
- (cons s (part-parts part))))
- (if (splice? (car l))
- (loop (append (splice-run (car l)) (cdr l)) s-accum)
- (loop (cdr l) (cons (car l) s-accum))))))]
- [(splice? (car l))
- (loop (append (splice-run (car l)) (cdr l))
- next? keys colls accum title tag-prefix tags vers style)]
- [(null? (cdr l))
- (loop null #f keys colls (cons (car l) accum) title tag-prefix tags
- vers style)]
- [(part-index-decl? (car l))
- (loop (cdr l) next? (cons (car l) keys) colls accum title tag-prefix
- tags vers style)]
- [(part-collect-decl? (car l))
- (loop (cdr l) next? keys
- (cons (part-collect-decl-element (car l)) colls)
- accum title tag-prefix tags vers style)]
- [(part-tag-decl? (car l))
- (loop (cdr l) next? keys colls accum title tag-prefix
- (append tags (list (part-tag-decl-tag (car l))))
- vers style)]
- [(and (pair? (cdr l))
- (splice? (cadr l)))
- (loop (cons (car l) (append (splice-run (cadr l)) (cddr l)))
- next? keys colls accum title tag-prefix tags vers style)]
- [(line-break? (car l))
- (if next?
- (loop (cdr l) #t keys colls accum title tag-prefix tags vers style)
- (let ([m (match-newline-whitespace (cdr l))])
- (if m
- (let ([part (loop m #t keys colls null title tag-prefix tags vers
- style)])
- (make-part
- (part-tag-prefix part)
- (part-tags part)
- (part-title-content part)
- (part-style part)
- (part-to-collect part)
- (append (decode-accum-para accum)
- (part-blocks part))
- (part-parts part)))
- (loop (cdr l) #f keys colls (cons (car l) accum) title tag-prefix
- tags vers style))))]
- [else (loop (cdr l) #f keys colls (cons (car l) accum) title tag-prefix
- tags vers style)])))
- (define (decode-part l tags title depth)
- (decode-flow* l null null #f tags #f plain title depth))
- (define (decode-styled-part l tag-prefix tags style title depth)
- (decode-flow* l null null tag-prefix tags #f style title depth))
- (define (decode-flow l)
- (part-blocks (decode-flow* l null null #f null #f plain #f #f)))
- (define (match-newline-whitespace l)
- (cond [(null? l) #f]
- [(void? (car l)) (match-newline-whitespace (cdr l))]
- [(line-break? (car l)) (skip-whitespace l)]
- [(splice? (car l))
- (match-newline-whitespace (append (splice-run (car l)) (cdr l)))]
- [(whitespace? (car l)) (match-newline-whitespace (cdr l))]
- [else #f]))
- (define (skip-whitespace l)
- (if (or (null? l)
- (not (or (whitespace? (car l))
- (void? (car l)))))
- l
- (skip-whitespace (cdr l))))
- (define (decode l)
- (decode-part l null #f 0))
- (define (decode-paragraph l)
- (make-paragraph plain (decode-content l)))
- (define (decode-content l)
- (append-map (lambda (s) (cond
- [(string? s) (decode-string s)]
- [(void? s) null]
- [(splice? s) (decode-content (splice-run s))]
- [else (list s)]))
- (skip-whitespace l)))
- (define (decode-compound-paragraph l)
- (define (finish-accum para-accum)
- (if (null? para-accum)
- null
- (list (make-paragraph plain (skip-whitespace (apply append (reverse para-accum)))))))
- (let ([r (let loop ([l (skip-whitespace l)]
- [para-accum null])
- (cond
- [(null? l)
- (finish-accum para-accum)]
- [else
- (let ([s (car l)])
- (cond
- [(block? s) (append
- (finish-accum para-accum)
- (cons s (loop (skip-whitespace (cdr l)) null)))]
- [(string? s) (loop (cdr l)
- (cons (decode-string s) para-accum))]
- [else (loop (cdr l)
- (cons (list (car l)) para-accum))]))]))])
- (cond
- [(null? r)
- (make-paragraph plain null)]
- [(null? (cdr r))
- (car r)]
- [(make-compound-paragraph plain r)])))