From 6df17a7069a1670e29a26a9313d79781b67536bf Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Sat, 3 Oct 2026 15:50:24 +0200 Subject: [PATCH] Gather the plain flavour's code in markdown/plain/ --- docs/decisions.md | 7 +++++-- src/conformance/adf-property.test.ts | 4 ++-- src/conformance/property-harness.ts | 2 +- src/index.ts | 2 +- src/markdown/emit/adf-to-markdown.ts | 4 ++-- src/markdown/emit/inline-line.ts | 4 ++-- src/markdown/emit/line-escaping.ts | 4 ++-- src/markdown/emit/pipe-table.ts | 2 +- src/markdown/parse/inline-content.ts | 4 ++-- src/markdown/parse/markdown-to-adf.ts | 8 ++++---- src/markdown/parse/plain-markdown-to-adf.test.ts | 2 +- .../adf-to-plain-markdown.test.ts} | 2 +- .../plain-reduction.ts => plain/adf-to-plain-markdown.ts} | 8 ++++---- .../{plain-conventions.ts => plain/conventions.ts} | 2 +- src/{adf => markdown/plain}/editor-normal.test.ts | 4 ++-- src/{adf => markdown/plain}/editor-normal.ts | 6 +++--- .../{emit/plain-inline.ts => plain/inline-reduction.ts} | 6 +++--- src/markdown/{parse => plain}/task-ids.test.ts | 0 src/markdown/{parse => plain}/task-ids.ts | 0 todo.md | 2 +- 20 files changed, 38 insertions(+), 35 deletions(-) rename src/markdown/{emit/plain-reduction.test.ts => plain/adf-to-plain-markdown.test.ts} (99%) rename src/markdown/{emit/plain-reduction.ts => plain/adf-to-plain-markdown.ts} (99%) rename src/markdown/{plain-conventions.ts => plain/conventions.ts} (97%) rename src/{adf => markdown/plain}/editor-normal.test.ts (97%) rename src/{adf => markdown/plain}/editor-normal.ts (95%) rename src/markdown/{emit/plain-inline.ts => plain/inline-reduction.ts} (98%) rename src/markdown/{parse => plain}/task-ids.test.ts (100%) rename src/markdown/{parse => plain}/task-ids.ts (100%) diff --git a/docs/decisions.md b/docs/decisions.md index b8f09d3..74cce04 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -642,8 +642,8 @@ is the markdown flavour's choice, not ADF's. ## The source parts by ADF and format -2026-08-27, placement 2026-09-18, `adf/`'s bar 2026-09-21, the maintainer. Goal 2. Valid while -each format has a reader and a writer through ADF. +2026-08-27, placement 2026-09-18, `adf/`'s bar 2026-09-21, `plain/` 2026-10-03, the maintainer. +Goal 2. Valid while each format has a reader and a writer through ADF. `src/adf/` holds ADF's own knowledge, imports no format, and is where a construct both formats read lives: the question is answered in ADF's vocabulary — a node type, an attribute kind, a content @@ -666,3 +666,6 @@ conservative the copy would be. Where the rule is the emitter's own choice, inpu rather than restating it, and that is the only 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. diff --git a/src/conformance/adf-property.test.ts b/src/conformance/adf-property.test.ts index 4b787ac..96a8c83 100644 --- a/src/conformance/adf-property.test.ts +++ b/src/conformance/adf-property.test.ts @@ -5,10 +5,10 @@ import test from 'node:test' import type { AdfNode } from '../adf/document.ts' import { adfDocument, propertyRuns, propertyTimeout } from './property-harness.ts' import { adfToMarkdown } from '../markdown/emit/adf-to-markdown.ts' -import { adfToPlainMarkdown, reduceToPlain } from '../markdown/emit/plain-reduction.ts' +import { adfToPlainMarkdown, reduceToPlain } from '../markdown/plain/adf-to-plain-markdown.ts' import { directivePrefix } from '../markdown/directive-syntax.ts' import { markdownToAdf, plainMarkdownToAdf } from '../markdown/parse/markdown-to-adf.ts' -import { toEditorNormal } from '../adf/editor-normal.ts' +import { toEditorNormal } from '../markdown/plain/editor-normal.ts' const gateRuns = 1600 const renamedPrefix = '!adg:' diff --git a/src/conformance/property-harness.ts b/src/conformance/property-harness.ts index 32ddcf5..0743e5a 100644 --- a/src/conformance/property-harness.ts +++ b/src/conformance/property-harness.ts @@ -11,7 +11,7 @@ import { blockNodes } from '../adf/block-nodes.ts' import { directivePrefix } from '../markdown/directive-syntax.ts' import { emptyKeys, mergeAdjacentText } from '../adf/document.ts' import { inlineNodes } from '../adf/inline-nodes.ts' -import { joinsNormally } from '../adf/editor-normal.ts' +import { joinsNormally } from '../markdown/plain/editor-normal.ts' import { markAttributes } from '../adf/mark-attributes.ts' type Positions = { block: AdfNode; inline: AdfNode } diff --git a/src/index.ts b/src/index.ts index a25f670..e4de874 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,6 +3,6 @@ export type { AdfAttributes, AdfDocument, AdfMark, AdfNode } from './adf/documen export type { ConvertError, ConvertErrorCode, ConvertErrorPath, ParseError, Result, SourcePosition } from './result.ts' export type { JsonValue } from './json-value.ts' export { adfToMarkdown } from './markdown/emit/adf-to-markdown.ts' -export { adfToPlainMarkdown } from './markdown/emit/plain-reduction.ts' +export { adfToPlainMarkdown } from './markdown/plain/adf-to-plain-markdown.ts' export { isAdfDocument } from './adf/document.ts' export { markdownToAdf, plainMarkdownToAdf } from './markdown/parse/markdown-to-adf.ts' diff --git a/src/markdown/emit/adf-to-markdown.ts b/src/markdown/emit/adf-to-markdown.ts index 867dfc8..99331ec 100644 --- a/src/markdown/emit/adf-to-markdown.ts +++ b/src/markdown/emit/adf-to-markdown.ts @@ -1,8 +1,8 @@ import type { AdfDocument, AdfNode } from '../../adf/document.ts' import type { BlockNodeModel } from '../../adf/block-nodes.ts' -import type { Flavour } from '../plain-conventions.ts' +import type { Flavour } from '../plain/conventions.ts' import { adfDocumentFault, carriesOnly, isPlainText, nodeAttrs, nodeContent } from '../../adf/document.ts' -import { alertMarker, foldedAlertMarker, leadingMarker, readAlertMarker, readTaskMarker, taskMarker } from '../plain-conventions.ts' +import { alertMarker, foldedAlertMarker, leadingMarker, readAlertMarker, readTaskMarker, taskMarker } from '../plain/conventions.ts' import { blockDirectiveForm, documentSpelling, listBreakSpelling } from '../block-directive.ts' import { blockNodeModel, blockNodes } from '../../adf/block-nodes.ts' import { carriedBlock } from '../opaque-carry.ts' diff --git a/src/markdown/emit/inline-line.ts b/src/markdown/emit/inline-line.ts index 6be52b0..6513e8d 100644 --- a/src/markdown/emit/inline-line.ts +++ b/src/markdown/emit/inline-line.ts @@ -1,5 +1,5 @@ import type { AdfMark, AdfNode } from '../../adf/document.ts' -import type { Flavour } from '../plain-conventions.ts' +import type { Flavour } from '../plain/conventions.ts' import type { InlineNodeModel } from '../../adf/inline-nodes.ts' import type { LineContainer } from '../line-container.ts' import { assembleInlineLine, isSyntax, type InlineEscaping, type InlineSegment, type MarkRun, type NodeRange } from './line-escaping.ts' @@ -9,7 +9,7 @@ import { commonMarkLink, linkHref, markSpelling, spellMarkAttributes } from '../ import { identicalMark, isPlainText, nodeAttrs, nodeContent, nodeMarks } from '../../adf/document.ts' import { escapeUnbalanced, spellDestination } from '../commonmark/link-syntax.ts' import { failure, faulted, success, type ConvertErrorPath, type Result } from '../../result.ts' -import { highlightDelimiter } from '../plain-conventions.ts' +import { highlightDelimiter } from '../plain/conventions.ts' import { inlineNodeModel } from '../../adf/inline-nodes.ts' import { largestNesting } from '../../nesting.ts' import { longestBacktickRun } from '../commonmark/backtick-runs.ts' diff --git a/src/markdown/emit/line-escaping.ts b/src/markdown/emit/line-escaping.ts index 253df18..120faf8 100644 --- a/src/markdown/emit/line-escaping.ts +++ b/src/markdown/emit/line-escaping.ts @@ -1,10 +1,10 @@ -import type { Flavour } from '../plain-conventions.ts' +import type { Flavour } from '../plain/conventions.ts' import type { LineContainer } from '../line-container.ts' import { backslashEscape, escapesLineClaim, inlineHtmlConstruct, opensBracketedAutolink, opensEmailAutolink, type LinePosition } from '../commonmark/grammar.ts' import { backtickRun, closingBacktickRun } from '../commonmark/backtick-runs.ts' import { claimsDirectivePrefix } from '../directive-syntax.ts' import { delimiterFlags, isWordCharacter, matchEmphasis, runLength } from '../commonmark/emphasis-matching.ts' -import { highlightDelimiter, highlightFlanking } from '../plain-conventions.ts' +import { highlightDelimiter, highlightFlanking } from '../plain/conventions.ts' import { isBareDelimiterRow } from '../pipe-table-syntax.ts' import { opensLinkDefinition } from '../commonmark/link-reference-definitions.ts' import { readEntityReference } from '../commonmark/entity-references.ts' diff --git a/src/markdown/emit/pipe-table.ts b/src/markdown/emit/pipe-table.ts index f200e6d..89ab454 100644 --- a/src/markdown/emit/pipe-table.ts +++ b/src/markdown/emit/pipe-table.ts @@ -1,6 +1,6 @@ import type { AdfNode } from '../../adf/document.ts' import type { ConvertErrorPath } from '../../result.ts' -import type { Flavour } from '../plain-conventions.ts' +import type { Flavour } from '../plain/conventions.ts' import { carriesOnly, nodeContent } from '../../adf/document.ts' import { spellPipeDelimiter, spellPipeRow } from '../pipe-table-syntax.ts' import { tryPipeCell } from './inline-line.ts' diff --git a/src/markdown/parse/inline-content.ts b/src/markdown/parse/inline-content.ts index b2bfd69..22d7114 100644 --- a/src/markdown/parse/inline-content.ts +++ b/src/markdown/parse/inline-content.ts @@ -1,7 +1,7 @@ import type { AdfMark, AdfNode } from '../../adf/document.ts' import type { DirectiveSpan, NestedSpans } from '../directive-syntax.ts' import type { EmphasisPairing } from '../commonmark/emphasis-matching.ts' -import type { Flavour } from '../plain-conventions.ts' +import type { Flavour } from '../plain/conventions.ts' import type { LineContainer } from '../line-container.ts' import type { LinkDefinition } from '../commonmark/link-syntax.ts' import { backslashEscape, decodeTextEscapes, inlineHtmlConstruct, readBracketedAutolink, readEmailAutolink, trimTrailingSpace } from '../commonmark/grammar.ts' @@ -9,7 +9,7 @@ import { backtickRun, closingBacktickRun } from '../commonmark/backtick-runs.ts' import { commonMarkLink, linkHref } from '../mark-spellings.ts' import { delimiterFlags, matchEmphasis, runLength } from '../commonmark/emphasis-matching.ts' import { failure, faulted, success, type ConvertErrorPath, type Result } from '../../result.ts' -import { highlightDelimiter, highlightFlanking } from '../plain-conventions.ts' +import { highlightDelimiter, highlightFlanking } from '../plain/conventions.ts' import { identicalMarks, mergeAdjacentText, nodeAttrs, nodeMarks } from '../../adf/document.ts' import { inlineNodeModel } from '../../adf/inline-nodes.ts' import { noSpans, readInlineDirective } from '../directive-syntax.ts' diff --git a/src/markdown/parse/markdown-to-adf.ts b/src/markdown/parse/markdown-to-adf.ts index 1df55ff..26907f8 100644 --- a/src/markdown/parse/markdown-to-adf.ts +++ b/src/markdown/parse/markdown-to-adf.ts @@ -2,7 +2,7 @@ import type { AdfDocument, AdfNode } from '../../adf/document.ts' import type { Block, DirectiveBlock } from './blocks.ts' import type { BlockDirectiveNode } from './directive-nodes.ts' import type { ConvertFault } from '../../result.ts' -import type { Flavour } from '../plain-conventions.ts' +import type { Flavour } from '../plain/conventions.ts' import type { LineContainer } from '../line-container.ts' import type { LinkDefinitions } from './inline-content.ts' import { carryFenceType, readCarriedBlock } from '../opaque-carry.ts' @@ -10,11 +10,11 @@ import { commonMarkSpelling, type SpellingMemo } from '../emit/adf-to-markdown.t import { documentAttribute, documentName, documentSpelling, listBreakName, listBreakSpelling } from '../block-directive.ts' import { emptyKeys, nodeAttrs, nodeContent } from '../../adf/document.ts' import { failure, faulted, positioned, success, type ConvertErrorPath, type ParseError, type Result, type SourcePosition } from '../../result.ts' -import { inlineLeaves } from '../emit/plain-inline.ts' +import { inlineLeaves } from '../plain/inline-reduction.ts' import { languageSlot } from '../code-language.ts' import { largestNesting } from '../../nesting.ts' -import { leadingMarker, readAlertMarker, readTaskMarker } from '../plain-conventions.ts' -import { mintTaskIds } from './task-ids.ts' +import { leadingMarker, readAlertMarker, readTaskMarker } from '../plain/conventions.ts' +import { mintTaskIds } from '../plain/task-ids.ts' import { parseBlocks } from './blocks.ts' import { parseInlineContent } from './inline-content.ts' import { readBlockDirectiveNode } from './directive-nodes.ts' diff --git a/src/markdown/parse/plain-markdown-to-adf.test.ts b/src/markdown/parse/plain-markdown-to-adf.test.ts index ae1f96d..af6aee2 100644 --- a/src/markdown/parse/plain-markdown-to-adf.test.ts +++ b/src/markdown/parse/plain-markdown-to-adf.test.ts @@ -3,7 +3,7 @@ import test from 'node:test' import type { AdfAttributes, AdfDocument, AdfMark, AdfNode } from '../../adf/document.ts' import { adfToMarkdown } from '../emit/adf-to-markdown.ts' -import { adfToPlainMarkdown } from '../emit/plain-reduction.ts' +import { adfToPlainMarkdown } from '../plain/adf-to-plain-markdown.ts' import { largestNesting } from '../../nesting.ts' import { markdownToAdf, plainMarkdownToAdf } from './markdown-to-adf.ts' diff --git a/src/markdown/emit/plain-reduction.test.ts b/src/markdown/plain/adf-to-plain-markdown.test.ts similarity index 99% rename from src/markdown/emit/plain-reduction.test.ts rename to src/markdown/plain/adf-to-plain-markdown.test.ts index 185ae42..28db1b7 100644 --- a/src/markdown/emit/plain-reduction.test.ts +++ b/src/markdown/plain/adf-to-plain-markdown.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict' import test from 'node:test' import type { AdfAttributes, AdfDocument, AdfMark, AdfNode } from '../../adf/document.ts' -import { adfToPlainMarkdown, reduceToPlain } from './plain-reduction.ts' +import { adfToPlainMarkdown, reduceToPlain } from './adf-to-plain-markdown.ts' import { largestNesting } from '../../nesting.ts' const code: AdfMark = { type: 'code' } diff --git a/src/markdown/emit/plain-reduction.ts b/src/markdown/plain/adf-to-plain-markdown.ts similarity index 99% rename from src/markdown/emit/plain-reduction.ts rename to src/markdown/plain/adf-to-plain-markdown.ts index 2545002..f324ba3 100644 --- a/src/markdown/emit/plain-reduction.ts +++ b/src/markdown/plain/adf-to-plain-markdown.ts @@ -1,14 +1,14 @@ import type { AdfDocument, AdfNode } from '../../adf/document.ts' import { adfDocumentFault, nodeAttrs, nodeContent } from '../../adf/document.ts' -import { commonMarkSpelling, largestListMarker, writeMarkdown, type SpellingMemo } from './adf-to-markdown.ts' +import { commonMarkSpelling, largestListMarker, writeMarkdown, type SpellingMemo } from '../emit/adf-to-markdown.ts' import { blockNodeModel } from '../../adf/block-nodes.ts' import { failure, faulted, success, type ConvertErrorPath, type Result } from '../../result.ts' -import { inlineLeaves, isBlockNodeType, oneLine, reduceInline, writableHref } from './plain-inline.ts' +import { inlineLeaves, isBlockNodeType, oneLine, reduceInline, writableHref } from './inline-reduction.ts' import { inlineNodeModel } from '../../adf/inline-nodes.ts' import { languageSlot } from '../code-language.ts' import { largestNesting } from '../../nesting.ts' -import { taskMarker } from '../plain-conventions.ts' -import { toEditorNormal } from '../../adf/editor-normal.ts' +import { taskMarker } from './conventions.ts' +import { toEditorNormal } from './editor-normal.ts' // depth: the level the node reduced stands at, counted as the emitter counts it. type Reduction = { depth: number; memo: SpellingMemo; path: ConvertErrorPath } diff --git a/src/markdown/plain-conventions.ts b/src/markdown/plain/conventions.ts similarity index 97% rename from src/markdown/plain-conventions.ts rename to src/markdown/plain/conventions.ts index c5d6f09..be6c5c7 100644 --- a/src/markdown/plain-conventions.ts +++ b/src/markdown/plain/conventions.ts @@ -1,4 +1,4 @@ -import { isWordCharacter } from './commonmark/emphasis-matching.ts' +import { isWordCharacter } from '../commonmark/emphasis-matching.ts' export type Flavour = 'lossless' | 'plain' diff --git a/src/adf/editor-normal.test.ts b/src/markdown/plain/editor-normal.test.ts similarity index 97% rename from src/adf/editor-normal.test.ts rename to src/markdown/plain/editor-normal.test.ts index bb0dd40..33d538a 100644 --- a/src/adf/editor-normal.test.ts +++ b/src/markdown/plain/editor-normal.test.ts @@ -1,8 +1,8 @@ import assert from 'node:assert/strict' import test from 'node:test' -import type { AdfNode } from './document.ts' -import type { JsonValue } from '../json-value.ts' +import type { AdfNode } from '../../adf/document.ts' +import type { JsonValue } from '../../json-value.ts' import { toEditorNormal } from './editor-normal.ts' test('merges adjacent text nodes carrying identical marks, at every level', () => { diff --git a/src/adf/editor-normal.ts b/src/markdown/plain/editor-normal.ts similarity index 95% rename from src/adf/editor-normal.ts rename to src/markdown/plain/editor-normal.ts index a89c0df..a5ffb7e 100644 --- a/src/adf/editor-normal.ts +++ b/src/markdown/plain/editor-normal.ts @@ -1,6 +1,6 @@ -import type { AdfAttributes, AdfDocument, AdfMark, AdfNode } from './document.ts' -import type { JsonValue } from '../json-value.ts' -import { identicalMark, identicalMarks, mergeAdjacentText, nodeAttrs, nodeContent, nodeMarks } from './document.ts' +import type { AdfAttributes, AdfDocument, AdfMark, AdfNode } from '../../adf/document.ts' +import type { JsonValue } from '../../json-value.ts' +import { identicalMark, identicalMarks, mergeAdjacentText, nodeAttrs, nodeContent, nodeMarks } from '../../adf/document.ts' type JsonContainer = JsonValue[] | { [key: string]: JsonValue } diff --git a/src/markdown/emit/plain-inline.ts b/src/markdown/plain/inline-reduction.ts similarity index 98% rename from src/markdown/emit/plain-inline.ts rename to src/markdown/plain/inline-reduction.ts index f8e89b5..b2d3501 100644 --- a/src/markdown/emit/plain-inline.ts +++ b/src/markdown/plain/inline-reduction.ts @@ -1,12 +1,12 @@ import type { AdfAttributes, AdfMark, AdfNode } from '../../adf/document.ts' import type { LineContainer } from '../line-container.ts' -import type { MarkRun } from './line-escaping.ts' +import type { MarkRun } from '../emit/line-escaping.ts' import { blockNodeModel } from '../../adf/block-nodes.ts' import { failure, success, type ConvertErrorPath, type Result } from '../../result.ts' -import { joinsNormally, sameMark } from '../../adf/editor-normal.ts' +import { joinsNormally, sameMark } from './editor-normal.ts' import { largestNesting } from '../../nesting.ts' import { mergeAdjacentText, nodeAttrs, nodeContent, nodeMarks } from '../../adf/document.ts' -import { plainLineFallback, type PlainLineFallback } from './inline-line.ts' +import { plainLineFallback, type PlainLineFallback } from '../emit/inline-line.ts' import { spellDestination, spellLinkTarget } from '../commonmark/link-syntax.ts' const highlight = 'backgroundColor' diff --git a/src/markdown/parse/task-ids.test.ts b/src/markdown/plain/task-ids.test.ts similarity index 100% rename from src/markdown/parse/task-ids.test.ts rename to src/markdown/plain/task-ids.test.ts diff --git a/src/markdown/parse/task-ids.ts b/src/markdown/plain/task-ids.ts similarity index 100% rename from src/markdown/parse/task-ids.ts rename to src/markdown/plain/task-ids.ts diff --git a/todo.md b/todo.md index 4e44c5e..f775b28 100644 --- a/todo.md +++ b/todo.md @@ -154,7 +154,7 @@ 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.ts`'s `leafEdges` finds the trail with an unanchored `/[ \t]*$/`, quadratic in a run +`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.