doc scribble/scheme; add make-element-id-transformer
svn: r13691 original commit: db5cab09e7fdcf6cc3b51ffb873ab359ec16a087
This commit is contained in:
parent
4139a7271c
commit
a174d220fd
|
@ -24,7 +24,10 @@
|
||||||
(struct-out shaped-parens)
|
(struct-out shaped-parens)
|
||||||
(struct-out just-context)
|
(struct-out just-context)
|
||||||
(struct-out literal-syntax)
|
(struct-out literal-syntax)
|
||||||
(for-syntax make-variable-id))
|
(for-syntax make-variable-id
|
||||||
|
variable-id?
|
||||||
|
make-element-id-transformer
|
||||||
|
element-id-transformer?))
|
||||||
|
|
||||||
(define no-color "schemeplain")
|
(define no-color "schemeplain")
|
||||||
(define reader-color "schemereader")
|
(define reader-color "schemereader")
|
||||||
|
@ -598,53 +601,56 @@
|
||||||
(define ((to-paragraph/prefix pfx1 pfx sfx) c)
|
(define ((to-paragraph/prefix pfx1 pfx sfx) c)
|
||||||
(typeset c #t pfx1 pfx sfx #t))
|
(typeset c #t pfx1 pfx sfx #t))
|
||||||
|
|
||||||
(begin-for-syntax (define-struct variable-id (sym) #:omit-define-syntaxes))
|
(begin-for-syntax
|
||||||
|
(define-struct variable-id (sym) #:omit-define-syntaxes)
|
||||||
|
(define-struct element-id-transformer (proc) #:omit-define-syntaxes))
|
||||||
|
|
||||||
(define-syntax (define-code stx)
|
(define-syntax (define-code stx)
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
[(_ code typeset-code uncode d->s stx-prop)
|
[(_ code typeset-code uncode d->s stx-prop)
|
||||||
(syntax/loc stx
|
(syntax/loc stx
|
||||||
(define-syntax (code stx)
|
(define-syntax (code stx)
|
||||||
|
(define (wrap-loc v ctx e)
|
||||||
|
`(,#'d->s ,ctx
|
||||||
|
,e
|
||||||
|
#(code
|
||||||
|
,(syntax-line v)
|
||||||
|
,(syntax-column v)
|
||||||
|
,(syntax-position v)
|
||||||
|
,(syntax-span v))))
|
||||||
(define (stx->loc-s-expr v)
|
(define (stx->loc-s-expr v)
|
||||||
(cond
|
(let ([slv (and (identifier? v)
|
||||||
[(and (identifier? v)
|
(syntax-local-value v (lambda () #f)))])
|
||||||
(variable-id? (syntax-local-value v (lambda () #f))))
|
(cond
|
||||||
`(,#'d->s #f
|
[(variable-id? slv)
|
||||||
(,#'make-var-id ',(variable-id-sym (syntax-local-value v)))
|
(wrap-loc v #f `(,#'make-var-id ',(variable-id-sym slv)))]
|
||||||
#(code
|
[(element-id-transformer? slv)
|
||||||
,(syntax-line v)
|
(wrap-loc v #f ((element-id-transformer-proc slv) v))]
|
||||||
,(syntax-column v)
|
[(syntax? v)
|
||||||
,(syntax-position v)
|
(let ([mk (wrap-loc
|
||||||
,(syntax-span v)))]
|
v
|
||||||
[(syntax? v)
|
`(quote-syntax ,(datum->syntax v 'defcode))
|
||||||
(let ([mk `(,#'d->s
|
(syntax-case v (uncode)
|
||||||
(quote-syntax ,(datum->syntax v 'defcode))
|
[(uncode e) #'e]
|
||||||
,(syntax-case v (uncode)
|
[else (stx->loc-s-expr (syntax-e v))]))])
|
||||||
[(uncode e) #'e]
|
(let ([prop (syntax-property v 'paren-shape)])
|
||||||
[else (stx->loc-s-expr (syntax-e v))])
|
(if prop
|
||||||
#(code
|
`(,#'stx-prop ,mk 'paren-shape ,prop)
|
||||||
,(syntax-line v)
|
mk)))]
|
||||||
,(syntax-column v)
|
[(null? v) 'null]
|
||||||
,(syntax-position v)
|
[(list? v) `(list . ,(map stx->loc-s-expr v))]
|
||||||
,(syntax-span v)))])
|
[(pair? v) `(cons ,(stx->loc-s-expr (car v))
|
||||||
(let ([prop (syntax-property v 'paren-shape)])
|
,(stx->loc-s-expr (cdr v)))]
|
||||||
(if prop
|
[(vector? v) `(vector ,@(map
|
||||||
`(,#'stx-prop ,mk 'paren-shape ,prop)
|
stx->loc-s-expr
|
||||||
mk)))]
|
(vector->list v)))]
|
||||||
[(null? v) 'null]
|
[(and (struct? v) (prefab-struct-key v))
|
||||||
[(list? v) `(list . ,(map stx->loc-s-expr v))]
|
`(make-prefab-struct (quote ,(prefab-struct-key v))
|
||||||
[(pair? v) `(cons ,(stx->loc-s-expr (car v))
|
,@(map
|
||||||
,(stx->loc-s-expr (cdr v)))]
|
stx->loc-s-expr
|
||||||
[(vector? v) `(vector ,@(map
|
(cdr (vector->list (struct->vector v)))))]
|
||||||
stx->loc-s-expr
|
[(box? v) `(box ,(stx->loc-s-expr (unbox v)))]
|
||||||
(vector->list v)))]
|
[else `(quote ,v)])))
|
||||||
[(and (struct? v) (prefab-struct-key v))
|
|
||||||
`(make-prefab-struct (quote ,(prefab-struct-key v))
|
|
||||||
,@(map
|
|
||||||
stx->loc-s-expr
|
|
||||||
(cdr (vector->list (struct->vector v)))))]
|
|
||||||
[(box? v) `(box ,(stx->loc-s-expr (unbox v)))]
|
|
||||||
[else `(quote ,v)]))
|
|
||||||
(define (cvt s)
|
(define (cvt s)
|
||||||
(datum->syntax #'here (stx->loc-s-expr s) #f))
|
(datum->syntax #'here (stx->loc-s-expr s) #f))
|
||||||
(syntax-case stx ()
|
(syntax-case stx ()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#lang scribble/doc
|
#lang scribble/doc
|
||||||
@(require scribble/manual
|
@(require scribble/manual
|
||||||
"utils.ss")
|
"utils.ss"
|
||||||
|
(for-label scribble/scheme))
|
||||||
|
|
||||||
@title[#:tag "scheme"]{Scheme}
|
@title[#:tag "scheme"]{Scheme}
|
||||||
|
|
||||||
|
@ -8,4 +9,144 @@
|
||||||
provides utilities for typesetting Scheme code. The
|
provides utilities for typesetting Scheme code. The
|
||||||
@scheme[scribble/manual] forms provide a higher-level interface.}
|
@scheme[scribble/manual] forms provide a higher-level interface.}
|
||||||
|
|
||||||
@italic{To do:} document this library!
|
@defform*[[(define-code id typeset-expr)
|
||||||
|
(define-code id typeset-expr uncode-id)
|
||||||
|
(define-code id typeset-expr uncode-id d->s-expr)
|
||||||
|
(define-code id typeset-expr uncode-id d->s-expr stx-prop-expr)]]{
|
||||||
|
|
||||||
|
Binds @scheme[id] to a form similar to @scheme[scheme] or
|
||||||
|
@scheme[schemeblock] for typesetting code. The form generated by
|
||||||
|
@scheme[define-code] handles source-location information, escapes via
|
||||||
|
@scheme[unquote], preservation of binding and property information,
|
||||||
|
and @tech{element transformers}.
|
||||||
|
|
||||||
|
The supplied @scheme[typeset-expr] expression should produce a
|
||||||
|
procedure that performs the actual typesetting. This expression is
|
||||||
|
normally @scheme[to-element] or @scheme[to-paragraph]. The argument
|
||||||
|
supplied to @scheme[typeset-expr] is normally a syntax object, but
|
||||||
|
more generally it is the result of applying @scheme[d->s-expr].
|
||||||
|
|
||||||
|
The optional @scheme[uncode-id] specifies the escape from literal code
|
||||||
|
to be recognized by @scheme[id]. The default is @scheme[unsyntax].
|
||||||
|
|
||||||
|
The optional @scheme[d->s-expr] should produce a procedure that
|
||||||
|
accepts three arguments suitable for @scheme[datum->syntax]: a syntax
|
||||||
|
object or @scheme[#f], an arbitrary value, and a vector for a source
|
||||||
|
location. The result should record as much or as little of the
|
||||||
|
argument information as needed by @scheme[typeset-expr] to typeset the
|
||||||
|
code. Normally, @scheme[d->s-expr] is @scheme[datum->syntax].
|
||||||
|
|
||||||
|
The @scheme[stx-prop-expr] should produce a procedure for recording a
|
||||||
|
@scheme['paren-shape] property when the source expression uses with
|
||||||
|
@scheme[id] has such a property. The default is
|
||||||
|
@scheme[syntax-property].}
|
||||||
|
|
||||||
|
@defproc[(to-paragraph [v any/c]) block?]{
|
||||||
|
|
||||||
|
Typesets an S-expression that is represented by a syntax object, where
|
||||||
|
source-location information in the syntax object controls the
|
||||||
|
generated layout.
|
||||||
|
|
||||||
|
Identifiers that have @scheme[for-label] bindings are typeset and
|
||||||
|
hyperlinked based on definitions declared elsewhere (via
|
||||||
|
@scheme[defproc], @scheme[defform], etc.). The identifiers
|
||||||
|
@schemeidfont{code:line}, @schemeidfont{code:comment}, and
|
||||||
|
@schemeidfont{code:blank} are handled as in @scheme[schemeblock], as
|
||||||
|
are identifiers that start with @litchar{_}.
|
||||||
|
|
||||||
|
In addition, the given @scheme[v] can contain @scheme[var-id],
|
||||||
|
@scheme[shaped-parens], @scheme[just-context], or
|
||||||
|
@scheme[literal-syntax] structures to be typeset specially (see each
|
||||||
|
structure type for details), or it can contain @scheme[element]
|
||||||
|
structures that are used directly in the output.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[((to-paragraph/prefix [prefix1 any/c] [prefix any/c] [suffix any/c])
|
||||||
|
[v any/c])
|
||||||
|
block?]{
|
||||||
|
|
||||||
|
Like @scheme[to-paragraph], but @scheme[prefix1] is prefixed onto the
|
||||||
|
first line, @scheme[prefix] is prefix to any subsequent line, and
|
||||||
|
@scheme[suffix] is added to the end. The @scheme[prefix1],
|
||||||
|
@scheme[prefix], and @scheme[suffix] arguments are used as
|
||||||
|
@tech{elements}, except that if @scheme[suffix] is a list of elements,
|
||||||
|
it is added to the end on its own line.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(to-element [v any/c]) element?]{
|
||||||
|
|
||||||
|
Like @scheme[to-paragraph], except that source-location information is
|
||||||
|
mostly ignored, since the result is meant to be inlined into a
|
||||||
|
paragraph.}
|
||||||
|
|
||||||
|
@defproc[(to-element/no-color [v any/c]) element?]{
|
||||||
|
|
||||||
|
Like @scheme[to-element], but @scheme[for-syntax] bindings are
|
||||||
|
ignored, and the generated text is uncolored. This variant is
|
||||||
|
typically used to typeset results.}
|
||||||
|
|
||||||
|
|
||||||
|
@defstruct[var-id ([sym (or/c symbol? identifier?)])]{
|
||||||
|
|
||||||
|
When @scheme[to-paragraph] and variants encounter a @scheme[var-id]
|
||||||
|
structure, it is typeset as @scheme[sym] in the variable font, like
|
||||||
|
@scheme[schemevarfont].}
|
||||||
|
|
||||||
|
|
||||||
|
@defstruct[shaped-parens ([val any/c]
|
||||||
|
[shape char?])]{
|
||||||
|
|
||||||
|
When @scheme[to-paragraph] and variants encounter a
|
||||||
|
@scheme[shaped-parens] structure, it is typeset like a syntax object
|
||||||
|
that has a @scheme['paren-shape] property with value @scheme[shape].}
|
||||||
|
|
||||||
|
|
||||||
|
@defstruct[just-context ([val any/c]
|
||||||
|
[context syntax?])]{
|
||||||
|
|
||||||
|
When @scheme[to-paragraph] and variants encounter a
|
||||||
|
@scheme[just-context] structure, it is typeset using the
|
||||||
|
source-location information of @scheme[val] just the lexical context
|
||||||
|
of @scheme[ctx].}
|
||||||
|
|
||||||
|
|
||||||
|
@defstruct[literal-syntax ([stx any/c])]{
|
||||||
|
|
||||||
|
When @scheme[to-paragraph] and variants encounter a
|
||||||
|
@scheme[literal-syntax] structure, it is typeset as the string form of
|
||||||
|
@scheme[stx]. This can be used to typeset a syntax-object value in the
|
||||||
|
way that the default printer would represent the value.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(element-id-transformer? [v any/c]) boolean?]{
|
||||||
|
|
||||||
|
Provided @scheme[for-syntax]; returns @scheme[#t] if @scheme[v] is an
|
||||||
|
@tech{element transformer} created by
|
||||||
|
@scheme[make-element-id-transformer], @scheme[#f] otherwise.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(make-element-id-transformer [proc (syntax? . -> . syntax?)])
|
||||||
|
element-id-transformer?]{
|
||||||
|
|
||||||
|
Provided @scheme[for-syntax]; creates an @deftech{element
|
||||||
|
transformer}. When an identifier has a transformer binding to an
|
||||||
|
@tech{element transformer}, then forms generated by
|
||||||
|
@scheme[define-code] (including @scheme[scheme] and
|
||||||
|
@scheme[schemeblock]) typeset the identifier by applying the
|
||||||
|
@scheme[proc] to the identifier. The result must be an expression
|
||||||
|
whose value, typically an @scheme[element], is passed on to functions
|
||||||
|
like @scheme[to-paragraph] .}
|
||||||
|
|
||||||
|
@defproc[(variable-id? [v any/c]) boolean?]{
|
||||||
|
|
||||||
|
Provided @scheme[for-syntax]; returns @scheme[#t] if @scheme[v] is an
|
||||||
|
@tech{element transformer} created by @scheme[make-variable-id],
|
||||||
|
@scheme[#f] otherwise.}
|
||||||
|
|
||||||
|
|
||||||
|
@defproc[(make-variable-id [sym (or/c symbol? identifier?)])
|
||||||
|
variable-id?]{
|
||||||
|
|
||||||
|
Provided @scheme[for-syntax]; like @scheme[element-id-transformer] for
|
||||||
|
a transformer that produces @scheme[sym] typeset as a variable (like
|
||||||
|
@scheme[schemevarfont]).}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user