Rich-Render Text Format — Core Specification v0.6

Date: March 29, 2026

Author: Kirk Siqveland / CyberTamer / AIKode

Status: Working Draft

Previous: Rich-Render Text Format v0.5 (March 26, 2026)


1. Overview

RichRender is a compact binary-compatible format for styled text. It extends UTF-8 with inline rendering metadata, replacing verbose HTML markup with small, efficient style descriptors called Style-Pips.

1.1 Target Use Cases

RichRender is designed as a method to extend HTML, providing compression and improved style clarity and conformance within the existing HTML ecosystem.

1.2 Design Philosophy

1.3 Implementation

1.4 The RichRender Ecosystem

RichRender is the canonical format at the center of a three-format ecosystem:

Libraries provide paired 1:1 conversions between these formats:

The format works comfortably at all three levels according to the user's needs, while remaining a single uniform format.

1.5 Four-Tier Architecture

RichRender is one format at four depths. Each tier is a superset of the one below. The continuation flag chain makes this work — each tier reads one more byte when it is ready to.


2. Terminology

Style-Pip — The style descriptor bytes that define visual formatting (bold, italic, color, font, etc.). Bytes one through three are spec-defined; additional bytes are preamble-defined via bitmap declarations. The Style-Pip is the atomic unit of visual style in RichRender. Each pip is a complete style declaration — it describes the full rendered state, not a delta from the previous style.

Style span (STX/ETX, 0x02/0x03) — A frame that applies a Style-Pip to a run of text. Visual formatting. STX opens a span and implicitly closes any previous style; ETX is used exclusively for nested close (see Section 3.5).

Inline element (SO/SI, 0x0E/0x0F) — A frame that wraps content in a semantic HTML inline element (code, kbd, em, strong, etc.).

Block element (SOH/EOT, 0x01/0x04) — A frame that wraps content in a structural HTML block element (p, div, table, h1–h6, etc.). Can contain other blocks, inline elements, and style spans.

Meta region (0xFE/0xFF) — A non-printing data region carrying element attributes, comments, or other metadata. May appear after any frame opener or standalone in the content stream.

Preamble — A Q-SET formatted header declaring color palettes, font palettes, extended bitmap layouts, and custom elements. May be inline or in an external .rrc file. Not required for Bit-Wise or Lite-Wire tiers.

Frame — General term for any open/close pair (style span, inline element, or block element).

Inflation — The process of converting RichRender content to Render-HTML for rendering in standard clients.

Deflation — The process of converting HTML content to RichRender for compact storage or transmission.

Wire format — RichRender optimized for transmission. Uses nested frames for semantic clarity and structural efficiency. Preferred for AI consumption.

Editor format — RichRender optimized for character-level editing. Uses flat consecutive spans. An intermediate representation, not a wire format.

Resuming pip — A Style-Pip that immediately follows the ETX close of a nested span, explicitly declaring the style that continues after the nested span ends. Eliminates the need for style stack maintenance in parsers.


3. Style-Pip Specification

The Style-Pip is a variable-length descriptor carried by style spans (STX frames). It describes the visual formatting applied to the span's content. Each pip is a complete description of the rendered style — not a delta or modification of a previous state.

The spec defines three bytes. Byte four and beyond are preamble-defined for documents requiring custom properties.

3.1 Byte One — Flags (Spec-Defined, Fixed)

BitNameDescription
7continuation1 = byte two follows; 0 = this is the only style byte
6vertical-hiHigh bit of vertical/variant field
5vertical-loLow bit of vertical/variant field
4underline1 = underline
3strikethrough1 = strikethrough
2italic1 = italic
1bold1 = bold
0reservedMust be 0. Reserved for future use

Vertical/variant field (bits 6–5):

ValueMeaning
00Normal
01Superscript
10Subscript
11Highlight (default yellow; byte two can specify color)

Pip value 0x00: All bits clear, including continuation. This represents the default unstyled state — no decorations, no variant, no extended bytes. Equivalent to plain text.

3.2 Byte Two — Color and Font (Spec-Defined, Fixed)

Present only when byte one's continuation flag (bit 7) is set.

BitNameDescription
7continuation1 = byte three follows; 0 = style ends here
6–5backgroundBackground/highlight color (2 bits, index values 0–3)
4–1colorForeground color index (4 bits, index values 0–15)
0fontFont family (0 = serif, 1 = sans-serif)

Background color values (bits 6–5):

ValueMeaning
00None (transparent)
01Yellow highlight
10Green highlight
11Pink highlight

Font bit (bit 0):

ValueMeaning
0Serif (system default: Times, Georgia, etc.)
1Sans-serif (system default: Arial, Helvetica, etc.)

Monospace is handled by the code inline element frame, not the style pip. Additional fonts (cursive, display, condensed) are preamble-defined.

Highlight interaction with byte one: When byte one highlight is set (bits 6–5 = 11) without byte two, the default yellow highlight applies — one byte total. When byte two is present, the background color field (bits 6–5) specifies the highlight color. When byte two background bits are set but byte one highlight is NOT set, the background color still applies. Both set: byte two background takes precedence.

3.3 Byte Three — Size and Typographic Extras (Spec-Defined, Fixed)

Present only when byte two's continuation flag (bit 7) is set.

BitNameDescription
7continuation1 = byte four follows (preamble-defined)
6–4sizeFont size index (3 bits, index values 0–7)
3reservedMust be 0. Reserved for future use
2double-underline1 = double underline
1overline1 = overline
0small-caps1 = small-caps

Font size table (spec-defined defaults):

IndexSizeTypical Use
0default (1em)Body text
12em~h1
21.5em~h2
31.17em~h3
41em (explicit)~h4
50.85emCaption / small
60.75emFine print
70.6emLegal / footnote

Preamble can override the default size table.

Double underline interaction: When both byte-one underline (bit 4) and byte-three double underline (bit 2) are set, double underline wins. The inflator checks double first, skips single if present. Three states: none, single, double.

3.4 Byte Four and Beyond — Preamble-Defined

Present only when byte three's continuation flag is set. Bit 7 remains the continuation flag; bits 6–0 are defined entirely by preamble bitmap declarations. The spec assigns no meaning to any bits in byte four or beyond.

3.5 STX/ETX and Nested Style Parsing

Style spans use STX (0x02) and ETX (0x03) with distinct roles:

STX (style open): Declares a new style. A new STX implicitly ends the previous style — no explicit close is needed for sequential style changes.

ETX (nested close): Used exclusively to close a nested span. A clear mask pip immediately follows, declaring which bits to remove from the current style. The parser computes current &= ~pip. Special case: ETX [0x00] clears all style (returns to unstyled) — since clearing no bits would be a no-op, 0x00 is given this special meaning.

Sequential styles — STX only, no ETX:

STX [bold] bold text STX [italic] italic text STX [0x00] normal text

Each STX replaces the previous style. The parser maintains a single current-style variable.

Nested styles — ETX with clear mask:

STX [italic] The quick STX [bold+italic] brown fox ETX [bold] jumps over

The parser reads strictly forward:

  1. STX + pip (italic) → apply italic
  2. Content flows
  3. STX + pip (bold+italic) → apply bold+italic
  4. Content flows
  5. ETX + clear mask (bold) → (bold+italic) &= ~bold → italic continues
  6. Content flows

The inner pip carries bold AND italic — the full rendered state. The clear mask after ETX names only what is being removed. The encoder never needs to look back to compute a resuming style; the decoder does one bitwise operation.

ETX [0x00] — clear all:

STX [bold+italic] styled text ETX [0x00] back to normal

Special case: 0x00 means clear all bits. Parser logic: if (pip == 0) style = 0; else style &= ~pip;

Structural boundaries: Block close (EOT), inline element close (SI), or end of stream all implicitly end the current style. No ETX needed.

Benefits of this model:


4. Frame Types

RichRender uses three distinct frame pairs. All follow the same structural pattern:

[opener] [descriptor] [optional meta region] [content] [closer]

4.1 Style Spans — STX/ETX (0x02 / 0x03)

Purpose: Visual text formatting.

Structure:

0x02 [style-pip] [optional 0xFE type meta 0xFF] [content] ...

4.2 Inline Elements — SO/SI (0x0E / 0x0F)

Purpose: Semantic inline HTML wrappers — elements whose identity carries meaning beyond visual formatting.

Structure:

0x0E [element-index] [optional 0xFE type meta 0xFF] [content] 0x0F

4.3 Block Elements — SOH/EOT (0x01 / 0x04)

Purpose: Structural containers — block-level HTML elements.

Structure:

0x01 [element-index] [optional 0xFE type meta 0xFF] [content] 0x04

4.4 Nesting Rules

Frames follow strict full-enclosure nesting. No overlapping. Every opened frame must close before its containing frame closes.

Containment hierarchy:

Style span nesting: Nesting of style spans is permitted and encouraged in wire format for semantic clarity. The outer span establishes a style scope; inner spans modify within it. Nested spans carry the complete rendered style in their pip. ETX closes the nested span and a clear mask pip follows (see Section 3.5).

Both flat consecutive spans and properly nested spans are valid RichRender. See Section 11 for the editor-to-wire pipeline.


5. Element Index Tables

Element indices are numbers from 1–127 (0 is reserved). Bit 7 is reserved as the ARIA flag (Section 6), leaving indices 1–127 for elements. The spec defines the base set at fixed positions. Preamble declarations extend the list beyond the last spec-defined index.

Block and inline elements use separate index namespaces — the opener byte (SOH vs SO) determines which table to look up.

5.1 Block Elements (SOH/EOT)

Sectioning and structure:

IndexElement
1div
2section
3article
4aside
5nav
6header
7footer
8main

Headings:

IndexElement
9h1
10h2
11h3
12h4
13h5
14h6

Text containers:

IndexElement
15p
16pre
17blockquote

Lists:

IndexElement
18ul
19ol
20li
21dl
22dt
23dd

Tables:

IndexElement
24table
25thead
26tbody
27tfoot
28tr
29th
30td
31caption
32colgroup
33col

Media and interactive:

IndexElement
34figure
35figcaption
36details
37summary
38fieldset
39legend

Other:

IndexElement
40hr
41form
42dialog
43pagebreak

Indices 44–127 are available for preamble-defined custom block elements.

Headings — dual mechanism: At the Lite-Wire and Wire tiers, headings use block element indices 9–14. At the Bit-Wise tier (no block frames), headings are expressed as style patterns (size + bold) and recognized by the inflator. See Section 13.6.

5.2 Inline Elements (SO/SI)

IndexElementNotes
1codeCode fragment
2kbdKeyboard input
3markHighlighted text
4abbrAbbreviation
5citeCitation
6sampSample output
7varVariable
8insInsertion
9delDeletion
10dfnDefinition term
11timeDate/time
12spanGeneric inline
13emEmphasis (semantic — distinct from pip italic)
14strongStrong emphasis (semantic — distinct from pip bold)
15aAnchor/link — URL carried in meta region
16qInline quotation
17bdiBidirectional isolate
18bdoBidirectional override
19dataMachine-readable value
20rubyRuby annotation
21rtRuby text
22rpRuby parenthesis
23wbrWord break opportunity
24outputOutput
25meterMeter
26progressProgress

Indices 27–127 are available for preamble-defined custom inline elements.

Links example:

0x0E [15] 0xFE [0x00] href="https://example.com" 0xFF display text 0x0F
 SO   a   meta  attr   attribute content           end   content    SI

6. ARIA Support

Accessibility is a first-class concern. RichRender supports ARIA through two mechanisms: roles via a compact spec-defined index, and attributes via the meta region.

6.1 ARIA Role Attachment

ARIA roles attach to element frames (both block and inline) via bit 7 of the element index byte.

Without ARIA:

0x01 [element-index]
      bit 7 = 0, bits 6–0 = element number

With ARIA role:

0x01 [element-index] [aria-role-byte]
      bit 7 = 1, bits 6–0 = element number

When bit 7 is set, the next byte is an ARIA role index from the table below. Zero overhead when ARIA is not used.

6.2 ARIA Role Index Table

IndexRoleIndexRole
1alert2alertdialog
3application4banner
5button6cell
7checkbox8columnheader
9combobox10complementary
11contentinfo12definition
13dialog14directory
15document16feed
17figure18form
19grid20gridcell
21group22heading
23img24link
25list26listbox
27listitem28log
29main30marquee
31math32menu
33menubar34menuitem
35menuitemcheckbox36menuitemradio
37navigation38none
39note40option
41presentation42progressbar
43radio44radiogroup
45region46row
47rowgroup48rowheader
49scrollbar50search
51searchbox52separator
53slider54spinbutton
55status56switch
57tab58table
59tablist60tabpanel
61term62textbox
63timer64toolbar
65tooltip66tree
67treegrid68treeitem

Indices 69–127 available for preamble-defined custom roles.

6.3 ARIA Attributes

ARIA attributes (aria-label, aria-describedby, aria-live, etc.) carry string values and are handled through the meta region as standard element attributes:

0x01 [nav+ARIA] [37] 0xFE [0x00] aria-label="Main navigation" 0xFF content 0x04
 SOH  bit7=1    nav   meta  attr                                end         EOT

No special mechanism is needed — ARIA attributes are just attributes.


7. Meta Region — 0xFE / 0xFF

0xFE and 0xFF are permanently invalid in UTF-8, allowing RichRender to repurpose them as delimiters for non-printing metadata regions.

7.1 Structure

0xFE [type-byte] [content] 0xFF

The type byte determines interpretation. Bit 7 is a continuation flag (reserved for future use). Bits 6–0 define the region type.

7.2 Defined Types

Type ByteMeaning
0x00Element attributes — the content is attribute text as it would appear inside an HTML opening tag
0x01Comment — non-rendering annotation, parsers may skip entirely

Types 0x02–0x7F are reserved for future use.

7.3 Context Rules

A meta region may appear in two positions:

After a frame descriptor — immediately following the Style-Pip (in a style span) or element index byte and optional ARIA role byte (in element frames). The meta region content is associated with that frame's element.

Standalone — anywhere in the content stream outside of a frame descriptor position. Typically used for comments and annotations.

The structure is identical in both positions. The type byte is always present.

7.4 Examples

Paragraph with attributes:

0x01 [15] 0xFE [0x00] id="intro" class="lead" 0xFF Content here 0x04
 SOH   p   meta  attr                          end               EOT

Link with href:

0x0E [15] 0xFE [0x00] href="https://example.com" title="Example" 0xFF Click here 0x0F
 SO    a   meta  attr                                             end             SI

Inline comment:

Content before 0xFE [0x01] TODO: review this section 0xFF content after
               meta  cmnt                             end

Styled span with attributes:

0x02 [pip:bold] 0xFE [0x00] data-ref="note3" 0xFF Bold text ...
 STX            meta  attr                    end

7.5 Safety

Since 0xFE and 0xFF cannot appear in valid UTF-8 byte sequences, there is no collision risk with text content. No escaping mechanism is required. If a RichRender stream encounters these bytes outside of the meta region structure, the data is malformed.

0xFE and 0xFF should never appear outside of a RichRender-formatted stream. They are permanently invalid in UTF-8 and any system passing content outside of RichRender context must ensure these bytes are not present.


8. Default Palettes

The spec defines standard default palettes for all color and font fields. Documents using only the defaults need no preamble. Preamble declarations override these defaults when a document requires custom values.

8.1 Foreground Color Palette (16 entries)

IndexColorHex
0Default (inherit)—
1Black#000000
2Dark gray#555555
3Red#CC0000
4Dark red / Maroon#800000
5Orange#DD6600
6Green#008800
7Dark green#005500
8Blue#0066CC
9Dark blue / Navy#003366
10Purple#7700AA
11Teal#008888
12Brown#885500
13Light gray#AAAAAA
14White#FFFFFF
15Gold / Yellow#CCAA00

8.2 Background Color Palette (4 entries)

IndexColor
0None (transparent)
1Yellow highlight
2Green highlight
3Pink highlight

8.3 Font Defaults

ValueFamily
0Serif (system default: Times, Georgia, etc.)
1Sans-serif (system default: Arial, Helvetica, etc.)

8.4 Font Size Table (8 entries)

IndexSizeTypical Use
0default (1em)Body text
12em~h1
21.5em~h2
31.17em~h3
41em (explicit)~h4
50.85emCaption / small
60.75emFine print
70.6emLegal / footnote

9. Preamble Specification

The preamble declares per-document overrides: custom color palettes, font palettes, extended Style-Pip bitmaps, and custom element definitions. A preamble is not required for Bit-Wise or Lite-Wire tier documents using only spec defaults.

9.1 Format

The preamble is a Q-SET structure using Set|Tag delimiters:

{SETTAG:RICHRENDER}

[COLORS]
0 | #1a1a2e
1 | #e94560
2 | #0f3460

[FONTS]
0 | Palatino
1 | Futura

[SIZES]
1 | 3em
2 | 2em

[STYLE-PIP-4]
bit6-3 | custom-color
bit2-0 | reserved

[BLOCK-ELEMENTS]
44 | my-container
45 | sidebar-panel

[INLINE-ELEMENTS]
27 | my-tooltip
28 | data-badge

{/SETTAG/}

9.2 Override Rules

9.3 Extended Bitmap Declarations

Groups named [STYLE-PIP-N] (where N is the byte number, starting at 4) define the bit layout for Style-Pip bytes beyond byte three. Each key|value pair maps bit positions to their meaning. Bit 7 is always the continuation flag and should not be declared.

9.4 Custom Elements

Groups named [BLOCK-ELEMENTS] and [INLINE-ELEMENTS] extend the spec-defined element tables. Index numbers must start after the last spec-defined index for each category (44+ for blocks, 27+ for inlines).

9.5 Preamble Location

The preamble may appear:

A .pip document without a preamble is valid — it uses spec-defined defaults for all palettes, sizes, and element tables.

A .pip document may reference an external .rrc file, carry its own inline preamble, or both (with inline declarations overriding external ones).


10. Control Character Map

10.1 RichRender-Assigned

ByteASCII NameRichRender Use
0x01SOHBlock element frame OPEN
0x02STXStyle span OPEN (implicitly closes previous style)
0x03ETXNested style span CLOSE (clear mask pip follows)
0x04EOTBlock element frame CLOSE
0x0ESOInline element frame OPEN
0x0FSIInline element frame CLOSE

10.2 RichRender-Assigned (Outside ASCII Range)

ByteUse
0xFEMeta region OPEN — permanently invalid in UTF-8, zero collision risk
0xFFMeta region CLOSE — permanently invalid in UTF-8, zero collision risk

10.3 Preserved as Standard

ByteASCII NameReason
0x00NULString terminator in C and many toolchains
0x09TABStandard whitespace — see Section 14
0x0ALFLine feed
0x0DCRCarriage return

10.4 Unassigned / Available

All other control characters (0x05–0x08, 0x0B–0x0C, 0x10–0x1F) are unassigned in this version. They have no RichRender meaning and should not appear in a RichRender stream. Future versions may assign roles to some of these.


11. Editor-to-Wire Pipeline

RichRender defines a transmission (wire) format. Editor implementations may use a different internal representation optimized for character-level manipulation.

11.1 Editor Mode (1:1)

An editor may expand any RichRender frame into per-character Style-Pip pairs. Each UTF-8 glyph is followed by its own Style-Pip. Consecutive characters sharing a style carry a pip value of 0x00 (all flags clear, no continuation) — one byte overhead per character meaning "same as before."

This is an implementation strategy, not a wire format. The spec does not mandate internal representation.

11.2 Wire Optimization

A wire-rendering agent takes editor output and optimizes it for transmission:

11.3 Round-Trip Fidelity

The transformation between editor format and wire format is lossless. Expanding wire-format frames to per-character pips and collapsing them back produces identical output. No information is lost in either direction.


12. File Types and Document Model

12.1 The .pip Document

A .pip file is a hybrid document, analogous to PHP — HTML provides the page skeleton, and RichRender handles styled content inline where it is most efficient.

The structural HTML remains as HTML: <!DOCTYPE>, <head>, <meta>, <script>, page layout. Inside content regions where HTML would normally use verbose inline styles and nested <span> elements, RichRender takes over using its frame system.

This means:

12.2 The .rrc Context File

A .rrc (RichRender Context) file is an external Q-SET preamble. It contains palette declarations, bitmap definitions, and custom element mappings that can be shared across multiple .pip documents.

This mirrors modern web practice where CSS, JS, and configuration files are external and included. A .rrc file is consumed at build or serve time — it is never delivered to the client as a separate request.

12.3 Content Negotiation

A server may serve the same content differently based on the HTTP Accept header:

12.4 MIME Type

RichRender streams are not valid UTF-8 due to the use of 0xFE and 0xFF. A dedicated MIME type is required for proper content negotiation and transport:


13. Inflation Rules

Inflation is the process of converting RichRender content to Render-HTML for rendering in standard clients.

13.1 Style Spans → Render-HTML

A style span inflates to a <span> with appropriate styling. All output elements carry mdr- prefixed classes for lossless round-trip back to RichRender.

Byte one flags:

Pip FlagCSS OutputRender-HTML Class
boldfont-weight: boldmdr-b
italicfont-style: italicmdr-i
strikethroughtext-decoration: line-throughmdr-s
underlinetext-decoration: underlinemdr-u
superscriptvertical-align: super; font-size: smallermdr-sup
subscriptvertical-align: sub; font-size: smallermdr-sub
highlightbackground-color: yellow (default)mdr-hl

Byte two fields:

Pip FieldCSS OutputRender-HTML Class
foreground colorResolved from palette → color: #rrggbbmdr-fg
background colorResolved from palette → background-color: ...mdr-bg
fontfont-family: serif or font-family: sans-serifmdr-font

Byte three fields:

Pip FieldCSS OutputRender-HTML Class
font sizeResolved from size table → font-size: ...mdr-sz
small-capsfont-variant: small-capsmdr-sc
overlinetext-decoration: overlinemdr-ol
double underlinetext-decoration: underline doublemdr-du

Multiple text-decoration flags combine: text-decoration: underline line-through overline.

Double underline overrides single underline when both are set.

13.2 Element Frames → Render-HTML

Inline and block element frames inflate to their corresponding HTML tags:

0x0E [3] 0xFE [0x00] data-ref="7" 0xFF Hello 0x0F
→ <mark data-ref="7">Hello</mark>

0x01 [15] 0xFE [0x00] id="intro" class="lead" 0xFF Content 0x04
→ <p id="intro" class="lead">Content</p>

13.3 ARIA Role Inflation

When an element carries an ARIA role:

0x01 [nav+ARIA] [37] 0xFE [0x00] aria-label="Main" 0xFF content 0x04
→ <nav role="navigation" aria-label="Main">content</nav>

13.4 Meta Region Comments

Comment meta regions (type 0x01) are inflated to Render-HTML comments or omitted entirely, at the inflater's discretion:

0xFE [0x01] Editor note 0xFF → <!-- Editor note --> or nothing

13.5 Generated CSS

An inflater may optionally generate a stylesheet that maps common pip patterns to CSS classes, reducing inline style repetition in the inflated output.

13.6 Heading Detection (Bit-Wise Tier)

At the Bit-Wise tier, headings are expressed as style patterns rather than block element frames. The inflator recognizes these patterns and emits semantic heading tags:

PatternEmitted TagRender-HTML Class
bold + size index 1 (2em)<h1>mdr-set-h1
bold + size index 2 (1.5em)<h2>mdr-set-h2
bold + size index 3 (1.17em)<h3>mdr-set-h3
bold + size index 4 (1em explicit)<h4>mdr-set-h4

At the Lite-Wire and Wire tiers, block element headings (indices 9–14) produce <h1> through <h6> with class mdr-h1 through mdr-h6.

The mdr-set-* vs mdr-h* class distinction enables lossless round-trip: mdr-set-h1 reconstructs as bold + size pips, mdr-h1 reconstructs as a block frame.


14. Tab Character Handling

14.1 Wire Format

Tab (U+0009) is stored as the raw byte 0x09 in the text stream. No special control character is needed — 0x09 is outside the RichRender control character range.

14.2 Editor Format

Stored as a normal character entry with pip bytes. Rendered in the editor via white-space: pre-wrap on the editing area, which preserves tab stops.

14.3 Render-HTML

HTML has no native tab stops. Browsers collapse \t to a single space in normal rendering. The Render-HTML inflator emits a styled span for tabs:

<span class="mdr-tab" style="display:inline-block;width:2em"></span>

The mdr-tab class allows CSS customization. The default width is 2em.

14.4 Future Configurability

Tab rendering is a policy decision, not a format decision. Future implementations may support configuration for tab width, tab replacement (e.g., &nbsp; sequences), or CSS tab-size property. The wire format is stable — only the inflator's rendering changes.


15. Render-HTML Boundary Conventions

15.1 Round-Trip Class Contract

All Render-HTML output from a RichRender inflator carries mdr- prefixed classes for lossless round-trip back to RichRender. See Section 13 for the complete class-to-pip mapping.

15.2 Document-Level Declaration

A fully Render-HTML document declares itself in <head>:

<meta name="richrender" content="full" data-tier="bitwise">

The data-tier attribute indicates the maximum pip depth used: bitwise (bytes 1–3) or wire (full frame structure).

15.3 Embedded Render-HTML Boundaries

When Render-HTML regions exist inside a larger HTML document (CMS page, email template, web app), each region is wrapped:

<div data-mdr="root" data-mdr-tier="bitwise">
  <!-- clean Render-HTML, mdr- classes throughout -->
</div>

Multiple data-mdr="root" regions may appear in one document. Each is independently round-trippable.

15.4 Outside Boundary Regions — Implementation Guidance

HTML outside data-mdr="root" boundaries is not Render-HTML. The spec does not mandate how implementations handle it. Three strategies are documented as guidance for implementers:

  1. Ignore: Treat non-Render-HTML as opaque. Do not attempt conversion. Simplest, no data loss, no editability.
  2. Best-effort: Heuristic mapping of standard HTML to RichRender pips (e.g., <strong> → bold bit, <h2> → size 2 + bold). Lossy but practical for paste-from-Word and similar workflows. Implementation decides what maps and what gets dropped.
  3. Passthrough: Wrap unmapped HTML in a meta region or inline element frame. RichRender carries the blob without understanding it. Round-trip back to HTML restores the original. Preserves fidelity but loses editability on those fragments.

Implementations may combine strategies — best-effort with passthrough fallback for elements that don't map cleanly. The choice is application-specific and should not be constrained by the spec.


16. Editor Palette — Implementation Guidance

This section is implementation guidance, not core spec. It describes a pattern for editors handling pasted content with colors outside the default palette.

16.1 The Problem

The spec defines 16 default foreground colors and 4 background colors. Pasted content often arrives with colors outside the default set. An editor that discards these colors violates user expectations; an editor that permanently alters the spec palette breaks round-trip fidelity for other documents.

16.2 The Solution

Editors maintain a document-specific mutable palette (the "editor palette") separate from the spec defaults. The editor palette is a sparse array — only slots that differ from the spec defaults are populated.

Resolution: for each index, check the editor palette first; if empty, fall back to the spec default. This applies at render time only — the pip bytes store the same index either way.

16.3 Scope

The editor palette is per-document, editor-only state. It is not encoded in the wire format. A document saved as a wire stream uses only the spec default colors or preamble overrides.


17. Resolved Questions

  1. VT and FF assignment. Resolved — hr is block element index 40; pagebreak is block element index 43. No control characters needed.
  2. Preamble reference syntax. Resolved — Q-SET's include() mechanism handles external .rrc file references.
  3. Hybrid boundary markers. Resolved — RichRender's control characters (SOH, STX, ETX, EOT, SO, SI, 0xFE, 0xFF) are themselves the boundary markers within a hybrid document.
  4. Index 0 convention. Resolved — index 0 is formally reserved in both block and inline element tables.
  5. Meta region nesting. Resolved — 0xFE and 0xFF cannot appear inside a meta region. Explicitly stated in Section 7.5.
  6. Links. Resolved — the anchor element (inline index 15) carries its URL and other attributes in the meta region.
  7. ARIA attributes. Resolved — handled as standard attributes in the meta region.
  8. MIME type. Resolved — application/richrender (see Section 12.4).
  9. Nested flag. Resolved — eliminated. Nesting is structural (STX/ETX distinction), not flag-based. Bit 0 of byte one is reserved.
  10. Heading detection. Resolved — dual mechanism. Bit-Wise uses style patterns (size + bold → mdr-set-h*), Wire uses block frames (→ mdr-h*). Round-trip disambiguated by class prefix.

Appendix A: Adoption Strategy

A.1 Server-Side Compression (Phase 1)

The lowest-friction adoption path requires no client changes and no standards adoption. An email provider or content host installs the deflator/inflator pair as a server-side storage optimization:

The value proposition is immediate and measurable: significant storage reduction on HTML email content with zero client-facing impact. This is an infrastructure cost optimization, not a format adoption decision.

A.2 Native Delivery (Phase 2)

Once the inflator/deflator infrastructure is in place on the server, native delivery to capable clients is a minimal additional step:

The server is the smart layer. Senders never need to know the recipient's client capabilities. The server stores one canonical .pip copy and serves the appropriate format per request.

A.3 Native Authoring (Phase 3)

With server infrastructure and client delivery in place, authoring tools can compose directly in RichRender:

A.4 Parallel Adoption Paths

The server-side email path is one of several independent adoption vectors:

Each path is independent. Progress on one does not block or require progress on the others.


RichRender is created by Kirk Siqveland. Specification developed in collaboration with Claude (Anthropic).