scribble/eval: add eval:result' and
eval:results'
original commit: 2d027e7ee5885b8c70e720db968f348df7fa2949
This commit is contained in:
parent
bad524ff54
commit
681837dc32
|
@ -1,6 +1,7 @@
|
||||||
#lang racket/base
|
#lang racket/base
|
||||||
|
|
||||||
(require "manual.rkt" "struct.rkt" "scheme.rkt" "decode.rkt"
|
(require "manual.rkt" "struct.rkt" "scheme.rkt" "decode.rkt"
|
||||||
|
(only-in "core.rkt" content?)
|
||||||
racket/list
|
racket/list
|
||||||
file/convertible ;; attached into new namespace via anchor
|
file/convertible ;; attached into new namespace via anchor
|
||||||
racket/pretty ;; attached into new namespace via anchor
|
racket/pretty ;; attached into new namespace via anchor
|
||||||
|
@ -110,6 +111,8 @@
|
||||||
(values (substring word 0 fits) (substring word fits) #f)
|
(values (substring word 0 fits) (substring word fits) #f)
|
||||||
(values #f word #f)))))
|
(values #f word #f)))))
|
||||||
|
|
||||||
|
(struct formatted-result (content))
|
||||||
|
|
||||||
(define (interleave inset? title expr-paras val-list+outputs)
|
(define (interleave inset? title expr-paras val-list+outputs)
|
||||||
(let ([lines
|
(let ([lines
|
||||||
(let loop ([expr-paras expr-paras]
|
(let loop ([expr-paras expr-paras]
|
||||||
|
@ -139,9 +142,11 @@
|
||||||
(map (lambda (v)
|
(map (lambda (v)
|
||||||
(list.flow.list
|
(list.flow.list
|
||||||
(make-paragraph
|
(make-paragraph
|
||||||
(list (elem #:style result-color
|
(list (if (formatted-result? v)
|
||||||
(to-element/no-color
|
(formatted-result-content v)
|
||||||
v #:expr? (print-as-expression)))))))
|
(elem #:style result-color
|
||||||
|
(to-element/no-color
|
||||||
|
v #:expr? (print-as-expression))))))))
|
||||||
val-list)))])
|
val-list)))])
|
||||||
(loop (cdr expr-paras) (cdr val-list+outputs) #f))))])
|
(loop (cdr expr-paras) (cdr val-list+outputs) #f))))])
|
||||||
(if inset?
|
(if inset?
|
||||||
|
@ -162,6 +167,25 @@
|
||||||
|
|
||||||
(struct nothing-to-eval ())
|
(struct nothing-to-eval ())
|
||||||
|
|
||||||
|
(struct eval-results (contents out err))
|
||||||
|
(define (make-eval-results contents out err)
|
||||||
|
(unless (and (list? contents)
|
||||||
|
(andmap content? contents))
|
||||||
|
(raise-type-error 'eval:results "list of content" contents))
|
||||||
|
(unless (string? out)
|
||||||
|
(raise-type-error 'eval:results "string" out))
|
||||||
|
(unless (string? err)
|
||||||
|
(raise-type-error 'eval:results "string" err))
|
||||||
|
(eval-results contents out err))
|
||||||
|
(define (make-eval-result content out err)
|
||||||
|
(unless (content? content)
|
||||||
|
(raise-type-error 'eval:result "content" content))
|
||||||
|
(unless (string? out)
|
||||||
|
(raise-type-error 'eval:result "string" out))
|
||||||
|
(unless (string? err)
|
||||||
|
(raise-type-error 'eval:result "string" err))
|
||||||
|
(eval-results (list content) out err))
|
||||||
|
|
||||||
(define (extract-to-evaluate s)
|
(define (extract-to-evaluate s)
|
||||||
(let loop ([s s] [expect #f])
|
(let loop ([s s] [expect #f])
|
||||||
(syntax-case s (code:line code:comment eval:alts eval:check)
|
(syntax-case s (code:line code:comment eval:alts eval:check)
|
||||||
|
@ -227,10 +251,14 @@
|
||||||
(raise-syntax-error 'eval "example result check failed" s))))
|
(raise-syntax-error 'eval "example result check failed" s))))
|
||||||
r)
|
r)
|
||||||
(lambda (str)
|
(lambda (str)
|
||||||
(let-values ([(s expect) (extract-to-evaluate str)])
|
(if (eval-results? str)
|
||||||
(if (nothing-to-eval? s)
|
(list (map formatted-result (eval-results-contents str))
|
||||||
(values (list (list (void)) "" ""))
|
(eval-results-out str)
|
||||||
(do-ev/expect s expect)))))
|
(eval-results-err str))
|
||||||
|
(let-values ([(s expect) (extract-to-evaluate str)])
|
||||||
|
(if (nothing-to-eval? s)
|
||||||
|
(list (list (void)) "" "")
|
||||||
|
(do-ev/expect s expect))))))
|
||||||
|
|
||||||
;; Since we evaluate everything in an interaction before we typeset,
|
;; Since we evaluate everything in an interaction before we typeset,
|
||||||
;; copy each value to avoid side-effects.
|
;; copy each value to avoid side-effects.
|
||||||
|
@ -373,12 +401,23 @@
|
||||||
[else s]))))
|
[else s]))))
|
||||||
list)))
|
list)))
|
||||||
|
|
||||||
;; Quote an expression to be evaluated:
|
;; Quote an expression to be evaluated or wrap as escaped:
|
||||||
(define-syntax-rule (quote-expr e) 'e)
|
(define-syntax quote-expr
|
||||||
;; This means that sandbox evaluation always works on sexprs, to get
|
(syntax-rules (eval:alts eval:result eval:results)
|
||||||
;; it to work on syntaxes, use this definition:
|
[(_ (eval:alts e1 e2)) (quote-expr e2)]
|
||||||
;; (require syntax/strip-context)
|
[(_ (eval:result e)) (make-eval-result (list e) "" "")]
|
||||||
;; (define-syntax-rule (quote-expr e) (strip-context (quote-syntax e)))
|
[(_ (eval:result e out)) (make-eval-result (list e) out "")]
|
||||||
|
[(_ (eval:result e out err)) (make-eval-result (list e) out err)]
|
||||||
|
[(_ (eval:results es)) (make-eval-results es "" "")]
|
||||||
|
[(_ (eval:results es out)) (make-eval-results es out "")]
|
||||||
|
[(_ (eval:results es out err)) (make-eval-results es out err)]
|
||||||
|
[(_ e)
|
||||||
|
;; Using quote means that sandbox evaluation works on
|
||||||
|
;; sexprs; to get it to work on syntaxes, use
|
||||||
|
;; (strip-context (quote-syntax e)))
|
||||||
|
;; while importing
|
||||||
|
;; (require syntax/strip-context)
|
||||||
|
'e]))
|
||||||
|
|
||||||
(define (do-interaction-eval ev e)
|
(define (do-interaction-eval ev e)
|
||||||
(let-values ([(e expect) (extract-to-evaluate e)])
|
(let-values ([(e expect) (extract-to-evaluate e)])
|
||||||
|
|
|
@ -36,17 +36,45 @@ are used as @tech{content}. Otherwise, when the default
|
||||||
@racket[current-print] is in place, result values are typeset using
|
@racket[current-print] is in place, result values are typeset using
|
||||||
@racket[to-element/no-color].
|
@racket[to-element/no-color].
|
||||||
|
|
||||||
Uses of @racket[code:comment] and @racketidfont{code:blank} are
|
Certain patterns in @racket[datum] are treated specially:
|
||||||
stipped from each @racket[datum] before evaluation.
|
|
||||||
|
|
||||||
If a @racket[datum] has the form @racket[(@#,indexed-racket[eval:alts]
|
@itemlist[
|
||||||
#,(svar show-datum) #,(svar eval-datum))], then @svar[show-datum] is
|
|
||||||
typeset, while @svar[eval-datum] is evaluated.
|
|
||||||
|
|
||||||
If a @racket[datum] has the form
|
@item{A @racket[datum] of the form
|
||||||
@racket[(@#,indexed-racket[eval:check] #,(svar eval-datum) #,(svar
|
@racket[(@#,indexed-racket[code:line] _code-datum (@#,racketidfont{code:comment} _comment-datum ...))]
|
||||||
expect-datum))], then both @svar[eval-datum] and @svar[check-datum]
|
is treated as @racket[_code-datum] for evaluation.}
|
||||||
are evaluated, and an error is raised if they are not @racket[equal?].
|
|
||||||
|
@item{Other uses of @racketidfont{code:comment} and
|
||||||
|
@racketidfont{code:blank} are stripped from each @racket[datum]
|
||||||
|
before evaluation.}
|
||||||
|
|
||||||
|
@item{A @racket[datum] of the form
|
||||||
|
@racket[(@#,indexed-racket[eval:alts] #,(svar show-datum) #,(svar eval-datum))]
|
||||||
|
is treated as @svar[show-datum] for typesetting and @svar[eval-datum] for evaluation.}
|
||||||
|
|
||||||
|
@item{A @racket[datum] of the form
|
||||||
|
@racket[(@#,indexed-racket[eval:check] #,(svar eval-datum) #,(svar expect-datum))]
|
||||||
|
is treated like @racket[_eval-datum], but @svar[check-datum] is also
|
||||||
|
evaluated, and an error is raised if they are not @racket[equal?].}
|
||||||
|
|
||||||
|
@item{A @racket[datum] of the form
|
||||||
|
@racket[(@#,indexed-racket[eval:result] _content-expr _out-expr _err-expr)]
|
||||||
|
involves no sandboxed evaluation; instead, the @tech{content} result of @racket[_content-expr] is used as the
|
||||||
|
typeset form of the result, @racket[_out-expr] is treated as output printed
|
||||||
|
by the expression, and @racket[_err-expr] is error output printed by the
|
||||||
|
expression. The @racket[_out-expr] and/or @racket[_err-expr] can be omitted,
|
||||||
|
in which case they default to empty strings.
|
||||||
|
|
||||||
|
Normally, @racketidfont{eval:result}
|
||||||
|
is used in the second part of an @racketidfont{eval:alts} combination.}
|
||||||
|
|
||||||
|
@item{A @racket[datum] of the form
|
||||||
|
@racket[(@#,indexed-racket[eval:results] _content-list-expr _out-expr _err-expr)]
|
||||||
|
is treated like an @racketidfont{eval:result} form, except that @racket[_content-list-expr]
|
||||||
|
should produce a list of @tech{content} for multiple results of evaluation. As
|
||||||
|
with @racketidfont{eval:result}, @racket[_out-expr] and @racket[_err-expr] are optional.}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
As an example,
|
As an example,
|
||||||
|
|
||||||
|
|
14
collects/tests/scribble/docs/eval-special.scrbl
Normal file
14
collects/tests/scribble/docs/eval-special.scrbl
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#lang scribble/manual
|
||||||
|
@(require scribble/eval)
|
||||||
|
|
||||||
|
@interaction[
|
||||||
|
(+ 1 2)
|
||||||
|
(code:line (+ 1 2) (code:comment "three"))
|
||||||
|
(eval:alts (+ 1 2) 5)
|
||||||
|
(eval:result @bold{example})
|
||||||
|
(eval:alts (+ 1 2) (eval:result @bold{same}))
|
||||||
|
(eval:alts (+ 1 2) (eval:result @elem{really the same} "Again..."))
|
||||||
|
(eval:alts (+ 1 2) (eval:result @bold{still the same} "!" "error: too many repeats"))
|
||||||
|
(eval:alts (+ 1 2) (eval:results (list @racketresult[1] @elem{2} "3") "counting"))
|
||||||
|
]
|
||||||
|
|
22
collects/tests/scribble/docs/eval-special.txt
Normal file
22
collects/tests/scribble/docs/eval-special.txt
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
> (+ 1 2)
|
||||||
|
3
|
||||||
|
> (+ 1 2) ; three
|
||||||
|
3
|
||||||
|
> (+ 1 2)
|
||||||
|
5
|
||||||
|
> (eval:result (bold "example"))
|
||||||
|
example
|
||||||
|
> (+ 1 2)
|
||||||
|
same
|
||||||
|
> (+ 1 2)
|
||||||
|
Again...
|
||||||
|
really the same
|
||||||
|
> (+ 1 2)
|
||||||
|
!
|
||||||
|
error: too many repeats
|
||||||
|
still the same
|
||||||
|
> (+ 1 2)
|
||||||
|
counting
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
Loading…
Reference in New Issue
Block a user