(U+52BF): Apply new conventions for glyph granularity.
[chise/xemacs-chise.git.1] / man / lispref / mule.texi
index d46ab25..e01a2a1 100644 (file)
@@ -47,7 +47,7 @@ hugely variant shapes as the "same" character.  Sometimes, especially
 where characters are extremely complicated to write, completely
 different shapes may be defined as the "same" character in national
 standards.  The Taiwanese variant of Hanzi is generally the most
-complicated; over the centuries, the Japanese, Koreans, and the People's 
+complicated; over the centuries, the Japanese, Koreans, and the People's
 Republic of China have adopted simplifications of the shape, but the
 line of descent from the original shape is recorded, and the meanings
 and pronunciation of different forms of the same character are
@@ -192,7 +192,7 @@ encoded by doing the same but also prefixing the character with the
 byte 0x8F.
 
   The advantage of a modal encoding is that it is generally more
-space-efficient, and is easily extendable because there are essentially
+space-efficient, and is easily extendible because there are essentially
 an arbitrary number of escape sequences that can be created.  The
 disadvantage, however, is that it is much more difficult to work with
 if it is not being processed in a sequential manner.  In the non-modal
@@ -399,8 +399,8 @@ properties of a charset.
 This function returns the name of @var{charset}.  This will be a symbol.
 @end defun
 
-@defun charset-doc-string charset
-This function returns the doc string of @var{charset}.
+@defun charset-description charset
+This function returns the documentation string of @var{charset}.
 @end defun
 
 @defun charset-registry charset
@@ -416,7 +416,7 @@ This function returns the number of characters per dimension of
 @var{charset}.
 @end defun
 
-@defun charset-columns charset
+@defun charset-width charset
 This function returns the number of display columns per character (in
 TTY mode) of @var{charset}.
 @end defun
@@ -426,12 +426,12 @@ This function returns the display direction of @var{charset}---either
 @code{l2r} or @code{r2l}.
 @end defun
 
-@defun charset-final charset
+@defun charset-iso-final-char charset
 This function returns the final byte of the ISO 2022 escape sequence
 designating @var{charset}.
 @end defun
 
-@defun charset-graphic charset
+@defun charset-iso-graphic-plane charset
 This function returns either 0 or 1, depending on whether the position
 codes of characters in @var{charset} map to the left or right half
 of their font, respectively.
@@ -442,14 +442,19 @@ This function returns the CCL program, if any, for converting
 position codes of characters in @var{charset} into font indices.
 @end defun
 
-  The only property of a charset that can currently be set after
-the charset has been created is the CCL program.
+  The two properties of a charset that can currently be set after the
+charset has been created are the CCL program and the font registry.
 
 @defun set-charset-ccl-program charset ccl-program
 This function sets the @code{ccl-program} property of @var{charset} to
 @var{ccl-program}.
 @end defun
 
+@defun set-charset-registry charset registry
+This function sets the @code{registry} property of @var{charset} to
+@var{registry}.
+@end defun
+
 @node Predefined Charsets, , Charset Property Functions, Charsets
 @subsection Predefined Charsets
 
@@ -501,8 +506,8 @@ chinese-cns11643-7       94x94 M  0  l2r CNS11643.1
 ethiopic                 94x94 2  0  l2r Ethio
 ascii-r2l                94    B  0  r2l ISO8859-1
 ipa                      96    0  1  l2r MuleIPA
-vietnamese-lower         96    1  1  l2r VISCII1.1
-vietnamese-upper         96    2  1  l2r VISCII1.1
+vietnamese-viscii-lower  96    1  1  l2r VISCII1.1
+vietnamese-viscii-upper  96    2  1  l2r VISCII1.1
 @end example
 
 For all of the above charsets, the dimension and number of columns are
@@ -520,13 +525,13 @@ This function makes a multi-byte character from @var{charset} and octets
 @var{arg1} and @var{arg2}.
 @end defun
 
-@defun char-charset ch
-This function returns the character set of char @var{ch}.
+@defun char-charset character
+This function returns the character set of char @var{character}.
 @end defun
 
-@defun char-octet ch &optional n
+@defun char-octet character &optional n
 This function returns the octet (i.e. position code) numbered @var{n}
-(should be 0 or 1) of char @var{ch}.  @var{n} defaults to 0 if omitted.
+(should be 0 or 1) of char @var{character}.  @var{n} defaults to 0 if omitted.
 @end defun
 
 @defun find-charset-region start end &optional buffer
@@ -550,7 +555,7 @@ character is the result of overstriking all the characters in the
 string.
 @end defun
 
-@defun composite-char-string ch
+@defun composite-char-string character
 This function returns a string of the characters comprising a composite
 character.
 @end defun
@@ -702,7 +707,7 @@ character set and UTF-8, for example).
   ISO 2022 provides for switching between character sets via escape
 sequences.  This switching is somewhat complicated, because ISO 2022
 provides for both legacy applications like Internet mail that accept
-only 7 significant bits in some contexts (RFC 822 headers, for example), 
+only 7 significant bits in some contexts (RFC 822 headers, for example),
 and more modern "8-bit clean" applications.  It also provides for
 compact and transparent representation of languages like Japanese which
 mix ASCII and a national script (even outside of computer programs).
@@ -719,7 +724,7 @@ the control character "ASCII DEL" respectively.
 C1 (0x80-0x9F), and GR (0xA0-0xFF).  GL and GR stand for "graphic left"
 and "graphic right", respectively, because of the standard method of
 displaying graphic character sets in tables with the high byte indexing
-columns and the low byte indexing rows.  I don't find it very intuitive, 
+columns and the low byte indexing rows.  I don't find it very intuitive,
 but these are called "registers".
 
   An ISO 2022-conformant encoding for a graphic character set must use a
@@ -800,7 +805,7 @@ well), or by use of shifting (affecting only the following character in
 the data stream) or locking (effective until the next designation or
 locking) control sequences.  An encoding conformant to ISO 2022 is
 typically defined by designating the initial contents of the G0-G3
-registers, specifying an 7 or 8 bit environment, and specifying whether
+registers, specifying a 7 or 8 bit environment, and specifying whether
 further designations will be recognized.
 
   Some examples of character sets and the registered final characters
@@ -890,7 +895,7 @@ bit environments.
 
 (#### Ben says: I think the above is slightly incorrect.  It appears that
 SS2 invokes G2 into GR and SS3 invokes G3 into GR, whereas ESC N and
-ESC O behave as indicated.  The above definitions will not parse 
+ESC O behave as indicated.  The above definitions will not parse
 EUC-encoded text correctly, and it looks like the code in mule-coding.c
 has similar problems.)
 
@@ -1021,25 +1026,25 @@ End-of-line conversion to be used.  It should be one of the types
 listed in @ref{EOL Conversion}.
 
 @item eol-lf
-The coding system which is the same as this one, except that it uses the 
+The coding system which is the same as this one, except that it uses the
 Unix line-breaking convention.
 
 @item eol-crlf
-The coding system which is the same as this one, except that it uses the 
+The coding system which is the same as this one, except that it uses the
 DOS line-breaking convention.
 
 @item eol-cr
-The coding system which is the same as this one, except that it uses the 
+The coding system which is the same as this one, except that it uses the
 Macintosh line-breaking convention.
 
 @item post-read-conversion
 Function called after a file has been read in, to perform the decoding.
-Called with two arguments, @var{beg} and @var{end}, denoting a region of
+Called with two arguments, @var{start} and @var{end}, denoting a region of
 the current buffer to be decoded.
 
 @item pre-write-conversion
 Function called before a file is written out, to perform the encoding.
-Called with two arguments, @var{beg} and @var{end}, denoting a region of
+Called with two arguments, @var{start} and @var{end}, denoting a region of
 the current buffer to be encoded.
 @end table
 
@@ -1098,7 +1103,7 @@ designation by escape sequence.
 If non-@code{nil}, don't use ISO6429's direction specification.
 
 @item escape-quoted
-If non-nil, literal control characters that are the same as the
+If non-@code{nil}, literal control characters that are the same as the
 beginning of a recognized ISO 2022 or ISO 6429 escape sequence (in
 particular, ESC (0x1B), SO (0x0E), SI (0x0F), SS2 (0x8E), SS3 (0x8F),
 and CSI (0x9B)) are ``quoted'' with an escape character so that they can
@@ -1274,10 +1279,10 @@ This function decodes a JIS X 0208 character of Shift-JIS coding-system.
 The corresponding character is returned.
 @end defun
 
-@defun encode-shift-jis-char ch
-This function encodes a JIS X 0208 character @var{ch} to SHIFT-JIS
-coding-system.  The corresponding character code in SHIFT-JIS is
-returned as a cons of two bytes.
+@defun encode-shift-jis-char character
+This function encodes a JIS X 0208 character @var{character} to
+SHIFT-JIS coding-system.  The corresponding character code in SHIFT-JIS
+is returned as a cons of two bytes.
 @end defun
 
 @defun decode-big5-char code
@@ -1286,8 +1291,8 @@ This function decodes a Big5 character @var{code} of BIG5 coding-system.
 is returned.
 @end defun
 
-@defun encode-big5-char ch
-This function encodes the Big5 character @var{char} to BIG5
+@defun encode-big5-char character
+This function encodes the Big5 character @var{character} to BIG5
 coding-system.  The corresponding character code in Big5 is returned.
 @end defun
 
@@ -1297,16 +1302,16 @@ coding-system.  The corresponding character code in Big5 is returned.
   MULE initializes most of the commonly used coding systems at XEmacs's
 startup.  A few others are initialized only when the relevant language
 environment is selected and support libraries are loaded.  (NB: The
-following list is based on XEmacs 21.2.19, the development branch at the 
+following list is based on XEmacs 21.2.19, the development branch at the
 time of writing.  The list may be somewhat different for other
 versions.  Recent versions of GNU Emacs 20 implement a few more rare
 coding systems; work is being done to port these to XEmacs.)
 
-  Unfortunately, there is not a consistent naming convention for character 
-sets, and for practical purposes coding systems often take their name 
+  Unfortunately, there is not a consistent naming convention for character
+sets, and for practical purposes coding systems often take their name
 from their principal character sets (ASCII, KOI8-R, Shift JIS).  Others
-take their names from the coding system (ISO-2022-JP, EUC-KR), and a few 
-from their non-text usages (internal, binary).  To provide for this, and 
+take their names from the coding system (ISO-2022-JP, EUC-KR), and a few
+from their non-text usages (internal, binary).  To provide for this, and
 for the fact that many coding systems have several common names, an
 aliasing system is provided.  Finally, some effort has been made to use
 names that are registered as MIME charsets (this is why the name
@@ -1337,7 +1342,7 @@ table of coding systems.)
 need language usage for the ISO-8859 family.
 
   Note that although true coding system aliases have been implemented for
-XEmacs 21.2, the coding system initialization has not yet been converted 
+XEmacs 21.2, the coding system initialization has not yet been converted
 as of 21.2.19.  So coding systems described as aliases have the same
 properties as the aliased coding system, but will not be equal as Lisp
 objects.
@@ -1671,7 +1676,7 @@ implements a virtual machine with 8 registers called @code{r0}, ...,
 @code{r7}, a number of control structures, and some I/O operators.  Take
 care when using registers @code{r0} (used in implicit @dfn{set}
 statements) and especially @code{r7} (used internally by several
-statements and operations, especially for multiple return values and I/O 
+statements and operations, especially for multiple return values and I/O
 operations).
 
   CCL is used for code conversion during process I/O and file I/O for
@@ -1707,9 +1712,9 @@ executed when the input is exhausted.  Both the main block and the EOF
 block are CCL blocks.
 
   A @dfn{CCL block} is either a CCL statement or list of CCL statements.
-A @dfn{CCL statement} is either a @dfn{set statement} (either an integer 
+A @dfn{CCL statement} is either a @dfn{set statement} (either an integer
 or an @dfn{assignment}, which is a list of a register to receive the
-assignment, an assignment operator, and an expression) or a @dfn{control 
+assignment, an assignment operator, and an expression) or a @dfn{control
 statement} (a list starting with a keyword, whose allowable syntax
 depends on the keyword).
 
@@ -1718,7 +1723,7 @@ depends on the keyword).
 * CCL Statements::      Semantics of CCL statements.
 * CCL Expressions::     Operators and expressions in CCL.
 * Calling CCL::         Running CCL programs.
-* CCL Examples::        The encoding functions for Big5 and KOI-8.
+* CCL Example::         A trivial program to transform the Web's URL encoding.
 @end menu
 
 @node    CCL Syntax, CCL Statements, , CCL
@@ -1804,7 +1809,7 @@ the form @code{(r0 = @var{integer})}.
 @heading I/O statements:
 
   The @dfn{read} statement takes one or more registers as arguments.  It
-reads one byte (a C char) from the input into each register in turn.  
+reads one byte (a C char) from the input into each register in turn.
 
   The @dfn{write} takes several forms.  In the form @samp{(write @var{reg}
 ...)} it takes one or more registers as arguments and writes each in
@@ -1841,7 +1846,7 @@ array, and the @code{branch} statement uses the @var{expression} as the
 index of the CCL block to execute.  Null CCL blocks may be used as
 no-ops, continuing execution with the statement following the
 @code{branch} statement in the containing CCL block.  Out-of-range
-values for the @var{EXPRESSION} are also treated as no-ops.
+values for the @var{expression} are also treated as no-ops.
 
   The @dfn{read-branch} variant of the @dfn{branch} statement takes an
 @var{register}, a @var{CCL block}, and an optional @var{second CCL
@@ -1852,19 +1857,19 @@ block just as the @code{branch} statement does.
 @heading Loop control statements:
 
   The @dfn{loop} statement creates a block with an implied jump from the
-end of the block back to its head.  The loop is exited on a @code{break} 
+end of the block back to its head.  The loop is exited on a @code{break}
 statement, and continued without executing the tail by a @code{repeat}
 statement.
 
   The @dfn{break} statement, written @samp{(break)}, terminates the
 current loop and continues with the next statement in the current
-block. 
+block.
 
   The @dfn{repeat} statement has three variants, @code{repeat},
 @code{write-repeat}, and @code{write-read-repeat}.  Each continues the
 current loop from its head, possibly after performing I/O.
 @code{repeat} takes no arguments and does no I/O before jumping.
-@code{write-repeat} takes a single argument (a register, an 
+@code{write-repeat} takes a single argument (a register, an
 integer, or a string), writes it to the output, then jumps.
 @code{write-read-repeat} takes one or two arguments.  The first must
 be a register.  The second may be an integer or an array; if absent, it
@@ -1937,7 +1942,7 @@ complicated transformation of the Japanese standard JIS encoding to
 Shift JIS.  CCL_DECODE_SJIS is its inverse.)  It is somewhat odd to
 represent the SJIS operations in infix form.
 
-@node    Calling CCL, CCL Examples, CCL Expressions, CCL
+@node    Calling CCL, CCL Example, CCL Expressions, CCL
 @comment Node,        Next,          Previous,        Up
 @subsection Calling CCL
 
@@ -1950,7 +1955,7 @@ other CCL programs, and from Lisp using these functions:
 @defun ccl-execute ccl-program status
 Execute @var{ccl-program} with registers initialized by
 @var{status}.  @var{ccl-program} is a vector of compiled CCL code
-created by @code{ccl-compile}.  It is an error for the program to try to 
+created by @code{ccl-compile}.  It is an error for the program to try to
 execute a CCL I/O command.  @var{status} must be a vector of nine
 values, specifying the initial value for the R0, R1 .. R7 registers and
 for the instruction counter IC.  A @code{nil} value for a register
@@ -1958,10 +1963,10 @@ initializer causes the register to be set to 0.  A @code{nil} value for
 the IC initializer causes execution to start at the beginning of the
 program.  When the program is done, @var{status} is modified (by
 side-effect) to contain the ending values for the corresponding
-registers and IC.  
+registers and IC.
 @end defun
 
-@defun ccl-execute-on-string ccl-program status str &optional continue
+@defun ccl-execute-on-string ccl-program status string &optional continue
 Execute @var{ccl-program} with initial @var{status} on
 @var{string}.  @var{ccl-program} is a vector of compiled CCL code
 created by @code{ccl-compile}.  @var{status} must be a vector of nine
@@ -1969,11 +1974,11 @@ values, specifying the initial value for the R0, R1 .. R7 registers and
 for the instruction counter IC.  A @code{nil} value for a register
 initializer causes the register to be set to 0.  A @code{nil} value for
 the IC initializer causes execution to start at the beginning of the
-program.  An optional fourth argument @var{continue}, if non-nil, causes
+program.  An optional fourth argument @var{continue}, if non-@code{nil}, causes
 the IC to
 remain on the unsatisfied read operation if the program terminates due
 to exhaustion of the input buffer.  Otherwise the IC is set to the end
-of the program.  When the program is done, @var{status} is modified (by 
+of the program.  When the program is done, @var{status} is modified (by
 side-effect) to contain the ending values for the corresponding
 registers and IC.  Returns the resulting string.
 @end defun
@@ -1982,9 +1987,9 @@ registers and IC.  Returns the resulting string.
 registered:
 
 @defun register-ccl-program name ccl-program
-Register @var{name} for CCL program @var{program} in
-@code{ccl-program-table}.  @var{program} should be the compiled form of
-a CCL program, or nil.  Return index number of the registered CCL
+Register @var{name} for CCL program @var{ccl-program} in
+@code{ccl-program-table}.  @var{ccl-program} should be the compiled form of
+a CCL program, or @code{nil}.  Return index number of the registered CCL
 program.
 @end defun
 
@@ -2003,11 +2008,307 @@ value and 0.
 Resets the CCL interpreter's internal elapsed time registers.
 @end defun
 
-@node    CCL Examples, ,  Calling CCL, CCL
+@node    CCL Example, ,  Calling CCL, CCL
 @comment Node,         Next, Previous,    Up
-@subsection CCL Examples
+@subsection CCL Example
+
+  In this section, we describe the implementation of a trivial coding
+system to transform from the Web's URL encoding to XEmacs' internal
+coding.  Many people will have been first exposed to URL encoding when
+they saw ``%20'' where they expected a space in a file's name on their
+local hard disk; this can happen when a browser saves a file from the
+web and doesn't encode the name, as passed from the server, properly.
+
+  URL encoding itself is underspecified with regard to encodings beyond
+ASCII.  The relevant document, RFC 1738, explicitly doesn't give any
+information on how to encode non-ASCII characters, and the ``obvious''
+way---use the %xx values for the octets of the eight bit MIME character
+set in which the page was served---breaks when a user types a character
+outside that character set.  Best practice for web development is to
+serve all pages as UTF-8 and treat incoming form data as using that
+coding system.  (Oh, and gamble that your clients won't ever want to
+type anything outside Unicode.  But that's not so much of a gamble with
+today's client operating systems.)  We don't treat non-ASCII in this
+example, as dealing with @samp{(read-multibyte-character ...)} and
+errors therewith would make it much harder to understand.
+
+  Since CCL isn't a very rich language, we move much of the logic that
+would ordinarily be computed from operations like @code{(member ..)},
+@code{(and ...)} and @code{(or ...)} into tables, from which register
+values are read and written, and on which @code{if} statements are
+predicated.  Much more of the implementation of this coding system is
+occupied with constructing these tables---in normal Emacs Lisp---than it
+is with actual CCL code.
+
+  All the @code{defvar} statements we deal with in the next few sections
+are surrounded by a @code{(eval-and-compile ...)}, which means that the
+logic which initializes these variables executes at compile time, and if
+XEmacs loads the compiled version of the file, these variables are
+initialized as constants.
+
+@menu
+* Four bits to ASCII::  Two tables used for getting hex digits from ASCII.
+* URI Encoding constants::  Useful predefined characters. 
+* Numeric to ASCII-hexadecimal conversion:: Trivial in Lisp, not so in CCL.
+* Characters to be preserved:: No transformation needed for these characters.
+* The program to decode to internal format:: .
+* The program to encode from internal format:: . 
+* The actual coding system:: .
+@end menu
+
+@node Four bits to ASCII, URI Encoding constants, , CCL Example
+@subsubsection Four bits to ASCII
+
+  The first @code{defvar} is for
+@code{url-coding-high-order-nybble-as-ascii}, a 256-entry table that
+maps from an octet's value to the ASCII encoding for the hex value of
+its most significant four bits.  That might sound complex, but it isn't;
+for decimal 65, hex value @samp{#x41}, the entry in the table is the
+ASCII encoding of `4'.  For decimal 122, ASCII `z', hex value
+@code{#x7a}, @code{(elt url-coding-high-order-nybble-as-ascii #x7a)}
+after this file is loaded gives the ASCII encoding of 7.
+
+@example
+(defvar url-coding-high-order-nybble-as-ascii
+  (let ((val (make-vector 256 0))
+       (i 0))
+    (while (< i (length val))
+      (aset val i (char-to-int (aref (format "%02X" i) 0)))
+      (setq i (1+ i)))
+    val)
+  "Table to find an ASCII version of an octet's most significant 4 bits.")
+@end example
+
+  The next table, @code{url-coding-low-order-nybble-as-ascii} is almost
+the same thing, but this time it has a map for the hex encoding of the
+low-order four bits.  So the sixty-fifth entry (offset @samp{#x41}) is
+the ASCII encoding of `1', the hundred-and-twenty-second (offset
+@samp{#x7a}) is the ASCII encoding of `A'.
 
-  This section is not yet written.
+@example
+(defvar url-coding-low-order-nybble-as-ascii 
+  (let ((val (make-vector 256 0))
+       (i 0))
+    (while (< i (length val))
+      (aset val i (char-to-int (aref (format "%02X" i) 1)))
+      (setq i (1+ i)))
+    val)
+  "Table to find an ASCII version of an octet's least significant 4 bits.")
+@end example
+
+@node URI Encoding constants, Numeric to ASCII-hexadecimal conversion, Four bits to ASCII, CCL Example
+@subsubsection URI Encoding constants
+
+  Next, we have a couple of variables that make the CCL code more
+readable.  The first is the ASCII encoding of the percentage sign; this
+character is used as an escape code, to start the encoding of a
+non-printable character.  For historical reasons, URL encoding allows
+the space character to be encoded as a plus sign--it does make typing
+URLs like @samp{http://google.com/search?q=XEmacs+home+page} easier--and
+as such, we have to check when decoding for this value, and map it to
+the space character.  When doing this in CCL, we use the
+@code{url-coding-escaped-space-code} variable. 
+  
+@example
+(defvar url-coding-escape-character-code (char-to-int ?%)
+  "The code point for the percentage sign, in ASCII.")
+
+(defvar url-coding-escaped-space-code (char-to-int ?+)
+  "The URL-encoded value of the space character, that is, +.")
+@end example
+
+@node Numeric to ASCII-hexadecimal conversion, Characters to be preserved, URI Encoding constants, CCL Example
+@subsubsection Numeric to ASCII-hexadecimal conversion
+
+  Now, we have a couple of utility tables that wouldn't be necessary in
+a more expressive programming language than is CCL. The first is sixteen
+in length, and maps a hexadecimal number to the ASCII encoding of that
+number; so zero maps to ASCII `0', ten maps to ASCII `A.' The second
+does the reverse; that is, it maps an ASCII character to its value when
+interpreted as a hexadecimal digit. ('A' => 10, 'c' => 12, '2' => 2, as
+a few examples.)
+
+@example
+(defvar url-coding-hex-digit-table 
+  (let ((i 0)
+       (val (make-vector 16 0)))
+    (while (< i 16)
+      (aset val i (char-to-int (aref (format "%X" i) 0)))
+      (setq i (1+ i)))
+    val)
+  "A map from a hexadecimal digit's numeric value to its encoding in ASCII.")
+
+(defvar url-coding-latin-1-as-hex-table
+  (let ((val (make-vector 256 0))
+       (i 0))
+    (while (< i (length val))
+      ;; Get a hex val for this ASCII character.
+      (aset val i (string-to-int (format "%c" i) 16))
+      (setq i (1+ i)))
+    val)
+  "A map from Latin 1 code points to their values as hexadecimal digits.")
+@end example
+
+@node Characters to be preserved, The program to decode to internal format, Numeric to ASCII-hexadecimal conversion, CCL Example
+@subsubsection Characters to be preserved
+
+  And finally, the last of these tables.  URL encoding says that
+alphanumeric characters, the underscore, hyphen and the full stop
+@footnote{That's what the standards call it, though my North American
+readers will be more familiar with it as the period character.} retain
+their ASCII encoding, and don't undergo transformation.
+@code{url-coding-should-preserve-table} is an array in which the entries
+are one if the corresponding ASCII character should be left as-is, and
+zero if they should be transformed.  So the entries for all the control
+and most of the punctuation charcters are zero.  Lisp programmers will
+observe that this initialization is particularly inefficient, but
+they'll also be aware that this is a long way from an inner loop where
+every nanosecond counts.
+
+@example
+(defvar url-coding-should-preserve-table 
+  (let ((preserve 
+        (list ?- ?_ ?. ?a ?b ?c ?d ?e ?f ?g ?h ?i ?j ?k ?l ?m ?n ?o 
+              ?p ?q ?r ?s ?t ?u ?v ?w ?x ?y ?z ?A ?B ?C ?D ?E ?F ?G
+              ?H ?I ?J ?K ?L ?M ?N ?O ?P ?Q ?R ?S ?T ?U ?V ?W ?X ?Y
+              ?Z ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9))
+       (i 0)
+       (res (make-vector 256 0)))
+    (while (< i 256)
+      (when (member (int-char i) preserve)
+       (aset res i 1))
+      (setq i (1+ i)))
+    res)
+  "A 256-entry array of flags, indicating whether or not to preserve an
+octet as its ASCII encoding.")
+@end example
+
+@node The program to decode to internal format, The program to encode from internal format, Characters to be preserved, CCL Example
+@subsubsection The program to decode to internal format
+
+  After the almost interminable tables, we get to the CCL.  The first
+CCL program, @code{ccl-decode-urlcoding} decodes from the URL coding to
+our internal format; since this version of CCL doesn't have support for
+error checking on the input, we don't do any verification on it.
+
+The buffer magnification--approximate ratio of the size of the output
+buffer to the size of the input buffer--is declared as one, because
+fractional values aren't allowed. (Since all those %20's will map to 
+` ', the length of the output text will be less than that of the input
+text.)  
+
+So, first we read an octet from the input buffer into register
+@samp{r0}, to set up the loop.  Next, we start the loop, with a
+@code{(loop ...)} statement, and we check if the value in @samp{r0} is a
+percentage sign.  (Note the comma before
+@code{url-coding-escape-character-code}; since CCL is a Lisp macro
+language, we can break out of the macro evaluation with a comman, and as
+such, ``@code{,url-coding-escape-character-code}'' will be evaluated as a
+literal `37.')  
+
+If it is a percentage sign, we read the next two octets into @samp{r2}
+and @samp{r3}, and convert them into their hexadecimal numeric values,
+using the @code{url-coding-latin-1-as-hex-table} array declared above.
+(But again, it'll be interpreted as a literal array.)  We then left
+shift the first by four bits, mask the two together, and write the
+result to the output buffer.
+
+If it isn't a percentage sign, and it is a `+' sign, we write a
+space--hexadecimal 20--to the output buffer. 
+
+If none of those things are true, we pass the octet to the output buffer
+untransformed.  (This could be a place to put error checking, in a more
+expressive language.)  We then read one more octet from the input
+buffer, and move to the next iteration of the loop. 
+
+@example
+(define-ccl-program ccl-decode-urlcoding
+  `(1  
+    ((read r0)
+     (loop
+       (if (r0 == ,url-coding-escape-character-code)
+          ((read r2 r3)
+           ;; Assign the value at offset r2 in the url-coding-hex-digit-table
+           ;; to r3.
+           (r2 = r2 ,url-coding-latin-1-as-hex-table)
+           (r3 = r3 ,url-coding-latin-1-as-hex-table)
+           (r2 <<= 4)
+           (r3 |= r2)
+           (write r3))
+        (if (r0 == ,url-coding-escaped-space-code)
+            (write #x20)
+          (write r0)))
+       (read r0)
+       (repeat))))
+  "CCL program to take URI-encoded ASCII text and transform it to our
+internal encoding. ")
+@end example
+
+@node The program to encode from internal format, The actual coding system, The program to decode to internal format, CCL Example
+@subsubsection The program to encode from internal format
+
+  Next, we see the CCL program to encode ASCII text as URL coded text.
+Here, the buffer magnification is specified as three, to account for ` '
+mapping to %20, etc.  As before, we read an octet from the input into
+@samp{r0}, and move into the body of the loop.  Next, we check if we
+should preserve the value of this octet, by reading from offset
+@samp{r0} in the @code{url-coding-should-preserve-table} into @samp{r1}.
+Then we have an @samp{if} statement predicated on the value in
+@samp{r1}; for the true branch, we write the input octet directly.  For
+the false branch, we write a percentage sign, the ASCII encoding of the
+high four bits in hex, and then the ASCII encoding of the low four bits
+in hex. 
+
+We then read an octet from the input into @samp{r0}, and repeat the loop.
+
+@example
+(define-ccl-program ccl-encode-urlcoding
+  `(3
+    ((read r0)
+     (loop
+       (r1 = r0 ,url-coding-should-preserve-table)
+       ;; If we should preserve the value, just write the octet directly.
+       (if r1
+          (write r0)
+        ;; else, write a percentage sign, and the hex value of the octet, in
+        ;; an ASCII-friendly format.
+        ((write ,url-coding-escape-character-code)
+         (write r0 ,url-coding-high-order-nybble-as-ascii)
+         (write r0 ,url-coding-low-order-nybble-as-ascii)))
+       (read r0)
+       (repeat))))
+  "CCL program to encode octets (almost) according to RFC 1738")
+@end example
+
+@node The actual coding system, , The program to encode from internal format, CCL Example
+@subsubsection The actual coding system
+
+To actually create the coding system, we call
+@samp{make-coding-system}.  The first argument is the symbol that is to
+be the name of the coding system, in our case @samp{url-coding}. The
+second specifies that the coding system is to be of type
+@samp{ccl}---there are several other coding system types available,
+including, see the documentation for @samp{make-coding-system} for the
+full list. Then there's a documentation string describing the wherefore
+and caveats of the coding system, and the final argument is a property
+list giving information about the CCL programs and the coding system's
+mnemonic. 
+
+@example
+(make-coding-system 
+ 'url-coding 'ccl 
+ "The coding used by application/x-www-form-urlencoded HTTP applications.
+This coding form doesn't specify anything about non-ASCII characters, so
+make sure you've transformed to a seven-bit coding system first."
+ '(decode ccl-decode-urlcoding
+   encode ccl-encode-urlcoding
+   mnemonic "URLenc"))
+@end example
+
+If you're lucky, the @samp{url-coding} coding system describe here
+should be available in the XEmacs package system. Otherwise, downloading
+it from @samp{http://www.parhasard.net/url-coding.el} should work for
+the foreseeable future. 
 
 @node Category Tables, , CCL, MULE
 @section Category Tables
@@ -2034,8 +2335,8 @@ whether the character is in that category.
   Special Lisp functions are provided that abstract this, so you do not
 have to directly manipulate bit vectors.
 
-@defun category-table-p obj
-This function returns @code{t} if @var{arg} is a category table.
+@defun category-table-p object
+This function returns @code{t} if @var{object} is a category table.
 @end defun
 
 @defun category-table &optional buffer
@@ -2049,24 +2350,23 @@ This function returns the standard category table.  This is the one used
 for new buffers.
 @end defun
 
-@defun copy-category-table &optional table
-This function constructs a new category table and return it.  It is a
-copy of the @var{table}, which defaults to the standard category table.
+@defun copy-category-table &optional category-table
+This function returns a new category table which is a copy of
+@var{category-table}, which defaults to the standard category table.
 @end defun
 
-@defun set-category-table table &optional buffer
-This function selects a new category table for @var{buffer}.  One
-argument, a category table.  @var{buffer} defaults to the current buffer
-if omitted.
+@defun set-category-table category-table &optional buffer
+This function selects @var{category-table} as the new category table for
+@var{buffer}.  @var{buffer} defaults to the current buffer if omitted.
 @end defun
 
-@defun category-designator-p obj
-This function returns @code{t} if @var{arg} is a category designator (a
+@defun category-designator-p object
+This function returns @code{t} if @var{object} is a category designator (a
 char in the range @samp{' '} to @samp{'~'}).
 @end defun
 
-@defun category-table-value-p obj
-This function returns @code{t} if @var{arg} is a category table value.
+@defun category-table-value-p object
+This function returns @code{t} if @var{object} is a category table value.
 Valid values are @code{nil} or a bit vector of size 95.
 @end defun