Prose round 3: retitle the floor decision, put the plain/ exception first, sharpen items 59-62
This commit is contained in:
@@ -48,7 +48,7 @@ In `docs/decisions.md`:
|
||||
- Firefox reads the build
|
||||
- The coverage floors
|
||||
- The size ratchet
|
||||
- The comprehension floor ships under 7 until items 59, 60, 61 and 62 land
|
||||
- The project ships under the comprehension floor until items 59, 60, 61 and 62 land
|
||||
- Properties on a fixed seed
|
||||
- The CommonMark suite checks three ways
|
||||
- The flavour spec is read as a source
|
||||
|
||||
@@ -198,7 +198,7 @@ emit refuses:
|
||||
| `unspellable-line-start` | a paragraph line begins with a code span whose backticks would read back as a code fence | put any text before the code span |
|
||||
| `unspellable-whitespace` | an `emoji`, `mention` or `status` holds a newline in the text its inline directive spells in the content slot | replace it with a space — an inline directive never spans lines |
|
||||
| `unsupported-nesting-depth` | blocks, marks, an attribute's JSON or a carried node's JSON nest past 500 levels | keep the ADF and pass the document over, or show it read-only; flatten the input where you are the one who wrote it |
|
||||
| `unsupported-node-shape` | a node carries an attribute, value, argument or body its type does not take, or lacks one it needs — or markdown writes as a directive a node or mark the lossless flavour spells as CommonMark, or a reserved directive stands out of place: `!adf:textBreak{}` or `!adf:listBreak` parting nothing, `!adf:doc` beside another block | fix what the message names, or give the node the shape it names; `spec/flavour.md` lists every type's attributes and body |
|
||||
| `unsupported-node-shape` | a node carries an attribute, value, argument or body its type does not take, or lacks one it needs — or markdown writes as a directive a node or mark the lossless flavour spells as CommonMark, or a reserved directive stands out of place: `!adf:textBreak{}` or `!adf:listBreak` parting nothing, `!adf:doc` anywhere but as the whole document | fix what the message names; `spec/flavour.md` lists every type's attributes and body |
|
||||
|
||||
## The guarantees
|
||||
|
||||
|
||||
+12
-15
@@ -496,14 +496,13 @@ config gone missing fails the leg instead of falling back to oxlint's own defaul
|
||||
`--deny-warnings`, since a rule from a category this config never names arrives as a warning it
|
||||
exits 0 on.
|
||||
|
||||
## The comprehension floor ships under 7 until items 59, 60, 61 and 62 land
|
||||
## The project ships under the comprehension floor until items 59, 60, 61 and 62 land
|
||||
|
||||
2026-10-03, the maintainer. KISS, a technical principle, and its comprehension floor of 7. Valid
|
||||
while `todo.md` items 59, 60, 61 and 62 are open.
|
||||
|
||||
A four-seat comprehension panel scored the project 6 against the floor of 7, and the project ships
|
||||
under it while the restructures it named land: `todo.md` items 59, 60, 61 and 62 end this. The
|
||||
scores are the baseline — a later panel may not score lower on any dimension:
|
||||
A four-seat comprehension panel scored the project 6 against the floor of 7. The scores are the
|
||||
baseline: a later panel may not score lower on any dimension.
|
||||
|
||||
| Seat | Navigation | Locality | Shape | Self-sufficiency | Overall |
|
||||
|---|---|---|---|---|---|
|
||||
@@ -672,16 +671,14 @@ them. A primitive knowing neither ADF nor a format stays at `src/` root. A const
|
||||
`spec/flavour.md` draws, and a placement nothing here settles goes beside its only reader, or in
|
||||
what both read where there are two.
|
||||
|
||||
Each format directory parts into `emit/` (ADF→format) and `parse/` (format→ADF), the rest of it
|
||||
holding what both directions read. A construct's reader lives there beside the regex the emitter
|
||||
escapes against, so the two cannot drift; a reader with no emit counterpart goes in `parse/`,
|
||||
unless it is part of a construct that side already holds — a grammar stays in one file rather than
|
||||
splitting across the seam. A rule both directions must answer alike — whether a list marker
|
||||
interrupts a paragraph — is one function there too, never a copy per direction, however
|
||||
conservative the copy would be. Where the rule is the emitter's own choice, input consults it
|
||||
rather than restating it, and that is the only import `parse/` takes from `emit/` —
|
||||
A flavour's own code, both directions included, sits in its own directory: `markdown/plain/`.
|
||||
Otherwise each format directory parts into `emit/` (ADF→format) and `parse/` (format→ADF), the rest
|
||||
of it holding what both directions read. A construct's reader lives there beside the regex the
|
||||
emitter escapes against, so the two cannot drift; a reader with no emit counterpart goes in
|
||||
`parse/`, unless it is part of a construct that side already holds — a grammar stays in one file
|
||||
rather than splitting across the seam. A rule both directions must answer alike — whether a list
|
||||
marker interrupts a paragraph — is one function there too, never a copy per direction, however
|
||||
conservative the copy would be. Where the rule is the emitter's own choice, input consults it rather
|
||||
than restating it, and that is the only value import `parse/` takes from `emit/` —
|
||||
`commonMarkSpelling` and `openingLinkTakesDirective` — so no fixture the emitter writes can be
|
||||
refused, and a spelling the emitter refuses gives its own error rather than a second name for it.
|
||||
`markdown/plain/` holds the plain flavour's own code — the writer's reduction to editor-normal ADF
|
||||
and the conventions and task ids the reader takes — so neither direction reaches into the other
|
||||
for it.
|
||||
|
||||
@@ -14,7 +14,7 @@ export function joinsWhenRead(previous: AdfNode, node: AdfNode): boolean {
|
||||
return isPlainText(previous) && isPlainText(node) && identicalMarks(nodeMarks(previous), nodeMarks(node))
|
||||
}
|
||||
|
||||
// The editor's rule, parting from the reader's only on shapes editor-normal ADF erases: an empty attrs, content or marks, and -0 in a mark.
|
||||
// The editor's rule, differing from the reader's only on shapes editor-normal ADF erases: an empty attrs, content or marks, and -0 in a mark.
|
||||
export function joinsWhenEditorNormal(previous: AdfNode, node: AdfNode): boolean {
|
||||
if (!joinsAsEditorText(previous) || !joinsAsEditorText(node)) return false
|
||||
return identicalMarks(nodeMarks(previous).map(normalMark), nodeMarks(node).map(normalMark))
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
| 52 | 0.2.0 | | **Spell `colwidth` as a comma list, `colwidth="340,420"`.** | 3 | 3 | 5 | 6 | 5 | 13.0 |
|
||||
| 51 | 0.2.0 | | **Match a reference label to its definition under Unicode case folding.** | 2 | 2 | 2 | 7 | 3, 4 | 12.4 |
|
||||
| 53 | 0.2.0 | | **Put a block's `marks` spelling to the writer panel and adopt its pick.** | 4 | 5 | 5 | 6 | 5 | 11.5 |
|
||||
| 60 | 0.2.0 | decision | **Give the parser's questions to the emitter one named module, so the parse→emit dependency reads as intended.** | 3 | 4 | 2 | 6 | 2 | 10.7 |
|
||||
| 59 | 0.2.0 | decision | **Group the directive grammar into `src/markdown/directive/`, and move `Read<T>` to `result.ts` and `Flavour` out of the plain flavour.** | 3 | 5 | 2 | 6 | 2 | 10.4 |
|
||||
| 60 | 0.2.0 | decision | **Collect the questions `parse/` asks `emit/` into one named module.** | 3 | 4 | 2 | 6 | 2 | 10.7 |
|
||||
| 59 | 0.2.0 | decision | **Group the directive grammar into `src/markdown/directive/`, move `Read<T>` to `result.ts`, and move `Flavour` to `markdown/flavour.ts`.** | 3 | 5 | 2 | 6 | 2 | 10.4 |
|
||||
| 50 | 0.2.0 | | **Read `[](/url)` and `[]()` as CommonMark's empty link.** | 4 | 4 | 3 | 6 | 3, 4, 6 | 10.4 |
|
||||
| 62 | 0.2.0 | decision | **Move the plain reader out of `parse/markdown-to-adf.ts` into `markdown/plain/`.** | 3 | 4 | 2 | 5 | 2 | 8.9 |
|
||||
| 38 | 0.3.0 | | **Spell a lone surrogate in a text node so it survives a UTF-8 encode.** | 2 | 2 | 4 | 7 | 1 | 19.5 |
|
||||
@@ -106,7 +106,7 @@ spellings" bullet, which counts one fewer.
|
||||
|
||||
The comprehension panel's worst place: `escapeClaims` and `escapeClosedRuns` re-implement the
|
||||
reader's view — flanking, code-span closers, link-definition openings, highlight flanking — and
|
||||
only the property tests catch drift. It caps Locality.
|
||||
only the property tests catch drift. It caps the panel's Locality score.
|
||||
|
||||
### 52. Spell `colwidth` as a comma list, `colwidth="340,420"`.
|
||||
|
||||
@@ -126,16 +126,17 @@ Today `marks="[{\"attrs\":{\"mode\":\"wide\"},\"type\":\"breakout\"}]"`, the mar
|
||||
escaped JSON. Breaking where the panel picks another spelling: `MIGRATION.md`'s Spellings table
|
||||
gains its row.
|
||||
|
||||
### 60. Give the parser's questions to the emitter one named module, so the parse→emit dependency reads as intended.
|
||||
### 60. Collect the questions `parse/` asks `emit/` into one named module.
|
||||
|
||||
`parse/` asks `emit/` through `commonMarkSpelling` and `openingLinkTakesDirective`, each imported
|
||||
from where it happens to live. One module naming the questions keeps `docs/decisions.md` §The source
|
||||
parts by ADF and format true as they grow.
|
||||
|
||||
### 59. Group the directive grammar into `src/markdown/directive/`, and move `Read<T>` to `result.ts` and `Flavour` out of the plain flavour.
|
||||
### 59. Group the directive grammar into `src/markdown/directive/`, move `Read<T>` to `result.ts`, and move `Flavour` to `markdown/flavour.ts`.
|
||||
|
||||
Eight directive files sit across three directories, and the `markdown/` root holds 14 entries. HTML
|
||||
needs `Read<T>`, `Flavour`, the carry and the mark spellings out of `markdown/`.
|
||||
needs `Read<T>` and `Flavour` out of the plain flavour and `markdown/`; it needs the carry and the
|
||||
mark spellings too, which item 7 moves where it learns what HTML shares.
|
||||
|
||||
### 50. Read `[](/url)` and `[]()` as CommonMark's empty link.
|
||||
|
||||
@@ -148,7 +149,8 @@ which counts one fewer.
|
||||
|
||||
### 62. Move the plain reader out of `parse/markdown-to-adf.ts` into `markdown/plain/`.
|
||||
|
||||
|
||||
What moves: the plain reader's code in `markdown-to-adf.ts` — the alert and task-marker reads, the
|
||||
`mintTaskIds` call and the `inlineLeaves` use.
|
||||
|
||||
### 38. Spell a lone surrogate in a text node so it survives a UTF-8 encode.
|
||||
|
||||
@@ -172,8 +174,8 @@ punctuation — and, where they do, read the code point, with a fixture per dire
|
||||
|
||||
### 42. Trim a text leaf's trailing blanks in linear time.
|
||||
|
||||
`plain/inline-reduction.ts`'s `leafEdges` finds the trail with an unanchored `/[ \t]*$/`, quadratic in a run
|
||||
of blanks inside one leaf: a paragraph of `a`, 80 000 spaces, `b` takes 6.5 s in
|
||||
`plain/inline-reduction.ts`'s `leafEdges` finds the trail with an unanchored `/[ \t]*$/`, quadratic
|
||||
in a run of blanks inside one leaf: a paragraph of `a`, 80 000 spaces, `b` takes 6.5 s in
|
||||
`adfToPlainMarkdown`. Scan backward, as the expand title's trim does.
|
||||
|
||||
### 48. Keep the release path publishing past npm's bypass-2FA token retirement.
|
||||
|
||||
Reference in New Issue
Block a user