RFC 1563

The text/enriched MIME Content-type

๐Ÿ“… published January 1994, from ietf

RFC 1563: The text/enriched MIME Content-type โœจ

okay bestie, this is RFC 1563 ๐ŸŽ€ by N. Borenstein from Bellcore, dated January 1994. It's Informational, so it's sharing info with the internet crowd and isn't an official standard ๐Ÿ’… It also obsoletes RFC 1523, so 1523 is officially retired and this is the new vibe ๐Ÿฆ‹

Status of this Memo

ok so this memo is here to provide information for the Internet community ๐ŸŒธ it does NOT specify an Internet standard of any kind, and distribution of it is unlimited ๐Ÿซถ

Abstract

ngl the Abstract is giving "here's the big picture" ๐ŸŒˆ [RFC-1341, RFC-1521] defines a format and general framework for representing a wild variety of data types in Internet mail ๐Ÿ“ฌ this doc zooms in on one of those types, text/enriched, which is a refined version of the "text/richtext" type from RFC 1341 โœจ the whole goal is to make simple enriched text play nicely across tons of hardware and software ๐Ÿ’–

Table of Contents

The Text/enriched MIME type..............................  2
Formatting Commands......................................  4
      Font-Alteration Commands...........................  4
      Fill/Justification Commands........................  5
      Indentation Commands...............................  6
      Miscellaneous Commands.............................  6
      Balancing and Nesting of Formatting Commands.......  7
      Unrecognized formatting commands...................  8
White Space in Text/enriched Data........................  8
Initial State of a text/enriched interpreter.............  8
Non-ASCII character sets.................................  8
Minimal text/enriched conformance........................  9
Notes for Implementors...................................  9
Extensions to text/enriched.............................. 10
An Example............................................... 11
Security Considerations.................................. 12
Author's Address......................................... 12
Acknowledgements......................................... 12
References............................................... 12
Appendix A -- A Simple enriched-to-plain Translator in C. 13
Appendix B -- Differences from RFC 1341 text/richtext.... 15

The Text/enriched MIME type

okay so the goal here is wider interoperability for simple formatted text ๐Ÿ’… this doc makes an extremely simple subtype of the MIME content-type "text", called "text/enriched" ๐Ÿงš it was designed around four main criteria:

  1. Easy to parse ๐Ÿ“ The syntax MUST be extremely simple to parse, so that even teletype-oriented mail systems can easily strip away the formatting information and leave only the readable text.
  2. Extensible โœจ The syntax MUST be extensible to allow for new formatting commands that are deemed essential for some application.
  3. Readable even raw ๐Ÿ‘€ If the character set in use is ASCII or an 8-bit ASCII superset, then the raw form of the data MUST be readable enough to be largely unobjectionable in the event that it is displayed on the screen of the user of a non-MIME-conformant mail reader.
  4. Strictly limited ๐Ÿซ  The capabilities MUST be extremely limited, so it can represent no more than what the user's primary word processor is likely to represent. yes this limits what can be sent, but it means what IS sent is way more likely to display properly ๐Ÿ’œ

This document defines a brand new MIME content-type, "text/enriched" ๐ŸŽ€ The content-type line for this type MAY have one optional parameter, the "charset" parameter, which takes the same values permitted for the "text/plain" MIME content-type.

The syntax of "text/enriched" is very simple ๐ŸŒท it represents text in a single character set. the default is US-ASCII, but you can pick a different one with the "charset" parameter. (the semantics of text/enriched in non-ASCII character sets get covered later in the doc, so hang tight ๐Ÿ’–) every character represents itself, with one exception: the "<" character (ASCII 60), which marks the beginning of a formatting command. Formatting instructions are formatting commands wrapped in angle brackets ("<>", ASCII 60 and 62). Each formatting command MAY be no more than 60 characters in length, all in US-ASCII, restricted to alphanumeric characters and the hyphen ("-") character. Formatting commands MAY be preceded by a solidus ("/", ASCII 47), which makes them negations, and such negations MUST always exist to balance the initial opening commands. So if the formatting command <bold> shows up at some point, there MUST later be a </bold> to balance it ๐Ÿฆ‹

NOTE: The 60 character limit on formatting commands does NOT include the "<", ">", or "/" characters that might be attached to such commands. ๐Ÿ™ˆ

Formatting commands are always case-insensitive โœจ so "bold" and "BoLd" are equivalent in effect, if not in good taste ๐Ÿ’…๐Ÿ˜ญ

Beyond tokens delimited by "<" and ">", there are two other special processing rules ๐ŸŒˆ First, a literal less-than sign ("<") can be represented by a sequence of two such characters, "<<". Second, line breaks (CRLF pairs in standard network representation) get handled specially. Isolated CRLF pairs are translated into a single SPACE character. Sequences of N consecutive CRLF pairs, however, are translated into N-1 actual line breaks. this is what lets long lines of data look natural even though Internet mailers wrap lines all the time ๐Ÿงš When preparing the data for mail transport, isolated line breaks SHOULD be inserted wherever necessary to keep each line shorter than 80 characters. When preparing that data for presentation to the user, isolated line breaks SHOULD be replaced by a single SPACE character, and N consecutive CRLF pairs SHOULD be presented to the user as N-1 line breaks.

Thus, text/enriched data that looks like this:

                 This is
                 a single
                 line

                 This is the
                 next line.


                 This is the
                 next paragraph.

SHOULD be displayed by a text/enriched interpreter as follows:

                 This is a single line
                 This is the next line.

                 This is the next paragraph.

The formatting commands, not all of which will be implemented by every implementation, are described in the following sections ๐ŸŒธ


Formatting Commands

okay the formatting commands all begin with <commandname> and end with </commandname>, and they affect the formatting of the text sitting between those two tokens ๐ŸŽ€ they're grouped by type below, so you can find your faves easily ๐Ÿ’–

Font-Alteration Commands

these commands are meant to change the font the text is displayed in, but NOT the indentation or justification state ๐Ÿซถ here's the lineup:

  • Bold ๐Ÿ’œ causes the affected text to be in a bold font. Nested bold commands have the same effect as a single bold command.
  • Italic ๐ŸŒท causes the affected text to be in an italic font. Nested italic commands have the same effect as a single italic command.
  • Fixed ๐Ÿ–ฅ๏ธ causes the affected text to be in a fixed width font. Nested fixed commands have the same effect as a single fixed command.
  • Smaller ๐Ÿค causes the affected text to be in a smaller font. It is RECOMMENDED that the font size be changed by two points, but other amounts MAY be more appropriate in some environments. Nested smaller commands produce ever-smaller fonts, up to the limits of the implementation's capacity to reasonably display them, after which further smaller commands have no incremental effect.
  • Bigger ๐Ÿ™Œ causes the affected text to be in a bigger font. It is RECOMMENDED that the font size be changed by two points, but other amounts MAY be more appropriate in some environments. Nested bigger commands produce ever-bigger fonts, up to the limits of the implementation's capacity to reasonably display them, after which further bigger commands have no incremental effect.
  • Underline ๐Ÿฆ‹ causes the affected text to be underlined. Nested underline commands have the same effect as a single underline command.

while "bigger" and "smaller" are basically inverses of each other, it is NOT RECOMMENDED to use <smaller> to end the effect of <bigger> ๐Ÿ™…โ€โ™€๏ธ that's properly done with </bigger> โœจ

Fill/Justification Commands

by default, text/enriched text is meant to be displayed fully filled, with kerning and letter-tracking that suit the receiving user agent software ๐Ÿงš the actual line width is left up to the receiver, who is expected to fold lines smartly (preferring soft line breaks) to the best of its ability ๐Ÿ’…

the following commands change that state ๐Ÿ‘‘ each of them forces a line break before and after the formatting environment, unless there's already a line break there. so if one of these commands shows up anywhere other than the start of a line of text as presented, a new line begins ๐ŸŒˆ

  • Center ๐ŸŽฏ causes the affected text to be centered.
  • FlushLeft โฌ…๏ธ causes the affected text to be left-justified with a ragged right margin.
  • FlushRight โžก๏ธ causes the affected text to be right-justified with a ragged left margin.
  • FlushBoth ๐Ÿซง causes the affected text to be filled and padded so it has smooth left and right margins, i.e., it's fully justified.
  • Nofill ๐Ÿƒ causes the affected text to be displayed without filling or justification.

the center, flushleft, flushright, and flushboth commands are mutually exclusive, and when nested, the inner command takes precedence ๐Ÿ’–

whether text is justified by default (so whether the default environment is flushleft, flushright, or flushboth) is unspecified ๐Ÿคทโ€โ™€๏ธ it depends on the user's preferences, the capabilities of the local software and hardware, and the character set in use. on systems where justification is considered undesirable, the flushboth environment MAY be identical to the default environment. Note that justification SHOULD NOT be performed inside of center, flushleft, flushright, or nofill environments ๐Ÿ™ˆ and also, for some non-ASCII character sets, full justification MAY be fundamentally inappropriate ๐ŸŒธ

Indentation Commands โœจ

okay so text/enriched starts out using the maximum available margins ๐ŸŒธ (the widest space your text can have). Two formatting commands let you tweak those margins:

  • Indent pushes the running left margin over to the right. The recommended indentation change is the width of four characters, but this may differ among implementations.
  • IndentRight pulls the running right margin over to the left. The recommended indentation change is the width of four characters, but this may differ among implementations.

A margin change does NOT force a line break ๐Ÿฆ‹, which is what makes "hanging" text possible. Here's an example:

Now <indent> is the time for all good horses to come to the aid of
their stable, assuming that </indent> any stable is really stable.

In a 40-character-wide window, that would display as:

            Now is the time for all good horses to
                come to the aid of their stable,
                assuming that any stable is
            really stable.

Miscellaneous Commands ๐ŸŽ€

  • Excerpt marks the affected text as a textual excerpt from another source, probably a message you're replying to ๐Ÿ’Œ. It's typically shown with indentation and an alternate font, or by indenting the lines and putting "> " in front of them, but the implementation gets to decide. (Fun fact: this is the only truly declarative markup construct in text/enriched. It doesn't fit super neatly with the other commands, but it's a style that's everywhere in email, and it has no procedural equivalent. iconic ๐Ÿ’…)
  • Param marks the affected text as command parameters. These are there for the text/enriched interpreter to use or ignore, but they are NOT to be shown to the reader ๐Ÿ™ˆ. The syntax of the parameter data (everything between the opening <param> and the closing </param>) isn't defined by this memo. It's left for future text/enriched extensions to decide. What is required: the parameter data must NOT contain nested <param> commands, and it must either avoid the < character entirely or use it in a way that's compatible with text/enriched parsing. The point is that the end of the data should be findable with either of two algorithms: searching for the first occurrence of </param>, or parsing until a balanced </param> command is found. Either way, the parameter data should NOT be shown to the human reader ๐Ÿ”’.

Note that, like the justification commands, Excerpt implicitly begins and ends with a line break if there isn't already one there.


Balancing and Nesting of Formatting Commands ๐Ÿงถ

Pairs of formatting commands must be properly balanced and nested. So a proper way to write bold italics is:

<bold><italic>the-text</italic></bold>

or, alternately:

<italic><bold>the-text</bold></italic>

But the following is illegal text/enriched ๐Ÿ’€:

<bold><italic>the-text</bold></italic>

The nesting rule is a bit more work for the people composing the text ๐Ÿ˜ค, but it makes life way easier for displayers, since they can be stack-based. The big goal of text/enriched is to make multifont, formatted email readable for everyone, so people who can send it can do so with confidence ๐Ÿซถ. So a little extra complexity on the composing side was seen as a fair trade for simpler reading software. Still, implementors of text/enriched readers are encouraged to follow the general Internet guideline of being conservative in what you send and liberal in what you accept โœจ. Implementations that can handle it are encouraged to deal reasonably with improperly nested text/enriched data.

Unrecognized formatting commands ๐ŸŒˆ

Implementations must regard any unrecognized formatting command as a "no-op" command, meaning it has no effect. This keeps the door open for future extensions to "text/enriched" ๐Ÿšช. Private extensions can be defined with formatting commands that begin with "X-", which is modeled on Internet mail header field names.

If you want to formally define extended commands, a new Internet document should be published ๐Ÿ“„.

White Space in Text/enriched Data ๐Ÿ“

No special behavior is required for the SPACE or TAB (HT) character. It is recommended, though, that when fixed-width fonts are in use, the common TAB (HT) semantics should be observed. That means the TAB moves to the next column position that is a multiple of 8. (Put differently: if a TAB occurs in column n, where the leftmost column is column 0, then that TAB should be replaced by 8-(n mod 8) SPACE characters.) Also, some mail gateways are notorious for losing (or, less commonly, adding) white space at the end of lines ๐Ÿ˜ฉ. So relying on SPACE or TAB characters at the end of a line is not recommended.

Initial State of a text/enriched interpreter ๐ŸŒท

Text/enriched is assumed to begin with filled text in a variable-width font, in a normal typeface, at a size that's average for the current display and user. Both the left and right margins are assumed to be maximal, which means they sit at the leftmost and rightmost acceptable positions.

Non-ASCII character sets ๐ŸŒ

If the character set given by the charset parameter on the Content-type line is anything other than "US-ASCII", the text described by the text/enriched formatting commands is in a non-ASCII character set. The commands themselves, though, are still the same ASCII commands defined in this document. This creates an ambiguity only for the "<" character, the octet with numeric value 60 ๐Ÿค”. In single-byte character sets, such as the ISO-8859 family, that's not a problem: the octet 60 can be quoted by including it twice, just like in ASCII. It gets trickier with multi-byte character sets, where the octet 60 might show up anywhere in the byte sequence for any of several characters.

In practice, most multibyte character sets solve this internally. For example, the ISO-2022 family can switch back into ASCII at any moment โœจ. So it's specified that, before text/enriched formatting commands, the prevailing character set should be "switched back" into ASCII. Also, only those characters that would be interpreted as "<" in plain text should be interpreted as token delimiters in text/enriched.

What to do for hypothetical future character sets that do NOT subsume ASCII is not addressed in this memo ๐Ÿ”ฎ.


Minimal text/enriched conformance ๐Ÿงธ

A minimal text/enriched implementation is one that does the following:

  • converts << to <
  • removes everything between a <param> command and the next balancing </param> command
  • removes all other formatting commands (all text enclosed in angle brackets)
  • and, outside of <nofill> environments, converts any series of n CRLFs to n-1 CRLFs
  • converts any lone CRLF pairs to SPACE

That's the whole thing, bestie. Super easy ๐Ÿฅฐ.

Notes for Implementors ๐Ÿ“

It's known that implementors of future mail systems will want rich text features way beyond what text/enriched currently defines ๐Ÿš€. The goal of text/enriched is to give those features a common format, one that a lot of it (at least) will be understood by software that interoperates. So software with a richer idea of formatted text can still use text/enriched as its basic representation. It can extend it with new formatting commands, and hide system-specific information inside text/enriched <param> constructs ๐Ÿซง. As those systems evolve, the definition of text/enriched is expected to be refined further by future published specifications. But text/enriched as defined here is a platform that evolutionary refinements can be built on ๐Ÿ—๏ธ.

A common way sophisticated mail programs will generate text/enriched data is as part of a multipart/alternative construct ๐Ÿ’ซ. For example, a mail agent that can generate enriched mail in ODA format can make a more widely interoperable version by generating both a text/enriched and an ODA version of the same data, like this:

Content-type: multipart/alternative; boundary=foo

--foo
Content-type: text/enriched

[text/enriched version of data]
--foo
Content-type: application/oda

[ODA version of data]
--foo--

If a MIME-conformant mail reader that understands ODA reads this message, the ODA version gets displayed. Otherwise, the text/enriched version is shown ๐Ÿ“ฌ.

In some environments, it might be impossible to combine certain text/enriched formatting commands, while in others they combine easily ๐Ÿคทโ€โ™€๏ธ. For example, combining <bold> and <italic> might produce bold italics on systems that support such fonts. But some systems can make text bold or italic, just not both. In those cases, the most recently issued (innermost) recognized formatting command should be preferred ๐Ÿ‘‘.

One of the big design goals of text/enriched was to make it so simple that even text-only mailers would build enriched-to-plain-text translators ๐Ÿช„. That way, enriched text becomes "safe" to use very widely. To show off how simple it is, an extremely simple C program that converts text/enriched input into plain text output is included in Appendix A ๐Ÿ’–.

Extensions to text/enriched ๐Ÿฆ‹

Plenty of mail system authors will want to extend text/enriched, and that's expected ๐Ÿ™Œ. The simple syntax of text/enriched, plus the rule that unrecognized formatting commands should simply be ignored, are intended to encourage that.

Sometimes, though, you need formatting commands that take arguments. That's exactly what the <param> construct is for ๐Ÿงš. For instance, software that wanted to extend text/enriched with colored text might define an "x-color" environment that always starts with a color name parameter, to say what color the affected text should be ๐ŸŒˆ.

An Example โœจ

Okay so, putting ALL of this together ๐ŸŽ€, here's the following text/enriched body fragment:

                      From: Nathaniel Borenstein <nsb@bellcore.com>
                      To: Ned Freed <ned@innosoft.com>
                      Content-type: text/enriched

                      <bold>Now</bold> is the time for
                      <italic>all</italic> good men
                       <smaller>(and <<women>)</smaller> to
                      <ignoreme>come</ignoreme>

                      to the aid of their


                      <x-color><param>red</param>beloved</x-color>
                      country.

                      By the way, I think that <<smaller>

                      should

                      REALLY be called

                      <<tinier>
                      and that I am always right.

                      -- the end

And it turns into this formatted text ๐Ÿ’… (which will, no doubt, look kinda cryptic in the text-only version of this doc ๐Ÿ™ˆ):

                 Now is the time for all good men (and <women>)  to
                 come
                 to the aid of their

                 beloved country.
                 By the way, I think that <smaller>
                 should
                 REALLY be called
                 <tinier>
                 and that I am always right.
                 -- the end

The word "beloved" would be in red on a color display, but only if the receiving software implemented the "x-color" extension ๐ŸŒˆ.


Security Considerations ๐Ÿ”’

Security issues are not discussed in this memo, as the mechanism raises no security issues.


Author's Address ๐Ÿ“ฎ

For more information, the author of this document may be contacted via Internet mail:

Nathaniel S. Borenstein
MRE 2D-296, Bellcore
445 South St.
Morristown, NJ 07962-1910

Phone: +1 201 829 4270
Fax:  +1 201 829 5963
EMail: nsb@bellcore.com

Acknowledgements ๐Ÿซถ

This document reflects the input of many contributors, readers, and implementors of the original MIME specification, RFC 1341. It also reflects particular contributions and comments from Terry Crowley, Rhys Weatherley, and John LoVerso. Thank you all, you're literally the reason this is so good ๐Ÿ’–.


References ๐Ÿ“š

  • [RFC-1341] Borenstein, N., and N. Freed, "MIME (Multipurpose Internet Mail Extensions): Mechanisms for Specifying and Describing the Format of Internet Message Bodies", RFC 1341, Bellcore, Innosoft, June 1992.
  • [RFC-1521] Borenstein, N., and N. Freed, "MIME (Multipurpose Internet Mail Extensions) Part One: Mechanisms for Specifying and Describing the Format of Internet Message Bodies", RFC 1521, Bellcore, Innosoft, September 1993.

Appendix A -- A Simple enriched-to-plain Translator in C ๐Ÿงš

One of the major goals behind the text/enriched subtype of the text Content-Type is making formatted text so simple that even text-only mailers will bother implementing enriched-to-plain-text translators. That way, multifont text has a much better shot at becoming "safe" to use really widely ๐Ÿฆ‹. To show how simple it is, here's a little C program that turns text/enriched input into plain text output. Heads up: this program assumes the local newline convention (the single character represented by "\n"), but some systems might need special CRLF handling ๐Ÿค“.

#include <stdio.h>
#include <ctype.h>

main() {
    int c, i, paramct=0, newlinect=0, nofill=0;
    char token[62], *p;

    while ((c=getc(stdin)) != EOF) {
        if (c == '<') {
            if (newlinect == 1) putc(' ', stdout);
            newlinect = 0;
            c = getc(stdin);
            if (c == '<') {
                if (paramct <= 0) putc(c, stdout);
            } else {
                  ungetc(c, stdin);
                  for (i=0, p=token; (c=getc(stdin)) != EOF && c != '>';
                  i++)
                  { if (i < sizeof(token)-1)
                    *p++ = isupper(c) ? tolower(c) : c;
                  }
                  *p = '\0';
                  if (c == EOF) break;
                  if (strcmp(token, "param") == 0)
                      paramct++;
                  else if (strcmp(token, "nofill") == 0)
                      nofill++;
                  else if (strcmp(token, "/param") == 0)
                      paramct--;
                  else if (strcmp(token, "/nofill") == 0)
                      nofill--;
              }
        } else {
            if (paramct > 0)
                ; /* ignore params */
            else if (c == '\n' && nofill <= 0) {

                if (++newlinect > 1) putc(c, stdout);
            } else {
                if (newlinect == 1) putc(' ', stdout);
                newlinect = 0;
                putc(c, stdout);
            }
        }
     }
     /* The following line is only needed with line-buffering */
     putc('\n', stdout);
     exit(0);
}

Now, you can totally do way better than this when showing text/enriched on a dumb terminal ๐Ÿ˜ค. For example, you can swap font stuff like "bold" for textual emphasis, like *this* or _T_H_I_S_ โœจ. You can also handle the indentation, justification, and other formatting commands properly. BUT honestly, the program above is all you need to show text/enriched on a dumb terminal without the user ever seeing a single formatting artifact ๐Ÿ‘‘.


Appendix B -- Differences from RFC 1341 text/richtext ๐ŸŒธ

Text/enriched is a clarification, simplification, and refinement of the type defined as text/richtext in RFC 1341. If you already know text/richtext, or you want to reuse the similarities so your text/enriched software can display text/richtext data, here's the rundown on the differences between the two. Note, however, that text/enriched is meant to make text/richtext obsolete, so it is not recommended that new software generate text/richtext ๐Ÿ™…โ€โ™€๏ธ.

  1. The name "richtext" was changed to "enriched", both to tell the two versions apart and because "richtext" created widespread confusion with Microsoft's Rich Text Format (RTF) ๐Ÿ’€.
  2. Clarifications. Many things were ambiguous or unspecified in the text/richtext definition, particularly the initial state and the semantics of richtext with multibyte character sets. However, such differences are OPERATIONALLY irrelevant, since the clarifications offered in this document are at least reasonable interpretations of the text/richtext specification ๐Ÿง .
  3. Newline semantics have changed. In text/richtext, all CRLFs were mapped to spaces, and line breaks were indicated by "<nl>". This has been replaced by the "n-1" rule for CRLFs ๐Ÿ“.
  4. The representation of a literal "<" character was "<lt>" in text/richtext, but is "<<" in text/enriched.
  5. The "nofill" command did not exist in text/richtext.
  6. The "param" command did not exist in text/richtext.
  7. The following commands from text/richtext have been REMOVED from text/enriched: <COMMENT>, <OUTDENT>, <OUTDENTRIGHT>, <SAMEPAGE>, <SUBSCRIPT>, <SUPERSCRIPT>, <HEADING>, <FOOTING>, <ISO-8859-[1-9]>, <US-ASCII>, <PARAGRAPH>, <SIGNATURE>, <NO-OP>, <LT>, <NL>, and <NP> ๐Ÿ—‘๏ธ.
  8. All claims of SGML compatibility have been dropped. However, with the possible exceptions of the new semantics for CRLF and "<<" can be implemented, text/enriched should be no less SGML-friendly than text/richtext was ๐ŸŒท.
  9. In text/richtext, there were three commands (<NL>, <NP>, and <LT>) that did not use balanced closing delimiters. Since all of these have been eliminated, there are NO exceptions to the nesting/balancing rules in text/enriched ๐ŸŽ‰.
  10. The limit on the size of formatting tokens has been increased from 40 to 60 characters ๐Ÿ“.

That's the whole spec, bestie ๐ŸŒˆ๐Ÿ’–

๐Ÿ“ฆ where this page comes from