commit 2d702a109baec0c7ff7787e48630d2a12f0d9b1e
parent 3b66001cdcd4fdb642b9a0c2d2176c25c27c707a
Author: Eli Barzilay <eli@racket-lang.org>
Date: Thu, 6 Mar 2008 23:00:28 +0000
add an 'include' form to scribble/text
svn: r8909
original commit: fb493745279014f2829b64f2ed6c1fd7cfeac430
Diffstat:
3 files changed, 64 insertions(+), 6 deletions(-)
diff --git a/collects/scribble/text.ss b/collects/scribble/text.ss
@@ -1,9 +1,9 @@
#lang scheme/base
-(require scheme/promise)
+(require scheme/promise (for-syntax scheme/base))
(provide (all-from-out scheme/base scheme/promise))
-(define (show x p)
+(define (show x [p (current-output-port)])
(let show ([x x])
(cond [(or (void? x) (not x) (null? x)) (void)]
[(pair? x) (show (car x)) (show (cdr x))]
@@ -32,3 +32,29 @@
;; (require (prefix-in * "text/lang/reader.ss"))
;; (current-prompt-read
;; (lambda () (parameterize ([read-accept-reader #t]) (*read-syntax))))
+
+;; Utilities
+
+(require (prefix-in at: "reader.ss"))
+(provide at:read-inside at:read-inside-syntax)
+
+(provide include)
+(define-syntax (include stx)
+ (syntax-case stx ()
+ [(_ filename)
+ (let* ([source (syntax-source stx)]
+ [dir (or (and source
+ (let-values ([(base file dir?) (split-path source)])
+ (and (path? base) base)))
+ (current-load-relative-directory)
+ (current-directory))])
+ (with-syntax ([ns (if source
+ #`(module->namespace #,source)
+ #'(current-namespace))]
+ [dir dir])
+ #'(let ([contents
+ (with-input-from-file (path->complete-path filename dir)
+ at:read-inside-syntax)])
+ (parameterize ([current-namespace ns])
+ (for ([expr (syntax->list contents)])
+ (show (eval expr)))))))]))
diff --git a/collects/scribble/text/lang/reader.ss b/collects/scribble/text/lang/reader.ss
@@ -1,15 +1,15 @@
#lang scheme/base
-(require (prefix-in s: "../../reader.ss"))
+(require "../../text.ss")
(provide (rename-out [*read read])
(rename-out [*read-syntax read-syntax]))
(define (*read [inp (current-input-port)])
- (wrap inp (s:read-inside inp)))
+ (wrap inp (at:read-inside inp)))
(define (*read-syntax [src #f] [port (current-input-port)])
- (wrap port (s:read-inside-syntax src port)))
+ (wrap port (at:read-inside-syntax src port)))
(define (wrap port body)
(define (strip-leading-newlines stxs)
@@ -29,4 +29,4 @@
[body (if (syntax? body)
(strip-leading-newlines (syntax->list body))
body)])
- `(module ,name scribble/text (#%module-begin . ,body))))
+ `(module ,name scribble/text . ,body)))
diff --git a/collects/scribblings/scribble/preprocessor.scrbl b/collects/scribblings/scribble/preprocessor.scrbl
@@ -40,3 +40,35 @@ it through @exec{mzscheme}. Here is a sample file:
}|
(Note how @litchar["@;"] is used to avoid empty lines in the output.)
+
+
+@;--------------------------------------------------------------------
+@section{Using External Files}
+
+Using additional files that contain code for your preprocessing is
+trivial: the preprocessor source is a plain Scheme file, so you can
+@scheme[require] additional files as usual.
+
+However, things can become tricky if you want to include an external
+file that should also be preprocessed. Using @scheme[require] with a
+text file (that uses the @scheme[scribble/text] language) almost
+works, but when a module is required, it is invoked before the current
+module, which means that the required file will be preprocessed before
+the current file regardless of where the @scheme[require] expression
+happens to be. Alternatively, you can use @scheme[dynamic-require]
+with @scheme[#f] for the last argument (which makes it similar to a
+plain @scheme[load])---but remember that the path will be relative to
+the current directory, not to the source file.
+
+Finally, there is a convenient syntax for including text files to be
+processed:
+
+@defform[(include filename)]{
+
+Preprocess the @scheme[filename] using the same syntax as
+@scheme[scribble/text]. This is similar to using @scheme[load] in a
+namespace that can access names bound in the current file so included
+code can refer to bindings from the including module. Note, however,
+that the including module cannot refer to names that are bound the
+included file because it is still a plain scheme module---for such
+uses you should still use @scheme[require] as usual.}