\input texinfo @setfilename guile-email.info @settitle guile-email @copying Copyright @copyright{} 2019, 2021 Arun Isaac@* Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''. @end copying @ifnottex @node Top @top guile-email @end ifnottex @menu * Introduction:: What is guile-email? * Parsing Email:: Parsing email * Data Types:: Data types provided by guile-email * Encoding and Decoding:: Encoding and decoding Base64, Quoted-Printable and Q-encoding * Reading Email:: Reading emails from the mbox format * Contributing:: Contributing Indices * Procedure Index:: * Type Index:: @end menu @node Introduction @chapter Introduction guile-email is a collection of email utilities implemented in pure guile. It supports parsing MIME (Multipurpose Internet Mail Extensions) compliant email messages as specified in RFC5322, RFC2045, RFC2046, RF2047 and RFC2049. @section Features @itemize @item Parse @uref{https://tools.ietf.org/html/rfc5322,,RFC5322} compliant email messages (currently does not support @uref{https://tools.ietf.org/html/rfc5322#section-4,,obsolete syntax}) @item Parse MIME compliant email messages as specified in @uref{https://tools.ietf.org/html/rfc2045,,RFC2045}, @uref{https://tools.ietf.org/html/rfc2046,,RFC2046}, @uref{https://tools.ietf.org/html/rfc2047,,RFC2047} and @uref{https://tools.ietf.org/html/rfc2049,,RFC2049} @item Parse non-standard @uref{https://www.gnu.org/software/emacs/manual/html_node/emacs/Mail-Headers.html, Emacs message mode parens style addresses} @item Encode and decode Quoted-Printable encoding, Base64 encoding and Q-encoding @item Read emails from the @uref{https://en.wikipedia.org/wiki/Mbox, mbox format} @end itemize @node Parsing Email @chapter Parsing Email @example (use-modules (email email)) @end example @deftypefn {Scheme Procedure} parse-email (bytevector @var{email}) @deftypefnx {Scheme Procedure} parse-email (string @var{email}) Parse bytevector @var{email} and return result as an @code{} record. Parse string @var{email} and return result as an @code{} record. @end deftypefn @deffn {Scheme Procedure} parse-email-headers headers Parse string @var{headers} as email headers and return an association list of header keys and values. @end deffn @deftypefn {Scheme Procedure} parse-email-body (string @var{headers}) (bytevector @var{body}) @deftypefnx {Scheme Procedure} parse-email-body (string @var{headers}) (string @var{body}) Parse bytevector @var{body} as email body where @var{headers} is an association list of header keys and values as returned by @code{parse-email-headers}. Return a list of records if the body is a multipart message. Else, return a single record. Parse string @var{body} as email body where @var{headers} is an association list of header keys and values as returned by @code{parse-email-headers}. Return a list of records if the body is a multipart message. Else, return a single record. @end deftypefn Note that while an email can have characters encoded using different schemes, a string is constrained to have all characters encoded using the same scheme. Therefore, passing a string to @code{parse-email} or @code{parse-email-body} will not always produce correct results. Hence, this variant of @code{parse-email} and @code{parse-email-body} will be deprecated in the future. This variant is only provided in the interest of backward compatibility. @node Data Types @chapter Data Types guile-email provides data types for representing emails and MIME entities. @section email data type @deftp {Data Type} headers body This is the data type representing emails. @end deftp @deffn {Scheme Procedure} email? object @deffnx {Scheme Procedure} email-headers email @deffnx {Scheme Procedure} email-body email Predicate and field accessors for the @code{} data type. @end deffn @deffn {Scheme Procedure} make-email headers body Construct an @code{} object. @var{headers} is an association list of email headers. @var{body} is either a string or a list of @code{} objects. @end deffn @section mime-entity data type @deftp {Data Type} headers body This is the data type representing MIME entities. @end deftp @deffn {Scheme Procedure} mime-entity? object @deffnx {Scheme Procedure} mime-entity-headers mime-entity @deffnx {Scheme Procedure} mime-entity-body mime-entity Predicate and field accessors for the @code{} data type. @end deffn @deffn {Scheme Procedure} make-mime-entity headers body Construct a mime-entity object. @var{headers} is an association list of MIME entity headers. @var{body} is either a string or a list of @code{} objects. @end deffn @section email headers The following descriptions of email headers are only a summary. Please see the relevant RFCs for more details. @subsection email header types @deftp {Email Header Type} AssociationList An association list of key-value pairs (@pxref{Association Lists,,, guile}). Keys are the name of the email header, downcased and converted to symbols. Values are specific to the header and explained below. @end deftp @deftp {Email Header Type} Date An SRFI-19 date. @xref{SRFI-19 Date,,, guile}. @end deftp @deftp {Email Header Type} Address An association list of atmost two keys - 'name' and 'address'. The values corresponding to these keys are explained below. @table @code @item name Display name of the email address. When the email address does not specifiy a display name, this key will be absent. @item address Actual email address. @end table @end deftp @deftp {Email Header Type} AddressList A list of addresses, each of type 'Address'. @end deftp @deftp {Email Header Type} MessageID A string containing an email message ID with the surrounding angle brackets (@samp{<} and @samp{>}) removed. Email message IDs uniquely identify the email. @end deftp @deftp {Email Header Type} MessageIDList A list of message IDs, each of type @code{MessageID}. @end deftp @subsection email headers @deftypevr {Email Header} Date date The date the email was sent on, as specified in the @dfn{Date} header. @end deftypevr @deftypevr {Email Header} AddressList from The list of authors of the email, as specified in the @dfn{From} header. @end deftypevr @deftypevr {Email Header} Address sender The sender of the email, as specified in the @dfn{Sender} header. @end deftypevr @deftypevr {Email Header} AddressList reply-to The list of addresses the author of the email suggests replies be sent to, as specified in the @dfn{Reply-To} header. @end deftypevr @deftypevr {Email Header} AddressList to The list of primary recipients of the email, as specified in the @dfn{To} header. @end deftypevr @deftypevr {Email Header} AddressList cc The list of other recipients of the email at whom the content of the email may not be directed, as specified in the @dfn{Cc} header. @end deftypevr @deftypevr {Email Header} AddressList bcc THe list of recipients whose address is not to be revealed to other recipients of the email, as specified in the @dfn{Bcc} header. @end deftypevr @deftypevr {Email Header} MessageID message-id The message ID of the email, as specified in the @dfn{Message-ID} header. @end deftypevr @deftypevr {Email Header} MessageIDList in-reply-to The list of message IDs of emails to which this email is a reply, as specified in the @dfn{In-Reply-To} header. @end deftypevr @deftypevr {Email Header} MessageIDList references The list of message IDs specified in the @dfn{References} header. @end deftypevr @deftypevr {Email Header} String subject A string identifying the topic of the email, as specified in the @dfn{Subject} header. @end deftypevr @deftypevr {Email Header} String comments A string containing additional comments on the body of the email, as specified in the @dfn{Comments} header. @end deftypevr @deftypevr {Email Header} StringList keywords A list of strings each an important word or phrase, as specified in the @dfn{Keywords} header. @end deftypevr @deftypevr {Email Header} Date resent-date The date at which the resent message was dispatched by the resender, as specified in the @dfn{Resent-Date} header. @end deftypevr @deftypevr {Email Header} AddressList resent-from The list of addresses specified in the @dfn{Resent-From} header. @end deftypevr @deftypevr {Email Header} Address resent-sender The address specified in the @dfn{Resent-Sender} header. @end deftypevr @deftypevr {Email Header} AddressList resent-to The list of addresses specified in the @dfn{Resent-To} header. @end deftypevr @deftypevr {Email Header} AddressList resent-cc The list of addresses specified in the @dfn{Resent-Cc} header. @end deftypevr @deftypevr {Email Header} AddressList resent-bcc The list of addresses specified in the @dfn{Resent-Bcc} header. @end deftypevr @deftypevr {Email Header} MessageID resent-message-id The message ID specified in the @dfn{Resent-Message-ID} header. @end deftypevr @c TODO: Document trace fields @deftypevr {Email Header} String mime-version The MIME version specified in the @dfn{MIME-Version} header. @end deftypevr @deftypevr {Email Header} AssociationList content-type The MIME type of the body, as specified in the @dfn{Content-Type} header, as an association list. The following keys always exist in the association list. Any additional parameters will also be listed as key-value pairs. Keys are names of the parameters, downcased and converted to symbols. @table @code @item type The primary type @item subtype The secondary type @item charset The charset @end table @end deftypevr If no Content-Type header is present, a type of @code{text}, a subtype of @code{plain} and a charset of ``utf-8'' is assumed as the default. That is, the following: @example ((type . text) (subtype . plain) (charset . "utf-8")) @end example @deftypevr {Email Header} AssociationList content-disposition The content disposition type, as specified in the @dfn{Content-Disposition} header, as an association list. The following keys always exist in the association list. @table @code @item type @table @code @item inline @item attachment @end table @end table Other optional keys include @table @code @item filename @item creation-date @item modification-date @item read-date @item size @end table Any additional parameters will also be listed as key-value pairs. Keys are names of the parameters, downcased and converted to symbols. @end deftypevr @deftypevr {Email Header} Symbol content-transfer-encoding The encoding of the body of the email as specified in the @dfn{Content-Transfer-Encoding} header. This can be one of the following symbols. @table @code @item 7bit The message is 7-bit encoded. This is the default if no Content-Transfer-Encoding header is present. @item 8bit The message is 8-bit encoded. @item quoted-printable The message is encoded using Quoted-Printable encoding. @item base64 The message is encoded using Base64 encoding. @end table Note that guile-email automatically decodes the email. The user need not read the @code{content-transfer-encoding} and invoke the appropriate decoding procedure. The @code{content-transfer-encoding} header is only provided for the sake of completion. @end deftypevr @node Encoding and Decoding @chapter Encoding and Decoding guile-email supports encoding and decoding using Base64 encoding, Quoted-Printable encoding and Q-encoding. Note that guile-email automatically invokes the necessary decoding procedures while parsing email. The following procedures are only provided in case you need to use them in a context not automatically handled by guile-email. Character encoding schemes such as UTF-8 encode characters as bytes. Encoding schemes such as Quoted-Printable encoding, Base64 encoding and Q-encoding re-encode these bytes as 7-bit text suitable for transmission over a medium such as email that is not 8-bit clean. Therefore, the input to the following encoding procedures and the output from the following decoding procedures is a bytevector. Encoding characters to bytes or decoding bytes to characters is not within the scope of these procedures. @xref{Representing Strings as Bytes,,, guile} for more information on how to do this. @section Base64 encoding @example (use-modules (email base64)) @end example @deffn {Scheme Procedure} base64-encode bv Encode bytevector @var{bv} using Base64 encoding and return the encoded string. @end deffn @deffn {Scheme Procedure} base64-decode str Decode Base64 encoded string @var{str} and return the decoded bytevector. @end deffn @section Quoted-Printable encoding The Quoted-Printable encoding and decoding procedures in this section are typed functions in that they behave differently based on the types of their arguments. @example (use-modules (email quoted-printable)) @end example @deftypefn {Scheme Procedure} {} quoted-printable-encode (bytevector @var{bv}) @deftypefnx {Scheme Procedure} {} quoted-printable-encode (port @var{in}) @deftypefnx {Scheme Procedure} {} quoted-printable-encode (port @var{in}) (port @var{out}) Encode bytevector @var{bv} using Quoted-Printable encoding and return the encoded string. Read bytes from the bytevector input port @var{in} and return the Quoted-Printable encoded string. Read bytes from the bytevector input port @var{in} and write the Quoted-Printable encoded string to output port @var{out}. @end deftypefn @deftypefn {Scheme Procedure} {} quoted-printable-decode (string @var{str}) @deftypefnx {Scheme Procedure} {} quoted-printable-decode (port @var{in}) @deftypefnx {Scheme Procedure} {} quoted-printable-decode (port @var{in}) (port @var{out}) Decode Quoted-Printable encoded string @var{str} and return the decoded bytevector. Read Quoted-Printable encoded characters from input port @var{in} and return the decoded bytevector. Read Quoted-Printable encoded characters from port @var{in} and write the decoded bytevector to bytevector output port @var{out}. @end deftypefn @section Q-encoding @example (use-modules (email quoted-printable)) @end example @deffn {Scheme Procedure} q-encoding-encode bv Encode bytevector @var{bv} using Q-encoding and return the encoded string. @end deffn @deffn {Scheme Procedure} q-encoding-decode str Decode Q-encoding encoded string @var{str} and return the decoded bytevector. @end deffn @node Reading Email @chapter Reading Email @deffn {Scheme Procedure} mbox->emails port Read all emails from @var{port} and return as a list of bytevectors. @var{port} is an input port reading an mbox file. @end deffn @node Contributing @chapter Contributing Feedback, suggestions, feature requests, bug reports and patches are all welcome. Please write to the mailing list at @email{guile-email@@systemreboot.net}. @node Procedure Index @chapter Procedure Index @printindex fn @node Type Index @chapter Type Index @printindex tp @bye