# 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

- **Compressed storage and transmission of text-heavy web pages** — RichRender extends HTML by providing compact inline style encoding that integrates with existing web toolchains. The `.pip` hybrid document model allows HTML and RichRender to coexist, with RichRender handling styled content regions where markup overhead is highest.
- **Rich-text communication** — email, messaging, and other HTML-based rich-text contexts benefit from RichRender's compression and structural clarity.
- **AI-to-AI communication** — a format that is precise, unambiguous, and compact. As context windows become currency, RichRender offers significant compression over equivalent HTML for styled text content.

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

- **Spec defines the common.** Universal elements, fixed bit layouts, standard decorations — defined once, known to all parsers.
- **Preamble defines the specific.** Per-document colors, fonts, extended bitmaps, custom elements — declared in a Q-SET header, interpreted by any compliant parser.
- **The same mechanism at every level.** Index lookups, continuation flags, and preamble extension apply consistently throughout the format.
- **One pattern, three purposes.** All frame types follow the same structure: opener + descriptor + optional meta + content + closer.
- **Zero configuration through three bytes.** The spec defines default palettes and layouts for bytes one through three. Documents using only the defaults need no preamble at all.

### 1.3 Implementation

- **UTF-8, ASCII, & Style-Pips** — RichRender Style-Pips are variable byte-length blocks, like a D-Word, to define and carry style information. Like UTF-8, the 7th bit flags the need for an additional byte, allowing a compressed yet expansive style description. A Style-Pip may be only one byte long.
- **WIRE-Format** — implementation uses the Style-Pip always following one of the four Frame-opening characters to define a style used within that entire frame.
- **EDIT-Format** — alternates UTF-8 glyphs with Style-Pips as 1:1 pairs; each glyph carries its entire style in the associated Style-Pip.
- **Scope** — RichRender intentionally only carries the uniform style information in order to minimize the resulting content, rather than replace HTML for complex visual rendering.

### 1.4 The RichRender Ecosystem

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

- **Rich Markdown** (`.mdr`) — human authoring and reading format. Markdown extended for rich-text display, with 1:1 mapping to RichRender.
- **RichRender** (`.pip`) — the core binary format. The Rich-Render Text Format. The canonical source of truth for styled content.
- **Render-HTML** (`.html`) — RichRender inflated to HTML. Not the full breadth of HTML, only the rendered version of what RichRender expresses. Browser and email client output.

Libraries provide paired 1:1 conversions between these formats:

- Rich Markdown → RichRender (ingest human-authored markdown)
- RichRender → Rich Markdown (output human-readable markdown)
- RichRender → Render-HTML (inflation — the primary rendering path)
- Render-HTML → RichRender (deflation — compressing existing HTML)

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.

- **Bit-Wise (bytes 1–3):** All style properties encoded as atomic bits. Bold, italic, underline, strikethrough, superscript, subscript, highlight, 16 foreground colors, 4 background colors, serif/sans font, 8 font sizes, small-caps, overline, double underline. Headings are recognized as style patterns (size + bold) by the inflator. Zero configuration — spec-defined defaults for all palettes and sizes. Targets AI chat, IoT, smart devices, email, lightweight documents.

- **Lite-Wire:** Adds block and inline element frames (SOH/EOT blocks, SO/SI inlines) to Bit-Wise. Paragraphs, lists, links, blockquotes, horizontal rules. No preamble needed. Competitive with TinyMCE-class editors. A Bit-Wise stream is valid Lite-Wire.

- **Wire Format:** Full frame structure including meta regions, preamble, custom palettes, element tables. Complete HTML-equivalent expressiveness for document authoring. A Lite-Wire stream is valid Wire Format.

- **Editor:** Per-character pip arrays for cursor-addressable editing. Internal representation for selection, insertion, painting, and undo. Not a wire format — used by interactive editors only.

---

## 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)

| Bit | Name | Description |
|-----|------|-------------|
| 7 | continuation | 1 = byte two follows; 0 = this is the only style byte |
| 6 | vertical-hi | High bit of vertical/variant field |
| 5 | vertical-lo | Low bit of vertical/variant field |
| 4 | underline | 1 = underline |
| 3 | strikethrough | 1 = strikethrough |
| 2 | italic | 1 = italic |
| 1 | bold | 1 = bold |
| 0 | reserved | Must be 0. Reserved for future use |

**Vertical/variant field** (bits 6–5):

| Value | Meaning |
|-------|---------|
| 00 | Normal |
| 01 | Superscript |
| 10 | Subscript |
| 11 | Highlight (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.

| Bit | Name | Description |
|-----|------|-------------|
| 7 | continuation | 1 = byte three follows; 0 = style ends here |
| 6–5 | background | Background/highlight color (2 bits, index values 0–3) |
| 4–1 | color | Foreground color index (4 bits, index values 0–15) |
| 0 | font | Font family (0 = serif, 1 = sans-serif) |

**Background color values (bits 6–5):**

| Value | Meaning |
|-------|---------|
| 00 | None (transparent) |
| 01 | Yellow highlight |
| 10 | Green highlight |
| 11 | Pink highlight |

**Font bit (bit 0):**

| Value | Meaning |
|-------|--------|
| 0 | Serif (system default: Times, Georgia, etc.) |
| 1 | Sans-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.

| Bit | Name | Description |
|-----|------|-------------|
| 7 | continuation | 1 = byte four follows (preamble-defined) |
| 6–4 | size | Font size index (3 bits, index values 0–7) |
| 3 | reserved | Must be 0. Reserved for future use |
| 2 | double-underline | 1 = double underline |
| 1 | overline | 1 = overline |
| 0 | small-caps | 1 = small-caps |

**Font size table (spec-defined defaults):**

| Index | Size | Typical Use |
|-------|------|-------------|
| 0 | default (1em) | Body text |
| 1 | 2em | ~h1 |
| 2 | 1.5em | ~h2 |
| 3 | 1.17em | ~h3 |
| 4 | 1em (explicit) | ~h4 |
| 5 | 0.85em | Caption / small |
| 6 | 0.75em | Fine print |
| 7 | 0.6em | Legal / 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:**

- One fewer byte at every sequential style transition
- ETX has exactly one meaning: nested close with clear mask
- The clear mask names the change — readable without context
- No "am I inside a span?" tracking for sequential changes
- Nesting is structural, not flag-based
- The parser is a simple forward-reading state machine

---

## 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] ...
```

- The descriptor is a Style-Pip (Section 3).
- Content is UTF-8 text, which may include nested style spans, inline elements, and block elements.
- Each span's pip is a complete style declaration for that span's content.
- A new STX implicitly ends the previous style span.
- ETX is used only for nested close, followed by a clear mask pip (see Section 3.5).

### 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
```

- The descriptor is an element index byte (1–127) referencing either the spec-defined inline element table (Section 5.2) or preamble-extended entries.
- Bit 7 of the element index byte is the ARIA flag: when set, an ARIA role byte follows the index byte before any meta region (see Section 6).
- Content may include UTF-8 text, style spans, and other inline elements.

### 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
```

- The descriptor is an element index byte (1–127) referencing the spec-defined block element table (Section 5.1) or preamble-extended entries.
- Bit 7: ARIA flag, same mechanism as inline elements.
- Content may include other block elements, inline elements, style spans, and UTF-8 text.

### 4.4 Nesting Rules

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

**Containment hierarchy:**

- **Block elements** may contain: block elements, inline elements, style spans, raw text.
- **Inline elements** may contain: inline elements, style spans, raw text.
- **Style spans** may contain: style spans, inline elements, raw text.

**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:**

| Index | Element |
|-------|---------|
| 1 | div |
| 2 | section |
| 3 | article |
| 4 | aside |
| 5 | nav |
| 6 | header |
| 7 | footer |
| 8 | main |

**Headings:**

| Index | Element |
|-------|---------|
| 9 | h1 |
| 10 | h2 |
| 11 | h3 |
| 12 | h4 |
| 13 | h5 |
| 14 | h6 |

**Text containers:**

| Index | Element |
|-------|---------|
| 15 | p |
| 16 | pre |
| 17 | blockquote |

**Lists:**

| Index | Element |
|-------|---------|
| 18 | ul |
| 19 | ol |
| 20 | li |
| 21 | dl |
| 22 | dt |
| 23 | dd |

**Tables:**

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

**Media and interactive:**

| Index | Element |
|-------|---------|
| 34 | figure |
| 35 | figcaption |
| 36 | details |
| 37 | summary |
| 38 | fieldset |
| 39 | legend |

**Other:**

| Index | Element |
|-------|---------|
| 40 | hr |
| 41 | form |
| 42 | dialog |
| 43 | pagebreak |

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)

| Index | Element | Notes |
|-------|---------|-------|
| 1 | code | Code fragment |
| 2 | kbd | Keyboard input |
| 3 | mark | Highlighted text |
| 4 | abbr | Abbreviation |
| 5 | cite | Citation |
| 6 | samp | Sample output |
| 7 | var | Variable |
| 8 | ins | Insertion |
| 9 | del | Deletion |
| 10 | dfn | Definition term |
| 11 | time | Date/time |
| 12 | span | Generic inline |
| 13 | em | Emphasis (semantic — distinct from pip italic) |
| 14 | strong | Strong emphasis (semantic — distinct from pip bold) |
| 15 | a | Anchor/link — URL carried in meta region |
| 16 | q | Inline quotation |
| 17 | bdi | Bidirectional isolate |
| 18 | bdo | Bidirectional override |
| 19 | data | Machine-readable value |
| 20 | ruby | Ruby annotation |
| 21 | rt | Ruby text |
| 22 | rp | Ruby parenthesis |
| 23 | wbr | Word break opportunity |
| 24 | output | Output |
| 25 | meter | Meter |
| 26 | progress | Progress |

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

| Index | Role | Index | Role |
|-------|------|-------|------|
| 1 | alert | 2 | alertdialog |
| 3 | application | 4 | banner |
| 5 | button | 6 | cell |
| 7 | checkbox | 8 | columnheader |
| 9 | combobox | 10 | complementary |
| 11 | contentinfo | 12 | definition |
| 13 | dialog | 14 | directory |
| 15 | document | 16 | feed |
| 17 | figure | 18 | form |
| 19 | grid | 20 | gridcell |
| 21 | group | 22 | heading |
| 23 | img | 24 | link |
| 25 | list | 26 | listbox |
| 27 | listitem | 28 | log |
| 29 | main | 30 | marquee |
| 31 | math | 32 | menu |
| 33 | menubar | 34 | menuitem |
| 35 | menuitemcheckbox | 36 | menuitemradio |
| 37 | navigation | 38 | none |
| 39 | note | 40 | option |
| 41 | presentation | 42 | progressbar |
| 43 | radio | 44 | radiogroup |
| 45 | region | 46 | row |
| 47 | rowgroup | 48 | rowheader |
| 49 | scrollbar | 50 | search |
| 51 | searchbox | 52 | separator |
| 53 | slider | 54 | spinbutton |
| 55 | status | 56 | switch |
| 57 | tab | 58 | table |
| 59 | tablist | 60 | tabpanel |
| 61 | term | 62 | textbox |
| 63 | timer | 64 | toolbar |
| 65 | tooltip | 66 | tree |
| 67 | treegrid | 68 | treeitem |

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 Byte | Meaning |
|-----------|---------|
| 0x00 | Element attributes — the content is attribute text as it would appear inside an HTML opening tag |
| 0x01 | Comment — 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)

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

### 8.2 Background Color Palette (4 entries)

| Index | Color |
|-------|-------|
| 0 | None (transparent) |
| 1 | Yellow highlight |
| 2 | Green highlight |
| 3 | Pink highlight |

### 8.3 Font Defaults

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

### 8.4 Font Size Table (8 entries)

| Index | Size | Typical Use |
|-------|------|-------------|
| 0 | default (1em) | Body text |
| 1 | 2em | ~h1 |
| 2 | 1.5em | ~h2 |
| 3 | 1.17em | ~h3 |
| 4 | 1em (explicit) | ~h4 |
| 5 | 0.85em | Caption / small |
| 6 | 0.75em | Fine print |
| 7 | 0.6em | Legal / 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

- **Colors:** Preamble `[COLORS]` entries override the spec default foreground palette (Section 8.1) at matching indices. Unspecified indices retain the spec defaults.
- **Fonts:** Preamble `[FONTS]` entries override the font bit meaning. With a preamble, the font bit selects between the two preamble-defined families.
- **Sizes:** Preamble `[SIZES]` entries override the spec default size table (Section 8.4) at matching indices.
- Index 0 in color and size palettes represents the document default.

### 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:

- **Inline** — at the start of a `.pip` document, before any content.
- **External** — in a `.rrc` file, referenced by the document via Q-SET's `include()` mechanism.

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

| Byte | ASCII Name | RichRender Use |
|------|------------|----------------|
| 0x01 | SOH | Block element frame OPEN |
| 0x02 | STX | Style span OPEN (implicitly closes previous style) |
| 0x03 | ETX | Nested style span CLOSE (clear mask pip follows) |
| 0x04 | EOT | Block element frame CLOSE |
| 0x0E | SO | Inline element frame OPEN |
| 0x0F | SI | Inline element frame CLOSE |

### 10.2 RichRender-Assigned (Outside ASCII Range)

| Byte | Use |
|------|-----|
| 0xFE | Meta region OPEN — permanently invalid in UTF-8, zero collision risk |
| 0xFF | Meta region CLOSE — permanently invalid in UTF-8, zero collision risk |

### 10.3 Preserved as Standard

| Byte | ASCII Name | Reason |
|------|------------|--------|
| 0x00 | NUL | String terminator in C and many toolchains |
| 0x09 | TAB | Standard whitespace — see Section 14 |
| 0x0A | LF | Line feed |
| 0x0D | CR | Carriage 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:

- Collapses consecutive same-style characters into style spans (STX + pip + content).
- Uses STX for sequential style transitions — no ETX between consecutive styles.
- Detects opportunities for nesting (e.g., three consecutive italic/bold-italic/italic spans become one italic span with a nested bold+italic span inside).
- Emits ETX with a clear mask pip at nested close points.
- Validates full-enclosure nesting for block and inline element frames.
- Produces structurally tight, semantically clear output.

### 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:

- `.pip` documents are largely valid HTML with embedded RichRender sections.
- Any server can inflate the RichRender sections to Render-HTML before serving to standard clients.
- RichRender-aware clients can consume the raw format for efficiency.
- Adoption is incremental — existing HTML toolchains work with the non-RichRender portions unchanged.

### 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:

- **RichRender-aware client** → raw `.pip` content with RichRender sections intact.
- **Standard browser** → Render-HTML with RichRender sections inflated to HTML + CSS.

### 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:

- **`application/richrender`** — for RichRender content.
- **`application/richrender-context`** — for `.rrc` preamble files (if served independently).

---

## 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 Flag | CSS Output | Render-HTML Class |
|----------|------------|-------------------|
| bold | `font-weight: bold` | `mdr-b` |
| italic | `font-style: italic` | `mdr-i` |
| strikethrough | `text-decoration: line-through` | `mdr-s` |
| underline | `text-decoration: underline` | `mdr-u` |
| superscript | `vertical-align: super; font-size: smaller` | `mdr-sup` |
| subscript | `vertical-align: sub; font-size: smaller` | `mdr-sub` |
| highlight | `background-color: yellow` (default) | `mdr-hl` |

**Byte two fields:**

| Pip Field | CSS Output | Render-HTML Class |
|-----------|------------|-------------------|
| foreground color | Resolved from palette → `color: #rrggbb` | `mdr-fg` |
| background color | Resolved from palette → `background-color: ...` | `mdr-bg` |
| font | `font-family: serif` or `font-family: sans-serif` | `mdr-font` |

**Byte three fields:**

| Pip Field | CSS Output | Render-HTML Class |
|-----------|------------|-------------------|
| font size | Resolved from size table → `font-size: ...` | `mdr-sz` |
| small-caps | `font-variant: small-caps` | `mdr-sc` |
| overline | `text-decoration: overline` | `mdr-ol` |
| double underline | `text-decoration: underline double` | `mdr-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:

| Pattern | Emitted Tag | Render-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:

```html
<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>`:

```html
<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:

```html
<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:

- Incoming HTML email is deflated to `.pip` format for storage.
- Outgoing email requests are inflated back to Render-HTML for delivery.
- Clients send and receive standard HTML. Nothing changes externally.

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:

- A RichRender-capable client includes a RichRenderReady flag in its fetch request, using standard content negotiation (e.g., `Accept: application/richrender`).
- The server recognizes the flag and delivers the stored `.pip` content directly, skipping inflation.
- Non-capable clients continue receiving Render-HTML as before.

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:

- Email clients compose in `.pip` and send to the server in native format.
- The server stores as-is — no deflation step needed.
- Web authoring tools (EMU Editor, CMS plugins) produce `.pip` documents natively.

### A.4 Parallel Adoption Paths

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

- **CMS plugins** — WordPress and PmWiki plugins using the inflator can serve RichRender content to browsers as Render-HTML immediately. Site owners benefit from compressed storage without visitor-facing changes.
- **AI-to-AI communication** — AI providers adopt the spec for inter-agent messaging where precision and token efficiency matter. The format is unambiguous by design — no flavor variants, no edge-case interpretation differences.
- **Desktop authoring** — EMU Editor as a native `.pip` authoring tool, producing content ready for any output path (web, email, AI exchange).

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).*
