Skip to main content

Module reading

Module reading 

Source
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_with looks 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.