hyper-literate/collects/scribble/manual.ss
Matthew Flatt 4c40ffdd26 doc work (start on module guide)
svn: r6730

original commit: f7bf029234e0d3ce26e4200094b1986f5f538689
2007-06-25 06:37:25 +00:00

851 lines
36 KiB
Scheme

(module manual (lib "new-lambda.ss" "scribblings")
(require "decode.ss"
"struct.ss"
"scheme.ss"
"config.ss"
"basic.ss"
(lib "string.ss")
(lib "list.ss")
(lib "class.ss"))
(provide (all-from "basic.ss"))
(provide PLaneT)
(define PLaneT "PLaneT")
(define-code schemeblock0 to-paragraph)
(define-code schemeblock (to-paragraph/prefix (hspace 2)
(hspace 2)
""))
(define-code SCHEMEBLOCK (to-paragraph/prefix (hspace 2)
(hspace 2)
"")
UNSYNTAX)
(define-code SCHEMEBLOCK0 to-paragraph UNSYNTAX)
(define-code schemeinput (to-paragraph/prefix (make-element
#f
(list
(hspace 2)
(make-element 'tt (list "> " ))))
(hspace 4)
""))
(define-syntax (schememod stx)
(syntax-case stx ()
[(_ lang rest ...)
(with-syntax ([modtag (datum->syntax-object
#'here
`(unsyntax (schemefont ,(format "#module ~a" (syntax-e #'lang))))
#'lang)])
#'(schemeblock modtag rest ...))]))
(define (to-element/result s)
(make-element "schemeresult" (list (to-element/no-color s))))
(define (to-element/id s)
(make-element "schemesymbol" (list (to-element/no-color s))))
(define (keep-s-expr ctx s v)
(if (symbol? s)
(make-just-context s ctx)
s))
(define (add-sq-prop s name val)
(if (eq? name 'paren-shape)
(make-shaped-parens s val)
s))
(define-code scheme to-element unsyntax keep-s-expr add-sq-prop)
(define-code schemeresult to-element/result unsyntax keep-s-expr add-sq-prop)
(define-code schemeid to-element/id unsyntax keep-s-expr add-sq-prop)
(define-code schememodname to-element unsyntax keep-s-expr add-sq-prop)
(define (litchar . strs)
(unless (andmap string? strs)
(raise-type-error 'litchar "strings" strs))
(let ([s (apply string-append
(map (lambda (s) (if (string=? s "\n") " " s))
strs))])
(let ([spaces (regexp-match-positions #rx"^ *" s)]
[end-spaces (regexp-match-positions #rx" *$" s)])
(make-element "schemeinput"
(list (hspace (cdar spaces))
(make-element #f (list (substring s (cdar spaces) (caar end-spaces))))
(hspace (- (cdar end-spaces) (caar end-spaces))))))))
(define (verbatim s)
(let ([strs (regexp-split #rx"\n" s)])
(make-table
#f
(map (lambda (s)
(list (make-flow (list (make-paragraph
(let ([spaces (cdar (regexp-match-positions #rx"^ *" s))])
(list
(hspace spaces)
(make-element 'tt (list (substring s spaces))))))))))
strs))))
(provide schemeblock SCHEMEBLOCK
schemeblock0 SCHEMEBLOCK0
schemeinput
schememod
scheme schemeresult schemeid schememodname
litchar
verbatim)
(provide onscreen menuitem defterm
schemefont schemevalfont schemeresultfont schemeidfont
schemeparenfont schemekeywordfont schememetafont schememodfont
file exec
link procedure
idefterm)
(define (onscreen . str)
(make-element 'sf (decode-content str)))
(define (menuitem menu item)
(make-element 'sf (list menu "|" item)))
(define (defterm . str)
(make-element 'italic (decode-content str)))
(define (idefterm . str)
(let ([c (decode-content str)])
(make-element 'italic c)))
(define (schemefont . str)
(apply tt str))
(define (schemevalfont . str)
(make-element "schemevalue" (decode-content str)))
(define (schemeresultfont . str)
(make-element "schemeresult" (decode-content str)))
(define (schemeidfont . str)
(make-element "schemesymbol" (decode-content str)))
(define (schemeparenfont . str)
(make-element "schemeparen" (decode-content str)))
(define (schememetafont . str)
(make-element "schememeta" (decode-content str)))
(define (schememodfont . str)
(make-element "schememod" (decode-content str)))
(define (schemekeywordfont . str)
(make-element "schemekeyword" (decode-content str)))
(define (file . str)
(make-element 'tt (append (list "\"") (decode-content str) (list "\""))))
(define (exec . str)
(make-element 'tt (decode-content str)))
(define (procedure . str)
(make-element "schemeresult" (append (list "#<procedure:") (decode-content str) (list ">"))))
(define (link url . str)
(make-element (make-target-url url) (decode-content str)))
(provide t)
(define (t . str)
(decode-paragraph str))
(provide schememodule)
(define-syntax (schememodule stx)
(syntax-rules ()
[(_ body ...)
(code body ...)]))
;; ----------------------------------------
(provide margin-note)
(define (margin-note . c)
(make-styled-paragraph (list (make-element "refcontent"
c))
"refpara"))
;; ----------------------------------------
(provide deftech tech techlink)
(define (*tech make-elem style s)
(let* ([c (decode-content s)]
[s (regexp-replace* #px"[-\\s]+"
(regexp-replace
#rx"s$"
(string-foldcase (content->string c))
"")
" ")])
(make-elem style
c
(format "tech-term:~a" s))))
(define (deftech . s)
(*tech make-target-element #f (list (apply defterm s))))
(define (tech . s)
(*tech make-link-element "techlink" s))
(define (techlink . s)
(*tech make-link-element #f s))
;; ----------------------------------------
(provide defproc defproc* defstruct defthing defform defform* defform/subs defform*/subs defform/none
specform specform/subs
specsubform specspecsubform specsubform/inline
schemegrammar schemegrammar*
var svar void-const undefined-const)
(define void-const
(schemeresultfont "#<void>"))
(define undefined-const
(schemeresultfont "#<undefined>"))
(define dots0
(make-element "schememeta" (list "...")))
(define dots1
(make-element "schememeta" (list "...+")))
(define-syntax (arg-contract stx)
(syntax-case stx (... ...+)
[(_ [id contract])
(identifier? #'id)
#'(schemeblock0 contract)]
[(_ [id contract val])
(identifier? #'id)
#'(schemeblock0 contract)]
[(_ [kw id contract])
(and (keyword? (syntax-e #'kw))
(identifier? #'id))
#'(schemeblock0 contract)]
[(_ [kw id contract val])
(and (keyword? (syntax-e #'kw))
(identifier? #'id))
#'(schemeblock0 contract)]
[(_ (... ...))
#'#f]
[(_ (... ...+))
#'#f]
[(_ arg)
(raise-syntax-error
'defproc
"bad argument form"
#'arg)]))
(define-syntax defproc
(syntax-rules ()
[(_ (id arg ...) result desc ...)
(*defproc (list (quote-syntax id))
'[(id arg ...)]
(list (list (lambda () (arg-contract arg)) ...))
(list (lambda () (schemeblock0 result)))
(lambda () (list desc ...)))]))
(define-syntax defproc*
(syntax-rules ()
[(_ [[(id arg ...) result] ...] desc ...)
(*defproc (list (quote-syntax id) ...)
'[(id arg ...) ...]
(list (list (lambda () (arg-contract arg)) ...) ...)
(list (lambda () (schemeblock0 result)) ...)
(lambda () (list desc ...)))]))
(define-syntax defstruct
(syntax-rules ()
[(_ name fields desc ...)
(*defstruct (quote-syntax name) 'name 'fields (lambda () (list desc ...)))]))
(define-syntax (defform*/subs stx)
(syntax-case stx ()
[(_ #:literals (lit ...) [spec spec1 ...] ([non-term-id non-term-form ...] ...) desc ...)
(with-syntax ([new-spec
(syntax-case #'spec ()
[(name . rest)
(datum->syntax-object #'spec
(cons
(datum->syntax-object #'here
'(unsyntax x)
#'name)
#'rest)
#'spec)])]
[spec-id
(syntax-case #'spec ()
[(name . rest) #'name])])
#'(*defforms (quote-syntax spec-id) '(lit ...)
'(spec spec1 ...)
(list (lambda (x) (schemeblock0 new-spec))
(lambda (ignored) (schemeblock0 spec1)) ...)
'((non-term-id non-term-form ...) ...)
(list (list (lambda () (scheme non-term-id))
(lambda () (schemeblock0 non-term-form))
...)
...)
(lambda () (list desc ...))))]
[(fm [spec spec1 ...] ([non-term-id non-term-form ...] ...) desc ...)
#'(fm #:literals () [spec spec1 ...] ([non-term-id non-term-form ...] ...) desc ...)]))
(define-syntax (defform* stx)
(syntax-case stx ()
[(_ #:literals lits [spec ...] desc ...) #'(defform*/subs #:literals lits [spec ...] () desc ...)]
[(_ [spec ...] desc ...) #'(defform*/subs [spec ...] () desc ...)]))
(define-syntax (defform stx)
(syntax-case stx ()
[(_ spec desc ...) #'(defform*/subs [spec] () desc ...)]))
(define-syntax (defform/subs stx)
(syntax-case stx ()
[(_ #:literals lits spec subs desc ...) #'(defform*/subs #:literals lits [spec] subs desc ...)]
[(_ spec subs desc ...) #'(defform*/subs [spec] subs desc ...)]))
(define-syntax (defform/none stx)
(syntax-case stx ()
[(_ spec desc ...)
#'(*defforms #f null
'(spec) (list (lambda (ignored) (schemeblock0 spec)))
null null
(lambda () (list desc ...)))]))
(define-syntax specsubform
(syntax-rules ()
[(_ #:literals (lit ...) spec desc ...)
(*specsubform 'spec #f '(lit ...) (lambda () (schemeblock0 spec)) null null (lambda () (list desc ...)))]
[(_ spec desc ...)
(*specsubform 'spec #f null (lambda () (schemeblock0 spec)) null null (lambda () (list desc ...)))]))
(define-syntax specspecsubform
(syntax-rules ()
[(_ spec desc ...)
(make-blockquote "leftindent" (list (specsubform spec desc ...)))]))
(define-syntax specform
(syntax-rules ()
[(_ #:literals (lit ...) spec desc ...)
(*specsubform 'spec #t '(lit ...) (lambda () (schemeblock0 spec)) null null (lambda () (list desc ...)))]
[(_ spec desc ...)
(*specsubform 'spec #t null (lambda () (schemeblock0 spec)) null null (lambda () (list desc ...)))]))
(define-syntax specform/subs
(syntax-rules ()
[(_ #:literals (lit ...) spec ([non-term-id non-term-form ...] ...) desc ...)
(*specsubform 'spec #t
'(lit ...)
(lambda () (schemeblock0 spec))
'((non-term-id non-term-form ...) ...)
(list (list (lambda () (scheme non-term-id))
(lambda () (schemeblock0 non-term-form))
...)
...)
(lambda () (list desc ...)))]
[(_ spec ([non-term-id non-term-form ...] ...) desc ...)
(specform/subs #:literals () spec ([non-term-id non-term-form ...] ...) desc ...)]))
(define-syntax specsubform/inline
(syntax-rules ()
[(_ spec desc ...)
(*specsubform 'spec #f null #f null null (lambda () (list desc ...)))]))
(define-syntax defthing
(syntax-rules ()
[(_ id result desc ...)
(*defthing (quote-syntax id) 'id 'result (lambda () (list desc ...)))]))
(define-syntax schemegrammar
(syntax-rules ()
[(_ #:literals (lit ...) id clause ...) (*schemegrammar '(lit ...)
'(id clause ...)
(lambda () (list (list (scheme id) (schemeblock0 clause) ...))))]
[(_ id clause ...) (schemegrammar #:literals () id clause ...)]))
(define-syntax schemegrammar*
(syntax-rules ()
[(_ #:literals (lit ...) [id clause ...] ...) (*schemegrammar '(lit ...)
'(id ... clause ... ...)
(lambda ()
(list
(list (scheme id) (schemeblock0 clause) ...) ...)))]
[(_ [id clause ...] ...) (schemegrammar #:literals () [id clause ...] ...)]))
(define-syntax var
(syntax-rules ()
[(_ id) (*var 'id)]))
(define-syntax svar
(syntax-rules ()
[(_ id) (*var 'id)]))
(define (make-table-if-necessary style content)
(if (= 1 (length content))
(let ([paras (apply append (map flow-paragraphs (car content)))])
(if (andmap paragraph? paras)
(list (make-paragraph (apply append (map paragraph-content paras))))
(list (make-table style content))))
(list (make-table style content))))
(define (*defproc stx-ids prototypes arg-contractss result-contracts content-thunk)
(let ([spacer (hspace 1)]
[has-optional? (lambda (arg)
(and (pair? arg)
((length arg) . > . (if (keyword? (car arg))
3
2))))]
[to-flow (lambda (e)
(make-flow (list (make-paragraph (list e)))))]
[arg->elem (lambda (v)
(cond
[(pair? v)
(if (keyword? (car v))
(make-element #f (list (to-element (car v))
(hspace 1)
(to-element (cadr v))))
(to-element (car v)))]
[(eq? v '...+)
dots1]
[(eq? v '...)
dots0]
[else v]))]
[prototype-size (lambda (s)
(let loop ([s s])
(if (null? s)
1
(+ 1 (loop (cdr s))
(cond
[(symbol? (car s)) (string-length (symbol->string (car s)))]
[(pair? (car s))
(if (keyword? (caar s))
(+ (string-length (keyword->string (caar s)))
3
(string-length (symbol->string (cadar s))))
(string-length (symbol->string (caar s))))]
[else 0])))))])
(parameterize ([current-variable-list
(map (lambda (i)
(and (pair? i)
(if (keyword? (car i))
(cadr i)
(car i))))
(apply append (map cdr prototypes)))])
(make-splice
(cons
(make-table
'boxed
(apply
append
(map
(lambda (stx-id prototype arg-contracts result-contract first?)
(append
(list
(list (make-flow
(let-values ([(required optional more-required)
(let loop ([a (cdr prototype)][r-accum null])
(if (or (null? a)
(and (has-optional? (car a))))
(let ([req (reverse r-accum)])
(let loop ([a a][o-accum null])
(if (or (null? a)
(not (has-optional? (car a))))
(values req (reverse o-accum) a)
(loop (cdr a) (cons (car a) o-accum)))))
(loop (cdr a) (cons (car a) r-accum))))]
[(tagged) (if first?
(make-target-element
#f
(list (to-element (make-just-context (car prototype)
stx-id)))
(register-scheme-definition stx-id))
(to-element (make-just-context (car prototype)
stx-id)))]
[(short?) (or ((prototype-size prototype) . < . 40)
((length prototype) . < . 3))]
[(end) (list (to-flow spacer)
(to-flow 'rarr)
(to-flow spacer)
(make-flow (list (result-contract))))])
(if short?
(make-table-if-necessary
"prototype"
(list
(cons
(to-flow
(to-element (append
(list tagged)
(map arg->elem required)
(if (null? optional)
null
(list
(to-element
(syntax-property
(syntax-ize (map arg->elem optional) 0)
'paren-shape
#\?))))
(map arg->elem more-required))))
end)))
(let ([not-end
(list (to-flow spacer)
(to-flow spacer)
(to-flow spacer)
(to-flow spacer))])
(list
(make-table
"prototype"
(cons
(list* (to-flow (make-element
#f
(list
(schemeparenfont "(")
tagged)))
(cond
[(null? required)
(to-flow (make-element #f (list spacer "[")))]
[else
(to-flow spacer)])
(to-flow
(if (null? required)
(arg->elem (car optional))
(arg->elem (car required))))
not-end)
(let loop ([args (cdr (append required optional))]
[req (sub1 (length required))])
(if (null? args)
null
(cons (list* (to-flow spacer)
(if (zero? req)
(to-flow (make-element #f (list spacer "[")))
(to-flow spacer))
(let ([a (arg->elem (car args))])
(to-flow
(cond
[(null? (cdr args))
(if (null? optional)
(make-element
#f
(list a (schemeparenfont ")")))
(make-element
#f
(list a "]" (schemeparenfont ")"))))]
[else a])))
(if (null? (cdr args))
end
not-end))
(loop (cdr args) (sub1 req))))))))))))))
(apply append
(map (lambda (v arg-contract)
(cond
[(pair? v)
(list
(list
(make-flow
(make-table-if-necessary
"argcontract"
(list
(let ([v (if (keyword? (car v))
(cdr v)
v)])
(append
(list
(to-flow (hspace 2))
(to-flow (arg->elem v))
(to-flow spacer)
(to-flow ":")
(to-flow spacer)
(make-flow (list (arg-contract))))
(if (has-optional? v)
(list (to-flow spacer)
(to-flow "=")
(to-flow spacer)
(to-flow (to-element (caddr v))))
null))))))))]
[else null]))
(cdr prototype)
arg-contracts))))
stx-ids
prototypes
arg-contractss
result-contracts
(cons #t (map (lambda (x) #f) (cdr prototypes))))))
(content-thunk))))))
(define (make-target-element* stx-id content wrappers)
(if (null? wrappers)
content
(make-target-element*
stx-id
(make-target-element
#f
(list content)
(register-scheme-definition
(datum->syntax-object stx-id
(string->symbol
(apply string-append
(map symbol->string (car wrappers)))))))
(cdr wrappers))))
(define (*defstruct stx-id name fields content-thunk)
(define spacer (hspace 1))
(make-splice
(cons
(make-table
'boxed
(cons
(list (make-flow
(list
(make-paragraph
(list
(to-element
`(,(schemeparenfont "struct")
,(make-target-element*
stx-id
(to-element name)
(let ([name (if (pair? name)
(car name)
name)])
(list* (list name)
(list name '?)
(list 'make- name)
(append
(map (lambda (f)
(list name '- (car f)))
fields)
(map (lambda (f)
(list 'set- name '- (car f) '!))
fields)))))
,(map car fields))))))))
(map (lambda (v)
(cond
[(pair? v)
(list
(make-flow
(list
(make-paragraph (append
(list
(hspace 2)
(to-element (car v)))
(list
spacer
":"
spacer
(to-element (cadr v))))))))]
[else null]))
fields)))
(content-thunk))))
(define (*defthing stx-id name result-contract content-thunk)
(define spacer (hspace 1))
(make-splice
(cons
(make-table
'boxed
(list
(list (make-flow
(list
(make-paragraph
(list (make-target-element
#f
(list (to-element name))
(register-scheme-definition stx-id))
spacer ":" spacer
(to-element result-contract))))))))
(content-thunk))))
(define (meta-symbol? s) (memq s '(... ...+ ?)))
(define (*defforms kw-id lits forms form-procs subs sub-procs content-thunk)
(parameterize ([current-variable-list
(apply
append
(map (lambda (form)
(let loop ([form (cons (if kw-id (cdr form) form)
subs)])
(cond
[(symbol? form) (if (or (meta-symbol? form)
(memq form lits))
null
(list form))]
[(pair? form) (append (loop (car form))
(loop (cdr form)))]
[else null])))
forms))]
[current-meta-list '(... ...+)])
(make-splice
(cons
(make-table
'boxed
(append
(map (lambda (form form-proc)
(list
(make-flow
(list
((or form-proc
(lambda (x)
(make-paragraph
(list
(to-element
`(,x
. ,(cdr form)))))))
(and kw-id
(eq? form (car forms))
(make-target-element
#f
(list (to-element (make-just-context (car form) kw-id)))
(register-scheme-form-definition kw-id))))))))
forms form-procs)
(if (null? sub-procs)
null
(list (list (make-flow (list (make-paragraph (list (tt 'nbsp))))))
(list (make-flow (list (let ([l (map (lambda (sub)
(map (lambda (f) (f)) sub))
sub-procs)])
(*schemerawgrammars
"specgrammar"
(map car l)
(map cdr l))))))))))
(content-thunk)))))
(define (*specsubform form has-kw? lits form-thunk subs sub-procs content-thunk)
(parameterize ([current-variable-list
(append (let loop ([form (cons (if has-kw? (cdr form) form)
subs)])
(cond
[(symbol? form) (if (or (meta-symbol? form)
(memq form lits))
null
(list form))]
[(pair? form) (append (loop (car form))
(loop (cdr form)))]
[else null]))
(current-variable-list))]
[current-meta-list '(... ...+)])
(make-blockquote
"leftindent"
(cons
(make-table
'boxed
(cons
(list
(make-flow
(list
(if form-thunk
(form-thunk)
(make-paragraph (list (to-element form)))))))
(if (null? sub-procs)
null
(list (list (make-flow (list (make-paragraph (list (tt 'nbsp))))))
(list (make-flow (list (let ([l (map (lambda (sub)
(map (lambda (f) (f)) sub))
sub-procs)])
(*schemerawgrammars
"specgrammar"
(map car l)
(map cdr l))))))))))
(flow-paragraphs (decode-flow (content-thunk)))))))
(define (*schemerawgrammars style nonterms clauseses)
(make-table
`((valignment baseline baseline baseline baseline baseline)
(alignment right left center left left)
(style ,style))
(let ([empty-line (make-flow (list (make-paragraph (list (tt 'nbsp)))))]
[to-flow (lambda (i) (make-flow (list (make-paragraph (list i)))))])
(cdr
(apply append
(map
(lambda (nonterm clauses)
(list*
(list empty-line empty-line empty-line empty-line empty-line)
(list (to-flow nonterm)
empty-line
(to-flow "=")
empty-line
(make-flow (list (car clauses))))
(map (lambda (clause)
(list empty-line
empty-line
(to-flow "|")
empty-line
(make-flow (list clause))))
(cdr clauses))))
nonterms clauseses))))))
(define (*schemerawgrammar style nonterm clause1 . clauses)
(*schemerawgrammars style (list nonterm) (list (cons clause1 clauses))))
(define (*schemegrammar lits s-expr clauseses-thunk)
(parameterize ([current-variable-list
(let loop ([form s-expr])
(cond
[(symbol? form) (if (memq form lits)
null
(list form))]
[(pair? form) (append (loop (car form))
(loop (cdr form)))]
[else null]))])
(let ([l (clauseses-thunk)])
(*schemerawgrammars #f (map car l) (map cdr l)))))
(define (*var id)
(to-element (*var-sym id)))
(define (*var-sym id)
(string->symbol (format "_~a" id)))
;; ----------------------------------------
(provide centerline)
(define (centerline . s)
(make-table 'centered (list (list (make-flow (list (decode-paragraph s)))))))
(provide commandline)
(define (commandline . s)
(make-paragraph (list (hspace 2) (apply tt s))))
(define (secref s)
(make-link-element #f null `(part ,s)))
(define (seclink tag . s)
(make-link-element #f (decode-content s) `(part ,tag)))
(define (*schemelink stx-id id . s)
(make-link-element #f (decode-content s) (register-scheme-definition stx-id)))
(define-syntax schemelink
(syntax-rules ()
[(_ id . content) (*schemelink (quote-syntax id) 'id . content)]))
(provide secref seclink schemelink)
(define (pidefterm . s)
(let ([c (apply defterm s)])
(index (string-append (content->string (element-content c)) "s")
c)))
(provide pidefterm)
;; ----------------------------------------
(provide where-is-one-of
is-one-of)
(define (where-is-one-of id)
(make-element #f (list "where " id " is one of")))
(define (is-one-of id)
(make-element #f (list id " is one of")))
;; ----------------------------------------
(provide math)
(define (math . s)
(let ([c (decode-content s)])
(make-element #f (apply append
(map (lambda (i)
(let loop ([i i])
(cond
[(string? i)
(cond
[(regexp-match #rx"^(.*)([()])(.*)$" i)
=> (lambda (m)
(append (loop (cadr m))
(list (caddr m))
(loop (cadddr m))))]
[else
(list (make-element 'italic (list i)))])]
[(eq? i 'rsquo) (list 'prime)]
[else (list i)])))
c)))))
;; ----------------------------------------
(provide cite)
(define (cite #:key key #:title title #:author author #:location location #:date date)
"[...]"
#;
(make-bibliography-element
#f
(list "[...]")
key
(list (string-append
(content->string (list author))
", "
(content->string (list title))))
(list (make-element #f (list author
", "
title
", "
date
". "
location
".")))))
;; ----------------------------------------
)