Expand description
A message laid out for reading: who wrote to whom, the attachments apart, and the text cut into what this message says, the messages it quotes, the headers of the messages it forwards, and the signature.
HTML mail is shown formatted once made safe (safe_html): only text,
structure and links survive; images, styles, scripts and anything that
would load from the network are dropped, so nothing remote loads and
nothing runs. Plain text keeps its parts, its links made clickable.
Structs§
- Ahead 🔒
- What
parts_withlooks ahead for, read once from the end of the text: each line’s header field, where each run of header fields ends and whether it names a subject or a date, and the next line that is not blank. Looked for again from every line, they made the work grow with the square of the lines: 8,000 lines of “From: x” took half a minute. - Attachment
- Folded 🔒
- The words of
words::Quotes, folded once for a whole text, not once per line. - Html
- A message’s HTML, made safe and calm to read.
- Person
- One person, as a header names them.
- Reading
- A message, laid out for reading.
Enums§
- Part
- A piece of a message’s text.
Constants§
- CLOSES_
P 🔒 - The start tags before which the parser closes an open paragraph.
- DEEPEST 🔒
- How deep elements may stand in one another in a message’s HTML before the
deeper ones are left out, their words kept (
shallow). Mail nests a few dozen levels; web browsers stop at 512 too. - HEADINGS 🔒
- QUOTE_
MARKERS 🔒 - Where the messages a reply quotes or a forward carries begin, in the HTML of Gmail, Apple Mail and Thunderbird, and Outlook.
- VOID 🔒
- Elements that hold nothing: never left open.
Functions§
- attachment
- attachment_
from - An attachment from a message’s bytes: its name and content.
- calendar
- One attachment’s name and bytes, to open or save it. The iCalendar a message carries, inline or attached (an invitation, RFC 6047): the part with a METHOD first, as Gmail and Outlook send both.
- clean_
html 🔒 - Only text, structure and links: no images, styles, scripts, forms or frames, no attribute but a link’s address, and only web and mail links. Layout tables become plain blocks, headings bold paragraphs, empty blocks go.
- closed_
before 🔒 - What a start tag closes first when it is innermost, from the innermost out: the next list item closes the last, the next cell the last.
- closed_
on_ 🔒the_ way - The end tags that close what the parser closes for them on the way, and what, from the innermost out: a paragraph before a block’s end, a list item before its list’s, a cell and a row before their table’s. Any other end tag closes the innermost element only, when it is the one it names.
- escape 🔒
- file_
name 🔒 - A name safe to write in a folder, on every system, since what is saved may
be synced to another: no path, no control characters, none of the
characters Windows forbids (
"report.pdf:x"would write a hidden stream there), no dot or space at the end, and no device’s name (“nul.txt”); the extension kept. - header_
field 🔒 - “Name: value”, with a header name, possibly with a space before the colon.
- is_
attribution 🔒 - “On Thu, 1 Oct 2026, Jean wrote:” or “Le jeu. 1 oct. 2026, Jean a écrit :”
(
folded), right before a quote (next, the next line that is not blank). - is_
separator 🔒 - Outlook’s line of underscores before “De :”.
- linkify
- Plain text as HTML: escaped, its web links clickable and shown by their site (“example.org/…”), its lines kept.
- next_
link 🔒 - Where the next web address starts: “http://” or “https://”. One search for both: searched apart, a line of a thousand “https://” links had its whole rest read again for an “http://” before each of them.
- parts
- Cuts a message’s text into parts (see
Part), its quoted history read with the words in use (words::current). - parts_
with - Cuts a message’s text into parts with these words (
words::Quotes): the lines that open a forwarded or answered message, the header names of a repeated header block, the endings of an attribution, in any language your correspondents’ mail programs write them. Each line is read a set number of times, whatever comes after it (Ahead). - people 🔒
- push 🔒
- Adds a line to the last part when it is of the same kind, else starts a new part.
- quote_
depth 🔒 - “> > text” → (2, “text”).
- read
- Reads a message file for the reading pane.
- read_
bytes - A message laid out for reading, from its bytes (a decrypted message lives only in memory).
- safe_
html - A message’s HTML, made safe: the quoted history split off, then each part cleaned.
- shallow 🔒
- The HTML with no element deeper than
DEEPEST, in one pass. The parser under ammonia looks through the elements still open at most tags, so elements nested by the thousand cost it the square of their number (32,000 empty blocks in one another: 3 seconds; a megabyte of them, minutes). This follows the elements the parser keeps open without ever counting one closed before the parser closes it: an element closes on its own end tag when it is the innermost, or when the parser surely closes it then (closed_on_the_way,closed_before). Sloppy mail at worst seems deeper than it is; the parser, which also opens elements of its own (a table’s body and row), never holds more than a few times what is counted. A start tag past the depth is left out, a space in its place, so that no word runs into the next and no “<” before it starts a tag; its words stay. - take_
previous_ 🔒line_ into_ attribution - Gmail cuts long attributions in two: “Le jeu. 1 oct. 2026 à 12:03, Jean <” and “jean@example.org> a écrit :”. The first half is taken back from the text.
- tidy 🔒
- Trims blank lines around a part; empty parts go.
- without_
spacers 🔒 - Spacer blocks and runs of line breaks, which layouts use for room, taken
out in one pass: a block is dropped as its end is written, when nothing
but a space stands in it, so a block left empty by the spacers it held goes
too (
<div><p></p></div>), and a third line break in a row goes. Done by replacing them over the whole text until none was left, the work grew with the square of the nesting: 8,000 empty blocks in one another took seconds.