1""" 
    2    pygments.lexers.email 
    3    ~~~~~~~~~~~~~~~~~~~~~ 
    4 
    5    Lexer for the raw E-mail. 
    6 
    7    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. 
    8    :license: BSD, see LICENSE for details. 
    9""" 
    10 
    11from pygments.lexer import RegexLexer, DelegatingLexer, bygroups 
    12from pygments.lexers.mime import MIMELexer 
    13from pygments.token import Text, Keyword, Name, String, Number, Comment 
    14from pygments.util import get_bool_opt 
    15 
    16__all__ = ["EmailLexer"] 
    17 
    18 
    19class EmailHeaderLexer(RegexLexer): 
    20    """ 
    21    Sub-lexer for raw E-mail. This lexer only process header part of e-mail. 
    22 
    23    .. versionadded:: 2.5 
    24    """ 
    25 
    26    def __init__(self, **options): 
    27        super().__init__(**options) 
    28        self.highlight_x = get_bool_opt(options, "highlight-X-header", False) 
    29 
    30    def get_x_header_tokens(self, match): 
    31        if self.highlight_x: 
    32            # field 
    33            yield match.start(1), Name.Tag, match.group(1) 
    34 
    35            # content 
    36            default_actions = self.get_tokens_unprocessed( 
    37                match.group(2), stack=("root", "header")) 
    38            yield from default_actions 
    39        else: 
    40            # lowlight 
    41            yield match.start(1), Comment.Special, match.group(1) 
    42            yield match.start(2), Comment.Multiline, match.group(2) 
    43 
    44    tokens = { 
    45        "root": [ 
    46            (r"^(?:[A-WYZ]|X400)[\w\-]*:", Name.Tag, "header"), 
    47            (r"^(X-(?:\w[\w\-]*:))([\s\S]*?\n)(?![ \t])", get_x_header_tokens), 
    48        ], 
    49        "header": [ 
    50            # folding 
    51            (r"\n[ \t]", Text.Whitespace), 
    52            (r"\n(?![ \t])", Text.Whitespace, "#pop"), 
    53 
    54            # keywords 
    55            (r"\bE?SMTPS?\b", Keyword), 
    56            (r"\b(?:HE|EH)LO\b", Keyword), 
    57 
    58            # mailbox 
    59            (r"[\w\.\-\+=]+@[\w\.\-]+", Name.Label), 
    60            (r"<[\w\.\-\+=]+@[\w\.\-]+>", Name.Label), 
    61 
    62            # domain 
    63            (r"\b(\w[\w\.-]*\.[\w\.-]*\w[a-zA-Z]+)\b", Name.Function), 
    64 
    65            # IPv4 
    66            (r"(?<=\b)(?:(?:25[0-5]|2[0-4][0-9]|1?[0-9][0-9]?)\.){3}(?:25[0" 
    67             r"-5]|2[0-4][0-9]|1?[0-9][0-9]?)(?=\b)", 
    68             Number.Integer), 
    69 
    70            # IPv6 
    71            (r"(?<=\b)([0-9a-fA-F]{1,4}:){1,7}:(?!\b)", Number.Hex), 
    72            (r"(?<=\b):((:[0-9a-fA-F]{1,4}){1,7}|:)(?=\b)", Number.Hex), 
    73            (r"(?<=\b)([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}(?=\b)", Number.Hex), 
    74            (r"(?<=\b)([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}(?=\b)", Number.Hex), 
    75            (r"(?<=\b)[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})(?=\b)", Number.Hex), 
    76            (r"(?<=\b)fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}(?=\b)", Number.Hex), 
    77            (r"(?<=\b)([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}(?=\b)", Number.Hex), 
    78            (r"(?<=\b)([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}(?=\b)", 
    79             Number.Hex), 
    80            (r"(?<=\b)([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}(?=\b)", 
    81             Number.Hex), 
    82            (r"(?<=\b)([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}(?=\b)", 
    83             Number.Hex), 
    84            (r"(?<=\b)::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}" 
    85             r"[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}" 
    86             r"[0-9])(?=\b)", 
    87             Number.Hex), 
    88            (r"(?<=\b)([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9])" 
    89             r"{0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])(?=\b)", 
    90             Number.Hex), 
    91 
    92            # Date time 
    93            (r"(?:(Sun|Mon|Tue|Wed|Thu|Fri|Sat),\s+)?(0[1-9]|[1-2]?[0-9]|3[" 
    94             r"01])\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(" 
    95             r"19[0-9]{2}|[2-9][0-9]{3})\s+(2[0-3]|[0-1][0-9]):([0-5][0-9])" 
    96             r"(?::(60|[0-5][0-9]))?(?:\.\d{1,5})?\s+([-\+][0-9]{2}[0-5][0-" 
    97             r"9]|\(?(?:UTC?|GMT|(?:E|C|M|P)(?:ST|ET|DT)|[A-IK-Z])\)?)", 
    98             Name.Decorator), 
    99 
    100            # RFC-2047 encoded string 
    101            (r"(=\?)([\w-]+)(\?)([BbQq])(\?)([\[\w!\"#$%&\'()*+,-./:;<=>@[\\" 
    102             r"\]^_`{|}~]+)(\?=)", 
    103             bygroups(String.Affix, Name.Constant, String.Affix, Keyword.Constant, 
    104                      String.Affix, Number.Hex, String.Affix)), 
    105 
    106            # others 
    107            (r'[\s]+', Text.Whitespace), 
    108            (r'[\S]', Text), 
    109        ], 
    110    } 
    111 
    112 
    113class EmailLexer(DelegatingLexer): 
    114    """ 
    115    Lexer for raw E-mail. 
    116 
    117    Additional options accepted: 
    118 
    119    `highlight-X-header` 
    120        Highlight the fields of ``X-`` user-defined email header. (default: 
    121        ``False``). 
    122    """ 
    123 
    124    name = "E-mail" 
    125    aliases = ["email", "eml"] 
    126    filenames = ["*.eml"] 
    127    mimetypes = ["message/rfc822"] 
    128    url = "https://en.wikipedia.org/wiki/Email#Message_format" 
    129    version_added = '2.5' 
    130 
    131    def __init__(self, **options): 
    132        super().__init__(EmailHeaderLexer, MIMELexer, Comment, **options)