[racket] using scribble's evaluator for planet packages

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Fri Jun 3 16:42:31 EDT 2011

Thank you! I had run into the same problem today, but 
I had written conditionals to get around the silly string=? 
bug you mention at the end. Now I see how to do this right: 

#lang scribble/base

@(require scribble/eval racket/sandbox)

@(define-syntax sexp-eval
   (syntax-rules ()
     [(_ d ...)
      (let ()
        (define me
          (parameterize ([sandbox-output 'string]
                         [sandbox-error-output 'string])
            (make-module-evaluator '(module m "pseudolazy.rkt") #:allow-read '("pseudolazy.rkt"))))
        (interaction-eval #:eval me d)
        ...
        (lambda (x) 
          (define y (me x))
          y))]))
          

@title{What is @emph{Racket}}

@interaction[
#:eval (sexp-eval)
((lambda (x) 10) (/ 1 0))
]



On Jun 3, 2011, at 4:21 PM, Danny Yoo wrote:

> I survived in scribbling some documentation for a simple PLaneT
> package.  Here's a transcript of the struggle, just in case someone
> else is having similar issues.  Maybe I went about this in a
> convoluted way, in which case hopefully someone can show me the easy
> way to do this.
> 
> ---
> 
> I want to include examples in the documentation of my shiny new PLaneT
> package.  But in order to use the examples form,
> 
>    http://docs.racket-lang.org/scribble/eval.html#(form._((lib._scribble/eval..rkt)._examples))
> 
> I'll probably need to give it an evaluator that knows about my planet
> package, because when I try this:
> 
>    ;;;; in manual.scrbl
>    #lang scribble/manual
>    @(require planet/scribble planet/version planet/resolver scribble/eval
>                   (this-package-in main)
>                   (for-label (this-package-in main)))
>    @defmodule/this-package[main]
>    @examples[(closure-compile "alert('hello ' + 'world');")]}
> 
> the scribbled output contains:
> 
>    reference to undefined identifier: closure-compile
> 
> It fails because the basic, default evaluator doesn't know about my
> PLaneT package's bindings.
> 
> 
> Ok, let me try this.
> 
> ;;; manual.scribl
> #lang scribble/manual
> @(require planet/scribble planet/version planet/resolver scribble/eval)
> @(define my-evaluator
>   (let ([p (resolve-planet-path `(planet ,
> (this-package-version-symbol main)))])
>     ((make-eval-factory (list `(file ,(path->string p)))))))
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> 
> But I see the following error message when I try using this:
> 
> ################################################################
> ../../../../gpfs/data/pro/plt-data/software/racket/5.1.1/std/collects/racket/private/map.rkt:45:11:
> namespace-attach-module: a different module with the same name is
> already in the destination namespace, for name:
> "/research/plt/software/racket/5.1.1/std/collects/racket/contract.rkt"
> ################################################################
> 
> 
> Ok, so that didn't work, and the error message looks crazy to me.  Let
> me try something else.  Maybe I can make the evaluator directly, and
> avoid whatever internal weirdness is happening there.  I'll use
> racket/sandbox.
> 
> 
> I know my PLaneT package needs to touch the file system in somewhat
> unrestricted ways, so I need to use
> call-with-trusted-sandbox-configuration to get me a fairly
> unrestricted evaluator.
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> #lang scribble/manual
> @(require planet/scribble planet/version planet/resolver scribble/eval
> racket/sandbox)
> @(define my-evaluator
>   (call-with-trusted-sandbox-configuration
>    (lambda ()
>      (make-evaluator 'racket/base
>                              #:requires (list (resolve-planet-path
> `(planet , (this-package-version-symbol main))))))))
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> Ok, that gets me the evaluator.  Let me see if it runs ok.
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> (my-evaluator '(closure-compile "alert('hello, I see: ' + (3 + 4) + '!');"))
> "alert(\"hello, I see: 7!\");\n"
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> 
> 
> Ok, awesome; I have an evaluator that should work here.  Now let me
> use it in an examples form.
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> @examples[#:eval my-evaluator
>                   (closure-compile "alert('hello' + 'world');")]
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> Doh.  I get another error message from somewhere internal to Scribble.
> Here's what I see.
> 
> 
>    ../../../../gpfs/data/pro/plt-data/software/racket/5.1.1/std/collects/scribble/eval.rkt:126:11:
> string=?: expects type <string> as 2nd argument, given: #f; other
> arguments were: ""
> 
> 
> Ugh.  What did I do wrong here?
> 
> 
> (Some time passes; I read the evaluator section in the scribble
> documentation a few more times.)
> 
> 
> Oh.  Ok, so I need to do something extra with the evaluator setup; it
> looks like I've forgotten to tell it to feed sandbox output and
> sandbox-error-output, as described in
> http://docs.racket-lang.org/scribble/eval.html.  Ok, let me try that
> next.
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> @(define my-evaluator
>   (call-with-trusted-sandbox-configuration
>    (lambda ()
>      (parameterize ([sandbox-output 'string]
>                     [sandbox-error-output 'string])
>        (make-evaluator
>         'racket/base
>         #:requires
>         (list (resolve-planet-path `(planet ,
> (this-package-version-symbol main)))))))))
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> 
> I try again, and I finally get good Scribble output.
> (http://planet.racket-lang.org/package-source/dyoo/closure-compile.plt/1/1/planet-docs/manual/index.html)
> Huzzah.
> 
> 
> Still, that seems a lot more painful than it should have been.
> _________________________________________________
>  For list-related administrative tasks:
>  http://lists.racket-lang.org/listinfo/users




Posted on the users mailing list.