RFC 1563
The text/enriched MIME Content-type
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:
- 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.
- Extensible โจ The syntax MUST be extensible to allow for new formatting commands that are deemed essential for some application.
- 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.
- 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:
Indentpushes the running left margin over to the right. The recommended indentation change is the width of four characters, but this may differ among implementations.IndentRightpulls 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 ๐
Excerptmarks 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 ๐ )Parammarks 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 ๐ โโ๏ธ.
- 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) ๐. - 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 ๐ง .
- 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 ๐. - The representation of a literal
"<"character was"<lt>"in text/richtext, but is"<<"in text/enriched. - The
"nofill"command did not exist in text/richtext. - The
"param"command did not exist in text/richtext. - 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>๐๏ธ. - 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 ๐ท. - 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 ๐. - 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
- ietf: rfc1563 1994-01
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms