racket/collects/scribblings/slideshow/slides.scrbl
2010-05-02 12:19:25 -06:00

592 lines
20 KiB
Racket

#lang scribble/doc
@(require "ss.ss"
(for-label (except-in racket/gui drop)
slideshow/step
slideshow/slides-to-picts))
@(define d=> @elem['rarr])
@title[#:style 'toc]{Making Slides}
@declare-exporting[slideshow/base slideshow]
@defmodule*/no-declare[(slideshow/base)]{The
@racketmodname[slideshow/base] module, which is re-provided by
@racketmodname[slideshow], provides the functions for creating slides.}
@local-table-of-contents[]
@; ----------------------------------------------------------------------
@section{Primary Slide Functions}
@defproc[(slide [#:title title (or/c #f string? pict?) #f]
[#:name name (or/c #f string?) title]
[#:layout layout (or/c 'auto 'center 'top 'tall) 'auto]
[#:inset inset slide-inset? (make-slide-inset 0 0 0 0)]
[#:timeout secs (or/c #f real?) #f]
[#:condense? condense? any/c (and timeout #t)]
[element (flat-rec-contract elem/c
(or/c pict?
'next 'next! 'alts 'alts~ 'nothing
comment?
(listof (listof elem/c))))] ...)
void?]{
Creates and registers a slide. See @secref["staging"] for information
about @racket[element]s.
When this function is first called in non-printing mode, then the
viewer window is opened. Furthermore, each call to the function
@racket[yield]s, so that the viewer window can be refreshed, and so
the user can step through slides.
If @racket[title] is not @racket[#f], then a title is shown for the
slide. The @racket[name] is used in the slide-navigation dialog, and
it defaults to @racket[title].
If @racket[layout] is @racket['top], then the content is top-aligned,
with @racket[(* 2 gap-size)] space between the title and the
content. The @racket['tall] layout is similar, but with only
@racket[gap-size]. The @racket['center] mode centers the content
(ignoring space consumed by the title). The @racket['auto] mode is
like @racket['center], except when @racket[title] is non-@racket[#f]
and when the space between the title and content would be less than
@racket[(* 2 gap-size)], in which case it behaves like @racket['top].
The @racket[inset] argument supplies an inset that makes the
slide-viewing window smaller when showing the slide. See
@racket[make-slide-inset] for more information.
If @racket[secs] argument for @racket[#:timeout] is not @racket[#f],
then the viewer automatically advances from this slide to the next
after @racket[secs] seconds, and manual advancing skips this slide.
If @racket[condense?] is ture, then in condense mode (as specified by
the @Flag{c} command-line flag), the slide is not created and
registered.}
@defproc[(t [str string?]) pict?]{
The normal way to make plain text. Returns @racket[(text str
(current-main-font) (current-font-size))].}
@defproc[(it [str string?]) pict?]{
The normal way to make italic text. Returns @racket[(text str (cons
'italic (current-main-font)) (current-font-size))].}
@defproc[(bt [str string?]) pict?]{
The normal way to make bold text. Returns @racket[(text str (cons
'bold (current-main-font)) (current-font-size))].}
@defproc[(bit [str string?]) pict?]{
Bold-italic text. Returns @racket[(text str (list* 'bold 'italic
(current-main-font)) (current-font-size))].}
@defproc[(tt [str string?]) pict?]{
The normal way to make monospaced text. Returns @racket[(text str
`(bold . modern) (current-font-size))].}
@defproc[(rt [str string?]) pict?]{
The normal way to make serif text. Returns @racket[(text str 'roman
(current-font-size))].}
@defproc[(titlet [str string?]) pict?]{
Creates title text. Returns @racket[((current-titlet) str)].}
@defproc[(para [#:width width real? (current-para-width)]
[#:align align (or/c 'left 'center 'right) 'left]
[#:fill? fill? any/c #t]
[#:decode? decode? any/c #t]
[element (flat-rec-contract elem/c
(or/c string? pict? (listof elem/c)))] ...)
pict?]{
Generates a paragraph pict that is no wider than @racket[width] units,
and that is exactly @racket[width] units if @racket[fill?] is true. If
@racket[fill?] is @racket[#f], then the result pict is as wide as the
widest line.
Each list within @racket[element]s is spliced into the sequence of
string and pict elements. If @racket[decode?] is true, then strings
among the @racket[element]s are decoded by performing the following
substitutions: @litchar{---} @d=> @litchar["\u2014"], @litchar{--}
@d=> @litchar["\u2013"], @litchar{``} @d=> @litchar["\u201C"],
@litchar{''} @d=> @litchar["\u201D"], @litchar{'} @d=>
@litchar["\u2019"]. In addition, to better work with
@racketmodname[at-exp] notation, if an @racket[element] is @racket["\n"],
then it is dropped along with any spaces at the start of the next
element.
Strings are split at spaces for word-wrapping to fit the page, and a
space is added between elements. If a string element starts with one
of the following punctuation marks (after decoding), however, no space
is added before the string:
@t{
@hspace[2] @litchar{-} @litchar{'} @litchar{,} @litchar{.} @litchar{ } @litchar{:}
@litchar{;} @litchar{?} @litchar{!} @litchar{)} @litchar["\u201D"] @litchar["\u2019"]
}
The @racket[align] argument specifies how to align lines within the
paragraph.
See the spacing between lines is determined by the
@racket[current-line-sep] parameter.}
@defproc[(item [#:width width real? (current-para-width)]
[#:bullet blt pict? bullet]
[#:align align (or/c 'left 'center 'right) 'left]
[#:fill? fill? any/c #t]
[#:decode? decode? any/c #t]
[element (flat-rec-contract elem/c
(or/c string? pict? (listof elem/c)))] ...)
pict?]{
Like @racket[para], but with @racket[blt] followed by @racket[(/
gap-size 2)] space appended horizontally to the resulting paragraph,
aligned with the top line. The paragraph width of @racket[blt] plus
@racket[(/ gap-size 2)] is subtracted from the maximum width of the
paragraph.}
@defproc[(subitem [#:width width real? (current-para-width)]
[#:bullet blt pict? o-bullet]
[#:align align (or/c 'left 'center 'right) 'left]
[#:fill? fill? any/c #t]
[#:decode? decode? any/c #t]
[element (flat-rec-contract elem/c
(or/c string? pict? (listof elem/c)))] ...)
pict?]{
Like @racket[item], but an additional @racket[(* 2 gap-size)] is
subtracted from the paragraph width and added as space to the left of
the pict. Also, @racket[o-bullet] is the default bullet, instead of
@racket[bullet].}
@defproc[(clickback [pict pict?] [thunk (-> any)])
pict?]{
Creates a pict that embeds the given one, and is the same size as the
given pict, but that when clicked during a presentation calls
@racket[thunk].}
@defproc[(size-in-pixels [pict pict?]) pict?]{
Scales @racket[pict] so that it is displayed on the screen as
@racket[(pict-width pict)] pixels wide and @racket[(pict-height pict)]
pixels tall. The result is @racket[pict] when using a 1024 by 768
display.}
@defproc[(make-outline [name (or/c symbol? (listof symbol?))]
[title (or/c string? pict?)]
[subitems (or/c #f null?
(symbol? . -> . pict?))]
...)
(symbol? . -> . void?)]{
Returns a function that takes a symbol and generates an outline
slide.
The @racket[...] above applies to all three arguments together. Each
trio of arguments defines a section for the outline:
@itemize[
@item{The section @racket[name] is either a symbol or a list of symbols. When
the outline function is called later to make an outline, the
given symbol is compared to the section's symbol(s), and the
section is marked as current if the symbol matches.}
@item{The @racket[title] is used as the displayed name of the
section.}
@item{The @racket[subitems] are displayed when the section is
active. It can be @racket[#f] or @racket[null] (for historical
reasons) if no subitems are to be displayed. Otherwise, it
should be a function that takes a symbol (the same one passed
to the outline maker) and produces a pict.}
]}
@defproc[(comment [text (or/c string? pict?)] ...)
comment?]{
Combines strings and picts to be used as a slide element for (usually
hidden) commentary. Use the result as an argument to @racket[slide].}
@defproc[(comment? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a comment produced by
@racket[comment].}
@; ------------------------------------------------------------------------
@section{Slide Registration}
@defproc[(most-recent-slide) slide?]{
Returns a slide structure that be supplied @racket[re-slide] to make a
copy of the slide.}
@defproc[(retract-most-recent-slide) slide?]{
Cancels the most recently created slide, and also returns a slide
structure that be supplied to @racket[re-slide] to restore the slide
(usually in a later position).}
@defproc[(re-slide [slide slide?] [pict pict? (blank)])
void?]{
Re-inserts a slide, @racket[lt-superimpose]ing the given additional
@racket[pict].}
@defproc[(slide? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a slide produced by
@racket[most-recent-slide] or @racket[retract-most-recent-slide].}
@; ------------------------------------------------------------------------
@section{Viewer Control}
@defproc[(start-at-recent-slide) void?]{
Sets the starting slide for the talk to the most recently created
slide. If this function is used multiple times, the last use overrides
the earlier uses.}
@defproc[(enable-click-advance! [on? any/c]) void?]{
Enables or disables slide advance as a result of a mouse click.}
@defproc[(set-use-background-frame! [on? any/c]) void?]{
Enables or disables the creation of a background frame, which is
typically useful only when @racket[make-slide-inset] is used are
active. The last enable/disable before the first slide registration
takes effect once and for all.}
@defproc[(set-page-numbers-visible! [on? any/c]) void?]{
Determines whether slide numbers are initially visible in the viewer.}
@defparam[current-page-number-font font (is-a?/c font%)]{
Parameter that determines the font used to draw the page number (if
visible).}
@defparam[current-page-number-color color (or/c string? (is-a?/c color%))]{
Parameter that determines the color used to draw the page number (if
visible).}
@defparam[current-page-number-adjust proc (-> number? string? string?)]{
Parameter that controls the precise text
that appears to indicate the page numbers (if visible). The
input to the function is the default string and the slide
number, and the result is what is drawn in the bottom right
corner. The default parameter value just returns its first
argument.
}
@; ------------------------------------------------------------------------
@section{Constants and Layout Variables}
@defthing[gap-size 24]{
A width commonly used for layout.}
@defthing[bullet pict?]{
A filled bullet used by default by @racket[item].}
@defthing[o-bullet pict?]{
A hollow bullet used by default by @racket[subitem].}
@defidform[client-w]{
Produces the width of the display area, minus @racket[margin]s. The
result of the form changes if the margin is adjusted via
@racket[set-margin!].}
@defidform[client-h]{
Produces the height of the display area, minus @racket[margin]s, but
including the title area). The result of the form changes if the
margin is adjusted via @racket[set-margin!].}
@defidform[full-page]{
Produces an empty pict that is the same size as the client area, which
is like @racket[(blank client-w client-h)].}
@defidform[titleless-page]{
Produces an empty pict that is the same size as the client area minus
the title area in @racket['top] layout mode, which is like
@racket[(blank client-w (- client-h title-h (* 2 gap-size)))].}
@defidform[margin]{
Produces a number that corresponds to the current margin, which
surrounds every side of the slide. The client area for a slide
corresponds to the display area (which is always 1024 by 768) minus
this margin on each side. The default margin is @racket[20].
The margin can be adjusted via @racket[set-margin!].}
@defidform[title-h]{
Produces a number that corresponds to the height of a title created by
@racket[titlet].
If @racket[titlet] is changed via the @racket[current-titlet]
parameter, the title height should be updated via
@racket[set-title-h!].}
@defthing[printing? boolean?]{
The value is @racket[#t] if slides are being generated for printed
output, @racket[#f] for normal on-screen display. Printing mode is
normally triggered via the @DFlag{print} or @DFlag{ps} command-line
flag.}
@defthing[condense? boolean?]{
The value is @racket[#t] if slides are being generated in condensed
mode, @racket[#f] for normal mode. Condensed mode is normally
triggered via the @DFlag{condense} command-line flag.}
@; ------------------------------------------------------------------------
@section{Configuration}
@defparam[current-font-size n exact-nonnegative-integer?]{
Parameter that determines he font size used by @racket[t],
@racket[para], etc. The default size is @racket[32].}
@defparam[current-main-font style text-style/c]{
Parameter that determines the font size used by @racket[t],
@racket[para], etc. The default is platform-specific; possible
initial values include @racket['swiss], @racket["Verdana"], and
@racket["Gill Sans"].}
@defparam[current-line-sep n exact-nonnegative-integer?]{
Parameter that controls the amount of space used between lines by
@racket[para], @racket[item], and @racket[subitem].}
@defparam[current-para-width n exact-nonnegative-integer?]{
Parameter that controls the width of a pict created by
@racket[para], @racket[item], and @racket[subitem].}
@defparam[current-title-color color (or/c string? (is-a?/c color%))]{
Parameter used by the default @racket[current-titlet] to colorize the
title. The default is @racket["black"].}
@defparam[current-slide-assembler proc ((or/c string? #f)
exact-nonnegative-integer?
pict?
. -> .
pict?)]{
Parameter whose value is a function for assembling slide content into
a single pict; the assembling function takes a string for the title
(or @racket[#f]), a separation for the title (if any) and pict, and a
pict for the slide content (not counting the title).
The result is of the assembler is @racket[ct-superimpose]d with the
client area, but the result pict might draw outside the client region
to paint the screen margins, too.
The default assembler uses @racket[titlet] to turn a title string (if
any) to a pict. See also @racket[current-titlet] and
@racket[set-title-h!],.
The slide assembler is @emph{not} responsible for adding page
numbers to the slide; that job belongs to the viewer. See also
@racket[current-page-number-font], @racket[current-page-number-color],
and @racket[set-page-numbers-visible!].}
@defparam[current-titlet proc (string? . -> . pict?)]{
Parameter to configure @racket[titlet]. The default is
@racketblock[
(lambda (s)
(colorize (text s (current-main-font) 40)
(current-title-color)))
]
If this parameter is changed such that the result is a different
height, then @racket[set-title-h!] should be called to update the
value produced by @racket[title-h], @racket[titleless-page], etc.}
@defproc[(set-margin! [amt real?]) void?]{
Changes the margin that surrounds the client area. See also
@racket[margin].}
@defproc[(set-title-h! [amt real?]) void?]{
Changes the expected height of a title, which adjusts @racket[title-h],
@racket[client-h], @racket[full-page], and @racket[titleless-page].}
@defproc[(make-slide-inset [left-inset exact-nonnegative-integer?]
[top-inset exact-nonnegative-integer?]
[right-inset exact-nonnegative-integer?]
[bottom-inset exact-nonnegative-integer?])
slide-inset?]{
Creates a slide inset, which describes a number of pixels to inset the
viewer for a slide on each side.}
@defproc[(slide-inset? [v any/c]) boolean?]{
Returns @racket[#t] if @racket[v] is a slide inset created by
@racket[make-slide-inset], @racket[#f] otherwise.}
@; ----------------------------------------------------------------------
@section{Pict-Staging Helper}
@defmodule[slideshow/step]{The @racketmodname[slideshow/step] library
provides syntax for breaking a complex slide into steps that are more
complex than can be handled with @racket['next] and @racket['alts] in
a @racket[slide] sequence.}
@defform[(with-steps (id ...) body ...)]{
Evaluates the @racket[body]s once for each @racket[id], skipping an
@racket[id] if its name ends with @litchar{~} and @racket[condense?]
is true. The results of the last @racket[body] for each iteration are
collected into a list, which is the result of the @racket[with-steps]
form.
Within the @racket[body]s, several keywords are bound non-hygienically
(using the first @racket[body]'s lexical context):
@itemize[
@item{@racket[(only? id)] --- returns @racket[#t] during the
@racket[id] step (i.e., during the evaluation of the
@racket[body]s for @racket[id]), @racket[#f] otherwise.}
@item{@racket[(vonly id)] --- returns the identity function during
the @racket[id] step, @racket[ghost] otherwise.}
@item{@racket[(only id _then-expr)] returns the result of
@racket[_then-expr] during the @racket[id] step, @racket[values]
otherwise.}
@item{@racket[(only id _then-expr _else-expr)] returns the result
of @racket[_then-expr] during the @racket[id] step, the result of
@racket[_else-expr] otherwise.}
@item{@racket[(before? id)] --- returns @racket[#t] before the
@racket[id] step, @racket[#f] starting for the @racket[id] and
afterward.}
@item{@racket[(vbefore id)], @racket[(before id _then-expr)], or
@racket[(before id _then-expr _else-expr)] --- analogous to
@racket[vonly] and @racket[only].}
@item{@racket[(after? id)] --- returns @racket[#t] after the
@racket[id] step, @racket[#f] through the @racket[id] step.}
@item{@racket[(vafter id)], @racket[(after id _then-expr)], or
@racket[(after id _then-expr _else-expr)] --- analogous to
@racket[vonly] and @racket[only].}
@item{@racket[(between? _a-id _b-id)] --- returns @racket[#t]
starting from the @racket[_a-id] step through the @racket[_b-id]
step, @racket[#f] otherwise.}
@item{@racket[(vbetween _a-id _b-id)], @racket[(between _a-id
_b-id _then-expr)], or @racket[(between _a-id _b-id _then-expr
_else-expr)] --- analogous to @racket[vonly] and @racket[only].}
@item{@racket[(between-excel? _a-id _b-id)] --- returns
@racket[#t] starting from the @racket[_a-id] step through steps
before the @racket[_b-id] step, @racket[#f] for the @racket[_b-id]
step and afterward.}
@item{@racket[(vbetween-excl _a-id _b-id)], @racket[(between-excl
_a-id _b-id _then-expr)], or @racket[(between-excl _a-id _b-id
_then-expr _else-expr)] --- analogous to @racket[vonly] and
@racket[only].}
]}
@defform[(with-steps~ (id ...) body ...)]{
Like @racket[with-steps], but when @racket[condense?] is true, then
@racket[expr] is evaluated only for the last @racket[id] (independent
of whether the name fo the last @racket[id] name ends in @litchar{~}).
}
@; ----------------------------------------------------------------------
@section{Slides to Picts}
@defmodule[slideshow/slides-to-picts]
@defproc[(get-slides-as-picts [path path-string?]
[width real?]
[height real?]
[condense? any/c]
[stop-after (or/c #f exact-nonnegative-integer?) #f])
(listof pict?)]{
Executes the Slideshow program indicated by @racket[path] in a fresh
namespace, and returns a list of picts for the slides. Each pict has
the given @racket[width] and @racket[height], and @racket[condense?]
determines whether the Slideshow program is executed in condense
mode.
If @racket[stop-after] is not @racket[#f], then the list is truncated
after @racket[stop-after] slides are converted to picts.}