From 75c571ba6dbb55c7204faac9bb19d9cbf36d30ba Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 13 Jul 2007 19:03:22 +0000 Subject: [PATCH] added datum-reader customizing, documented interface svn: r6908 --- collects/scribble/doc.txt | 45 +++++++++++++-- collects/scribble/reader.ss | 18 +++++- collects/scribblings/scribble/reader.scrbl | 64 +++++++++++++++++++--- 3 files changed, 110 insertions(+), 17 deletions(-) diff --git a/collects/scribble/doc.txt b/collects/scribble/doc.txt index 1527867270..a720a211ff 100644 --- a/collects/scribble/doc.txt +++ b/collects/scribble/doc.txt @@ -28,11 +28,6 @@ function to switch the current readtable to a readtable that parses mzscheme -Le reader.ss scribble "(use-at-readtable)" -In addition to `read' and `read-syntax', which are used by `#reader', -the "reader.ss" library provides the procedures `read-inside' and -`read-inside-syntax'; these `-inner' variants parse as if starting -inside a "@{...}", and they return a (syntactic) list. - *** Concrete Syntax Informally, the concrete syntax of @-forms is @@ -570,7 +565,7 @@ matter, you can begin (or end) a line with a "@||". @|| bar @|| --reads-as--> (foo " bar " "\n" " baz") @|| baz} -* Syntax Properties +*** Syntax Properties The Scribble reader attaches properties to syntax objects. These properties might be useful in rare situations. @@ -634,3 +629,41 @@ Here is an example of this. bar } --> "foo\n bar" + +*** Interface + +The "reader.ss" module provides very little functionality for advanced +needs. + +> (read [input-port]) +> (read-syntax [source-name] [input-port]) + +These procedures implement the Scribble reader. They do so by +constructing a reader table based on the current one, and using that +in reading. + +> (read-inside [input-port]) +> (read-inside-syntax [source-name] [input-port]) + +These `-inner' variants parse as if starting inside a "@{...}", and +they return a (syntactic) list. Useful for implementing languages +that are textual by default (see "docreader.ss" for example). + +> (make-at-readtable [readtable]) + +Constructs an @-readtable, based on the input argument if given, or +`current-readtable' otherwise. + +> (use-at-readtable) + +Installs the Scribble readtable as the default. Useful for REPL +experimentation. (Note: enables line and column tracking.) + +> datum-readtable + +A parameter that determines the readtable used for reading the datum +part. The default (#t) is to use the current readtable (usually a +result of `make-at-readtable'), otherwise it can be a readtable, or a +readtable-to-readtable function that will construct one. (The idea is +that you may want to have completely different uses for the datum +part.) diff --git a/collects/scribble/reader.ss b/collects/scribble/reader.ss index 036bbcf992..e3ce09b345 100644 --- a/collects/scribble/reader.ss +++ b/collects/scribble/reader.ss @@ -36,7 +36,7 @@ ;; -------------------------------------------------------------------------- ;; syntax - ;; basic customization + ;; basic syntax customization (define ch:command #\@) (define ch:comment #\;) (define ch:expr-escape #\|) @@ -46,7 +46,13 @@ (define ch:lines-end #\}) (define str:lines-begin* #"(\\|[^a-zA-Z0-9 \t\r\n\f@\\\177-\377{]*)\\{") + (define str:end-of-line "[ \t]*\r?\n[ \t]*") ; eat spaces on the next line + ;; other + (provide datum-readtable) + (define datum-readtable (make-parameter #t)) + + ;; regexps based on the above (define re:command (^px ch:command ;; the following identifies string and ;; expression escapes, see how it is used below @@ -60,7 +66,6 @@ (define re:lines-begin (^px ch:lines-begin)) (define re:lines-begin* (^px str:lines-begin*)) (define re:lines-end (^px ch:lines-end)) - (define str:end-of-line "[ \t]*\r?\n[ \t]*") ; eat spaces on the next line (define re:end-of-line (^px str:end-of-line)) (define (re:line-item* bgn end cmd-prefix) (^px "(.+?)(?:" (and bgn `(,bgn"|")) (and end `(,end"|")) @@ -378,7 +383,13 @@ [else #f])) (define (get-datums) - (read-delimited-list re:datums-begin re:datums-end ch:datums-end)) + (let ([drt (datum-readtable)]) + (if (eq? #t drt) + (read-delimited-list re:datums-begin re:datums-end ch:datums-end) + (parameterize ([current-readtable + (if (procedure? drt) (drt (current-readtable)) drt)]) + (read-delimited-list + re:datums-begin re:datums-end ch:datums-end))))) (define (get-escape-expr single?) ;; single? means expect just one expression (or none, which is returned @@ -483,6 +494,7 @@ ;; -------------------------------------------------------------------------- ;; readtables + (provide make-at-readtable) (define make-at-readtable (readtable-cached (lambda (rt) diff --git a/collects/scribblings/scribble/reader.scrbl b/collects/scribblings/scribble/reader.scrbl index 7a2061ed7a..a61d6e90a8 100644 --- a/collects/scribblings/scribble/reader.scrbl +++ b/collects/scribblings/scribble/reader.scrbl @@ -37,12 +37,7 @@ function to switch the current readtable to a readtable that parses @commandline{mzscheme -Le reader.ss scribble "(use-at-readtable)"} -In addition to @scheme[read] and @scheme[read-syntax], which are used -by @schemefont{#reader}, the @file{reader.ss} library provides the -procedures @scheme[read-inside] and @scheme[read-inside-syntax]; these -@schemeid[-inner] variants parse as if starting inside a -@litchar["@{"]...@litchar["}"], and they return a (syntactic) list. - +@;-------------------------------------------------------------------- @section{Concrete Syntax} Informally, the concrete syntax of @"@"-forms is @@ -140,7 +135,7 @@ use Scheme's @scheme[quote]. '@foo{bar} }===| -@; - - - - - - - - - - - - - - - - - - - - - - - - +@;-------------------------------------------------------------------- @subsection{The Command Part} Besides being a Scheme identifier, the @nonterm{cmd} part of an @@ -229,6 +224,7 @@ Finally, note that there are currently no special rules for using @@foo{bar}{baz} }===| +@;-------------------------------------------------------------------- @subsection{The Datum Part} The datum part can contains arbitrary Scheme expressions, which @@ -265,6 +261,7 @@ keyword-value arguments that precede the body of text arguments. @foo[#:style 'big]{bar} }===| +@;-------------------------------------------------------------------- @subsection{The Body Part} The syntax of the body part is intended to be as convenient as @@ -330,6 +327,7 @@ of the text. This works for @litchar["@"] too: @foo{@"@x{y}" --> (x "y")} }===| +@;-------------------------------------------------------------------- @subsubsub*section{Alternative Body Syntax} In addition to the above, there is an alternative syntax for the body, @@ -375,6 +373,7 @@ string for confusing situations. This works well when you only need to quote short pieces, and the above works well when you have larger multi-line body texts. +@;-------------------------------------------------------------------- @subsubsub*section{Scheme Expression Escapes} In some cases, you may want to use a Scheme identifier (or a number or @@ -431,6 +430,7 @@ is little point in Scheme code that uses braces. @|{blah}| }===| +@;-------------------------------------------------------------------- @subsubsub*section{Comments} As noted above, there are two kinds of Scribble comments: @litchar["@;{...}"] is @@ -456,6 +456,7 @@ you can get further control of the subforms. Note how this is different from using @litchar["@||"]s in that strings around it are not merged. +@;-------------------------------------------------------------------- @subsubsub*section{Spaces, Newlines, and Indentation} The Scribble syntax treats spaces and newlines in a special way is @@ -631,7 +632,8 @@ matter, you can begin (or end) a line with a "@||". @|| baz} }===| -@subsubsub*section{Syntax Properties} +@;-------------------------------------------------------------------- +@section{Syntax Properties} The Scribble reader attaches properties to syntax objects. These properties might be useful in rare situations. @@ -715,3 +717,49 @@ an example of this. bar }) ] + +@;-------------------------------------------------------------------- +@section{Interface} + +The @file{reader.ss} module provides very little functionality for +advanced needs. + +@defproc[(read [in input-port? (current-input-port)]) any]{} +@defproc[(read-syntax [source-name any/c (object-name in)] + [in input-port? (current-input-port)]) + (or/c syntax? eof-object?)]{ +These procedures implement the Scribble reader. They do so by +constructing a reader table based on the current one, and using that +in reading. +} + +@defproc[(read-inside [in input-port? (current-input-port)]) any]{} +@defproc[(read-inside-syntax [source-name any/c (object-name in)] + [in input-port? (current-input-port)]) + (or/c syntax? eof-object?)]{ +These @schemeid[-inner] variants parse as if starting inside a +@litchar["@{"]...@litchar["}"], and they return a (syntactic) list. +Useful for implementing languages that are textual by default (see +@file{docreader.ss} for example). +} + +@defproc[(make-at-readtable + [readtable (or/c readtable? false/c) (current-readtable)]) + readtable?]{ +Constructs an @"@"-readtable, based on the input argument. +} + +@defproc[(use-at-readtable) void?]{ +Installs the Scribble readtable as the default. Useful for REPL +experimentation. (Note: enables line and column tracking.) +} + +@defparam[datum-readtable readtable + (or/c #t false/c readtable? (readtable? . -> . readtable?))]{ +A parameter that determines the readtable used for reading the datum +part. The default (@scheme[#t]) is to use the current readtable +(usually a result of @scheme[make-at-readtable]), otherwise it can be +a readtable, or a readtable-to-readtable function that will construct +one. (The idea is that you may want to have completely different uses +for the datum part.) +}