diff --git a/collects/help/search.ss b/collects/help/search.ss index a8ebce65e2..f2a8173435 100644 --- a/collects/help/search.ss +++ b/collects/help/search.ss @@ -107,7 +107,7 @@ (make-link-element "indexlink" (entry-content entry) - (entry-link-key entry)) + (entry-tag entry)) (make-extra-content (entry-desc entry)))) (limit-length diff --git a/collects/net/doc/cgi.scrbl b/collects/net/doc/cgi.scrbl new file mode 100644 index 0000000000..915fbf4c67 --- /dev/null +++ b/collects/net/doc/cgi.scrbl @@ -0,0 +1,156 @@ +#lang scribble/doc +@(require "common.ss" + (for-label net/cgi + net/cgi-unit + net/cgi-sig)) + +@title{CGI Scripts} + +@defmodule[net/cgi]{The @schememodname[net/cgi] module provides tools +for scripts that follow the Common Gateway Interface @cite["CGI"].} + +The @schememodname[net/cgi] library expects to be run in a certain +context as defined by the CGI standard. This means, for instance, +that certain environment variables will be bound. + +Unfortunately, not all CGI environments provide this. For instance, +the FastCGI library, despite its name, does not bind the environment +variables required of the standard. Users of FastCGI will need to +bind @envvar{REQUEST_METHOD} and possibly also @envvar{QUERY_STRING} +to successfully employ the CGI library. The FastCGI library ought to +provide a way to extract the values bound to these variables; the user +can then put these into the CGI program's environment using the +@scheme[putenv] function. + +A CGI @deftech{binding} is an association of a form item with its +value. Some form items, such as checkboxes, may correspond to +multiple bindings. A binding is a tag-string pair, where a tag is a +symbol or a string. + +@; ---------------------------------------- + +@section{CGI Functions} + +@deftogether[( +@defproc[(get-bindings) (listof (cons/c (or/c symbol? string?) string?))] +@defproc[(get-bindings/post) (listof (cons/c (or/c symbol? string?) string?))] +@defproc[(get-bindings/get) (listof (cons/c (or/c symbol? string?) string?))] +)]{ + +Returns the bindings that corresponding to the options specified by +the user. The @scheme[get-bindings/post] and +@scheme[get-bindings/get] variants work only when POST and GET forms +are used, respectively, while @scheme[get-bindings] determines the +kind of form that was used and invokes the appropriate function.} + + +@defproc[(extract-bindings [key? (or/c symbol? string?)] + [bindings (listof (cons/c (or/c symbol? string?) string?))]) + (listof string?)]{ + +Given a key and a set of bindings, determines which ones correspond to +a given key. There may be zero, one, or many associations for a given +key.} + + +@defproc[(extract-binding/single [key? (or/c symbol? string?)] + [bindings (listof (cons/c (or/c symbol? string?) string?))]) + string?]{ + +Like @scheme[extract-bindings], but for a key that has exactly one +association.} + + +@defproc[(output-http-headers) void?]{ + +Outputs all the HTTP headers needed for a normal response. Only +call this function if you are not using @scheme[generate-html-output] or +@scheme[generate-error-output].} + + +@defproc[(generate-html-output [title string?] + [body (listof string?)] + [text-color string? "#000000"] + [bg-color string? "#ffffff"] + [link-color string? "#cc2200"] + [vlink-color string? "#882200"] + [alink-color string? "#444444"]) + void?]{ + +Outputs an response: a title and a list of strings for the body. + +The last five arguments are each strings representing a HTML color; in +order, they represent the color of the text, the background, +un-visited links, visited links, and a link being selected.} + + +@defproc[(string->html [str string?]) string?]{ + +Converts a string into an HTML string by applying the appropriate HTML +quoting conventions.} + + +@defproc[(generate-link-text [str string?] [html-str string?]) string?]{ + +Takes a string representing a URL, a HTML string for the anchor +text, and generates HTML corresponding to an anchor.} + + +@defproc[(generate-error-output [strs (listof string?)]) any]{ + +The procedure takes a list of HTML strings representing the body, +prints them with the subject line "Internal error", and exits via +@scheme[exit].} + + +@defproc[(get-cgi-method) (one-of/c "GET" "POST")]{ + +Returns either @scheme["GET"] or @scheme["POST"] when invoked inside a +CGI script, unpredictable otherwise.} + + +@defproc[(bindings-as-html (listof (cons/c (or/c symbol? string?) string?))) + (listof string?)]{ + +Converts a set of bindings into a list of HTML strings, which is +useful for debugging.} + + +@defstruct[cgi-error ()]{ + +A supertype for all exceptions thrown by the @schememodname[net/cgi] +library.} + + +@defstruct[(incomplete-%-suffix cgi-error) ([chars (listof char?)])]{ + +Raised when a @litchar{%} in a query is followed by an incomplete +suffix. The characters of the suffix---excluding the +@litchar{%}---are provided by the exception.} + + +@defstruct[(invalid-%-suffix cgi-error) ([char char?])]{ + +Raised when the character immediately following a @litchar{%} in a +query is invalid.} + + +@; ---------------------------------------- + +@section{CGI Unit} + +@defmodule[net/cgi-unit] + +@defthing[cgi@ unit?]{ + +Imports nothing, exports @scheme[cgi^].} + +@; ---------------------------------------- + +@section{CGI Signature} + +@defmodule[net/cgi-sig] + +@defsignature[cgi^ ()]{} + +Includes everything exported by the @schememodname[net/cgi] module. diff --git a/collects/net/doc/common.ss b/collects/net/doc/common.ss new file mode 100644 index 0000000000..7b1497d834 --- /dev/null +++ b/collects/net/doc/common.ss @@ -0,0 +1,9 @@ +#lang scheme/base + +(require scribble/manual + (for-label scheme/base + scheme/contract)) + +(provide (all-from-out scribble/manual) + (for-label (all-from-out scheme/base + scheme/contract))) diff --git a/collects/net/doc/info.ss b/collects/net/doc/info.ss new file mode 100644 index 0000000000..3cbc2bca08 --- /dev/null +++ b/collects/net/doc/info.ss @@ -0,0 +1,3 @@ +(module info setup/infotab + (define name "Net documentation") + (define scribblings '(("net.scrbl" (multi-page main-doc))))) diff --git a/collects/net/doc/net.scrbl b/collects/net/doc/net.scrbl new file mode 100644 index 0000000000..694460d437 --- /dev/null +++ b/collects/net/doc/net.scrbl @@ -0,0 +1,36 @@ +#lang scribble/doc +@(require "common.ss") + +@title{@bold{Net}: PLT Networking Libraries} + +@table-of-contents[] + +@include-section["url.scrbl"] +@include-section["sendurl.scrbl"] +@include-section["smtp.scrbl"] +@include-section["cgi.scrbl"] +@include-section["sendmail.scrbl"] + +@(bibliography + + (bib-entry #:key "CGI" + #:title "Common Gateway Interface (CGI/1.1)" + #:url "http://hoohoo.ncsa.uiuc.edu/cgi/") + + (bib-entry #:key "RFC2396" + #:title "Uniform Resource Identifiers (URI): Generic Syntax" + #:author "T. Berners-Lee, R. Fielding, and L. Masinter" + #:location "RFC" + #:url "http://www.ietf.org/rfc/rfc2396.txt" + #:date "1998") + + (bib-entry #:key "RFC3986" + #:title "Uniform Resource Identifier (URI): Generic Syntax" + #:author "T. Berners-Lee, R. Fielding, and L. Masinter" + #:location "RFC" + #:url "http://www.ietf.org/rfc/rfc3986.txt" + #:date "2005") + +) + +@index-section[] diff --git a/collects/net/doc/sendmail.scrbl b/collects/net/doc/sendmail.scrbl new file mode 100644 index 0000000000..9317719593 --- /dev/null +++ b/collects/net/doc/sendmail.scrbl @@ -0,0 +1,82 @@ +#lang scribble/doc +@(require "common.ss" + (for-label net/sendmail + net/sendmail-unit + net/sendmail-sig)) + +@title{Sending E-Mail via @exec{sendmail}} + +@defmodule[net/sendmail]{The @schememodname[net/sendmail] module +provides tools for sending electronic mail messages using a +@exec{sendmail} program on the local system. See also the +@scheme[net/smtp] package, which sends mail via SMTP.} + +All strings used in mail messages are assumed to conform to their +corresponding SMTP specifications, except as noted otherwise. + +@section{Sendmail Functions} + +@defproc[(send-mail-message/port [from string?] + [subject string?] + [to (listof string?)] + [cc (listof string?)] + [bcc (listof string?)] + [extra-header string?] ...) + output-port?]{ + +The first argument is the header for the sender, the second is the +subject line, the third a list of ``To:'' recipients, the fourth a +list of ``CC:'' recipients, and the fifth a list of ``BCC:'' +recipients. Additional arguments argument supply other mail headers, +which must be provided as lines (not terminated by a linefeed or +carriage return) to include verbatim in the header. + +The return value is an output port into which the client must write +the message. Clients are urged to use @scheme[close-output-port] on +the return value as soon as the necessary text has been written, so +that the sendmail process can complete. + +The @scheme[from] argument can be any value; of course, spoofing +should be used with care.} + +@defproc[(send-mail-message/port [from string?] + [subject string?] + [to (listof string?)] + [cc (listof string?)] + [bcc (listof string?)] + [body (listof string?)] + [extra-header string?] ...) + void?]{ + +Like @scheme[send-mail-message/port], but with @scheme[body] as a list +of strings, each providing a line of the message body. + +Lines that contain a single period do not need to be quoted.} + + +@defstruct[(no-mail-recipients exn) ()]{ + +Raised when no mail recipients were specified for +@scheme[send-mail-message/port].} + + + +@; ---------------------------------------- + +@section{Sendmail Unit} + +@defmodule[net/sendmail-unit] + +@defthing[sendmail@ unit?]{ + +Imports nothing, exports @scheme[sendmail^].} + +@; ---------------------------------------- + +@section{Sendmail Signature} + +@defmodule[net/sendmail-sig] + +@defsignature[sendmail^ ()]{} + +Includes everything exported by the @schememodname[net/sendmail] module. diff --git a/collects/net/doc/sendurl.scrbl b/collects/net/doc/sendurl.scrbl new file mode 100644 index 0000000000..b1ed47e493 --- /dev/null +++ b/collects/net/doc/sendurl.scrbl @@ -0,0 +1,69 @@ +#lang scribble/doc +@(require "common.ss" + (for-label net/sendurl + scheme/file)) + +@title{Opening a Web Browser} + +@defmodule[net/sendurl]{Provides @scheme[send-url] for opening a URL +in the user's chosen web browser.} + +See also @schememodname[browser/external], which requires +@scheme[scheme/gui], but can prompt the user for a browser if no +browser preference is set. + + +@defproc[(send-url [str string?] [separate-window? any/c #t]) + void?]{ + +Opens @scheme[str], which represents a URL, in a platform-specific +manner. For some platforms and configurations, the +@scheme[separate-window?] parameter determines if the browser creates +a new window to display the URL or not. + +Under Windows, @scheme[send-url] normally uses @scheme[shell-execute] +to launch a browser. If the URL appears to contain a fragment, it may +instead use @exec{ftype htmlfile} to obtain a command-line to run, +since @scheme[shell-execute] drops a fragment. + +Under Mac OS X, @scheme[send-url] runs @exec{osascript} to start the +user's chosen browser. + +Under Unix, @scheme[send-url] uses the value of the +@scheme[external-browser] parameter to select a browser.} + + +@defparam[external-browser cmd browser-preference?]{ + +A parameter that, under Unix, determines the browser started +@scheme[send-url]. + +The parameter is initialized to the value of the +@scheme['external-browser] preference. + +The parameter value can be any of the symbols in +@scheme[unix-browser-list], @scheme[#f] to indicate that the +preference is under, or a pair of strings. If the preference is +unset, @scheme[send-url] uses the first of the browsers from +@scheme[unix-browser-list] for which the executable is found. If the +parameter is a pair of strings, then a command line is constructed by +concatenating in order the first string, the URL string, and the +second string. + +If the preferred or default browser can't be launched, +@scheme[send-url] fails. See @scheme[get-preference] and +@scheme[put-preferences] for details on setting preferences.} + +@defproc[(browser-preference? [a any/c]) boolean?]{ + +Returns @scheme[#t] if @scheme[v] is a valid browser preference, +@scheme[#f] otherwise. See @scheme[external-browser] for more +information.} + +@defthing[unix-browser-list (listof symbol?)]{ + +A list of symbols representing Unix executable names that may be tried +in order by @scheme[send-url]. The @scheme[send-url] function +internally includes information on how to launch each executable with +a URL.} + diff --git a/collects/net/doc/smtp.scrbl b/collects/net/doc/smtp.scrbl new file mode 100644 index 0000000000..43f523b97c --- /dev/null +++ b/collects/net/doc/smtp.scrbl @@ -0,0 +1,123 @@ +#lang scribble/doc +@(require "common.ss" + (for-label net/smtp + net/smtp-unit + net/smtp-sig + scheme/tcp + openssl)) + +@title{Sending E-Mail via SMTP} + +@defmodule[net/smtp]{The @schememodname[net/smtp] module provides +tools for sending electronic mail messages using SMTP. The client must +provide the address of an SMTP server; in contrast, the +@schememodname[net/sendmail] module uses a pre-configured +@exec{sendmail} on the local system.} + +The @schememodname[net/head] library defines the format of a +@tech{header} string, which is used by @scheme[send-smtp-message]. The +@schememodname[net/head] module also provides utilities to verify the +formatting of a mail address. The procedures of the @scheme[net/smtp] +module assume that the given string arguments are well-formed. + + +@section{SMTP Functions} + +@defproc[(smtp-send-message [server-address string?] + [from string?] + [to (listof string?)] + [header string?] + [message (listof (or/c string? bytes?))] + [#:port-no port-no/k (integer-in 0 65535) 25] + [#:auth-user user (or/c string? false/c) #f] + [#:auth-passwd pw (or/c string? false/c) #f] + [#:tcp-connect connect + ((string? (integer-in 0 65535)) + . ->* . (input-port? output-port?)) + tcp-connect] + [#:tls-encode encode + (or/c false/c + ((input-port? output-port? + #:mode (one-of/c 'connect) + #:encrypt (one-of/c 'tls) + #:close-original? (one-of/c #t)) + . ->* . (input-port? output-port?))) + #f] + [port-no (integer-in 0 65535) port-no/k]) + void?]{ + +Connects to the server at @scheme[server-address] and @scheme[port-no] +to send a message. The @scheme[from] argument specifies the mail +address of the sender, and @scheme[to] is a list of recipient +addresses (including ``To:'', ``CC'', and ``BCC'' recipients). + +The @scheme[header] argument is the complete message header, which +should already include ``From:'', ``To:'', and ``CC:'' fields +consistent with the given sender and recipients. See also the +@schememodname[net/head] library for header-creating utilities. + +The @scheme[message] argument is the body of the message, where each +string or byte string in the list corresponds to a single line of +message text. No string in @scheme[message] should contain a carriage +return or linefeed character. + +The optional @scheme[port-no] argument---which can be specified either +with the @scheme[#:port-no] keyword or, for backward compatibility, as +an extra argument after keywords---specifies the IP port to use in +contacting the SMTP server. + +The optional @scheme[#:auth-user] and @scheme[#:auth-passwd] keyword +argument supply a username and password for authenticated SMTP (using +the AUTH PLAIN protocol). + +The optional @scheme[#:tcp-connect] keyword argument supplies a +connection procedure to be used in place of @scheme[tcp-connect]. For +example, use @scheme[ssl-connect] to connect to the server via SSL. + +If the optional @scheme[#:tls-encode] keyword argument supplies a +procedure instead of #f, then the ESMTP STARTTLS protocol is used to +initiate SSL communication with the server. The procedure given as the +#:tls-encode argument should be like @scheme[ports->ssl-ports]; it +will be called as + +@schemeblock[ +(encode r w #:mode 'connect #:encrypt 'tls #:close-original? #t) +] + +and it should return two values: an input port and an export port. +All further SMTP communication uses the returned ports. + +For encrypted communication, normally either @scheme[ssl-connect] +should be supplied for @scheme[#:tcp-connect], or +@scheme[ports->ssl-ports] should be supplied for +@scheme[#:tls-encode]---one or the other (depending on what the server +expects), rather than both.} + +@defparam[smtp-sending-end-of-message proc (-> any)]{ + +A parameter that determines a send-done procedure to be called after +@scheme[smtp-send-message] has completely sent the message. Before the +send-done procedure is called, breaking the thread that is executing +@scheme[smtp-send-message] cancels the send. After the send-done +procedure is called, breaking may or may not cancel the send (and +probably will not).} + +@; ---------------------------------------- + +@section{SMTP Unit} + +@defmodule[net/SMTP-unit] + +@defthing[smtp@ unit?]{ + +Imports nothing, exports @scheme[smtp^].} + +@; ---------------------------------------- + +@section{SMTP Signature} + +@defmodule[net/smtp-sig] + +@defsignature[smtp^ ()]{} + +Includes everything exported by the @schememodname[net/smtp] module. diff --git a/collects/net/doc/url.scrbl b/collects/net/doc/url.scrbl new file mode 100644 index 0000000000..f806a6a09a --- /dev/null +++ b/collects/net/doc/url.scrbl @@ -0,0 +1,304 @@ +#lang scribble/doc +@(require "common.ss" + scribble/bnf + (for-label net/url + net/url-unit + net/url-sig + net/head + net/uri-codec)) + +@title{URLs and HTTP} + +@defmodule[net/url]{The @schememodname[net/url] library provides +utilities to parse and manipulate URIs, as specified in RFC 2396 +@cite["RFC2396"], and to use the HTTP protocol.} + +To access the text of a document from the web, first obtain its URL as +a string. Convert the address into a @scheme[url] structure using +@scheme[string->url]. Then, open the document using +@scheme[get-pure-port] or @scheme[get-impure-port], depending on +whether or not you wish to examine its MIME headers. At this point, +you have a regular input port with which to process the document, as with +any other file. + +Currently the only supported protocols are @scheme["http"] and +sometimes @scheme["file"]. See also the @schememodname[net/news] +library. + +@section{URL Structure} + +@declare-exporting[net/url-struct net/url] + +@defmodule*/no-declare[(net/url-struct)]{The URL structure types are +provided by the @schememodname[net/url-struct] library, and +re-exported by @schememodname[net/url].} + +@; ---------------------------------------- + + +@defstruct[url ([scheme (or/c false/c string?)] + [user (or/c false/c string?)] + [host (or/c false/c string?)] + [port (or/c false/c exact-nonnegative-integer?)] + [path-absolute? boolean?] + [path (listof path/param?)] + [query (listof (cons/c symbol? (or/c false/c string?)))] + [fragment (union false/c string?)])]{ + +The basic structure for all URLs, hich is explained in RFC 3986 +@cite["RFC3986"]. The following diagram illustrates the parts: + +@verbatim[#<url] and @scheme[url->string] translate encodings such +as @litchar{%20} into spaces and back again. + +By default, query associations are parsed with either @litchar{;} or +@litchar{&} as a separator, and they are generated with @litchar{&} as +a separator. The @scheme[current-alist-separator-mode] parameter +adjusts the behavior. + +An empty string at the end of the @scheme[path] list corresponds to a +URL that ends in a slash. For example, the result of +@scheme[(string->url "http://www.drscheme.org/a/")] has a +@scheme[path] field with strings @scheme["a"] and @scheme[""], while +the result of @scheme[(string->url "http://www.drscheme.org/a")] has a +@scheme[path] field with only the string @scheme["a"].} + +@defstruct[path/param ([path (or/c string? (one-of/c 'up 'same))] + [param (listof string?)])]{ + +A pair that joins a path segment with its params in a URL.} + +@; ---------------------------------------- + +@section{URL Functions} + +An HTTP connection is created as a @deftech{pure port} or a +@deftech{impure port}. A pure port is one from which the MIME headers +have been removed, so that what remains is purely the first content +fragment. An impure port is one that still has its MIME headers. + +@defproc[(string->url [str string?]) url?]{ + +Parses the URL specified by @scheme[str] into a @scheme[url] +struct. The @scheme[string->url] procedure uses +@scheme[form-urlencoded->alist] when parsing the query, so it is +sensitive to the @scheme[current-alist-separator-mode] parameter for +determining the association separator.} + + +@defproc[(combine-url/relative [base url?] [relative string?]) url?]{ + +Given a base URL and a relative path, combines the two and returns a +new URL as per the URL combination specification. They are combined +according to the rules in RFC 3986 @cite["RFC3986"]. + +This function does not raise any exceptions.} + + +@defproc[(netscape/string->url [str string?]) url?]{ + +Turns a string into a URL, applying (what appear to be) Netscape's +conventions on automatically specifying the scheme: a string starting +with a slash gets the scheme @scheme["file"], while all others get the +scheme @scheme["http"].} + + +@defproc[(url->string [URL url?]) string?]{ + +Generates a string corresponding to the contents of a @scheme[url] struct. +For a @scheme["file:"] URL, empty strings in the path list are treated as +@scheme['same] for @scheme[build-path]. + +The @scheme[url->string] procedure uses +@scheme[alist->form-urlencoded] when formatting the query, so it it +sensitive to the @scheme[current-alist-separator-mode] parameter for +determining the association separator. The default is to separate +associations with a @litchar{&}.} + + + +@deftogether[( +@defproc[(get-pure-port [URL url?] + [header (listof string?) null]) + input-port?] +@defproc[(head-pure-port [URL url?] + [header (listof string?) null]) + input-port?] +@defproc[(delete-pure-port [URL url?] + [header (listof string?) null]) + input-port?] +)]{ + +Initiates a GET/HEAD/DELETE request for @scheme[URL] and returns a +@tech{pure port} corresponding to the body of the response. The +optional list of strings can be used to send header lines to the +server. + +The GET method is used to retrieve whatever information is identified +by @scheme[URL]. + +The HEAD method is identical to GET, except the server must not return +a message body. The meta-information returned in a response to a HEAD +request should be identical to the information in a response to a GET +request. + +The DELETE method is used to delete the entity identified by +@scheme[URL]. + +The @scheme["file"] scheme for URLs is handled only by +@scheme[get-pure-port], which uses @scheme[open-input-file], does not +handle exceptions, and ignores the optional strings.} + +@deftogether[( +@defproc[(get-impure-port [URL url?] + [header (listof string?) null]) + input-port?] +@defproc[(head-impure-port [URL url?] + [header (listof string?) null]) + input-port?] +@defproc[(delete-impure-port [URL url?] + [header (listof string?) null]) + input-port?] +)]{ + +Like @scheme[get-pure-port], etc., but the resulting @tech{impure +port} contains both the returned headers and the body. The +@scheme["file"] URL scheme is not handled by these functions.} + +@deftogether[( +@defproc[(post-pure-port [URL url?] + [post bytes?] + [header (listof string?) null]) + input-port?] +@defproc[(put-pure-port [URL url?] + [post bytes?] + [header (listof string?) null]) + input-port?] +)]{ + +Initiates a POST/PUT request for @scheme[URL] and sends the +@scheme[post] byte string. The result is a @tech{pure port}, which +contains the body of the response is returned. The optional list of +strings can be used to send header lines to the server.} + +@deftogether[( +@defproc[(post-impure-port [URL url?] + [post bytes?] + [header (listof string?) null]) + input-port?] +@defproc[(put-impure-port [URL url?] + [post bytes?] + [header (listof string?) null]) + input-port?] +)]{ + +Like @scheme[post-pure-port] and @scheme[put-pure-port], but the +resulting @tech{impure port} contains both the returned headers and +body.} + + +@defproc[(display-pure-port [in input-port?]) void?]{ + +Writes the output of a pure port, which is useful for debugging purposes.} + + +@defproc[(purify-port [in input-port?]) string?]{ + +Purifies a port, returning the MIME headers, plus a leading line for +the form @litchar{HTTP/}@nonterm{vers}@litchar{ +}@nonterm{code}@litchar{ }@nonterm{message}, where @nonterm{vers} is +something like @litchar{1.0} or @litchar{1.1}, @nonterm{code} is an +exact integer for the response code, and @nonterm{message} is +arbitrary text without a return or newline. + +The @schememodname[net/head.ss] library provides procedures, such as +@scheme[extract-field] for manipulating the header. + +Since web servers sometimes return mis-formatted replies, +@scheme[purify-port] is liberal in what it accepts as a header. as a +result, the result string may be ill formed, but it will either be the +empty string, or it will be a string matching the following regexp: + +@schemeblock[ +#rx"^HTTP/.*?(\r\n\r\n|\n\n|\r\r)" +]} + + +@defproc*[([(call/input-url [URL url?] + [connect (url? . -> . input-port?)] + [handle (input-port? . -> . any)]) + any] + [(call/input-url [URL url?] + [connect (url? (listof string?) . -> . input-port?)] + [handle (input-port? . -> . any)] + [header (listof string?)]) + any])]{ + +Given a URL and a @scheme[connect] procedure like +@scheme[get-pure-port] to convert the URL to an input port (either a +@tech{pure port} or @tech{impure port}), calls the @scheme[handle] +procedure on the port and closes the port on return. The result of the +@scheme[handle] procedure is the result of @scheme[call/input-url]. + +When a @scheme[header] argument is supplied, it is passed along to the +@scheme[connect] procedure. + +The connection is made in such a way that the port is closed before +@scheme[call/input-url] returns, no matter how it returns. In +particular, it is closed if @scheme[handle] raises an exception, or if +the connection process is interruped by an asynchronous break +exception.} + + +@defparam[current-proxy-servers mapping (listof (list/c string? string? (integer-in 0 65535)))]{ + +A parameter that determines a mapping of proxy servers used for +connections. Each mapping is a list of three elements: + +@itemize{ + + @item{the URL scheme, such as @scheme["http"];} + + @item{the proxy server address; and} + + @item{the proxy server port number.} + +} + +Currently, the only proxiable scheme is @scheme["http"]. The default +mapping is the empty list (i.e., no proxies).} + +@; ---------------------------------------- + +@section{URL Unit} + +@defmodule[net/url-unit] + +@defthing[url@ unit?]{ + +Imports @scheme[tcp^], exports @scheme[url^].} + +@; ---------------------------------------- + +@section{URL Signature} + +@defmodule[net/url-sig] + +@defsignature[url^ ()]{ + +Includes everything exported by the @schememodname[net/url] module.} + diff --git a/collects/scheme/help.ss b/collects/scheme/help.ss index 004da3d950..374e9cb40c 100644 --- a/collects/scheme/help.ss +++ b/collects/scheme/help.ss @@ -66,22 +66,25 @@ (define (find-help id) (let ([b (or (identifier-label-binding id) - (identifier-binding id))]) + (identifier-binding id))] + [xref (load-collections-xref + (lambda () + (printf "Loading help index...\n")))]) (if b (let ([tag (xref-binding->definition-tag - (load-collections-xref) + xref (car b) (cadr b))]) (if tag - (go-to-tag tag) + (go-to-tag xref tag) (error 'help "no documentation found for: ~e provided by: ~a" (syntax-e id) (module-path-index-resolve (car b))))) - (search-for-exports (syntax-e id))))) + (search-for-exports xref (syntax-e id))))) -(define (search-for-exports sym) - (let ([idx (xref-index (load-collections-xref))] +(define (search-for-exports xref sym) + (let ([idx (xref-index xref)] [libs null]) (for-each (lambda (entry) (when (exported-index-desc? (entry-desc entry)) @@ -98,8 +101,8 @@ (printf " ~a\n" (car libs))) (loop (cdr libs)))))))) -(define (go-to-tag t) - (let-values ([(file anchor) (xref-tag->path+anchor (load-collections-xref) t)]) +(define (go-to-tag xref t) + (let-values ([(file anchor) (xref-tag->path+anchor xref t)]) (printf "Sending to web browser...\n file: ~a\n anchor: ~a\n" file anchor) diff --git a/collects/scribble/xref.ss b/collects/scribble/xref.ss index de1989cf97..80cf1169d3 100644 --- a/collects/scribble/xref.ss +++ b/collects/scribble/xref.ss @@ -20,7 +20,7 @@ (define-struct entry (words ; list of strings: main term, sub-term, etc. content ; Scribble content to the index label - link-key ; for generating a Scribble link + tag ; for generating a Scribble link desc)) ; further info that depends on the kind of index entry ;; Private: @@ -33,14 +33,13 @@ (define-namespace-anchor here) -(define (load-xref sources) - (let* ([renderer (new (html:render-mixin render%) +(define (load-xref sources #:render% [render% (html:render-mixin render%)]) + (let* ([renderer (new render% [dest-dir (find-system-path 'temp-dir)])] [ci (send renderer collect null null)]) (for-each (lambda (src) (parameterize ([current-namespace (namespace-anchor->empty-namespace here)]) - (let ([r (with-input-from-file src read)]) - (send renderer deserialize-info (cadr r) ci)))) + (send renderer deserialize-info (src) ci))) sources) (make-xrefs renderer (send renderer resolve null null ci)))) @@ -59,11 +58,11 @@ (cadr k) (caddr v))))))) -(define (xref-render xrefs doc dest-file) +(define (xref-render xrefs doc dest-file #:render% [render% (html:render-mixin render%)]) (let* ([dest-file (if (string? dest-file) (string->path dest-file) dest-file)] - [renderer (new (html:render-mixin render%) + [renderer (new render% [dest-dir (path-only dest-file)])] [ci (send renderer collect (list doc) (list dest-file))]) (send renderer transfer-info ci (resolve-info-ci (xrefs-ri xrefs))) @@ -114,7 +113,7 @@ (let-values ([(tag form?) (xref-binding-tag xrefs src id)]) tag)) -(define (xref-tag->path+anchor xrefs tag) - (let ([renderer (new (html:render-mixin render%) +(define (xref-tag->path+anchor xrefs tag #:render% [render% (html:render-mixin render%)]) + (let ([renderer (new render% [dest-dir (find-system-path 'temp-dir)])]) (send renderer tag->path+anchor (xrefs-ri xrefs) tag))) diff --git a/collects/scribblings/scribble/manual.scrbl b/collects/scribblings/scribble/manual.scrbl index b83012c70a..ec9fa2007d 100644 --- a/collects/scribblings/scribble/manual.scrbl +++ b/collects/scribblings/scribble/manual.scrbl @@ -1,14 +1,15 @@ #lang scribble/doc -@require[scribble/manual] -@require["utils.ss"] -@require[(for-syntax scheme/base)] +@(require scribble/manual + "utils.ss" + (for-syntax scheme/base) + (for-label scribble/manual-struct)) @title[#:tag "manual"]{PLT Manual Forms} @defmodule[scribble/manual]{The @schememodname[scribble/manual] -provides all of @schememodname[scribble/basic], plus additional -functions that are relatively specific to writing PLT Scheme -documentation.} +library provides all of @schememodname[scribble/basic], plus +additional functions that are relatively specific to writing PLT +Scheme documentation.} @; ------------------------------------------------------------------------ @section[#:tag "scribble:manual:code"]{Typesetting Code} @@ -773,3 +774,69 @@ an inset command-line example (e.g., in typewriter font).} @defproc[(margin-note [pre-content any/c] ...) paragraph?]{Produces a paragraph to be typeset in the margin instead of inlined.} + +@; ------------------------------------------------------------------------ +@section{Index-Entry Descriptions} + +@defmodule[scribble/manual-struct]{The +@schememodname[scribble/manual-struct] library provides types used to +describe index entries created by @schememodname[scribble/manual] +functions. These structure types are provided separate from +@schememodname[scribble/manual] so that +@schememodname[scribble/manual] need not be loaded when deserializing +cross-reference information that was generated by a previously +rendered document.} + +@defstruct[module-path-index-desc ()]{ + +Indicates that the index entry corresponds to a module definition via +@scheme[defmodule] and company.} + +@defstruct[exported-index-desc ([name symbol?] + [from-libs (listof module-path?)])]{ + +Indicates that the index entry corresponds to the definition of an +exported binding. The @scheme[name] field and @scheme[from-libs] list +correspond to the documented name of the binding and the primary +modules that export the documented name (but this list is not +exhaustive, because new modules can re-export the binding).} + +@defstruct[(procedure-index-desc exported-index-desc) ()]{ + +Indicates that the index entry corresponds to the definition of a +syntactic form via @scheme[defform] and company.} + +@defstruct[(procedure-index-desc exported-index-desc) ()]{ + +Indicates that the index entry corresponds to the definition of a +procedure binding via @scheme[defproc] and company.} + +@defstruct[(thing-index-desc exported-index-desc) ()]{ + +Indicates that the index entry corresponds to the definition of a +binding via @scheme[defthing] and company.} + +@defstruct[(struct-index-desc exported-index-desc) ()]{ + +Indicates that the index entry corresponds to the definition of a +structure type via @scheme[defstruct] and company.} + +@defstruct[(class-index-desc exported-index-desc) ()]{ + +Indicates that the index entry corresponds to the definition of a +class via @scheme[defclass] and company.} + +@defstruct[(interface-index-desc exported-index-desc) ()]{ + +Indicates that the index entry corresponds to the definition of an +interface via @scheme[definterface] and company.} + +@defstruct[(method-index-desc exported-index-desc) ([method-name symbol?] + [class-tag tag?])]{ + +Indicates that the index entry corresponds to the definition of an +method via @scheme[defmethod] and company. The @scheme[_name] field +from @scheme[exported-index-desc] names the class or interface that +contains the method. The @scheme[method-name] field names the method. +The @scheme[class-tag] field provides a pointer to the start of the +documentation for the method's class or interface.} diff --git a/collects/scribblings/scribble/renderer.scrbl b/collects/scribblings/scribble/renderer.scrbl index 7f833b7371..2e6fe41b58 100644 --- a/collects/scribblings/scribble/renderer.scrbl +++ b/collects/scribblings/scribble/renderer.scrbl @@ -3,6 +3,15 @@ @require["utils.ss"] @require[(for-label scheme/class)] +@(define-syntax-rule (defmodule/local lib . content) + (begin + (define-syntax-rule (intro) + (begin + (require (for-label lib)) + (defmodule lib) + . content)) + (intro))) + @title[#:tag "renderer"]{Renderer} A renderer is an object that provides two main methods: @@ -13,26 +22,14 @@ tends to be format-independent, and it usually implemented completely by the base renderer. The latter method generates the actual output, which is naturally specific to a particular format. +@section{Base Renderer} + @defmodule[scribble/base-render]{The @schememodname[scribble/base-render] module provides @scheme[render%], -which implements the core of a renderer.} - -@defmodule*/no-declare[(scribble/text-render)]{The -@schememodname[scribble/text-render] module provides -@schemeidfont{renderer-mixin}, which specializes @scheme[render%] for -generating plain text.} - -@defmodule*/no-declare[(scribble/html-render)]{The -@schememodname[scribble/html-render] module provides -@schemeidfont{renderer-mixin}, which specializes @scheme[render%] for -generating a single HTML file. It also supplies -@schemeidfont{multi-renderer-mixin}, which further specializes the -renderer to produce multi-file HTML.} - -@defmodule*/no-declare[(scribble/latex-render)]{The -@schememodname[scribble/latex-render] module provides -@schemeidfont{renderer-mixin}, which specializes @scheme[render%] for -generating Latex.} +which implements the core of a renderer. This rendering class must be +refined with a mixin from @schememodname[scribble/text-render], +@schememodname[scribble/html-render], or +@schememodname[scribble/latex-render].} The mixin structure is meant to support document-specific extensions to the renderers. For example, the @exec{scribble} command-line tool @@ -97,3 +94,38 @@ Adds the deserialized form of @scheme[v] to @scheme[ci]. } } + +@; ---------------------------------------- + +@section{Text Renderer} + +@defmodule/local[scribble/text-render]{ + +@defthing[render-mixin ((subclass?/c render%) . -> . (subclass?/c render%))]{ + +Specializes @scheme[render%] for generating plain text.}} + +@; ---------------------------------------- + +@section{HTML Renderer} + +@defmodule/local[scribble/html-render]{ + +@defthing[render-mixin ((subclass?/c render%) . -> . (subclass?/c render%))]{ + +Specializes @scheme[render%] for generating a single HTML file.} + +@defthing[render-multi-mixin ((subclass?/c render%) . -> . (subclass?/c render%))]{ + +Further specializes @scheme[render%] for generating a multiple HTML +files. The input class must be first extended with @scheme[render-mixin].}} + +@; ---------------------------------------- + +@section{Latex Renderer} + +@defmodule/local[scribble/latex-render]{ + +@defthing[render-mixin ((subclass?/c render%) . -> . (subclass?/c render%))]{ + +Specializes @scheme[render%] for generating Latex input.}} diff --git a/collects/scribblings/scribble/scribble.scrbl b/collects/scribblings/scribble/scribble.scrbl index 60a4598431..1776e664c0 100644 --- a/collects/scribblings/scribble/scribble.scrbl +++ b/collects/scribblings/scribble/scribble.scrbl @@ -61,25 +61,31 @@ The layers are: @item{@schememodname[scribble/scheme]: a library of support functions for typesetting Scheme code. See @secref["scheme"].} - @item{@schememodname[scribble/manual]: a library of support functions for writing - PLT Scheme documentation; re-exports @schememodname[scribble/basic]. See - @secref["manual"].} + @item{@schememodname[scribble/manual]: a library of support functions + for writing PLT Scheme documentation; re-exports + @schememodname[scribble/basic]. Also, the + @schememodname[scribble/manual-struct] library provides + types for index-entry descriptions created by functions in + @schememodname[scribble/manual]. See @secref["manual"].} - @item{@schememodname[scribble/eval]: a library of support functions for ealuating - code at document-build time, especially for showing - examples. See @secref["eval"].} + @item{@schememodname[scribble/eval]: a library of support functions + for evaluating code at document-build time, especially for + showing examples. See @secref["eval"].} @item{@schememodname[scribble/bnf]: a library of support functions for writing grammars. See @secref["bnf"].} + @item{@schememodname[scribble/xref]: a library of support functions + for using cross-reference information, typically after a + document is rendered (e.g., to search). See @secref["xref"].} + } -The @exec{scribble} command-line utility works with a module that -exports a @scheme{struct.ss}-based document, generating output with a +The @exec{scribble} command-line utility generates output with a specified renderer. More specifically, the executable installs a -renderer, loads the specified modules and extracts the @scheme[doc] -export of each (which must be an instance of @scheme[section] from -@schememodname[scribble/struct]), and renders each. Use @exec{scribble -h} for more +renderer, loads the modules specified on the command line, extracts +the @scheme[doc] export of each module (which must be an instance of +@scheme[part]), and renders each. Use @exec{scribble -h} for more information. @; ------------------------------------------------------------------------ @@ -94,5 +100,6 @@ information. @include-section["manual.scrbl"] @include-section["eval.scrbl"] @include-section["bnf.scrbl"] +@include-section["xref.scrbl"] @index-section[] diff --git a/collects/scribblings/scribble/struct.scrbl b/collects/scribblings/scribble/struct.scrbl index e968e298a2..76c000eb1a 100644 --- a/collects/scribblings/scribble/struct.scrbl +++ b/collects/scribblings/scribble/struct.scrbl @@ -1,6 +1,7 @@ #lang scribble/doc -@require[scribble/manual] -@require["utils.ss"] +@(require scribble/manual + "utils.ss" + (for-label scribble/manual-struct)) @title[#:tag "struct"]{Document Structures And Processing} @@ -362,16 +363,32 @@ Hyperlinks the content to @scheme[tag]. @defstruct[(index-element element) ([tag tag?] - [plain-seq (listof string?)] - [entry-seq list?])]{ + [plain-seq (and/c (listof string?) cons?)] + [entry-seq list?] + [desc any/c])]{ The @scheme[plain-seq] specifies the keys for sorting, where the first - element is the main key, the second is a sub-key, etc. The - @scheme[entry-seq] list must have the same length, and it provides - the form of each key to render in the final document. See also - @scheme[index]. +element is the main key, the second is a sub-key, etc. For example, an +``night'' portion of an index might have sub-entries for ``night, +things that go bump in'' and ``night, defender of the''. The former +would be represented by @scheme[plain-seq] @scheme['("night" "things +that go bump in")], and the latter by @scheme['("night" "defender of +the")]. Naturally, single-element @scheme[plain-seq] lists are the +common case, and at least one word is required, but there is no limit +to the word-list length. -} +The @scheme[entry-seq] list must have the same length as +@scheme[plain-seq]. It provides the form of each key to render in the +final document. + +The @scheme[desc] field provides additional information about the +index entry as supplied by the entry creator. For example, a reference +to a procedure binding can be recognized when @scheme[desc] is an +instance of @scheme[procedure-index-desc]. See +@schememodname[scribble/manual-struct] for other typical types of +@scheme[desc] values. + +See also @scheme[index].} @defstruct[(aux-element element) ()]{ diff --git a/collects/scribblings/scribble/xref.scrbl b/collects/scribblings/scribble/xref.scrbl new file mode 100644 index 0000000000..f4f938fad3 --- /dev/null +++ b/collects/scribblings/scribble/xref.scrbl @@ -0,0 +1,108 @@ +#lang scribble/doc +@(require scribble/manual + "utils.ss" + (for-label scribble/xref + scribble/base-render + scribble/html-render)) + +@title[#:tag "xref"]{Cross-Reference Utilities} + +@defmodule[scribble/xref]{The @schememodname[scribble/xref] library +provides utilities for querying cross-reference information that was +collected from a document build.} + +@; ------------------------------------------------------------------------ + +@defproc[(xref? [v any/c]) boolean?]{ + +Returns @scheme[#t] if @scheme[v] is a cross-reference record created +by @scheme[load-xref], @scheme[#f] otherwise.} + + +@defproc[(load-xref [sources (listof (-> any/c))] + [#:render% using-render% (subclass?/c render%) + (render-mixin render%)]) + xref?]{ + +Creates a cross-reference record given a list of functions that each +produce a serialized information obtained from @xmethod[render% +serialize-info]. + +Since the format of serialized information is specific to a rendering +class, the optional @scheme[using-render%] argument accepts the +relevant class. It default to HTML rendering.} + + +@defproc[(xref-binding->definition-tag [xref xref?] + [mod (or/c module-path? + module-path-index? + path? + resolved-module-path?)] + [sym symbol?]) + (or/c tag? false/c)]{ + +Locates a tag in @scheme[xref] that documents @scheme[sym] as defined +by @scheme[mod]. The @scheme[sym] and @scheme[mod] combination +correspond to the first two elements of a @scheme[identifier-binding] +list result. + +If a documentation point exists in @scheme[xref], a tag is returned, +which might be used with @scheme[xref-tag->path+anchor] or embedded in +a document rendered via @scheme[xref-render]. If no definition point +is found in @scheme[xref], the result is @scheme[#f].} + + +@defproc[(xref-tag->path+anchor [xref xref?] + [tag tag?] + [#:render% using-render% (subclass?/c render%) + (render-mixin render%)]) + (values (or/c false/c path?) + (or/c false/c string?))]{ + +Returns a path and anchor string designated by the key @scheme[tag] +according the cross-reference @scheme[xref]. The first result is +@scheme[#f] if no mapping is found for the given tag. The second +result is @scheme[#f] if the first result is @scheme[#f], and it can +also be @scheme[#f] if the tag refers to a page rather than a specific +point in a page. + +The optional @scheme[using-render%] argument is as for +@scheme[load-xref].} + + + +@defproc[(xref-render [xref xref?] + [doc part?] + [dest path-string?] + [#:render% using-render% (subclass?/c render%) + (render-mixin render%)]) + void?]{ + +Renders @scheme[doc] using the cross-reference info in @scheme[xref] +to the destination @scheme[dest]. For example, @scheme[doc] might be a +generated document of search results using link tags described in +@scheme[xref]. + +The optional @scheme[using-render%] argument is as for +@scheme[load-xref]. It determines the kind of output that is +generated.} + + +@defproc[(xref-index [xref xref?]) (listof entry?)]{ + +Converts indexing information @scheme[xref] into a list of +@scheme[entry] structures.} + + +@defstruct[entry ([words (and/c (listof string?) cons?)] + [content list?] + [tag tag?] + [desc any/c])]{ + +Represents a single entry in a Scribble document index. + +The @scheme[words] list corresponds to +@scheme[index-element-plain-seq]. The @scheme[content] list +corresponds to @scheme[index-element-entry-seq]. The @scheme[desc] +value corresponds to @scheme[index-element-desc]. The @scheme[tag] is +the destination for the index link into the main document.} diff --git a/collects/setup/xref.ss b/collects/setup/xref.ss index 1bcde1877f..ddc51de7fb 100644 --- a/collects/setup/xref.ss +++ b/collects/setup/xref.ss @@ -8,34 +8,40 @@ (define cached-xref #f) -(define (load-collections-xref) +(define (load-collections-xref [report-loading void]) (or cached-xref - (let* ([dirs (find-relevant-directories '(scribblings))] - [infos (map get-info/full dirs)] - [dests (filter - values - (apply append - (map (lambda (i dir) - (let ([s (i 'scribblings)]) - (map (lambda (d) - (if (pair? d) - (let ([flags (if (pair? (cdr d)) - (cadr d) - null)]) - (let ([name (if (and (pair? (cdr d)) - (pair? (cddr d)) - (caddr d)) - (cadr d) - (let-values ([(base name dir?) (split-path (car d))]) - (path-replace-suffix name #"")))]) - (build-path - (if (memq 'main-doc flags) - (build-path (find-doc-dir) name) - (build-path dir "compiled" "doc" name)) - "out.sxref"))) - #f)) - s))) - infos - dirs)))]) - (set! cached-xref (load-xref dests)) - cached-xref))) + (begin + (report-loading) + (let* ([dirs (find-relevant-directories '(scribblings))] + [infos (map get-info/full dirs)] + [dests (filter + values + (apply append + (map (lambda (i dir) + (let ([s (i 'scribblings)]) + (map (lambda (d) + (if (pair? d) + (let ([flags (if (pair? (cdr d)) + (cadr d) + null)]) + (let ([name (if (and (pair? (cdr d)) + (pair? (cddr d)) + (caddr d)) + (cadr d) + (let-values ([(base name dir?) (split-path (car d))]) + (path-replace-suffix name #"")))]) + (build-path + (if (memq 'main-doc flags) + (build-path (find-doc-dir) name) + (build-path dir "compiled" "doc" name)) + "out.sxref"))) + #f)) + s))) + infos + dirs)))]) + (set! cached-xref (load-xref (map (lambda (dest) + (lambda () + (let ([r (with-input-from-file dest read)]) + (cadr r)))) + dests))) + cached-xref))))