Kaydet (Commit) c5f8fe3a authored tarafından Barry Warsaw's avatar Barry Warsaw

Updates do email package documentation for markup, style, and

organization.
üst c86f6ca2
...@@ -14,8 +14,9 @@ ...@@ -14,8 +14,9 @@
The \module{email} package is a library for managing email messages, The \module{email} package is a library for managing email messages,
including MIME and other \rfc{2822}-based message documents. It including MIME and other \rfc{2822}-based message documents. It
subsumes most of the functionality in several older standard modules subsumes most of the functionality in several older standard modules
such as \module{rfc822}, \module{mimetools}, \module{multifile}, and such as \refmodule{rfc822}, \refmodule{mimetools},
other non-standard packages such as \module{mimecntl}. \refmodule{multifile}, and other non-standard packages such as
\module{mimecntl}.
The primary distinguishing feature of the \module{email} package is The primary distinguishing feature of the \module{email} package is
that it splits the parsing and generating of email messages from the that it splits the parsing and generating of email messages from the
...@@ -38,8 +39,8 @@ manipulated, and finally the model is rendered back into ...@@ -38,8 +39,8 @@ manipulated, and finally the model is rendered back into
flat text. flat text.
It is perfectly feasible to create the object model out of whole cloth It is perfectly feasible to create the object model out of whole cloth
-- i.e. completely from scratch. From there, a similar progression can --- i.e. completely from scratch. From there, a similar progression
be taken as above. can be taken as above.
Also included are detailed specifications of all the classes and Also included are detailed specifications of all the classes and
modules that the \module{email} package provides, the exception modules that the \module{email} package provides, the exception
...@@ -49,76 +50,13 @@ some auxiliary utilities, and a few examples. For users of the older ...@@ -49,76 +50,13 @@ some auxiliary utilities, and a few examples. For users of the older
descendent, a section on differences and porting is provided. descendent, a section on differences and porting is provided.
\subsection{Representing an email message} \subsection{Representing an email message}
\input{emailmessage}
The primary object in the \module{email} package is the
\class{Message} class, provided in the \refmodule{email.Message}
module. \class{Message} is the base class for the \module{email}
object model. It provides the core functionality for setting and
querying header fields, and for accessing message bodies.
Conceptually, a \class{Message} object consists of \emph{headers} and
\emph{payloads}. Headers are \rfc{2822} style field name and
values where the field name and value are separated by a colon. The
colon is not part of either the field name or the field value.
Headers are stored and returned in case-preserving form but are
matched case-insensitively. There may also be a single
\emph{Unix-From} header, also known as the envelope header or the
\mailheader{From_} header. The payload is either a string in the case of
simple message objects, a list of \class{Message} objects for
multipart MIME documents, or a single \class{Message} instance for
\mimetype{message/rfc822} type objects.
\class{Message} objects provide a mapping style interface for
accessing the message headers, and an explicit interface for accessing
both the headers and the payload. It provides convenience methods for
generating a flat text representation of the message object tree, for
accessing commonly used header parameters, and for recursively walking
over the object tree.
\subsection{Parsing email messages} \subsection{Parsing email messages}
Message object trees can be created in one of two ways: they can be \input{emailparser}
created from whole cloth by instantiating \class{Message} objects and
stringing them together via \method{add_payload()} and
\method{set_payload()} calls, or they can be created by parsing a flat text
representation of the email message.
The \module{email} package provides a standard parser that understands
most email document structures, including MIME documents. You can
pass the parser a string or a file object, and the parser will return
to you the root \class{Message} instance of the object tree. For
simple, non-MIME messages the payload of this root object will likely
be a string (e.g. containing the text of the message). For MIME
messages, the root object will return 1 from its
\method{is_multipart()} method, and the subparts can be accessed via
the \method{get_payload()} and \method{walk()} methods.
Note that the parser can be extended in limited ways, and of course
you can implement your own parser completely from scratch. There is
no magical connection between the \module{email} package's bundled
parser and the
\class{Message} class, so your custom parser can create message object
trees in any way it find necessary. The \module{email} package's
parser is described in detail in the \refmodule{email.Parser} module
documentation.
\subsection{Generating MIME documents} \subsection{Generating MIME documents}
One of the most common tasks is to generate the flat text of the email \input{emailgenerator}
message represented by a message object tree. You will need to do
this if you want to send your message via the \refmodule{smtplib}
module or the \refmodule{nntplib} module, or print the message on the
console. Taking a message object tree and producing a flat text
document is the job of the \refmodule{email.Generator} module.
Again, as with the \refmodule{email.Parser} module, you aren't limited
to the functionality of the bundled generator; you could write one
from scratch yourself. However the bundled generator knows how to
generate most email in a standards-compliant way, should handle MIME
and non-MIME email messages just fine, and is designed so that the
transformation from flat text, to an object tree via the
\class{Parser} class,
and back to flat text, be idempotent (the input is identical to the
output).
\subsection{Creating email and MIME objects from scratch} \subsection{Creating email and MIME objects from scratch}
...@@ -156,9 +94,10 @@ of \class{MIMEBase}, although you could. \class{MIMEBase} is provided ...@@ -156,9 +94,10 @@ of \class{MIMEBase}, although you could. \class{MIMEBase} is provided
primarily as a convenient base class for more specific MIME-aware primarily as a convenient base class for more specific MIME-aware
subclasses. subclasses.
\var{_maintype} is the \code{Content-Type:} major type (e.g. \code{text} or \var{_maintype} is the \mailheader{Content-Type} major type
\code{image}), and \var{_subtype} is the \code{Content-Type:} minor type (e.g. \mimetype{text} or \mimetype{image}), and \var{_subtype} is the
(e.g. \code{plain} or \code{gif}). \var{_params} is a parameter \mailheader{Content-Type} minor type
(e.g. \mimetype{plain} or \mimetype{gif}). \var{_params} is a parameter
key/value dictionary and is passed directly to key/value dictionary and is passed directly to
\method{Message.add_header()}. \method{Message.add_header()}.
...@@ -195,10 +134,11 @@ constructor. ...@@ -195,10 +134,11 @@ constructor.
\begin{classdesc}{MIMEText}{_text\optional{, _subtype\optional{, \begin{classdesc}{MIMEText}{_text\optional{, _subtype\optional{,
_charset\optional{, _encoder}}}} _charset\optional{, _encoder}}}}
A subclass of \class{MIMEBase}, the \class{MIMEText} class is used to A subclass of \class{MIMEBase}, the \class{MIMEText} class is used to
create MIME objects of major type \mimetype{text}. \var{_text} is the string create MIME objects of major type \mimetype{text}. \var{_text} is the
for the payload. \var{_subtype} is the minor type and defaults to string for the payload. \var{_subtype} is the minor type and defaults
\mimetype{plain}. \var{_charset} is the character set of the text and is to \mimetype{plain}. \var{_charset} is the character set of the text and is
passed as a parameter to the \class{MIMEBase} constructor; it defaults passed as a parameter to the \class{MIMEBase} constructor; it defaults
to \code{us-ascii}. No guessing or encoding is performed on the text to \code{us-ascii}. No guessing or encoding is performed on the text
data, but a newline is appended to \var{_text} if it doesn't already data, but a newline is appended to \var{_text} if it doesn't already
...@@ -221,27 +161,24 @@ Optional \var{_subtype} sets the subtype of the message; it defaults ...@@ -221,27 +161,24 @@ Optional \var{_subtype} sets the subtype of the message; it defaults
to \mimetype{rfc822}. to \mimetype{rfc822}.
\end{classdesc} \end{classdesc}
\subsection{Encoders, Exceptions, Utilities, and Iterators} \subsection{Encoders}
\input{emailencoders}
The \module{email} package provides various encoders for safe \subsection{Exception classes}
transport of binary payloads in \class{MIMEImage} and \class{MIMEText} \input{emailexc}
instances. See the \refmodule{email.Encoders} module for more
details.
All of the class exceptions that the \module{email} package can raise \subsection{Miscellaneous utilities}
are available in the \refmodule{email.Errors} module. \input{emailutil}
Some miscellaneous utility functions are available in the \subsection{Iterators}
\refmodule{email.Utils} module. \input{emailiter}
Iterating over a message object tree is easy with the
\method{Message.walk()} method; some additional helper iterators are
available in the \refmodule{email.Iterators} module.
\subsection{Differences from \module{mimelib}} \subsection{Differences from \module{mimelib}}
The \module{email} package was originally prototyped as a separate The \module{email} package was originally prototyped as a separate
library called \module{mimelib}. Changes have been made so that library called
\ulink{\module{mimelib}}{http://mimelib.sf.net/}.
Changes have been made so that
method names are more consistent, and some methods or modules have method names are more consistent, and some methods or modules have
either been added or removed. The semantics of some of the methods either been added or removed. The semantics of some of the methods
have also changed. For the most part, any functionality available in have also changed. For the most part, any functionality available in
...@@ -282,7 +219,7 @@ The \class{Message} class has the following differences: ...@@ -282,7 +219,7 @@ The \class{Message} class has the following differences:
\method{get_params()}. \method{get_params()}.
Also, whereas \method{getparams()} returned a list of strings, Also, whereas \method{getparams()} returned a list of strings,
\method{get_params()} returns a list of 2-tuples, effectively \method{get_params()} returns a list of 2-tuples, effectively
the key/value pairs of the parameters, split on the \samp{=} the key/value pairs of the parameters, split on the \character{=}
sign. sign.
\item The method \method{getparam()} was renamed to \method{get_param()}. \item The method \method{getparam()} was renamed to \method{get_param()}.
\item The method \method{getcharsets()} was renamed to \item The method \method{getcharsets()} was renamed to
...@@ -355,4 +292,3 @@ function in the \refmodule{email.Iterators} module. ...@@ -355,4 +292,3 @@ function in the \refmodule{email.Iterators} module.
\subsection{Examples} \subsection{Examples}
Coming soon... Coming soon...
\section{\module{email.Encoders} ---
Email message payload encoders}
\declaremodule{standard}{email.Encoders} \declaremodule{standard}{email.Encoders}
\modulesynopsis{Encoders for email message payloads.} \modulesynopsis{Encoders for email message payloads.}
\sectionauthor{Barry A. Warsaw}{barry@zope.com}
\versionadded{2.2}
When creating \class{Message} objects from scratch, you often need to When creating \class{Message} objects from scratch, you often need to
encode the payloads for transport through compliant mail servers. encode the payloads for transport through compliant mail servers.
This is especially true for \code{image/*} and \code{text/*} type This is especially true for \mimetype{image/*} and \mimetype{text/*}
messages containing binary data. type messages containing binary data.
The \module{email} package provides some convenient encodings in its The \module{email} package provides some convenient encodings in its
\module{Encoders} module. These encoders are actually used by the \module{Encoders} module. These encoders are actually used by the
...@@ -18,7 +12,7 @@ The \module{email} package provides some convenient encodings in its ...@@ -18,7 +12,7 @@ The \module{email} package provides some convenient encodings in its
encodings. All encoder functions take exactly one argument, the encodings. All encoder functions take exactly one argument, the
message object to encode. They usually extract the payload, encode message object to encode. They usually extract the payload, encode
it, and reset the payload to this newly encoded value. They should also it, and reset the payload to this newly encoded value. They should also
set the \code{Content-Transfer-Encoding:} header as appropriate. set the \mailheader{Content-Transfer-Encoding} header as appropriate.
Here are the encoding functions provided: Here are the encoding functions provided:
...@@ -34,7 +28,7 @@ printable data, but contains a few unprintable characters. ...@@ -34,7 +28,7 @@ printable data, but contains a few unprintable characters.
\begin{funcdesc}{encode_base64}{msg} \begin{funcdesc}{encode_base64}{msg}
Encodes the payload into \emph{Base64} form and sets the Encodes the payload into \emph{Base64} form and sets the
\code{Content-Transfer-Encoding:} header to \mailheader{Content-Transfer-Encoding} header to
\code{base64}. This is a good encoding to use when most of your payload \code{base64}. This is a good encoding to use when most of your payload
is unprintable data since it is a more compact form than is unprintable data since it is a more compact form than
Quoted-Printable. The drawback of Base64 encoding is that it Quoted-Printable. The drawback of Base64 encoding is that it
...@@ -43,11 +37,11 @@ renders the text non-human readable. ...@@ -43,11 +37,11 @@ renders the text non-human readable.
\begin{funcdesc}{encode_7or8bit}{msg} \begin{funcdesc}{encode_7or8bit}{msg}
This doesn't actually modify the message's payload, but it does set This doesn't actually modify the message's payload, but it does set
the \code{Content-Transfer-Encoding:} header to either \code{7bit} or the \mailheader{Content-Transfer-Encoding} header to either \code{7bit} or
\code{8bit} as appropriate, based on the payload data. \code{8bit} as appropriate, based on the payload data.
\end{funcdesc} \end{funcdesc}
\begin{funcdesc}{encode_noop}{msg} \begin{funcdesc}{encode_noop}{msg}
This does nothing; it doesn't even set the This does nothing; it doesn't even set the
\code{Content-Transfer-Encoding:} header. \mailheader{Content-Transfer-Encoding} header.
\end{funcdesc} \end{funcdesc}
\section{\module{email.Errors} --- \declaremodule{standard}{email.Errors}
email package exception classes}
\declaremodule{standard}{email.Exceptions}
\modulesynopsis{The exception classes used by the email package.} \modulesynopsis{The exception classes used by the email package.}
\sectionauthor{Barry A. Warsaw}{barry@zope.com}
\versionadded{2.2}
The following exception classes are defined in the The following exception classes are defined in the
\module{email.Errors} module: \module{email.Errors} module:
...@@ -41,13 +35,14 @@ It can be raised from the \method{Parser.parse()} or ...@@ -41,13 +35,14 @@ It can be raised from the \method{Parser.parse()} or
\method{Parser.parsestr()} methods. \method{Parser.parsestr()} methods.
Situations where it can be raised include not being able to find the Situations where it can be raised include not being able to find the
starting or terminating boundary in a \code{multipart/*} message. starting or terminating boundary in a \mimetype{multipart/*} message.
\end{excclassdesc} \end{excclassdesc}
\begin{excclassdesc}{MultipartConversionError}{} \begin{excclassdesc}{MultipartConversionError}{}
Raised when a payload is added to a \class{Message} object using Raised when a payload is added to a \class{Message} object using
\method{add_payload()}, but the payload is already a scalar and the \method{add_payload()}, but the payload is already a scalar and the
message's \code{Content-Type:} main type is not either \code{multipart} message's \mailheader{Content-Type} main type is not either
or missing. \exception{MultipartConversionError} multiply inherits \mimetype{multipart} or missing. \exception{MultipartConversionError}
from \exception{MessageError} and the built-in \exception{TypeError}. multiply inherits from \exception{MessageError} and the built-in
\exception{TypeError}.
\end{excclassdesc} \end{excclassdesc}
\section{\module{email.Generator} ---
Generating flat text from an email message object tree}
\declaremodule{standard}{email.Generator} \declaremodule{standard}{email.Generator}
\modulesynopsis{Generate flat text email messages to from a message \modulesynopsis{Generate flat text email messages from a message object tree.}
object tree.}
\sectionauthor{Barry A. Warsaw}{barry@zope.com} One of the most common tasks is to generate the flat text of the email
message represented by a message object tree. You will need to do
this if you want to send your message via the \refmodule{smtplib}
module or the \refmodule{nntplib} module, or print the message on the
console. Taking a message object tree and producing a flat text
document is the job of the \class{Generator} class.
\versionadded{2.2} Again, as with the \refmodule{email.Parser} module, you aren't limited
to the functionality of the bundled generator; you could write one
from scratch yourself. However the bundled generator knows how to
generate most email in a standards-compliant way, should handle MIME
and non-MIME email messages just fine, and is designed so that the
transformation from flat text, to an object tree via the
\class{Parser} class,
and back to flat text, be idempotent (the input is identical to the
output).
The \class{Generator} class is used to render a message object model Here are the public methods of the \class{Generator} class:
into its flat text representation, including MIME encoding any
sub-messages, generating the correct \rfc{2822} headers, etc. Here
are the public methods of the \class{Generator} class.
\begin{classdesc}{Generator}{outfp\optional{, mangle_from_\optional{, \begin{classdesc}{Generator}{outfp\optional{, mangle_from_\optional{,
maxheaderlen}}} maxheaderlen}}}
...@@ -25,8 +32,9 @@ character in front of any line in the body that starts exactly as ...@@ -25,8 +32,9 @@ character in front of any line in the body that starts exactly as
\samp{From } (i.e. \code{From} followed by a space at the front of the \samp{From } (i.e. \code{From} followed by a space at the front of the
line). This is the only guaranteed portable way to avoid having such line). This is the only guaranteed portable way to avoid having such
lines be mistaken for \emph{Unix-From} headers (see lines be mistaken for \emph{Unix-From} headers (see
\url{http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html} \ulink{WHY THE CONTENT-LENGTH FORMAT IS BAD}
for details). {http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html}
for details).
Optional \var{maxheaderlen} specifies the longest length for a Optional \var{maxheaderlen} specifies the longest length for a
non-continued header. When a header line is longer than non-continued header. When a header line is longer than
......
\section{\module{email.Iterators} ---
Message object tree iterators}
\declaremodule{standard}{email.Iterators} \declaremodule{standard}{email.Iterators}
\modulesynopsis{Iterate over a message object tree.} \modulesynopsis{Iterate over a message object tree.}
\sectionauthor{Barry A. Warsaw}{barry@zope.com}
\versionadded{2.2}
Iterating over a message object tree is fairly easy with the Iterating over a message object tree is fairly easy with the
\method{Message.walk()} method. The \module{email.Iterators} module \method{Message.walk()} method. The \module{email.Iterators} module
...@@ -29,9 +23,9 @@ subparts that match the MIME type specified by \var{maintype} and ...@@ -29,9 +23,9 @@ subparts that match the MIME type specified by \var{maintype} and
Note that \var{subtype} is optional; if omitted, then subpart MIME Note that \var{subtype} is optional; if omitted, then subpart MIME
type matching is done only with the main type. \var{maintype} is type matching is done only with the main type. \var{maintype} is
optional too; it defaults to \code{text}. optional too; it defaults to \mimetype{text}.
Thus, by default \function{typed_subpart_iterator()} returns each Thus, by default \function{typed_subpart_iterator()} returns each
subpart that has a MIME type of \code{text/*}. subpart that has a MIME type of \mimetype{text/*}.
\end{funcdesc} \end{funcdesc}
This diff is collapsed.
\section{\module{email.Parser} ---
Parsing flat text email messages}
\declaremodule{standard}{email.Parser} \declaremodule{standard}{email.Parser}
\modulesynopsis{Parse flat text email messages to produce a message \modulesynopsis{Parse flat text email messages to produce a message
object tree.} object tree.}
\sectionauthor{Barry A. Warsaw}{barry@zope.com}
\versionadded{2.2}
The \module{Parser} module provides a single class, the \class{Parser}
class, which is used to take a message in flat text form and create
the associated object model. The resulting object tree can then be
manipulated using the \class{Message} class interface as described in
\refmodule{email.Message}, and turned over
to a generator (as described in \refmodule{emamil.Generator}) to
return the textual representation of the message. It is intended that
the \class{Parser} to \class{Generator} path be idempotent if the
object model isn't modified in between.
\subsection{Parser class API} Message object trees can be created in one of two ways: they can be
created from whole cloth by instantiating \class{Message} objects and
stringing them together via \method{add_payload()} and
\method{set_payload()} calls, or they can be created by parsing a flat text
representation of the email message.
The \module{email} package provides a standard parser that understands
most email document structures, including MIME documents. You can
pass the parser a string or a file object, and the parser will return
to you the root \class{Message} instance of the object tree. For
simple, non-MIME messages the payload of this root object will likely
be a string (e.g. containing the text of the message). For MIME
messages, the root object will return 1 from its
\method{is_multipart()} method, and the subparts can be accessed via
the \method{get_payload()} and \method{walk()} methods.
Note that the parser can be extended in limited ways, and of course
you can implement your own parser completely from scratch. There is
no magical connection between the \module{email} package's bundled
parser and the \class{Message} class, so your custom parser can create
message object trees in any way it find necessary.
\subsubsection{Parser class API}
\begin{classdesc}{Parser}{\optional{_class}} \begin{classdesc}{Parser}{\optional{_class}}
The constructor for the \class{Parser} class takes a single optional The constructor for the \class{Parser} class takes a single optional
...@@ -75,22 +81,22 @@ prompt: ...@@ -75,22 +81,22 @@ prompt:
>>> msg = email.message_from_string(myString) >>> msg = email.message_from_string(myString)
\end{verbatim} \end{verbatim}
\subsection{Additional notes} \subsubsection{Additional notes}
Here are some notes on the parsing semantics: Here are some notes on the parsing semantics:
\begin{itemize} \begin{itemize}
\item Most non-\code{multipart} type messages are parsed as a single \item Most non-\mimetype{multipart} type messages are parsed as a single
message object with a string payload. These objects will return message object with a string payload. These objects will return
0 for \method{is_multipart()}. 0 for \method{is_multipart()}.
\item One exception is for \code{message/delivery-status} type \item One exception is for \mimetype{message/delivery-status} type
messages. Because such the body of such messages consist of messages. Because the body of such messages consist of
blocks of headers, \class{Parser} will create a non-multipart blocks of headers, \class{Parser} will create a non-multipart
object containing non-multipart subobjects for each header object containing non-multipart subobjects for each header
block. block.
\item Another exception is for \code{message/*} types (i.e. more \item Another exception is for \mimetype{message/*} types (i.e. more
general than \code{message/delivery-status}. These are general than \mimetype{message/delivery-status}). These are
typically \code{message/rfc822} type messages, represented as a typically \mimetype{message/rfc822} type messages, represented as a
non-multipart object containing a singleton payload, another non-multipart object containing a singleton payload, another
non-multipart \class{Message} instance. non-multipart \class{Message} instance.
\end{itemize} \end{itemize}
\section{\module{email.Utils} ---
Miscellaneous email package utilities}
\declaremodule{standard}{email.Utils} \declaremodule{standard}{email.Utils}
\modulesynopsis{Miscellaneous email package utilities.} \modulesynopsis{Miscellaneous email package utilities.}
\sectionauthor{Barry A. Warsaw}{barry@zope.com}
\versionadded{2.2}
There are several useful utilities provided with the \module{email} There are several useful utilities provided with the \module{email}
package. package.
...@@ -24,8 +18,8 @@ are stripped off. ...@@ -24,8 +18,8 @@ are stripped off.
\begin{funcdesc}{parseaddr}{address} \begin{funcdesc}{parseaddr}{address}
Parse address -- which should be the value of some address-containing Parse address -- which should be the value of some address-containing
field such as \code{To:} or \code{Cc:} -- into its constituent field such as \mailheader{To} or \mailheader{Cc} -- into its constituent
``realname'' and ``email address'' parts. Returns a tuple of that \emph{realname} and \emph{email address} parts. Returns a tuple of that
information, unless the parse fails, in which case a 2-tuple of information, unless the parse fails, in which case a 2-tuple of
\code{(None, None)} is returned. \code{(None, None)} is returned.
\end{funcdesc} \end{funcdesc}
...@@ -33,7 +27,7 @@ information, unless the parse fails, in which case a 2-tuple of ...@@ -33,7 +27,7 @@ information, unless the parse fails, in which case a 2-tuple of
\begin{funcdesc}{dump_address_pair}{pair} \begin{funcdesc}{dump_address_pair}{pair}
The inverse of \method{parseaddr()}, this takes a 2-tuple of the form The inverse of \method{parseaddr()}, this takes a 2-tuple of the form
\code{(realname, email_address)} and returns the string value suitable \code{(realname, email_address)} and returns the string value suitable
for a \code{To:} or \code{Cc:} header. If the first element of for a \mailheader{To} or \mailheader{Cc} header. If the first element of
\var{pair} is false, then the second element is returned unmodified. \var{pair} is false, then the second element is returned unmodified.
\end{funcdesc} \end{funcdesc}
...@@ -68,9 +62,9 @@ in the \var{charset} character set (Python can't reliably guess what ...@@ -68,9 +62,9 @@ in the \var{charset} character set (Python can't reliably guess what
character set a string might be encoded in). The default character set a string might be encoded in). The default
\var{charset} is \samp{iso-8859-1}. \var{charset} is \samp{iso-8859-1}.
\var{encoding} must be either the letter \samp{q} for \var{encoding} must be either the letter \character{q} for
Quoted-Printable or \samp{b} for Base64 encoding. If Quoted-Printable or \character{b} for Base64 encoding. If
neither, a \code{ValueError} is raised. Both the \var{charset} and neither, a \exception{ValueError} is raised. Both the \var{charset} and
the \var{encoding} strings are case-insensitive, and coerced to lower the \var{encoding} strings are case-insensitive, and coerced to lower
case in the returned string. case in the returned string.
\end{funcdesc} \end{funcdesc}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment