| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 |
- /** Render complete persistence documentation pairs without Git or file mutation. */
- import { readFileSync } from 'node:fs'
- import { hasLanguageSwitcher } from './translation-links.ts'
- import { translationPairPaths } from './translation-pairing-record.ts'
- import {
- blobHash, languageSwitcherTargets, parseTranslationMarkdown, parseTranslationPairingManifest,
- renderPairMeta, requiresSourceLanguageSwitcher, translationPairSourcePredicate,
- translationStructureDiff, translationStructureSignature,
- } from './translation-pairing.ts'
- const isTranslationPairSource = translationPairSourcePredicate(parseTranslationPairingManifest(
- readFileSync(new URL('./translation-pairing.manifest.json', import.meta.url), 'utf8'),
- ))
- /** One repository-relative generated file and its complete UTF-8 content. */
- export interface PersistenceArtifact {
- readonly path: string
- readonly content: string
- }
- /**
- * Check a pair's code, structure and localized links, then render its three files.
- * Link existence remains the Markdown gate's responsibility. Pair hashes are
- * computed in-process; staging the documents stores the corresponding Git blobs.
- * @param root - checkout root used to resolve relative link identities.
- * @param source - repository-relative English document path.
- * @param en - complete authored or generated English Markdown.
- * @param zh - complete authored or generated Chinese Markdown.
- * @returns the documents and their matching consistency sidecar, without writing files.
- */
- export function renderPersistencePair(root: string, source: string, en: string, zh: string): PersistenceArtifact[] {
- const paths = translationPairPaths(source)
- const sourceTree = parseTranslationMarkdown(en)
- const zhTree = parseTranslationMarkdown(zh)
- const sourceTargets = languageSwitcherTargets(paths.source)
- const zhTargets = languageSwitcherTargets(paths.zh)
- if (!hasLanguageSwitcher(zhTree, zh, sourceTargets)
- || requiresSourceLanguageSwitcher(source) && !hasLanguageSwitcher(sourceTree, en, zhTargets)) {
- throw new Error(`${source}: both authored languages need their counterpart switcher`)
- }
- const context = { repoRoot: root, isTranslationPairSource, repositoryFileExists: () => true }
- const errors = translationStructureDiff(
- translationStructureSignature(sourceTree, zhTargets, { ...context, sourcePath: paths.source, markdown: en }),
- translationStructureSignature(zhTree, sourceTargets, { ...context, sourcePath: paths.zh, markdown: zh }),
- )
- if (errors.length > 0) throw new Error(`${source}: bilingual structure mismatch: ${errors.join('; ')}`)
- return [
- { path: paths.source, content: en },
- { path: paths.zh, content: zh },
- { path: paths.meta, content: renderPairMeta(paths.source, blobHash(Buffer.from(en)), paths.zh, blobHash(Buffer.from(zh))) },
- ]
- }
|