continued work on the guide

svn: r6338
This commit is contained in:
Matthew Flatt 2007-05-26 06:31:34 +00:00
parent 0a07ed3b18
commit 5f37b5e912
13 changed files with 335 additions and 101 deletions

View File

@ -278,7 +278,6 @@
(append
(format-number number
(list
"."
(make-element 'hspace '(" "))))
(part-title-content part))
`(part ,(part-tag part))))))))

View File

@ -122,19 +122,36 @@
(with-handlers ([exn? (lambda (e)
(exn-message e))])
(cons (let ([v (do-plain-eval s #t)])
(copy-value v))
(copy-value v (make-hash-table)))
(get-output-string o)))))]))
(define (install ht v v2)
(hash-table-put! ht v v2)
v2)
;; Since we evaluate everything in an interaction before we typeset,
;; copy each value to avoid side-effects.
(define (copy-value v)
(define (copy-value v ht)
(cond
[(string? v) (string-copy v)]
[(bytes? v) (bytes-copy v)]
[(pair? v) (cons (copy-value (car v))
(copy-value (cdr v)))]
[(and v (hash-table-get ht v #f))
=> (lambda (v) v)]
[(string? v) (install ht v (string-copy v))]
[(bytes? v) (install ht v (bytes-copy v))]
[(pair? v) (let ([p (cons #f #f)])
(hash-table-put! ht v p)
(set-car! p (copy-value (car v) ht))
(set-cdr! p (copy-value (cdr v) ht))
p)]
[(vector? v) (let ([v2 (make-vector (vector-length v))])
(hash-table-put! ht v v2)
(let loop ([i (vector-length v2)])
(unless (zero? i)
(let ([i (sub1 i)])
(vector-set! v2 i (copy-value (vector-ref v i) ht))
(loop i))))
v2)]
[else v]))
(define (strip-comments s)
(cond
[(and (pair? s)

View File

@ -92,7 +92,7 @@
[(0) 'h2]
[(1) 'h3]
[else 'h4])
,@(format-number number '("." (tt nbsp)))
,@(format-number number '((tt nbsp)))
,@(if (part-tag d)
`((a ((name ,(format "~a" `(part ,(part-tag d)))))))
null)
@ -186,6 +186,7 @@
[(boxed) '((width "100%") (bgcolor "lightgray"))]
[(centered) '((align "center"))]
[(at-right) '((align "right"))]
[(at-left) '((align "left"))]
[else null]))
,@(map (lambda (flows)
`(tr ,@(map (lambda (d a)
@ -278,6 +279,8 @@
ds
fns))
(define contents-content '("contents"))
(define index-content '("index"))
(define prev-content '(larr " prev"))
(define up-content '("up"))
(define next-content '("next " rarr))
@ -299,9 +302,12 @@
(and (pair? (cdr l))
(cadr l)))]
[else (loop (cdr l) (car l))]))))
(define/private (part-parent d)
(collected-info-parent (part-collected-info d)))
(define/private (navigation d ht)
(let ([parent (collected-info-parent (part-collected-info d))])
(let ([parent (part-parent d)])
(let*-values ([(prev next) (find-siblings d)]
[(prev) (if prev
(let loop ([prev prev])
@ -322,39 +328,78 @@
(let-values ([(prev next)
(find-siblings parent)])
next)]
[else next])])
(render-table (make-table
'at-right
(list
(list
(make-flow
(list
(make-paragraph
(list
(if parent
[else next])]
[(index) (let loop ([d d])
(let ([p (part-parent d)])
(if p
(loop p)
(let ([subs (part-parts d)])
(and (pair? subs)
(let ([d (car (last-pair subs))])
(and (equal? '("Index") (part-title-content d))
d)))))))])
`(,@(render-table (make-table
'at-left
(list
(cons
(make-flow
(list
(make-paragraph
(list
(make-element
(make-target-url (if prev
(derive-filename prev)
"index.html"))
(if parent
(make-target-url "index.html")
"nonavigation")
contents-content)))))
(if index
(list
(make-flow
(list
(make-paragraph
(list
'nbsp
(if (eq? d index)
(make-element
"nonavigation"
index-content)
(make-link-element
#f
index-content
`(part ,(part-tag index)))))))))
null))))
d ht)
,@(render-table (make-table
'at-right
(list
(list
(make-flow
(list
(make-paragraph
(list
(make-element
(if parent
(make-target-url (if prev
(derive-filename prev)
"index.html"))
"nonavigation")
prev-content)
"")
sep-element
(if parent
sep-element
(make-element
(make-target-url
(if (toc-part? parent)
(derive-filename parent)
"index.html"))
(if parent
(make-target-url
(if (toc-part? parent)
(derive-filename parent)
"index.html"))
"nonavigation")
up-content)
"")
sep-element
(make-element
(if next
(make-target-url (derive-filename next))
"nonavigation")
next-content))))))))
d
ht))))
sep-element
(make-element
(if next
(make-target-url (derive-filename next))
"nonavigation")
next-content))))))))
d
ht)))))
(define/override (render-part d ht)
(let ([number (collected-info-number (part-collected-info d))])

View File

@ -200,15 +200,21 @@
(convert-infix c quote-depth))
=> (lambda (converted)
((loop init-line! quote-depth) converted))]
[(pair? (syntax-e c))
[(or (pair? (syntax-e c))
(vector? (syntax-e c)))
(let* ([sh (or (syntax-property c 'paren-shape)
#\()]
[quote-depth (if (vector? (syntax-e c))
+inf.0
quote-depth)]
[p-color (if (positive? quote-depth)
value-color
(if (eq? sh #\?)
opt-color
paren-color))])
(advance c init-line!)
(when (vector? (syntax-e c))
(out (format "#~a" (vector-length (syntax-e c))) p-color))
(out (case sh
[(#\[ #\?) "["]
[(#\{) "{"]
@ -216,7 +222,9 @@
p-color)
(set! src-col (+ src-col 1))
(hash-table-put! col-map src-col dest-col)
(let lloop ([l c])
(let lloop ([l (if (vector? (syntax-e c))
(vector->short-list (syntax-e c) syntax-e)
c)])
(cond
[(and (syntax? l)
(pair? (syntax-e l)))
@ -357,6 +365,29 @@
(define syntax-ize-hook (make-parameter (lambda (v col) #f)))
(define (vector->short-list v extract)
(let ([l (vector->list v)])
(reverse (list-tail
(reverse l)
(- (vector-length v)
(let loop ([i (sub1 (vector-length v))])
(cond
[(zero? i) 1]
[(eq? (extract (vector-ref v i))
(extract (vector-ref v (sub1 i))))
(loop (sub1 i))]
[else (add1 i)])))))))
(define (short-list->vector v l)
(list->vector
(let ([n (length l)])
(if (n . < . (vector-length v))
(reverse (let loop ([r (reverse l)][i (- (vector-length v) n)])
(if (zero? i)
r
(loop (cons (car r) r) (sub1 i)))))
l))))
(define (syntax-ize v col)
(cond
[((syntax-ize-hook) v col)
@ -370,20 +401,29 @@
c)
(list #f 1 col (+ 1 col)
(+ 1 (syntax-span c)))))]
[(list? v)
(let ([l (let loop ([col (+ col 1)]
[v v])
(if (null? v)
null
(let ([i (syntax-ize (car v) col)])
(cons i
(loop (+ col 1 (syntax-span i)) (cdr v))))))])
(datum->syntax-object #f
l
(list #f 1 col (+ 1 col)
(+ 2
(sub1 (length l))
(apply + (map syntax-span l))))))]
[(or (list? v)
(vector? v))
(let* ([vec-sz (if (vector? v)
(+ 1 (string-length (format "~a" (vector-length v))))
0)])
(let ([l (let loop ([col (+ col 1 vec-sz)]
[v (if (vector? v)
(vector->short-list v values)
v)])
(if (null? v)
null
(let ([i (syntax-ize (car v) col)])
(cons i
(loop (+ col 1 (syntax-span i)) (cdr v))))))])
(datum->syntax-object #f
(if (vector? v)
(short-list->vector v l)
l)
(list #f 1 col (+ 1 col)
(+ 2
vec-sz
(sub1 (length l))
(apply + (map syntax-span l)))))))]
[(pair? v)
(let* ([a (syntax-ize (car v) (+ col 1))]
[sep (if (pair? (cdr v)) 0 3)]

View File

@ -219,7 +219,7 @@
}
.nonavigation {
color: gray;
color: #EEEEEE;
}
.disable {

View File

@ -0,0 +1,75 @@
#reader(lib "docreader.ss" "scribble")
@require[(lib "manual.ss" "scribble")]
@require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"]
@title[#:tag "bytes"]{Bytes and Byte Strings}
A @defterm{byte} is an inexact integer between @scheme[0] and
@scheme[255], inclusive. The @scheme[byte?] predicate recognizes
numbers that represent bytes.
@examples[
(byte? 0)
(byte? 256)
]
A @defterm{byte string} is similar to a string---see
@secref["strings"]---but its content is a sequence of bytes instead of
characters. Byte strings can be used in applications that process pure
ASCII instead of Unicode text. The printed and form of a byte string
supports such uses in particular, because a byte string prints like
the ASCII decoding of the byte string, but prefixed with a
@schemefont{#}. Unprintable ASCII characters or non-ASCII bytes in the
byte string are written with octal notation.
@refdetails["mz:parse-string"]{the syntax of byte strings}
@examples[
#"Apple"
(bytes-ref #"Apple" 0)
(make-bytes 3 65)
(define b (make-bytes 2 0))
b
(bytes-set! b 0 1)
(bytes-set! b 1 255)
b
]
The @scheme[display] form of a byte string writes its raw bytes to the
current output port (see @secref["output"]). Technically,
@scheme[display] of a normal (i.e,. character) string prints the UTF-8
encoding of the string to the current output port, since output is
ultimately defined in terms of bytes; @scheme[display] of a byte
string, however, writes the raw bytes with no encoding. Along the same
lines, when this documentation shows output, it technically shows the
UTF-8-decoded form of the output.
@examples[
(display #"Apple")
(eval:alts (code:line (display #, @schemevalfont{"\316\273"}) (code:comment #, @t{same as @scheme["\316\273"]}))
(display "\316\273"))
(code:line (display #"\316\273") (code:comment #, @t{UTF-8 encoding of @elem["\u03BB"]}))
]
For explicitly converting between strings and byte strings, Scheme
supports three kinds of encodings directly: UTF-8, Latin-1, and the
current locale's encoding. General facilities for byte-to-byte
conversions (especially to and from UTF-8) fill the gap to support
arbitrary string encodings.
@examples[
(bytes->string/utf-8 #"\316\273")
(bytes->string/latin-1 #"\316\273")
(code:line
(parameterize ([current-locale "C"]) (code:comment #, @elem{C locale supports ASCII,})
(bytes->string/locale #"\316\273")) (code:comment #, @elem{only, so...}))
(let ([cvt (bytes-open-converter "cp1253" (code:comment #, @elem{Greek code page})
"UTF-8")]
[dest (make-bytes 2)])
(bytes-convert cvt #"\353" 0 1 dest)
(bytes-close-converter cvt)
(bytes->string/utf-8 dest))
]
@refdetails["mz:bytestrings"]{byte strings and byte-string procedures}

View File

@ -3,7 +3,7 @@
@require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"]
@title{Strings (Unicode)}
@title[#:tag "strings"]{Strings (Unicode)}
A @defterm{string} is a fixed-length array of
@seclink["characters"]{characters}. It prints using doublequotes,
@ -18,8 +18,8 @@ shown with @schemefont["\\u"] when the string is printed.
@refdetails["mz:parse-string"]{the syntax of strings}
The @scheme[display] procedure directly writes the characters of a
string to the current output stream, in contrast to the
string-constant syntax used to print a string result.
string to the current output port (see @secref["output"]), in contrast
to the string-constant syntax used to print a string result.
@examples[
"Apple"
@ -30,19 +30,42 @@ string-constant syntax used to print a string result.
(eval:alts (display #, @schemevalfont{"\u03BB"}) (display "\u03BB"))
]
A string can be mutable or immutable; strings written as constant
A string can be mutable or immutable; strings written directly as
expressions are immutable, but most other strings are mutable. The
@scheme[string] procedure creates a mutable string given content
characters. The @scheme[string-ref] procedure accesses a character
from a string (with 0-based indexing); the @scheme[string-set!]
procedure changes a character in a mutable string.
@scheme[make-string] procedure creates a mutable string given a length
and optional fill character. The @scheme[string-ref] procedure
accesses a character from a string (with 0-based indexing); the
@scheme[string-set!] procedure changes a character in a mutable
string.
@examples[
(string-ref "Apple" 0)
(define s (string #\A #\p #\p #\l #\e))
(define s (make-string 5 #\.))
s
(string-set! s 3 #\u03BB)
(string-set! s 2 #\u03BB)
s
]
String ordering and case operations are generally
@defterm{locale-independent}; that is, they work the same for all
users. A few @defterm{locale-dependent} operations are provided that
allow the way that strings are case-folded and sorted to depend on the
end-user's locale. If you're sorting strings, for example, use
@scheme[string<?] or @scheme[string-ci<?] if the sort result should be
consistent across machines and users, but use @scheme[string-locale<?]
or @scheme[string-locale-ci<?] if the sort is purely to order strings
for an end user.
@examples[
(string<? "apple" "Banana")
(string-ci<? "apple" "Banana")
(string-upcase "Stra\xDFe")
(parameterize ([current-locale "C"])
(string-locale-upcase "Stra\xDFe"))
]
For working with plain ASCII, working with raw bytes, or
encoding/decoding Unicode strings as bytes, use @seclink["bytes"]{byte
strings}.
@refdetails["mz:strings"]{strings and string procedures}

View File

@ -3,7 +3,7 @@
@require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"]
@title[#:tag "characters"]{Characters (Unicode)}
@title[#:tag "characters"]{Characters}
A Scheme @defterm{character} corresponds to a Unicode @defterm{scalar
value}. Roughly, a scalar value is an unsigned integer whose
@ -38,8 +38,8 @@ and linefeed characters print as @scheme[#\space] and
]
The @scheme[display] procedure directly writes a character to the
current output stream, in contrast to the character-constant syntax
used to print a character result.
current output port (see @secref["output"]), in contrast to the
character-constant syntax used to print a character result.
@examples[
#\A

View File

@ -37,4 +37,5 @@ other than @scheme[#f] counts as true.
@include-section["numbers.scrbl"]
@include-section["chars.scrbl"]
@include-section["char-strings.scrbl"]
@include-section["byte-strings.scrbl"]
@include-section["vectors.scrbl"]

View File

@ -6,16 +6,15 @@
@title{A Guide to PLT Scheme}
This guide is intended for programmers who are new to Scheme, new to PLT
Scheme, or new to some part of PLT Scheme. It definitely assumes some
programming experience. If you are new to programming, consider
Scheme, or new to some part of PLT Scheme. It assumes some
programming experience, so if you are new to programming, consider
instead reading @|HtDP|. If you want a quick and pretty overview of PLT
Scheme, start with @|Quick|.
@seclink["to-scheme"]{Chapter 2} provides a brief introduction to
Scheme. After that, this guide dives into the details of putting
Scheme to work. Even though this guide covers much of the PLT Scheme
toolbox, it leaves precise details to @|MzScheme| and other reference
manuals.
Scheme. From @seclink["datatypes"]{Chapter 3} on, this guide dives
into details---covering much of the PLT Scheme toolbox, but leaving
precise details to @|MzScheme| and other reference manuals.
@table-of-contents[]
@ -25,29 +24,6 @@ manuals.
@include-section["data.scrbl"]
@; ----------------------------------------------------------------------
@section[#:tag "scheme-read"]{Reading and Printing}
As we mentioned @seclink["syntax-overview"]{before}, the syntax
of a Scheme program is specified in an unusual way. Specifically, it
is defined by two phases:
@itemize{
@item{a @defterm{read} phase, which parses a stream of characters
into a tree-structured @defterm{S-expression}; and}
@item{an @defterm{expand} phase, which parses the S-expression into a
program.}
}
The second phase is particularly easy to extend, so that Scheme has no
grammar in the traditional sense. At the same time, the first phase is
useful on it's own, and directly available through the @scheme[read]
function. Furthermore, reading of data is naturally matched with
conventions for @defterm{printing} data.
@; ----------------------------------------------------------------------
@section[#:tag "scheme-forms"]{Programs and Expressions}

View File

@ -0,0 +1,58 @@
#reader(lib "docreader.ss" "scribble")
@require[(lib "manual.ss" "scribble")]
@require[(lib "eval.ss" "scribble")]
@require["guide-utils.ss"]
@title[#:tag "vectors"]{Vectors}
A @defterm{vector} is a fixed-length array of arbitarary
values. Unlike a list, a vector supports constant-time access and
update of its elements.
A vector prints similar to a list---as a parenthesized sequence of its
elements---but a vector is prefixed with @schemefont{#} and the length
of the vector. The vector length is optional for a vector as an
expression. Also, a vector as an expression implicitly quotes the
forms for its content, which means that identifiers and parenthesized
forms in a vector constant represent symbols and lists.
@refdetails["mz:parse-vector"]{the syntax of vectors}
@examples[
(eval:alts #, @schemevalfont{#("a" "b" "c")} #("a" "b" "c"))
(eval:alts #, @schemevalfont{#(name (that tune))} #(name (that tune)))
(vector-ref #("a" "b" "c") 1)
(vector-ref #(name (that tune)) 1)
]
When the last @math{n} vector elements of a vector are the same value
(as determined by @scheme[eq?]), then the last @math{n-1} instances
are omitted from the printed form. The vector length shown after the
leading @scheme{#} effectively indicates when repeated trailing
elements are omitted. The same conventions apply for vectors as
expressions.
@examples[
(define v (make-vector 100 "."))
v
(vector-set! v 1 "!")
v
(vector-ref #10("." "?") 8)
]
Like strings, a vector is either mutable or immutable, and vectors
written directly as expressions are immutable.
Vector can be converted to lists and vice-versa via
@scheme[list->vector] and @scheme[vector->list]; such conversions are
particularly useful in combination with predefined procedures on
lists. When allocating extra lists seems too expensive, use consider
using looping forms like @scheme[fold-for], which recognize vectors as
well as lists.
@examples[
(list->vector (map string-titlecase
(vector->list #("three" "blind" "mice"))))
]
@refdetails["mz:vectors"]{vectors and vector procedures}

View File

@ -1,7 +1,7 @@
#reader(lib "docreader.ss" "scribble")
@require["mz.ss"]
@title[#:tag "bytestrings"]{Byte Strings}
@title[#:tag "mz:bytestrings"]{Byte Strings}
A @pidefterm{byte string} is a fixed-length arary of bytes. A
@pidefterm{byte} is an exact integer between @scheme[0] and

View File

@ -430,7 +430,7 @@ constant, the @exnraise[exn:fail:read].
@index['("byte strings" "parsing")]{A} string constant preceded by
@litchar{#} is parsed as a byte-string. (That is, @as-index{@litchar{#"}} starts
a byte-string literal.) See @secref["byte-strings"] for
a byte-string literal.) See @secref["mz:bytestrings"] for
information on byte strings. Byte string constants support the same
escape sequences as character strings, except @litchar["\\u"] and
@litchar["\\U"].