diff --git a/preserves-expressions.md b/preserves-expressions.md
index 2adf01e..7901621 100644
--- a/preserves-expressions.md
+++ b/preserves-expressions.md
@@ -67,25 +67,61 @@ documents to directly comprise a sequence of multiple values.
No changes to [the Preserves semantic model](preserves.html) are made.
Every Preserves text-syntax term is a valid P-expression, but in general
P-expressions must be rewritten or otherwise interpreted before a
-meaningful Preserves value can be arrived at.
+meaningful Preserves value can be arrived at ([see
+below](#reading-preserves)).
-## Encoding P-expressions as Preserves
+## Encoding P-expressions as Preserves
+
+We write ⌜*p*⌝ for the encoding into Preserves of P-expression *p*.
+
+{:.pseudocode.equations}
+| ⌜·⌝ | : | **P-expression** ⟶ **Preserves** |
Aside from the special classes `Group`, `Block`, `Comma`, `Semicolon` or
-`Colons`, P-expressions are directly encodable as Preserves data. All
-members of the special classes are encoded as Preserves text
-`Dictionary`[^encoding-rationale] values:
+`Colons`, P-expressions are encoded directly as Preserves data.
+
+{:.pseudocode.equations}
+| ⌜`[`*p* ...`]`⌝ | = | `[`⌜*p*⌝ ...`]` |
+| ⌜`<`*p* ...`>`⌝ | = | `<`⌜*p*⌝ ...`>` |
+| ⌜`#{`*p* ...`}`⌝ | = | `#{`⌜*p*⌝ ...`}` |
+| ⌜`#!`*p*⌝ | = | `#!`⌜*p*⌝ |
+| ⌜`@`*p* *q*⌝ | = | `@`⌜*p*⌝ ⌜*q*⌝ |
+| ⌜*p*⌝ | = | *p* **when** *p* ∈ **Atom** |
+
+All members of the special classes are encoded as Preserves text
+`Dictionary`[^encoding-rationale] values.
[^encoding-rationale]: In principle, it would be nice to use *records*
for this purpose, but if we did so we would have to also encode
usages of records!
-{:.pseudocode}
-> ⌜`(`*p* ...`)`⌝ ⟶ `{g:[`⌜*p*⌝ ...`]}`
-> ⌜`{`*p* ...`}`⌝ ⟶ `{b:[`⌜*p*⌝ ...`]}`
-> ⌜`,`⌝ ⟶ `{s:|,|}`
-> ⌜`;`⌝ ⟶ `{s:|;|}`
-> ⌜`:` ...⌝ ⟶ `{s:|:` ...`|}`
+{:.pseudocode.equations}
+| ⌜`(`*p* ...`)`⌝ | = | `{g:[`⌜*p*⌝ ...`]}` |
+| ⌜`{`*p* ...`}`⌝ | = | `{b:[`⌜*p*⌝ ...`]}` |
+| ⌜`,`⌝ | = | `{s:|,|}` |
+| ⌜`;`⌝ | = | `{s:|;|}` |
+| ⌜`:` ...⌝ | = | `{s:|:` ...`|}` |
+
+## Interpreting P-expressions as Preserves
+
+The [previous section](#encoding-pexprs) discussed ways of representing
+P-expressions using Preserves. Here, we discuss *interpreting*
+P-expressions *as* Preserves, so that (1) a Preserves datum (2) written
+using Preserves text syntax and then (3) read as a P-expression can be
+(4) interpreted from that P-expression to yield the original datum.
+
+A reader for P-expressions can be adapted to yield a reader for
+Preserves terms by processing (subterms of) each P-expression that the
+reader produces. The only subterms that need processing are the special
+classes mentioned above.
+
+ 1. Every `Group` or `Semicolon` that appears is an error.
+ 2. Every `Colons` with two or more colons in it is an error.
+ 3. Every `Comma` that appears is removed from its container.
+ 4. Every `Block` must contain triplets of `Value`, `Colons` (with a
+ single colon), `Value`. Any `Block` not following this pattern is an
+ error. Each `Block` following the pattern is translated to a
+ `Dictionary` containing a key/value pair for each triplet.
## Appendix: Examples
@@ -146,21 +182,6 @@ text-syntax encodings.
]}
```
-## Appendix: Using a P-expression reader to read Preserves
-
-A reader for P-expressions can be adapted to yield a reader for
-Preserves terms by processing (subterms of) each P-expression that the
-reader produces. The only subterms that need processing are the special
-classes mentioned above.
-
- 1. Every `Group` or `Semicolon` that appears is an error.
- 2. Every `Colons` with two or more colons in it is an error.
- 3. Every `Comma` that appears is removed from its container.
- 4. Every `Block` must contain triplets of `Value`, `Colons` (with a
- single colon), `Value`. Any `Block` not following this pattern is an
- error. Each `Block` following the pattern is translated to a
- `Dictionary` containing a key/value pair for each triplet.
-
## Appendix: Reading vs. Parsing
Lisp systems first *read* streams of bytes into S-expressions and then
diff --git a/preserves.css b/preserves.css
index 9c34209..7322cc7 100644
--- a/preserves.css
+++ b/preserves.css
@@ -1,6 +1,7 @@
:root {
--sans-font: "Open Sans", -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif;
--serif-font: palatino, "Palatino Linotype", "Palatino LT STD", "URW Palladio L", "TeX Gyre Pagella", serif;
+ --blockquote-indent: 40px;
}
body {
font-family: var(--serif-font);
@@ -230,6 +231,7 @@ table.postcard-grammar {
blockquote {
padding: 0.5rem 1rem;
border-left: solid #4f81bd 2px;
+ margin-left: var(--blockquote-indent);
margin-right: 0;
}
blockquote :first-child {
@@ -243,6 +245,10 @@ blockquote :last-child {
background-color: #e9f0f9;
}
+table.equations { width: auto; margin-left: var(--blockquote-indent); }
+table.equations tr > *:nth-child(1) { text-align: right; }
+table.equations tr > *:nth-child(2) { text-align: center; }
+
blockquote.pseudocode {
border-left: none;
padding: 0;