bkyk8rc3zvpnsf5inmcqq4n3k98cv6hj-my-site-hyper-literate-git.test.suzanne.soy-0.0.1

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

doc.txt (24022B)


      1 (The rest of the Scribble documentation is now a separate manual.)
      2 
      3 The Scribble Reader
      4 -------------------
      5 
      6 The Scribble @-reader is designed to be a convenient facility for
      7 using free-form text in Scheme code, where "@" is chosen as one of
      8 the least-used characters in Scheme code.
      9 
     10 You can use the reader via Racket's `#reader' form:
     11 
     12   #reader(lib "reader.ss" "scribble")@{This is free-form text!}
     13 
     14 Note that the reader will only read @-forms as S-expressions.  The
     15 meaning of these S-expressions depends on the rest of your own code.
     16 
     17 A PLT Scheme manual more likely starts with
     18 
     19   #reader(lib "docreader.ss" "scribble")
     20 
     21 which installs a reader, wraps the file content afterward into a
     22 Racket module, and parses the body into a document using
     23 "decode.ss".
     24 
     25 Another way to use the reader is to use the `use-at-readtable'
     26 function to switch the current readtable to a readtable that parses
     27 @-forms.  You can do this in a single command line:
     28 
     29   mzscheme -ile scribble/reader "(use-at-readtable)"
     30 
     31 *** Concrete Syntax
     32 
     33 Informally, the concrete syntax of @-forms is
     34 
     35   "@" <cmd> "[" <datum> ... "]" "{" <text-body> ... "}"
     36 
     37 where all three parts after "@" are optional, but at least one should
     38 be present.  (Note that spaces are not allowed between the three
     39 parts.)  "@" is set as a non-terminating reader macro, so it can be
     40 used as usual in Scheme identifiers unless you want to use it as a
     41 first character of an identifier; in this case you need to quote with
     42 a backslash (`\@foo') or quote the whole identifier with bars
     43 (`|@foo|').
     44 
     45   (define |@foo| '\@bar@baz)
     46 
     47 Of course, "@" is not treated specially in Scheme strings, character
     48 constants, etc.
     49 
     50 Roughly, a form matching the above grammar is read as
     51 
     52   (<cmd> <datum> ... <parsed-body> ...)
     53 
     54 where <parsed-body> is the translation of each <text-body> in the
     55 input.  Thus, the initial <cmd> determines the Scheme code that the
     56 input is translated into.  The common case is when <cmd> is a Scheme
     57 identifier, which generates a plain Scheme form.
     58 
     59 A <text-body> is made of text, newlines, and nested @-forms.  Note
     60 that the syntax for @-forms is the same in a <text-body> context as in
     61 a Scheme context.  A <text-body> that isn't an @-form is converted to
     62 a string expression for its <parsed-body>, and newlines are converted
     63 to "\n" expressions.
     64 
     65   @foo{bar baz
     66        blah}
     67   --reads-as-->
     68   (foo "bar baz" "\n" "blah")
     69 
     70   @foo{bar @baz[3]
     71        blah}
     72   --reads-as-->
     73   (foo "bar " (baz 3) "\n" "blah")
     74 
     75   @foo{bar @baz{3}
     76        blah}
     77   --reads-as-->
     78   (foo "bar " (baz "3") "\n" "blah")
     79 
     80   @foo{bar @baz[2 3]{4 5}
     81        blah}
     82   --reads-as-->
     83   (foo "bar " (baz 2 3 "4 5") "\n" "blah")
     84 
     85 Note that spaces are not allowed before a "[" or a "{", or they will
     86 be part of the following text (or Scheme code).  (More on using braces
     87 in body texts below.)
     88 
     89   @foo{bar @baz[2 3] {4 5}}
     90   --reads-as-->
     91   (foo "bar " (baz 2 3) " {4 5}")
     92 
     93 When the above @-forms appear in a Scheme expression context, the
     94 lexical environment must provide bindings for `foo' (as a procedure or
     95 a macro).
     96 
     97   (let* ([formatter (lambda (fmt)
     98           (lambda args (format fmt (apply string-append args))))]
     99          [bf (formatter "*~a*")]
    100          [it (formatter "/~a/")]
    101          [ul (formatter "_~a_")]
    102          [text string-append])
    103     @text{@it{Note}: @bf{This is @ul{not} a pipe}.})
    104   -->  "/Note/: *This is _not_ a pipe*."
    105 
    106 If you want to see the expression that is actually being read, you can
    107 use Scheme's `quote'.
    108 
    109   '@foo{bar}
    110 
    111 ** The Command Part
    112 
    113 Besides being a Scheme identifier, the <cmd> part of an @-form can
    114 have Scheme punctuation prefixes, which will end up wrapping the
    115 *whole* expression.
    116 
    117   @`',@foo{blah}    --reads-as-->    `',@(foo "blah")
    118 
    119 When writing Scheme code, this means that @`',@foo{blah} is exactly
    120 the same as `@',@foo{blah} and `',@@foo{blah}, but unlike the latter
    121 two, the first construct can appear in body texts with the same
    122 meaning, whereas the other two would not work (see below).
    123 
    124 After the optional punctuation prefix, the <cmd> itself is not limited
    125 to identifiers; it can be *any* Scheme expression.
    126 
    127   @(lambda (x) x){blah}    --reads-as-->    ((lambda (x) x) "blah")
    128   @`(unquote foo){blah}    --reads-as-->    `(,foo "blah")
    129 
    130 In addition, the command can be omitted altogether, which will omit it
    131 from the translation, resulting in an S-expression that usually
    132 contains, say, just strings:
    133 
    134   @{foo bar     --reads-as-->    ("foo bar" "\n" "baz")
    135     baz}
    136 
    137   @'{foo bar    --reads-as-->    '("foo bar" "\n" "baz")
    138      baz}
    139 
    140 If the command part begins with a ";" (with no newline between the "@"
    141 and the ";"), then the construct is a comment.  There are two comment
    142 forms, one for arbitrary-text and possibly nested comments, and
    143 another one for line comments:
    144 
    145   @;{<anything> ...}
    146 
    147   @;<anything-else-without-newline>
    148 
    149 In the first form, the commented body must still parse correctly; see
    150 the description of the body syntax below.  In the second form, all
    151 text from the "@;" to the end of the line *and* all following spaces
    152 (or tabs) are part of the comment (similar to "%" comments in TeX).
    153 
    154   @foo{bar @; comment    --reads-as-->    (foo "bar bazblah")
    155        baz@;
    156        blah}
    157 
    158 Tip: if you're editing in a Scheme-aware editor (like DrRacket or
    159 Emacs), it is useful to comment out blocks like this:
    160 
    161   @;{
    162     ...
    163   ;}
    164 
    165 so the editor does not treat the file as having unbalanced
    166 parenthesis.
    167 
    168 If only the <cmd> part of an @-form is specified, then the result is
    169 the command part only, without an extra set of parenthesis.  This
    170 makes it suitable for Scheme escapes in body texts.  (More on this
    171 below, in the description of the body part.)
    172 
    173   @foo{x @y z}          --reads-as-->    (foo "x " y " z")
    174   @foo{x @(* y 2) z}    --reads-as-->    (foo "x " (* y 2) " z")
    175   @{@foo bar}           --reads-as-->    (foo " bar")
    176 
    177 Finally, note that there are currently no special rules for using "@"
    178 in the command itself, which can lead to things like:
    179 
    180   @@foo{bar}{baz}    --reads-as-->    ((foo "bar") "baz")
    181 
    182 ** The Datum Part
    183 
    184 The datum part can contain arbitrary Scheme expressions, which are
    185 simply stacked before the body text arguments:
    186 
    187   @foo[1 (* 2 3)]{bar}     --reads-as-->    (foo 1 (* 2 3) "bar")
    188   @foo[@bar{...}]{blah}    --reads-as-->    (foo (bar "...") "blah")
    189 
    190 The body part can still be omitted, which is essentially an
    191 alternative syntax for plain (non-textual) S-expressions:
    192 
    193   @foo[bar]              --reads-as-->    (foo bar)
    194   @foo{bar @f[x] baz}    --reads-as-->    (foo "bar " (f x) " baz")
    195 
    196 The datum part can be empty, which makes no difference, except when
    197 the body is omitted.  It is more common, however, to use an empty body
    198 for the same purpose.
    199 
    200   @foo[]{bar}    --reads-as-->    (foo "bar")
    201   @foo[]         --reads-as-->    (foo)
    202   @foo           --reads-as-->    foo
    203   @foo{}         --reads-as-->    (foo)
    204 
    205 The most common use of the datum part is for Scheme forms that expect
    206 keyword-value arguments that precede the body of text arguments.
    207 
    208   @foo[#:style 'big]{bar}    --reads-as-->    (foo #:style 'big "bar")
    209 
    210 ** The Body Part
    211 
    212 The syntax of the body part is intended to be as convenient as
    213 possible for free text.  It can contain almost any text -- the only
    214 characters with special meaning is "@" for sub-@-forms, and "}" for
    215 the end of the text.  In addition, a "{" is allowed as part of the
    216 text, and it makes the matching "}" be part of the text too -- so
    217 balanced braces are valid text.
    218 
    219   @foo{f{o}o}     --reads-as-->    (foo "f{o}o")
    220   @foo{{{}}{}}    --reads-as-->    (foo "{{}}{}")
    221 
    222 As described above, the text turns to a sequence of string arguments
    223 for the resulting form.  Spaces at the beginning and end of lines are
    224 discarded, and newlines turn to individual "\n" strings (i.e., they
    225 are not merged with other body parts).  (See also the information
    226 about newlines and indentation below.)  Spaces are *not* discarded if
    227 they appear after the open "{" (before the closing "}") when there is
    228 also text that follows (precedes) it; specifically, they are preserved
    229 in a single-line body.
    230 
    231   @foo{bar}         --reads-as-->    (foo "bar")
    232   @foo{ bar }       --reads-as-->    (foo " bar ")
    233   @foo[1]{ bar }    --reads-as-->    (foo 1 " bar ")
    234 
    235 If "@" appears in a body, then it is interpreted as Scheme code, which
    236 means that the @-reader is applied recursively, and the resulting
    237 syntax appears as part of the S-expression, among other string
    238 contents.
    239 
    240   @foo{a @bar{b} c}    --reads-as-->    (foo "a " (bar "b") " c")
    241 
    242 If the nested "@" construct has only a command -- no body or datum
    243 parts -- it will not appear in a subform.  Given that the command part
    244 can be any Scheme expression, this makes "@" a general escape to
    245 arbitrary Scheme code.
    246 
    247   @foo{a @bar c}        --reads-as-->    (foo "a " bar " c")
    248   @foo{a @(bar 2) c}    --reads-as-->    (foo "a " (bar 2) " c")
    249 
    250 This is particularly useful with strings, which can be used to include
    251 arbitrary text.
    252 
    253   @foo{A @"}" marks the end}
    254   --reads-as-->
    255   (foo "A } marks the end")
    256 
    257 Note that the escaped string is (intentionally) merged with the rest
    258 of the text.  This works for "@" too:
    259 
    260   @foo{The prefix: @"@".}
    261   --reads-as-->
    262   (foo "The prefix: @.")
    263 
    264   @foo{@"@x{y}" --> (x "y")}
    265   --reads-as-->
    266   (foo "@x{y} --> (x \"y\")")
    267 
    268 * Alternative Body Syntax
    269 
    270 In addition to the above, there is an alternative syntax for the body,
    271 one that specifies a new marker for its end: use "|{" for the opening
    272 marker to have the text terminated by a "}|".
    273 
    274   @foo|{...}|
    275   --reads-as-->
    276   (foo "...")
    277 
    278   @foo|{"}" follows "{"}|
    279   --reads-as-->
    280   (foo "\"}\" follows \"{\"")
    281 
    282   @foo|{Nesting |{is}| ok}|
    283   --reads-as-->
    284   (foo "Nesting |{is}| ok")
    285 
    286 This applies to sub-@-forms too -- the "@" must be prefixed with a
    287 "|":
    288 
    289   @foo|{Maze
    290         |@bar{is}
    291         Life!}|
    292   --reads-as-->
    293   (foo "Maze" "\n" (bar "is") "Life!")
    294 
    295   @t|{In |@i|{sub|@"@"s}| too}|
    296   --reads-as-->
    297   (t "In " (i "sub@s") " too")
    298 
    299 Note that the subform uses its own delimiters, "{...}" or "|{...}|".
    300 This means that you can copy and paste Scribble text with @-forms
    301 freely, just prefix the "@" if the immediate surrounding text has a
    302 prefix.
    303 
    304 For even better control, you can add characters in the opening
    305 delimiter, between the "|" and the "{".  Characters that are put there
    306 (non alphanumeric ASCII characters only, excluding "{" and "@") should
    307 also be used for sub-@-forms, and the end-of-body marker should have
    308 these characters in reverse order with paren-like characters ("(",
    309 "[", "<") mirrored.
    310 
    311   @foo|<<<{@x{foo} |@{bar}|.}>>>|
    312   --reads-as-->
    313   (foo "@x{foo} |@{bar}|.")
    314 
    315   @foo|!!{X |!!@b{Y}...}!!|
    316   --reads-as-->
    317   (foo "X " (b "Y") "...")
    318 
    319 Finally, remember that you can use an expression escape with a Scheme
    320 string for confusing situations.  This works well when you only need
    321 to quote short pieces, and the above works well when you have larger
    322 multi-line body texts.
    323 
    324 * Scheme Expression Escapes
    325 
    326 In some cases, you may want to use a Scheme identifier (or a number or
    327 a boolean etc.) in a position that touches the following text; in
    328 these situations you should surround the escaped Scheme expression by
    329 a pair of "|" characters.  The text inside the bars is parsed as a
    330 Scheme expression.
    331 
    332   @foo{foo@bar.}      --reads-as-->    (foo "foo" bar.)
    333   @foo{foo@|bar|.}    --reads-as-->    (foo "foo" bar ".")
    334   @foo{foo@3.}        --reads-as-->    (foo "foo" 3.0)
    335   @foo{foo@|3|.}      --reads-as-->    (foo "foo" 3 ".")
    336 
    337 This form is a generic Scheme expression escape, there is no body text
    338 or datum part when you use this form.
    339 
    340   @foo{foo@|(f 1)|{bar}}    --reads-as-->   (foo "foo" (f 1) "{bar}")
    341   @foo{foo@|bar|[1]{baz}}   --reads-as-->   (foo "foo" bar "[1]{baz}")
    342 
    343 This works for string expressions too, but note that unlike the above,
    344 the string is (intentionally) not merged with the rest of the text:
    345 
    346   @foo{x@"y"z}      --reads-as-->    (foo "xyz")
    347   @foo{x@|"y"|z}    --reads-as-->    (foo "x" "y" "z")
    348 
    349 Expression escapes also work with *any* number of expressions,
    350 
    351   @foo{x@|1 (+ 2 3) 4|y}    --reads-as-->    (foo "x" 1 (+ 2 3) 4 "y")
    352 
    353   @foo{x@|*                 --reads-as-->    (foo "x" * * "y")
    354           *|y}
    355 
    356 It seems that "@||" has no purpose -- but remember that these escapes
    357 are never merged with the surrounding text, which can be useful when
    358 you want to control the sub expressions in the form.
    359 
    360   @foo{Alice@||Bob@|    --reads-as-->    (foo "Alice" "Bob" "Carol")
    361        |Carol}
    362 
    363 Note that "@|{...}|" can be parsed as either an escape expression or
    364 as a no-command @-form.  The latter is used in this case (since there
    365 is little point in Scheme code that uses braces.
    366 
    367   @|{blah}|    --reads-as-->    ("blah")
    368 
    369 * Comments
    370 
    371 As noted above, there are two kinds of Scribble comments: "@;{...}" is
    372 a (nestable) comment for a whole body of text (following the same
    373 rules for @-forms), and "@;..." is a line-comment.
    374 
    375   @foo{First line@;{there is still a
    376                     newline here;}
    377        Second line}
    378   --reads-as-->
    379   (foo "First line" "\n" "Second line")
    380 
    381 One useful property of line-comments is that they continue to the end
    382 of the line *and* all following spaces (or tabs).  Using this, you can
    383 get further control of the subforms.
    384 
    385   @foo{A long @;
    386        single-@;
    387        string arg.}
    388   --reads-as-->
    389   (foo "A long single-string arg.")
    390 
    391 Note how this is different from using "@||"s in that strings around it
    392 are not merged.
    393 
    394 * Spaces, Newlines, and Indentation
    395 
    396 The Scribble syntax treats spaces and newlines in a special way is
    397 meant to be sensible for dealing with text.  As mentioned above,
    398 spaces at the beginning and end of body lines are discarded, except
    399 for spaces between a "{" and text, or between text and a "}".
    400 
    401   @foo{bar}         --reads-as-->    (foo "bar")
    402 
    403   @foo{ bar }       --reads-as-->    (foo " bar ")
    404 
    405   @foo{ bar         --reads-as-->    (foo " bar" "\n" "baz ")
    406        baz }
    407 
    408 A single newline that follows an open brace or precedes a closing
    409 brace is discarded, unless there are only newlines in the body; other
    410 newlines are read as a "\n" string
    411 
    412   @foo{bar     --reads-as-->    (foo "bar")
    413   }
    414 
    415   @foo{
    416     bar        --reads-as-->    (foo "bar")
    417   }
    418 
    419   @foo{
    420 
    421     bar        --reads-as-->    (foo "\n" "bar" "\n")
    422 
    423   }
    424 
    425   @foo{
    426     bar
    427                --reads-as-->    (foo "bar" "\n" "\n" "baz")
    428     baz
    429   }
    430 
    431   @foo{        --reads-as-->    (foo "\n")
    432   }
    433 
    434   @foo{
    435                --reads-as-->    (foo "\n" "\n")
    436   }
    437 
    438   @foo{ bar    --reads-as-->    (foo " bar" "\n" "baz ")
    439        baz }
    440 
    441 In the parsed S-expression syntax, a single newline string is used for
    442 all newlines; you can use `eq?' to identify this line.  This can be
    443 used to identify newlines in the original <text-body>.
    444 
    445   (let ([nl (car @'{
    446                    })])
    447     (for-each (lambda (x) (display (if (eq? x nl) "\n... " x)))
    448               @`{foo
    449                  @,@(list "bar" "\n" "baz")
    450                  blah})
    451     (newline))
    452   --prints-->
    453   foo
    454   ... bar
    455   baz
    456   ... blah
    457 
    458 Spaces at the beginning of body lines do not appear in the resulting
    459 S-expressions, but the column of each line is noticed, and all-space
    460 indentation strings are added so the result has the same indentation.
    461 A indentation string is added to each line according to its distance
    462 from the leftmost syntax object (except for empty lines).  (Note: if
    463 you try these examples on a mzscheme REPL, you should be aware that
    464 the reader does not know about the "> " prompt.)
    465 
    466   @foo{       --reads-as-->    (foo "bar" "\n"
    467     bar                             "baz" "\n"
    468     baz                             "blah")
    469     blah
    470   }
    471 
    472   @foo{       --reads-as-->    (foo "begin" "\n"
    473     begin                           "  " "x++;" "\n"
    474       x++;                          "end")
    475     end}
    476 
    477   @foo{       --reads-as-->    (foo "  " "a" "\n"
    478       a                             " " "b" "\n"
    479      b                              "c")
    480     c}
    481 
    482 If the first string came from the openning "{" line, it is not
    483 prepended with an indentation (but it can affect the leftmost syntax
    484 object used for indentation).  This makes sense when formatting
    485 structured code as well as text (see the last example in the following
    486 block).
    487 
    488   @foo{bar    --reads-as-->    (foo "bar" "\n"
    489          baz                        "  " "baz" "\n"
    490        bbb}                         "bbb")
    491 
    492   @foo{ bar   --reads-as-->    (foo " bar" "\n"
    493           baz                       "   " "baz" "\n"
    494         bbb}                        " " "bbb")
    495 
    496   @foo{bar    --reads-as-->    (foo "bar" "\n"
    497      baz                            "baz" "\n"
    498      bbb}                           "bbb")
    499 
    500   @foo{ bar   --reads-as-->    (foo " bar" "\n"
    501      baz                            "baz" "\n"
    502      bbb}                           "bbb")
    503 
    504   @foo{ bar   --reads-as-->    (foo " bar" "\n"
    505      baz                            "baz" "\n"
    506        bbb}                         "  " "bbb")
    507 
    508   @text{Some @b{bold
    509     text}, and
    510     more text.}
    511   --reads-as-->
    512   (text "Some " (b "bold" "\n" "text") ", and" "\n" "more text.")
    513 
    514 Note that each @-form is parsed to an S-expression that has its own
    515 indentation.  This means that Scribble source can be indented like
    516 code, but if indentation matters then you may need to apply
    517 indentation of the outer item to all lines of the inner one.  For
    518 example, in
    519 
    520   @code{
    521     begin
    522       i = 1, r = 1
    523       @bold{while i < n do
    524               r *= i++
    525             done}
    526     end
    527   }
    528   --reads-as-->
    529   (code "begin" "\n"
    530         "  " "i = 1, r = 1" "\n"
    531         "  " (bold "while i < n do" "\n"
    532                    "  " "r *= i++" "\n"
    533                    "done") "\n"
    534         "end")
    535 
    536 a formatter will need to apply the 2-space indentation to the
    537 rendering of the `bold' body.
    538 
    539 Note that to get a first-line text to be counted as a leftmost line,
    540 line and column accounting should be on for the input port
    541 (`use-at-readtable' turns them on for the current input port).
    542 Without this,
    543 
    544   @foo{x1
    545          x2
    546          x3}
    547 
    548 will not have 2-space indentations in the parsed S-expression if
    549 source accounting is not on, but
    550 
    551   @foo{x1
    552          x2
    553        x3}
    554 
    555 will (due to the last line).  Pay attention to this, as it can be a
    556 problem with Scheme code, for example:
    557 
    558   @code{(define (foo x)
    559           (+ x 1))}
    560 
    561 For rare situations where spaces at the beginning (or end) of lines
    562 matter, you can begin (or end) a line with a "@||".
    563 
    564   @foo{
    565     @|| bar @||    --reads-as-->    (foo " bar " "\n" " baz")
    566     @|| baz}
    567 
    568 *** Syntax Properties
    569 
    570 The Scribble reader attaches properties to syntax objects.  These
    571 properties might be useful in rare situations.
    572 
    573 Forms that Scribble reads is marked with a 'scribble property, and a
    574 value of a list of three elements: the first is 'form, the second is
    575 the number of items that were read from the datum part, and the third
    576 is the number of items in the body part (strings, sub-forms, and
    577 escapes).  In both cases, a 0 means an empty datum/body part, and #f
    578 means that the corresponding part was omitted.  If the form has
    579 neither parts, the property is not attached to the result.  This
    580 property can be used to give different meanings to expressions from
    581 the datum and the body parts, for example, implicitly quoted keywords:
    582 
    583   (define-syntax (foo stx)
    584     (let ([p (syntax-property stx 'scribble)])
    585       (syntax-case stx ()
    586         [(_ x ...)
    587          (and (pair? p) (eq? (car p) 'form) (even? (cadr p)))
    588          (let loop ([n (/ (cadr p) 2)]
    589                     [as '()]
    590                     [xs (syntax->list #'(x ...))])
    591            (if (zero? n)
    592              #`(list 'foo `#,(reverse as) #,@xs)
    593              (loop (sub1 n)
    594                    (cons #`(#,(car xs) ,#,(cadr xs)) as)
    595                    (cddr xs))))])))
    596   @foo[x 1 y (* 2 3)]{blah}
    597   --> (foo ((x 1) (y 6)) "blah")
    598 
    599 In addition, the Scribble parser uses syntax properties to mark syntax
    600 items that are not physically in the original source -- indentation
    601 spaces and newlines.  Both of these will have a 'scribble property; an
    602 indentation string of spaces will have 'indentation as the value of
    603 the property, and a newline will have a '(newline S) value where S is
    604 the original newline string including spaces that precede and follow
    605 it (which includes the indentation for the following item).  This can
    606 be used to implement a verbatim environment: drop indentation strings,
    607 and use the original source strings instead of single-newline string.
    608 Here is an example of this.
    609 
    610   (define-syntax (verb stx)
    611     (syntax-case stx ()
    612       [(_ cmd item ...)
    613        #`(cmd
    614           #,@(let loop ([items (syntax->list #'(item ...))])
    615                (if (null? items)
    616                  '()
    617                  (let* ([fst  (car items)]
    618                         [prop (syntax-property fst 'scribble)]
    619                         [rst  (loop (cdr items))])
    620                    (cond [(eq? prop 'indentation) rst]
    621                          [(not (and (pair? prop)
    622                                     (eq? (car prop) 'newline)))
    623                           (cons fst rst)]
    624                          [else (cons (datum->syntax-object
    625                                       fst (cadr prop) fst)
    626                                      rst)])))))]))
    627   @verb[string-append]{
    628     foo
    629       bar
    630   }
    631   --> "foo\n      bar"
    632 
    633 *** Interface
    634 
    635 The "reader.ss" module provides very little functionality for advanced
    636 needs.
    637 
    638 > (read [input-port])
    639 > (read-syntax [source-name] [input-port])
    640 
    641 These procedures implement the Scribble reader.  They do so by
    642 constructing a reader table based on the current one, and using that
    643 in reading.
    644 
    645 > (read-inside [input-port])
    646 > (read-syntax-inside [source-name] [input-port])
    647 
    648 These `-inside' variants parse as if starting inside a "@{...}", and
    649 they return a (syntactic) list.  Useful for implementing languages
    650 that are textual by default (see "docreader.ss" for example).
    651 
    652 > (make-at-readtable [keyword-args...])
    653 
    654 Constructs an @-readtable.  The keyword arguments can customize the
    655 resulting reader in several ways.
    656 
    657 * #:readtable -- a readtable to base the @-readtable on.  Defaults to
    658   the current readtable.
    659 
    660 * #:command-char -- the character used for @-forms; defaults to `#\@'.
    661 
    662 * #:datum-readtable -- determines the readtable used for reading the
    663   datum part.  The default (#t) is to use the @-readtable, otherwise
    664   it can be a readtable, or a readtable-to-readtable function that
    665   will construct one from the @-readtable.  The idea is that you may
    666   want to have completely different uses for the datum part, for
    667   example, introducing a convenient `key=val' syntax for attributes.
    668 
    669 * #:syntax-post-processor -- a function that is applied on each
    670   resulting syntax value after it has been parsed (but before it is
    671   wrapped quoting punctuations).  You can use this to further control
    672   uses of @-forms, for example, making the command be the head of a
    673   list:
    674 
    675     (use-at-readtable
    676       #:syntax-post-processor
    677       (lambda (stx)
    678         (syntax-case stx ()
    679           [(cmd rest ...) #'(list 'cmd rest ...)]
    680           [_else (error "@ forms must have a body")])))
    681 
    682   Beware that the syntax may contain placeholder values at this stage
    683   (e.g: the command part), so you can `plant' your own form that will
    684   do some plain processing later.  For example, here's a setup that
    685   uses a `mk-' prefix for all command names:
    686 
    687     (use-at-readtable
    688       #:syntax-post-processor
    689       (lambda (stx)
    690         (syntax-case stx ()
    691           [(cmd rest ...) #'(add-mk cmd rest ...)]
    692           [_else (error "@ forms must have a body")])))
    693     (define-syntax (add-mk stx)
    694       (syntax-case stx ()
    695         [(_ cmd rest ...)
    696          (identifier? #'cmd)
    697          (with-syntax ([mk-cmd (datum->syntax-object
    698                                 #'cmd
    699                                 (string->symbol
    700                                  (format "mk-~a" (syntax-e #'cmd)))
    701                                 #'cmd)])
    702            (syntax/loc stx (mk-cmd rest ...)))]))
    703 
    704 > (use-at-readtable [keyword-args])
    705 
    706 Installs the Scribble readtable as the default.  Useful for REPL
    707 experimentation.  (Note: enables line and column tracking.)  The given
    708 keyword arguments are used with `make-at-readtable'.