NAME
    Mail::Message -- manipulate mail messages (parse, analyze and compose)

SYNOPSIS
    To parse the stdin and print it,

        use Mail::Message;
        my $m = Mail::Message->parse({ fh => *STDIN{IO} });
        $m1->print;

    to parse file $filename,

        use Mail::Message;
        my $m = Mail::Message->parse({ file => $filename });

    to make a message of the body part,

        my $msg = new Mail::Message {
            boundary  => $mime_boundary,
            data_type => $data_type_defined_in_header_content_type,
            data      => \$message_body,
        };

    Please specify SCALAR REFERENCE as "data".

    To make a message of the header,

        my $msg = new Mail::Message {
            boundary  => $mime_boundary,
            data_type => 'text/rfc822-headers',
            data      => $header,
        };

    Please specify "Mail::Header" or "FML::Header" object as "data".

       TODO:

        It is useful to C<parse()> the message but inconvenient to build a
        message from scratch.

DESCRIPTION
  OVERVIEW
    "A mail message" has the data to send and some delivery information in
    the header. "Mail::Message" objects construct a chain of header and
    data. "Mail::Message" object holds them and other control information
    such as the reference to the next "Mail::Message" object, et. al.

    "Mail::Message" provides useful functions to analyze a mail message.
    such as to analyze MIME information, to check and get information on
    message (part) size et. al. It can handle MIME multipart.

    "Mail::Message" also can compose a multipart message in primitive way.
    It is useful for you to use "Mail::Message::Compose" class to handle
    MIME multipart in more clever way. It is an adapter for "MIME::Lite"
    class.

  INTERNAL REPRESENTATION
    One mail consists of a message or messages. They are all plain text or a
    set of plain text, images, html and so on. "Mail::Message" is a chain
    which represents a set of several kinds of messages.

    Elements of one object chain are bi-directional among them. For example,
    a MIME/multipart message is a chain of message objects such as

        undef -> mesg1 -> mesg2 -> mesg3 -> undef
              <-       <-       <-       <-

    To describe such a chain, a message object consists of bi-directional
    object chains.

    Described below, "MIME delimiter" is also treated as a virtual message
    for convenience.

       $message = {
                    version        => 1.0,

                    next           => \$next_message,
                    prev           => \$prev_message,

                    base_data_type => "text/plain",

                    mime_version   => 1.0,
                    header         => $header,
                    data_type      => "text/plain",
                    data           => \$message_body,

                    # optional. if unknonw, speculate it from header info.
                    charset        => "iso-2022-jp",
                    encoding       => "7bit",

                    data_info      => \$information,
                   }

       key                value
       -----------------------------------------------------
       version            Mail::Message object version
       next               pointer to the next message
       prev               pointer to the previous message
       base_data_type     type of the whole message
       mime_version       MIME version
       header             MIME header of the part
       data_type          type of each message (part)
       data               reference to the data (that is, memory area)
       data_info          reference to miscellaneous information.

    Only rfc822/message type uses "data_info" field. "header" holds MIME
    content header of the corresponding message.

    The default value for each key follows:

       key              value
       -----------------------------------------------------
       version           1.0
       next              undef
       prev              undef
       base_data_type    text/plain
       mime_version      1.0
       header            undef
       data_type         text/plain
       data              ''
       data_info         ''

HOW TO PARSE
  plain/text
    If the message is just a plain/text, which is usual, internal
    representation follows:

       i  base_data_type               data_type
       ----------------------------------------------------------
       0: text/plain                      text/plain

    where the "i" is the "i"-th element of a chain.

  multipart/...
    Consider the following multipart message.

       Content-Type: multipart/mixed; boundary="boundary"

          ... preamble ...

       --boundary
       Content-Type: text/plain; charset="iso-2022-jp"

       --boundary
       Content-Type: image/gif;

       --boundary--
          ... trailor ...

    "Mail::Message" parser interpetes it as follows:

          base_data_type                 data_type
       ----------------------------------------------------------
       0: multipart/mixed                multipart.preamble
       1: multipart/mixed                multipart.delimiter
       2: multipart/mixed                text/plain
       3: multipart/mixed                multipart.delimiter
       4: multipart/mixed                image/gif
       5: multipart/mixed                multipart.close-delimiter
       6: multipart/mixed                multipart.trailer

    "multipart.something" is a faked type to treat both real content, MIME
    delimiters and others in the same Mail::Message framework.

METHODS to create a message object
  new($args)
    constructor which makes "one" message object.

    In almost cases, new() is used to make a message object, which is a part
    of one mail message.

    We use this framework to make a header object by specifying

           data_type => text/rfc822-headers,
           data      => Mail::Header or FML::Header object,

    in $args (HASH REFERENCE). Pay attention the type of "data".

    "WARNING:"

    It is useful to treate the message header and body in separate way when
    we compose the message by sequential attachments.

    If you build a message by scratch, you must compose a header object.
    When you "parse()" to a mail, you will get the whole set of a chain and
    a body message.

  dup_header()
    duplicate a message chain. Precisely speaking, it duplicates only the
    header object but not duplicate body part. So, the next object of the
    duplicated header, "dup_header0" in the following figure, is the first
    body part "part1" of the origianl chain.

        header0 ----> part1 -> part2 -> ...
                       A
                       |
        dup_header0 ---

METHODS TO PARSE
  parse($args)
    read data from file descriptor $fd and parse it to the mail header and
    the body.

        parse({
            fd => $fd,
        });

    You can specify file not file descriptor.

        parse({
            file => $file,
        });

  prepend($data)
    prepend the message to the object chain.

  append($data)
    append the message to the object chain.

  whole_message_header()
    return Mail::Header object corresponding to the header part for the
    object $self.

  whole_message_body()
    alias of "whole_message_body_head()".

  whole_message_body_head()
    return the first or the head Mail::Message object in a chain for the
    body part of the message $self.

  whole_message_as_str($args)
    To extract the first 2048 bytes in the whole message (body), specify the
    following parameters in $args.

        $args = {
            start => 0,
            end   => 2048,
            type  => 'exact',
        };

    By default, parameters

        $args = {
            start  => 0,
            end    => 2048,
            indent => '   ',
        };

    It returns the text until the first null line over the first 2048 bytes.

  whole_message_header_data_type()
    return the "type" string. It is the whole message type which is
    speculated from header "Content-Type:".

METHODS to manipulate a chain
  find($args)
    return the first "Mail::Message" object with the specified attrribute.
    You can specify "data_type" in $args HASH REFERENCE. For example,

        $m = $msg->find( { data_type => 'text/plain' } );

    $m is the first "text/plain" object in a chain of $msg object. This
    method is used for the exact match.

        $m = $msg->find( { data_type_regexp => 'text' } );

    $m is the first "text/*" object in a chain of $msg object.

  __head_message()
    no argument. It return the head object of a chain of "Mail::Message"
    objects. Usually it is the header part.

  __last_message()
    no argument. It return the last object of a chain of "Mail::Message"
    objects. Usually it is the last message in the body part.

  _next_message_is( $obj )
    The next part of $self object is $obj.

  _prev_message_is( $obj )
    The previous part of $self object is $obj.

METHODS to print
  print( $fd )
    print out a chain of messages to the file descriptor $fd. If $fd is not
    specified, STDOUT is used.

  set_print_mode(mode)
    set print mode to "mode". The available <mode> is "raw" or "smtp".

  reset_print_mode()
    reset print() mode. It sets the mode to be "raw".

METHODS to manipulate a multipart message
  build_mime_multipart_chain($args)
    build a mime message by scratch. This may be obsolete since we use
    "MIME::Lite" to build a mime message now.

  parse_and_build_mime_multipart_chain($args)
    parse the multipart mail. Actually it calculates the begin and end
    offset for each part of content, not split() and so on. "new()" calls
    this routine if the message looks MIME multipart.

  build_mime_header($args)
    make a fundamental mime header fields and return it.

CREATE MESSAGE SUMMARY
  outline($params)
  one_line_summary($params)
    return one line summary.

  summary($params)
    return short summary.

METHODS (UTILITY FUNCTIONS)
  size()
    return the message size of this object.

  is_empty()
    return this message has empty content or not.

  is_multipart()
    return this message has empty content or not.

  charset()
    return charset.

  encoding_mechanism()
    return encoding type for specified Mail::Message not whole mail. The
    return value is one of base64, quoted-printable or undef.

  offset_pair()
    return offset information in the data. return value is ARRAY

       ($offset_begin, $offset_end)

    on the Mail::Message object.

  header_size()
    get whole header size for this object ($self)

  body_size()
    get whole body size for this object ($self)

  envelope_sender()
    return reverse_path for this object ($self)

  data_type()
    return the data type of the given message object ($self) not the whole
    mail message.

  num_paragraphs()
    same as paragraph_total().

  paragraph_total()
    return the number of paragraphs in the message ($self).

  nth_paragraph($n)
    return the string of $n-th paragraph. For example, nth_paragraph(1)
    returns the 1st paragraph. The syntax is usual not C language flabour.

  message_fields()
    return header string in the message content. It is mie header for whole
    mail or each message of MIME/multipart.

  message_text($size)
    get body string in the message content, which is the whole mail (plain
    text) or body part of a block of multipart.

    If $size is specified, return the first $size bytes in the body.

  find_first_plaintext_message($args)
    return the Messages object for the first "plain/text" message in a
    chain. For example,

             $m    = $msg->find_first_plaintext_message();
             $body = $m->message_text();

    where $body is the mail body (string).

  message_chain_as_array_ref()
    return the chain of message objects as ARRAY_REF of OBJ's like this:

       [ Mail::Message, Mail::Message, ... ]

  set_log_function()
    internal use. set CODE REFERENCE to the log function

  unset_log_function()
    unset CODE REFERENCE used as log functions.

  data_type_list()
    show the list of data_types in the chain order. This is defined for
    debug and removed in the future.

UTILITY for Accept-Language:
  accept_language_list()
    return list of languages to accept as ARRAY_REF such as [ 'ja', 'en',
    '*' ] but [ '*' ] if Accept-Language: unavailable.

METHODS to make a whole mail message
    Please use "Mail::Message::Compose" class. This is an adapter for
    "MIME::Lite", so your request is forwarded to "MIME::Lite" class :-)

        use Mail::Message::Compose;
        $msg = Mail::Message::Compose->new(
           From     => 'fukachan@fml.org',
           To       => 'rudo@nuinui.net',
           Cc       => 'kenken@nuinui.net',
           Subject  => 'help',
           Type     => 'text/plain',
           Path     => 'help',
        );
        $msg->attr('content-type.charset' => 'us-ascii');

        # show message;
        print $msg->as_string;

APPENDIX (RFC2046 Appendix A)
    Appendix A -- Collected Grammar

       This appendix contains the complete BNF grammar for all the syntax
       specified by this document.

       By itself, however, this grammar is incomplete.  It refers by name to
       several syntax rules that are defined by RFC 822.  Rather than
       reproduce those definitions here, and risk unintentional differences
       between the two, this document simply refers the reader to RFC 822
       for the remaining definitions. Wherever a term is undefined, it
       refers to the RFC 822 definition.

         boundary := 0*69<bchars> bcharsnospace

         bchars := bcharsnospace / " "

         bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" /
                          "+" / "_" / "," / "-" / "." /
                          "/" / ":" / "=" / "?"

         body-part := <"message" as defined in RFC 822, with all
                       header fields optional, not starting with the
                       specified dash-boundary, and with the
                       delimiter not occurring anywhere in the
                       body part.  Note that the semantics of a
                       part differ from the semantics of a message,
                       as described in the text.>

         close-delimiter := delimiter "--"

         dash-boundary := "--" boundary
                          ; boundary taken from the value of
                          ; boundary parameter of the
                          ; Content-Type field.

         delimiter := CRLF dash-boundary

         discard-text := *(*text CRLF)
                         ; May be ignored or discarded.

         encapsulation := delimiter transport-padding
                          CRLF body-part

         epilogue := discard-text

         multipart-body := [preamble CRLF]
                           dash-boundary transport-padding CRLF
                           body-part *encapsulation
                           close-delimiter transport-padding
                           [CRLF epilogue]

         preamble := discard-text

         transport-padding := *LWSP-char
                              ; Composers MUST NOT generate
                              ; non-zero length transport
                              ; padding, but receivers MUST
                              ; be able to handle padding
                              ; added by message transports.

CODING STYLE
    See "http://www.fml.org/software/FNF/" on fml coding style guide.

AUTHOR
    Ken'ichi Fukamachi

COPYRIGHT
    Copyright (C) 2001,2002,2003,2004,2005,2006 Ken'ichi Fukamachi

    All rights reserved. This program is free software; you can redistribute
    it and/or modify it under the same terms as Perl itself.

HISTORY
    Mail::Message first appeared in fml8 mailing list driver package. See
    "http://www.fml.org/" for more details.

