mirror of
https://github.com/larvit/adf-codec.git
synced 2026-11-12 19:58:28 +01:00
Answer architecture round 1: 0 🔴, 2 🟡; join empty-keys to the directive grammar and name the readers by direction
This commit is contained in:
@@ -1,17 +1,22 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { dirname, join } from 'node:path'
|
||||
import { dirname, join, relative } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { readdirSync, readFileSync } from 'node:fs'
|
||||
import { readdirSync, readFileSync, statSync } from 'node:fs'
|
||||
import test from 'node:test'
|
||||
|
||||
const markdown = join(dirname(fileURLToPath(import.meta.url)), '..', 'markdown')
|
||||
const importSpecifier = /\bfrom '([^']+)'/g
|
||||
|
||||
function importsOf(directory: string): { file: string; specifier: string }[] {
|
||||
const imports: { file: string; specifier: string }[] = []
|
||||
for (const file of readdirSync(join(markdown, directory)).filter((name) => name.endsWith('.ts') && !name.endsWith('.test.ts'))) {
|
||||
for (const match of readFileSync(join(markdown, directory, file), 'utf8').matchAll(importSpecifier)) {
|
||||
imports.push({ file: `${directory}/${file}`, specifier: match[1] ?? '' })
|
||||
function importsOf(directory: string): { file: string; target: string }[] {
|
||||
const imports: { file: string; target: string }[] = []
|
||||
for (const name of readdirSync(join(markdown, directory))) {
|
||||
const path = join(directory, name)
|
||||
if (statSync(join(markdown, path)).isDirectory()) {
|
||||
imports.push(...importsOf(path))
|
||||
} else if (name.endsWith('.ts') && !name.endsWith('.test.ts')) {
|
||||
for (const match of readFileSync(join(markdown, path), 'utf8').matchAll(importSpecifier)) {
|
||||
imports.push({ file: path, target: relative(markdown, join(markdown, directory, match[1] ?? '')) })
|
||||
}
|
||||
}
|
||||
}
|
||||
return imports
|
||||
@@ -19,10 +24,19 @@ function importsOf(directory: string): { file: string; specifier: string }[] {
|
||||
|
||||
// docs/decisions.md §The source parts by ADF and format
|
||||
test('parse/ asks emit/ only through the module that names its questions', () => {
|
||||
const reached = importsOf('parse').filter(({ specifier }) => specifier.startsWith('../emit/'))
|
||||
const reached = importsOf('parse').filter(({ target }) => target.startsWith('emit/'))
|
||||
assert.ok(reached.length > 0)
|
||||
assert.deepEqual(
|
||||
reached.filter(({ specifier }) => specifier !== '../emit/spelling-questions.ts'),
|
||||
reached.filter(({ target }) => target !== 'emit/spelling-questions.ts'),
|
||||
[],
|
||||
)
|
||||
})
|
||||
|
||||
test('directive/ imports nothing from emit/ or parse/', () => {
|
||||
const imports = importsOf('directive')
|
||||
assert.ok(imports.length > 0)
|
||||
assert.deepEqual(
|
||||
imports.filter(({ target }) => target.startsWith('emit/') || target.startsWith('parse/')),
|
||||
[],
|
||||
)
|
||||
})
|
||||
|
||||
@@ -4,7 +4,7 @@ import { attributeNestingMessage, nodeAttrs, nodeMarks } from '../../adf/documen
|
||||
import { blockArgument, marksAttribute, spellBlockMarks } from './block.ts'
|
||||
import { failure, success, type ConvertErrorPath, type Result } from '../../result.ts'
|
||||
import { isBareToken, spellAttributes, spellDirectiveOpener, spellVocabulary } from './syntax.ts'
|
||||
import { spellEmptyKeys } from '../empty-keys.ts'
|
||||
import { spellEmptyKeys } from './empty-keys.ts'
|
||||
import { vocabularyPairs } from '../../adf/attribute-vocabulary.ts'
|
||||
|
||||
export function spellBlockDirectiveOpener(node: AdfNode, model: BlockNodeModel, path: ConvertErrorPath, spelledByBody: readonly string[] = []): Result<string> | undefined {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { DirectiveAttributes, DirectiveValue } from './directive/syntax.ts'
|
||||
import type { EmptyKey } from '../adf/document.ts'
|
||||
import type { Read } from '../result.ts'
|
||||
import { emptyKeys } from '../adf/document.ts'
|
||||
import { unsupportedNodeShape } from './directive/syntax.ts'
|
||||
import type { DirectiveAttributes, DirectiveValue } from './syntax.ts'
|
||||
import type { EmptyKey } from '../../adf/document.ts'
|
||||
import type { Read } from '../../result.ts'
|
||||
import { emptyKeys } from '../../adf/document.ts'
|
||||
import { unsupportedNodeShape } from './syntax.ts'
|
||||
|
||||
type EmptyKeysRead = { empty: ReadonlySet<EmptyKey>; rest: Map<string, DirectiveValue> }
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { AdfNode } from '../../adf/document.ts'
|
||||
import type { InlineNodeModel } from '../../adf/inline-nodes.ts'
|
||||
import { nodeAttrs } from '../../adf/document.ts'
|
||||
import { spellAttributes, spellVocabulary } from './syntax.ts'
|
||||
import { spellEmptyKeys } from '../empty-keys.ts'
|
||||
import { spellEmptyKeys } from './empty-keys.ts'
|
||||
import { vocabularyPairs } from '../../adf/attribute-vocabulary.ts'
|
||||
|
||||
export function spellInlineNodeAttributes(node: AdfNode, model: InlineNodeModel): string | undefined {
|
||||
|
||||
@@ -6,8 +6,8 @@ import type { MarkSpelling } from '../mark-spellings.ts'
|
||||
import { directivePrefix } from './syntax.ts'
|
||||
import { failure, faulted, success, type ConvertErrorPath, type Result } from '../../result.ts'
|
||||
import { markSpelling } from '../mark-spellings.ts'
|
||||
import { readEmptyKeys } from '../empty-keys.ts'
|
||||
import { readVocabulary } from './attributes.ts'
|
||||
import { readEmptyKeys } from './empty-keys.ts'
|
||||
import { readVocabulary } from './attribute-reading.ts'
|
||||
|
||||
export function readDirectiveMark(name: string, attributes: DirectiveAttributes, path: ConvertErrorPath): Result<AdfMark> | undefined {
|
||||
const spelling = markSpelling(name)
|
||||
@@ -2,18 +2,18 @@ import type { AdfAttributes, AdfMark, AdfNode, EmptyKey } from '../../adf/docume
|
||||
import type { BlockNodeModel } from '../../adf/block-nodes.ts'
|
||||
import type { ConvertFault } from '../../result.ts'
|
||||
import type { DirectiveAttributes, DirectiveValue } from './syntax.ts'
|
||||
import type { Elsewhere } from './attributes.ts'
|
||||
import type { Elsewhere } from './attribute-reading.ts'
|
||||
import { attributeNestingMessage, isUnmarkedSpellableText } from '../../adf/document.ts'
|
||||
import { attributePairCause, attributeValue, directivePrefix, readAttributes, readDirectiveName, unknownDirectiveFault } from './syntax.ts'
|
||||
import { blockArgument, blockDirectiveForm, marksAttribute, readMarkValues, spellBlockMarks } from './block.ts'
|
||||
import { blockNodeModel } from '../../adf/block-nodes.ts'
|
||||
import { carryFencePrefix, carryName } from '../opaque-carry.ts'
|
||||
import { failure, faulted, success, type ConvertErrorPath, type Result } from '../../result.ts'
|
||||
import { inlineMarkSpellingFault, readMarkAttributes } from './marks.ts'
|
||||
import { inlineMarkSpellingFault, readMarkAttributes } from './mark-reading.ts'
|
||||
import { inlineNodeModel } from '../../adf/inline-nodes.ts'
|
||||
import { markVocabularies } from '../../adf/mark-attributes.ts'
|
||||
import { readEmptyKeys, spellsEmpty } from '../empty-keys.ts'
|
||||
import { readVocabulary } from './attributes.ts'
|
||||
import { readEmptyKeys, spellsEmpty } from './empty-keys.ts'
|
||||
import { readVocabulary } from './attribute-reading.ts'
|
||||
import { slotFault } from './syntax.ts'
|
||||
import { textBreakName } from '../adjacent-text.ts'
|
||||
import { textDirectiveName } from './text.ts'
|
||||
@@ -8,7 +8,7 @@ import { holdsDirectivePrefix, spellAttributes, spellVocabulary } from './direct
|
||||
import { holdsEntityReference } from './commonmark/entity-references.ts'
|
||||
import { isAutolink } from './commonmark/grammar.ts'
|
||||
import { isMarkType, markAttributes } from '../adf/mark-attributes.ts'
|
||||
import { spellEmptyKeys } from './empty-keys.ts'
|
||||
import { spellEmptyKeys } from './directive/empty-keys.ts'
|
||||
import { vocabularyPairs } from '../adf/attribute-vocabulary.ts'
|
||||
|
||||
type Spelling = { kind: 'code' | 'directive' | 'link'; spelling?: undefined } | { kind: 'emphasis'; spelling: string }
|
||||
|
||||
@@ -19,8 +19,8 @@ import { normalizeLabel, readInlineTarget, readLabel } from '../commonmark/link-
|
||||
import { noSpans, readInlineDirective } from '../directive/syntax.ts'
|
||||
import { openingLinkTakesDirective } from '../emit/spelling-questions.ts'
|
||||
import { readCarriedInline } from '../opaque-carry.ts'
|
||||
import { readDirectiveMark } from '../directive/marks.ts'
|
||||
import { readInlineDirectiveNode } from '../directive/nodes.ts'
|
||||
import { readDirectiveMark } from '../directive/mark-reading.ts'
|
||||
import { readInlineDirectiveNode } from '../directive/node-reading.ts'
|
||||
import { inlineSource, readInlineToken } from '../inline-tokens.ts'
|
||||
import { readTextDirective } from '../directive/text.ts'
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { AdfDocument, AdfNode } from '../../adf/document.ts'
|
||||
import type { Block, DirectiveBlock } from './blocks.ts'
|
||||
import type { BlockDirectiveNode } from '../directive/nodes.ts'
|
||||
import type { BlockDirectiveNode } from '../directive/node-reading.ts'
|
||||
import type { ConvertFault } from '../../result.ts'
|
||||
import type { Flavour } from '../flavour.ts'
|
||||
import type { LineContainer } from '../line-container.ts'
|
||||
@@ -17,9 +17,9 @@ import { leadingMarker, readAlertMarker, readTaskMarker } from '../portable/conv
|
||||
import { mintTaskIds } from '../portable/task-ids.ts'
|
||||
import { parseBlocks } from './blocks.ts'
|
||||
import { parseInlineContent } from './inline-content.ts'
|
||||
import { readBlockDirectiveNode } from '../directive/nodes.ts'
|
||||
import { readBlockDirectiveNode } from '../directive/node-reading.ts'
|
||||
import { spellStringAttribute, unsupportedNodeShape } from '../directive/syntax.ts'
|
||||
import { spellsEmpty } from '../empty-keys.ts'
|
||||
import { spellsEmpty } from '../directive/empty-keys.ts'
|
||||
import { splitPlace, splitTaskList } from '../portable/task-list.ts'
|
||||
import { withinEngineLimits } from '../length-bound.ts'
|
||||
|
||||
|
||||
@@ -225,6 +225,10 @@ documents markdown, its comparison table names HTML, and its tagline and `packag
|
||||
description and keywords name HTML again. `htmlToAdf` refuses a value that is not a string as
|
||||
`not-a-string` (`docs/decisions.md` §Which code a cause takes).
|
||||
|
||||
`html/` may not import `markdown/`, so it learns here which of the carry (`opaque-carry.ts`) and the
|
||||
mark spellings (`mark-spellings.ts`) it shares and moves them out of `markdown/`; a composed call
|
||||
naming a markdown `Flavour` sits above both peers.
|
||||
|
||||
### 46. Publish the bundle size in the README, failing the release pipeline when it drifts.
|
||||
|
||||
Item 7 changes the size. The quantity is what a consumer downloads and loads: the
|
||||
|
||||
Reference in New Issue
Block a user