(define nntp-doc
  (mk-document {nntp}
    {The PLT NNTP Toolkit}

    {[(paragraph {The NNTP toolkit implements routines which form the
	basis for a client that can converse with an NNTP (Usenet
	News) server.  The toolkit defines both procedures to
	interface with the server, and exceptions which indicate
	erroneous behavior.})]

      [(paragraph
	 {The toolkit is parameterized over [(italic
	 {communicator})]s, which are structures representing a
	 connection to a particular server.  Several communicators can
	 be open at any given time.  A communicator has four fields:

	   [(mk-itemize
	      (list
		{[(italic {sender})], an output port which sends
		commands to the the server;
		  }
		{[(italic {receiver})], an input port for receiving
		responses from the server;
		  }
		{[(italic {server})], a string containing the name of
		the server, which is useful for error messages and
		identification; and,
		  }
		{[(italic {port})], a number denoting the port number
		on the server to which this connection was
		established.
		  }))]})]

      [(paragraph {The following procedures are defined:})]

      [(mk-itemize
	 (list
	   {[(bold {connect-to-server})] accepts a string, the server's
	     name, and optionally the port number.  If no port number
	     is provided, the default NNTP port (119) is used.  A
	     communicator is returned.}
	   {[(bold {disconnect-from-server})] takes a communicator and
	     closes its connections.}
	   {[(bold {open-news-group})] accepts a communicator and a
	     string, representing the group's name, and makes it the
	     current group.  Three values are returned: the number of
	     articles the server has for the group, the first
	     available article number, and the last article number.}
	   {[(bold {head-of-message})] takes a communicator and a
	     message number, and returns the message's headers as a
	     list of strings.}
	   {[(bold {body-of-message})] takes a communicator and a
	     message number, and returns the message's body as a list
	     of strings.}
	   {[(bold {make-desired-header})] takes a string representing a
	     header, and returns a regular expression which can be
	     matched against header lines.  The string should be given
	     sans a trailing colon; regular expressions may be used
	     within the string.}
	   {[(bold {extract-desired-headers})] accepts a list of strings
	     representing the header and a list of regular expressions
	     representing desired headers, and returns a list of
	     strings denoting the desired headers.}))]

      [(paragraph {This library only interfaces using the NNTP
	 protocol; it does not attempt to improve it by providing an
	 alternative, perhaps more functional, formulation.  Hence, it
	 generates the same errors as those returned by NNTP servers.
	 These errors are expressed as Scheme exceptions.  They are
	 all sub-types of the exception [(bold {nntp})] (which has
	 no fields).})]

      [(itemize
	 {[(bold {unexpected-response})] has two fields: [(italic
	 {code})], a number and [(italic {text})], a string containing
	 the error message returned by the server.  This is raised
	 when the return code is not recognized by the toolkit.}

	 {[(bold {premature-close})] is raised when the server
	 generates an end-of-file in the midst of a multi-line
	 response (such as the message header or body).  The exception
	 has a [(italic {communicator})] field.}

	 {[(bold {non-existent-group})] is raised when the group being
	 opened is not recognized by the server.  Note that not all
	 servers carry all groups.}

	 {[(bold {article-not-in-group})] is raised when an attempt is
	 made to get the header or body of a group outside the range
	 for the group or which has expired or been cancelled.  The
	 [(italic {article})] field holds the article number.}

	 {[(bold {article-not-found})] is raised in other situations
	 when an article cannot be found.  The article number is given
	 in the [(italic {article})] field.}

	 {[(bold {no-group-selected})] is raised when an attempt is
	 made to get the header or body of an article before any group
	 has been selected.}

	 {[(bold {bad-newsgroup-line})] is raised when the server is
	 not following the RFC specification acknowledging that a
	 newsgroup has been set.  It holds the line in the [(italic
	 {line})] field.}

	 {[(bold {bad-status-line})] has one field: [(italic {line})],
	 a string.  This is only flagged when the server does not
	 follow the RFC specification.})]

      [(paragraph {There are at least two routes to take when
	 improving the library's design.  One possibility is to
	 provide a construct, similar to Scheme's i/o functions, in
	 whose dynamic range groups are selected, and inside which all
	 article reading is done.  Another approach is to require all
	 article accesses to also specify a group.  The current group
	 state would be maintained by the implementation, which can
	 optimize away the need to make the current group setting for
	 each article read.  It can also anticipate certain errors.
	 The state would be cached with each communicator.})]

      [(paragraph {This implementation currently provides no posting
	 conveniences, though since the output port to the server is
	 available, the user could implement this.  However, that same
	 argument can be made for the rest of the toolkit as well.})]

      }))

(render-html nntp-doc)
