doc edits and rendering improvements

svn: r6260
This commit is contained in:
Matthew Flatt 2007-05-24 09:35:34 +00:00
parent 0c4996b84a
commit 51e52cea87
6 changed files with 87 additions and 73 deletions

View File

@ -5,6 +5,7 @@
(provide render-mixin) (provide render-mixin)
(define current-table-depth (make-parameter 0)) (define current-table-depth (make-parameter 0))
(define rendering-tt (make-parameter #f))
(define-struct (toc-paragraph paragraph) ()) (define-struct (toc-paragraph paragraph) ())
@ -24,7 +25,7 @@
(printf "\\parskip=10pt%\n") (printf "\\parskip=10pt%\n")
(printf "\\parindent=0pt%\n") (printf "\\parindent=0pt%\n")
(printf "\\usepackage{graphicx}\n") (printf "\\usepackage{graphicx}\n")
(printf "\\usepackage{times}\n") (printf "\\renewcommand{\\rmdefault}{ptm}\n")
;; (printf "\\usepackage{fullpage}\n") ;; (printf "\\usepackage{fullpage}\n")
(printf "\\usepackage{longtable}\n") (printf "\\usepackage{longtable}\n")
(printf "\\usepackage[usenames,dvipsnames]{color}\n") (printf "\\usepackage[usenames,dvipsnames]{color}\n")
@ -37,17 +38,17 @@
(define-color "schemesymbol" "NavyBlue") (define-color "schemesymbol" "NavyBlue")
(define-color "schemevalue" "ForestGreen") (define-color "schemevalue" "ForestGreen")
(define-color "schemevaluelink" "blue") (define-color "schemevaluelink" "blue")
(define-color "schemeresult" "blue") (define-color "schemeresult" "NavyBlue")
(define-color "schemestdout" "Purple") (define-color "schemestdout" "Purple")
(define-color "schemevariablecol" "NavyBlue") (define-color "schemevariablecol" "NavyBlue")
(printf "\\newcommand{\\schemevariable}[1]{{\\schemevariablecol{\\textsl{#1}}}}\n") (printf "\\newcommand{\\schemevariable}[1]{{\\schemevariablecol{\\textsl{#1}}}}\n")
(define-color "schemeerrorcol" "red") (define-color "schemeerrorcol" "red")
(printf "\\newcommand{\\schemeerror}[1]{{\\schemeerrorcol{\\textit{#1}}}}\n") (printf "\\newcommand{\\schemeerror}[1]{{\\schemeerrorcol{\\textrm{\\textit{#1}}}}}\n")
(printf "\\newcommand{\\schemeopt}[1]{#1}\n") (printf "\\newcommand{\\schemeopt}[1]{#1}\n")
(printf "\\newcommand{\\textsub}[1]{$_{#1}$}\n") (printf "\\newcommand{\\textsub}[1]{$_{#1}$}\n")
(printf "\\newcommand{\\textsuper}[1]{$^{#1}$}\n") (printf "\\newcommand{\\textsuper}[1]{$^{#1}$}\n")
(printf "\\definecolor{LightGray}{rgb}{0.85,0.85,0.85}\n") (printf "\\definecolor{LightGray}{rgb}{0.90,0.90,0.90}\n")
(printf "\\newcommand{\\schemeinput}[1]{\\colorbox{LightGray}{\\schemeinputcol{#1}}}\n") (printf "\\newcommand{\\schemeinput}[1]{\\colorbox{LightGray}{\\hspace{-0.5ex}\\schemeinputcol{#1}\\hspace{-0.5ex}}}\n")
(printf "\\begin{document}\n") (printf "\\begin{document}\n")
(when (part-title-content d) (when (part-title-content d)
(printf "\\title{") (printf "\\title{")
@ -82,7 +83,7 @@
(define/override (render-paragraph p part ht) (define/override (render-paragraph p part ht)
(printf "\n\n") (printf "\n\n")
(if (toc-paragraph? p) (if (toc-paragraph? p)
(printf "\\tableofcontents") (printf "\\newpage \\tableofcontents \\newpage")
(super render-paragraph p part ht)) (super render-paragraph p part ht))
(printf "\n\n") (printf "\n\n")
null) null)
@ -90,30 +91,36 @@
(define/override (render-element e part ht) (define/override (render-element e part ht)
(when (and (link-element? e) (when (and (link-element? e)
(pair? (link-element-tag e)) (pair? (link-element-tag e))
(eq? 'part (car (link-element-tag e)))) (eq? 'part (car (link-element-tag e)))
(null? (element-content e)))
(printf "\\S\\ref{section:~a} " (cadr (link-element-tag e)))) (printf "\\S\\ref{section:~a} " (cadr (link-element-tag e))))
(let ([style (and (element? e) (let ([style (and (element? e)
(element-style e))] (element-style e))]
[wrap (lambda (e s) [wrap (lambda (e s tt?)
(printf "{\\~a{" s) (printf "{\\~a{" s)
(super render-element e part ht) (parameterize ([rendering-tt (or tt?
(rendering-tt))])
(super render-element e part ht))
(printf "}}"))]) (printf "}}"))])
(cond (cond
[(symbol? style) [(symbol? style)
(case style (case style
[(italic) (wrap e "textit")] [(italic) (wrap e "textit" #f)]
[(bold) (wrap e "textbf")] [(bold) (wrap e "textbf" #f)]
[(tt) (wrap e "texttt")] [(tt) (wrap e "texttt" #t)]
[(sf) (wrap e "textsf")] [(sf) (wrap e "textsf" #f)]
[(subscript) (wrap e "textsub")] [(subscript) (wrap e "textsub" #f)]
[(superscript) (wrap e "textsuper")] [(superscript) (wrap e "textsuper" #f)]
[(hspace) (let ([s (content->string (element-content e))]) [(hspace) (let ([s (content->string (element-content e))])
(unless (zero? (string-length s)) (case (string-length s)
(printf "{\\texttt ~a}" [(0) (void)]
(regexp-replace* #rx"." s "~"))))] [(1) (printf "{\\texttt{ }}")] ; allows a line break to replace the space
[else
(printf "{\\texttt{~a}}"
(regexp-replace* #rx"." s "~"))]))]
[else (error 'latex-render "unrecognzied style symbol: ~s" style)])] [else (error 'latex-render "unrecognzied style symbol: ~s" style)])]
[(string? style) [(string? style)
(wrap e style)] (wrap e style (regexp-match? #px"^scheme(?!error)" style))]
[(image-file? style) [(image-file? style)
(let ([fn (install-file (image-file-path style))]) (let ([fn (install-file (image-file-path style))])
(printf "\\includegraphics{~a}" fn))] (printf "\\includegraphics{~a}" fn))]
@ -135,11 +142,13 @@
(parameterize ([current-table-depth (add1 (current-table-depth))]) (parameterize ([current-table-depth (add1 (current-table-depth))])
(if index? (if index?
(printf "\n\n\\begin{theindex}\n") (printf "\n\n\\begin{theindex}\n")
(printf "\n\n~a\\begin{~a}~a{@{}~a@{}}\n" (printf "\n\n~a\\begin{~a}~a{@{}~a}\n"
(if boxed? "\\vspace{4ex}\\hrule\n\\vspace{-2ex}\n" "") (if boxed? "\\vspace{4ex}\\hrule\n\\vspace{-2ex}\n" "")
tableform tableform
opt opt
(make-string (length (car (table-flowss t))) #\l))) (apply string-append
(map (lambda (i) "l@{}")
(car (table-flowss t))))))
(for-each (lambda (flows) (for-each (lambda (flows)
(let loop ([flows flows]) (let loop ([flows flows])
(unless (null? flows) (unless (null? flows)
@ -150,7 +159,11 @@
(unless index? (unless index?
(printf " \\\\\n"))) (printf " \\\\\n")))
(table-flowss t)) (table-flowss t))
(printf "\n\n\\end{~a}\n" tableform)))) (printf "\n\n\\end{~a}~a\n"
tableform
(if (equal? tableform "longtable")
"\\vspace{-3ex}" ;; counteracts mysterious space added after longtable
"")))))
null) null)
(define/override (render-itemization t part ht) (define/override (render-itemization t part ht)
@ -185,16 +198,28 @@
(case c (case c
[(#\\) (display "$\\backslash$")] [(#\\) (display "$\\backslash$")]
[(#\_) (display "$\\_$")] [(#\_) (display "$\\_$")]
[(#\>) (display "{\\texttt >}")] [(#\>) (if (rendering-tt)
[(#\<) (display "{\\texttt <}")] (display "{\\texttt >}")
(display "$>$"))]
[(#\<) (if (rendering-tt)
(display "{\\texttt <}")
(display "$<$"))]
[(#\? #\! #\. #\:) (if (rendering-tt)
(printf "{\\hbox{\\texttt{~a}}}" c)
(display c))]
[(#\~) (display "$\\sim$")] [(#\~) (display "$\\sim$")]
[(#\{ #\} #\# #\% #\&) (display "\\") (display c)] [(#\{ #\} #\# #\% #\&) (display "\\") (display c)]
[(#\uDF) (display "{\\ss}")] [(#\uDF) (display "{\\ss}")]
[(#\u039A #\u0391 #\u039F #\u03A3 [(#\u039A) (display "K")] ; kappa
#\u03BA #\u03b1 #\u03BF #\u03C3) [(#\u0391) (display "A")] ; alpha
(printf "$\\backslash$u~a" [(#\u039F) (display "O")] ; omicron
(let ([s (format "0000~x" (char->integer c))]) [(#\u03A3) (display "$\\Sigma$")]
(substring s (- (string-length s) 4))))] [(#\u03BA) (display "$\\kappa$")]
[(#\u03B1) (display "$\\alpha$")]
[(#\u03BF) (display "o")] ; omicron
[(#\u03C3) (display "$\\sigma$")]
[(#\u03BB) (display "$\\lambda$")]
[(#\u03BC) (display "$\\mu$")]
[else (display c)])) [else (display c)]))
(loop (add1 i)))))) (loop (add1 i))))))

View File

@ -81,7 +81,7 @@
(let ([amt (+ (- c src-col) (- d-col dest-col))]) (let ([amt (+ (- c src-col) (- d-col dest-col))])
(when (positive? amt) (when (positive? amt)
(let ([old-dest-col dest-col]) (let ([old-dest-col dest-col])
(out (make-element 'hspace (list (make-string amt #\space))) no-color) (out (make-element 'hspace (list (make-string amt #\space))) #f)
(set! dest-col (+ old-dest-col amt)))))) (set! dest-col (+ old-dest-col amt))))))
(set! src-col (+ c (or span 1)))))) (set! src-col (+ c (or span 1))))))
(define (convert-infix c quote-depth) (define (convert-infix c quote-depth)
@ -240,7 +240,7 @@
(values (substring s 1) #t #f) (values (substring s 1) #t #f)
(values s #f #f))))]) (values s #f #f))))])
(if (element? (syntax-e c)) (if (element? (syntax-e c))
(out (syntax-e c) no-color) (out (syntax-e c) #f)
(out (if (and (identifier? c) (out (if (and (identifier? c)
color? color?
(quote-depth . <= . 0) (quote-depth . <= . 0)
@ -278,7 +278,7 @@
[else paren-color]))) [else paren-color])))
(hash-table-put! col-map src-col dest-col))]))) (hash-table-put! col-map src-col dest-col))])))
(hash-table-put! col-map src-col dest-col) (hash-table-put! col-map src-col dest-col)
(out prefix1 no-color) (out prefix1 #f)
((loop (lambda () (set! src-col init-col) (set! dest-col 0)) 0) c) ((loop (lambda () (set! src-col init-col) (set! dest-col 0)) 0) c)
(unless (null? content) (unless (null? content)
(finish-line!)) (finish-line!))

View File

@ -33,7 +33,7 @@ Many predefined procedures operate on lists. Here are a few examples:
@interaction[ @interaction[
(code:line (length (list "a" "b" "c")) (code:comment #, @t{count the elements})) (code:line (length (list "a" "b" "c")) (code:comment #, @t{count the elements}))
(code:line (list-ref (list "a" "b" "c") 0) (code:comment #, @t{extract an element by position})) (code:line (list-ref (list "a" "b" "c") 0) (code:comment #, @t{extract by position}))
(list-ref (list "a" "b" "c") 1) (list-ref (list "a" "b" "c") 1)
(code:line (append (list "a" "b") (list "c")) (code:comment #, @t{combine lists})) (code:line (append (list "a" "b") (list "c")) (code:comment #, @t{combine lists}))
(code:line (reverse (list "a" "b" "c")) (code:comment #, @t{reverse order})) (code:line (reverse (list "a" "b" "c")) (code:comment #, @t{reverse order}))
@ -50,22 +50,7 @@ languages. The body of a Scheme iteration is packaged into a procedure
to be applied to each element, so the @scheme[lambda] form becomes to be applied to each element, so the @scheme[lambda] form becomes
particularly handy in combination with iteration procedures. particularly handy in combination with iteration procedures.
The @scheme[for-each] procedure acts the most like a @tt{for} loop: Different list-iteration procedures combine iteration results in
@interaction[
(for-each (lambda (elem)
(printf "I have ~a\n" elem))
(list "pie"
"stew"
"carrots and pizza, and pineapple, too"))
]
The @scheme[for-each] procedure completely ignores the per-element
result of the iteration body, so it is used with loop bodies that have
a side-effect (such as printing output). Keeping in mind that Scheme
programmers avoid side-effects, they also avoid @scheme[for-each].
Other list-iteration procedures use the per-element results, but in
different ways. The @scheme[map] procedure uses the per-element different ways. The @scheme[map] procedure uses the per-element
results to create a new list: results to create a new list:
@ -93,10 +78,10 @@ is true, and discards elements for which it is @scheme[#f]:
(filter positive? (list 1 -2 6 7 0)) (filter positive? (list 1 -2 6 7 0))
] ]
The @scheme[for-each], @scheme[map], @scheme[andmap], @scheme[ormap], The @scheme[map], @scheme[andmap], @scheme[ormap], and @scheme[filter]
and @scheme[filter] procedures can all handle multiple lists, instead procedures can all handle multiple lists, instead of just a single
of just a single list. The lists must all have the same length, and list. The lists must all have the same length, and the given procedure
the given procedure must accept one argument for each list: must accept one argument for each list:
@interaction[ @interaction[
(map (lambda (s n) (substring s 0 n)) (map (lambda (s n) (substring s 0 n))
@ -385,7 +370,7 @@ tail-recursive programs automatically run the same as a loop, lead
Scheme programmers to embrace recursive forms rather than avoid them. Scheme programmers to embrace recursive forms rather than avoid them.
Suppose, for example, that you want to remove consecutive duplicates Suppose, for example, that you want to remove consecutive duplicates
from a list. While that procedure can be written as a loop that from a list. While such a procedure can be written as a loop that
remembers the previous element for each iteration, a Scheme programmer remembers the previous element for each iteration, a Scheme programmer
would more likely just write the following: would more likely just write the following:
@ -394,9 +379,11 @@ would more likely just write the following:
(cond (cond
[(empty? l) empty] [(empty? l) empty]
[(empty? (rest l)) l] [(empty? (rest l)) l]
[(equal? (first l) (first (rest l))) (remove-dups (rest l))] [else
[else (cons (first l) (let ([i (first l)])
(remove-dups (rest l)))])) (if (equal? i (first (rest l)))
(remove-dups (rest l))
(cons i (remove-dups (rest l)))))]))
(remove-dups (list "a" "b" "b" "b" "c" "c")) (remove-dups (list "a" "b" "b" "b" "c" "c"))
] ]
@ -405,10 +392,9 @@ list of length @math{n}, but that's fine, since it produces an
@math{O(n)} result. If the input list happens to be mostly consecutive @math{O(n)} result. If the input list happens to be mostly consecutive
duplicates, then the resulting list can be much smaller than duplicates, then the resulting list can be much smaller than
@math{O(n)}---and @scheme[remove-dups] will also use much less than @math{O(n)}---and @scheme[remove-dups] will also use much less than
@math{O(n)} space! The reason is that the third case in the @math{O(n)} space! The reason is that when the procedure discards
@scheme[cond], which discards duplicates, returns the result of a duplicates, it returns the result of a @scheme[remove-dups] call
@scheme[remove-dups] call directly, so the tail-call ``optimization'' directly, so the tail-call ``optimization'' kicks in:
kicks in:
@schemeblock[ @schemeblock[
(remove-dups (list "a" "b" "b" "b" "b" "b")) (remove-dups (list "a" "b" "b" "b" "b" "b"))

View File

@ -117,7 +117,7 @@ substring
] ]
Within a module, each definition must bind a distinct Within a module, each definition must bind a distinct
@nonterm{id}, and only identifiers with no imported bindings @nonterm{id}, and only identifiers without an imported binding
can be defined. A definition in the REPL, in contrast, overwrites any can be defined. A definition in the REPL, in contrast, overwrites any
previous definition for the same @nonterm{id}. previous definition for the same @nonterm{id}.
@ -413,8 +413,8 @@ clearly written as follows:
[else "huh?"])) [else "huh?"]))
(reply-more "hello scheme") (reply-more "hello scheme")
(reply-more "goodbye cruel world") (reply-more "goodbye cruel world")
(reply-more "what is the airspeed velocity of an unladen swallow?") (reply-more "what is your favorite color?")
(reply-more "but I like the cookie!") (reply-more "mine is lime green")
] ]
The use of square brackets for @scheme[cond] clauses is a The use of square brackets for @scheme[cond] clauses is a

View File

@ -133,7 +133,7 @@ map
(eval:alts (symbol->string (#, @scheme[quote] #, @schemeidfont{map})) (symbol->string 'map)) (eval:alts (symbol->string (#, @scheme[quote] #, @schemeidfont{map})) (symbol->string 'map))
] ]
Naturally, when @scheme[quote] is used on a parenthesized sequence of When @scheme[quote] is used on a parenthesized sequence of
identifiers, it creates a list of symbols: identifiers, it creates a list of symbols:
@interaction[ @interaction[
@ -164,8 +164,8 @@ however, we routinely assume that standard bindings are in scope, and
so we paint quoted forms in green for extra clarity. so we paint quoted forms in green for extra clarity.
A @litchar{'} expands to a @scheme[quote] form in quite a literal A @litchar{'} expands to a @scheme[quote] form in quite a literal
way. You can see this if you put a quote in front of a form that has a way. You can see this if you put a @litchar{'} in front of a form that has a
quote: @litchar{'}:
@interaction[ @interaction[
(eval:alts (car '(#, @schemevalfont{quote} #, @schemevalfont{road})) 'quote) (eval:alts (car '(#, @schemevalfont{quote} #, @schemevalfont{road})) 'quote)
@ -182,8 +182,8 @@ Beware, however, that the REPL's printer recognizes the symbol
(eval:alts '(#, @schemevalfont{quote} #, @schemevalfont{road}) ''road) (eval:alts '(#, @schemevalfont{quote} #, @schemevalfont{road}) ''road)
] ]
There is a method to this madness; it has to do with the true nature There's a method to this madness; it has to do with the true nature of
of Scheme syntax (which we discuss in the next section) and the Scheme syntax (which we discuss in the next section) and the
traditional Lisp approach to meta-programming (which we discuss in the traditional Lisp approach to meta-programming (which we discuss in the
@seclink["quote-eval"]{section afterward}). @seclink["quote-eval"]{section afterward}).
@ -267,7 +267,7 @@ conversion enables a kind of general infix notation:
'(1 . < . 2) '(1 . < . 2)
] ]
This two-dot convension is untraditional, and it has essentially This two-dot convension is non-traditional, and it has essentially
nothing to do with the dot notation for non-list pairs. PLT Scheme nothing to do with the dot notation for non-list pairs. PLT Scheme
programmers use the infix convension sparingly---mostly for asymmetric programmers use the infix convension sparingly---mostly for asymmetric
binary operators such as @scheme[<] and @scheme[is-a?]. binary operators such as @scheme[<] and @scheme[is-a?].

View File

@ -33,9 +33,12 @@
(for-each (lambda (name) (for-each (lambda (name)
(let ([pdf (path-replace-suffix name #".pdf")]) (let ([pdf (path-replace-suffix name #".pdf")])
(rename-file-or-directory (build-path temp-dir pdf)
(build-path temp-dir "tmp.pdf")
#t)
(when (file-exists? pdf) (when (file-exists? pdf)
(delete-file pdf)) (delete-file pdf))
(copy-file (build-path temp-dir pdf) pdf))) (copy-file (build-path temp-dir "tmp.pdf") pdf)))
names)) names))