@miliastry/quasar 1.0.6 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Visuals/lyne.css +117 -6
- package/dist/Visuals/osu.css +36 -5
- package/dist/index.js +9664 -3282
- package/dist/index.mjs +9535 -3283
- package/dist/types/Analysis/Contracts/AnalysisReport.d.ts +22 -0
- package/dist/types/Analysis/Contracts/Contribution.d.ts +68 -0
- package/dist/types/Analysis/Contracts/Pass.d.ts +59 -0
- package/dist/types/Analysis/Contracts/PipelineContext.d.ts +34 -0
- package/dist/types/Analysis/Passes/Analysis/ColorUsageAnalyzer.d.ts +56 -0
- package/dist/types/Analysis/Passes/Analysis/GradientAnalyzer.d.ts +111 -0
- package/dist/types/Analysis/Passes/Analysis/MergeableColorAnalyzer.d.ts +26 -0
- package/dist/types/Analysis/Passes/Analysis/RainbowAnalyzer.d.ts +47 -0
- package/dist/types/Analysis/Passes/Analysis/SymbolAnalyzer.d.ts +89 -0
- package/dist/types/Analysis/Passes/Analysis/WaveAnalyzer.d.ts +44 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/GradientAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/MergeableColorAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/RainbowAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Analysis/__tests__/WaveAnalyzer.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Decision/DefaultDecision.d.ts +30 -0
- package/dist/types/Analysis/Passes/Decision/PaletteRemapDecision.d.ts +169 -0
- package/dist/types/Analysis/Passes/Decision/__tests__/DefaultDecision.test.d.ts +4 -0
- package/dist/types/Analysis/Passes/Transform/CollapseGradientTransform.d.ts +37 -0
- package/dist/types/Analysis/Passes/Transform/MergeColorsTransform.d.ts +28 -0
- package/dist/types/Analysis/Passes/Transform/RainbowCollapseTransform.d.ts +19 -0
- package/dist/types/Analysis/Passes/Transform/WaveCollapseTransform.d.ts +20 -0
- package/dist/types/Analysis/Passes/Utility/CharacterCountAnalyzer.d.ts +19 -0
- package/dist/types/Analysis/Pipeline/Pipeline.d.ts +69 -0
- package/dist/types/Analysis/Pipeline/PipelineBuilder.d.ts +31 -0
- package/dist/types/Analysis/Pipeline/PipelineStage.d.ts +17 -0
- package/dist/types/Analysis/Utils/color-utils.d.ts +60 -0
- package/dist/types/Analysis/__tests__/Integration.test.d.ts +8 -0
- package/dist/types/Analysis/__tests__/PaletteRemap.test.d.ts +14 -0
- package/dist/types/Analysis/__tests__/Pipeline.test.d.ts +10 -0
- package/dist/types/Analysis/__tests__/RoundTrip.test.d.ts +30 -0
- package/dist/types/Analysis/__tests__/SymbolAnalyzer.test.d.ts +11 -0
- package/dist/types/Analysis/index.d.ts +40 -0
- package/dist/types/BBCode/BBCodeDocumentModel.d.ts +92 -0
- package/dist/types/BBCode/BBCodeToGreenNode.d.ts +111 -0
- package/dist/types/BBCode/Parser.d.ts +78 -0
- package/dist/types/BBCode/index.d.ts +4 -0
- package/dist/types/Collab/positions.d.ts +55 -0
- package/dist/types/Commands/Command.d.ts +37 -0
- package/dist/types/Commands/CommandRegistry.d.ts +48 -0
- package/dist/types/Commands/DeleteNode.d.ts +7 -0
- package/dist/types/Commands/InsertText.d.ts +8 -0
- package/dist/types/Commands/SplitMerge.d.ts +9 -0
- package/dist/types/Commands/WrapInTag.d.ts +8 -0
- package/dist/types/Commands/index.d.ts +6 -0
- package/dist/types/Diff/TreeDiffer.d.ts +52 -0
- package/dist/types/Diff/__tests__/TreeDiffer.test.d.ts +1 -0
- package/dist/types/Diff/index.d.ts +2 -0
- package/dist/types/Edits/EditPlan.d.ts +144 -0
- package/dist/types/Edits/Optimizer.d.ts +78 -0
- package/dist/types/Edits/Rules/Rule.d.ts +91 -0
- package/dist/types/Edits/Rules/dropEmptyTags.d.ts +40 -0
- package/dist/types/Edits/Rules/dropRedundantNesting.d.ts +59 -0
- package/dist/types/Edits/Rules/index.d.ts +9 -0
- package/dist/types/Edits/Rules/mergeAdjacent.d.ts +93 -0
- package/dist/types/Edits/Rules/reorderWrappers.d.ts +42 -0
- package/dist/types/Edits/Rules/shortenHex.d.ts +30 -0
- package/dist/types/Edits/Rules/tagValue.d.ts +56 -0
- package/dist/types/Edits/Rules/unwrapInvisibleColor.d.ts +47 -0
- package/dist/types/Edits/applyEdits.d.ts +36 -0
- package/dist/types/Edits/index.d.ts +6 -0
- package/dist/types/Events/EventBus.d.ts +103 -0
- package/dist/types/Events/index.d.ts +2 -0
- package/dist/types/Formatter/Formatter.d.ts +32 -0
- package/dist/types/Formatter/index.d.ts +2 -0
- package/dist/types/HTML/HTMLDocumentModel.d.ts +13 -0
- package/dist/types/HTML/HTMLToGreenNode.d.ts +4 -0
- package/dist/types/Incremental/BracketIndex.d.ts +101 -0
- package/dist/types/Incremental/ChangeTracker.d.ts +69 -0
- package/dist/types/Incremental/IncrementalParser.d.ts +246 -0
- package/dist/types/Incremental/__tests__/BracketIndex.test.d.ts +1 -0
- package/dist/types/Incremental/__tests__/IncrementalParser.test.d.ts +1 -0
- package/dist/types/Incremental/index.d.ts +4 -0
- package/dist/types/Lexer/BBCodeLexer.d.ts +74 -0
- package/dist/types/Lexer/Lexer.d.ts +54 -0
- package/dist/types/Lexer/index.d.ts +4 -0
- package/dist/types/Linter/Linter.d.ts +58 -0
- package/dist/types/Linter/index.d.ts +2 -0
- package/dist/types/Markdown/MarkdownAST.d.ts +122 -0
- package/dist/types/Markdown/MarkdownDocumentModel.d.ts +15 -0
- package/dist/types/Markdown/MarkdownLexer.d.ts +155 -0
- package/dist/types/Markdown/MarkdownParser.d.ts +42 -0
- package/dist/types/Markdown/MarkdownToGreenNode.d.ts +6 -0
- package/dist/types/MilHibri/MilHibriDocumentModel.d.ts +21 -0
- package/dist/types/Model/DocumentModel.d.ts +318 -0
- package/dist/types/Model/NodeFactory.d.ts +29 -0
- package/dist/types/Model/TagRegistry.d.ts +165 -0
- package/dist/types/Model/index.d.ts +5 -0
- package/dist/types/Plugins/PluginAPI.d.ts +44 -0
- package/dist/types/Plugins/PluginRegistry.d.ts +81 -0
- package/dist/types/Plugins/index.d.ts +3 -0
- package/dist/types/Queries/QueryEngine.d.ts +32 -0
- package/dist/types/Queries/index.d.ts +1 -0
- package/dist/types/Reconciler/SurgicalReconciler.d.ts +23 -0
- package/dist/types/RenderPipeline/RenderPipeline.d.ts +46 -0
- package/dist/types/RenderPipeline/RenderTree.d.ts +55 -0
- package/dist/types/RenderPipeline/index.d.ts +4 -0
- package/dist/types/Repair/NestingRepair.d.ts +48 -0
- package/dist/types/Repair/index.d.ts +1 -0
- package/dist/types/Semantic/SemanticAnalyzer.d.ts +321 -0
- package/dist/types/Semantic/index.d.ts +2 -0
- package/dist/types/Symbols/SymbolTable.d.ts +47 -0
- package/dist/types/Symbols/index.d.ts +1 -0
- package/dist/types/Syntax/GreenNode.d.ts +154 -0
- package/dist/types/Syntax/GreenNodePool.d.ts +134 -0
- package/dist/types/Syntax/NodeMatcher.d.ts +75 -0
- package/dist/types/Syntax/RedNode.d.ts +280 -0
- package/dist/types/Syntax/RedNodeStore.d.ts +116 -0
- package/dist/types/Syntax/TreeBuilder.d.ts +54 -0
- package/dist/types/Syntax/__tests__/GreenNode.test.d.ts +1 -0
- package/dist/types/Syntax/__tests__/RedNode.test.d.ts +1 -0
- package/dist/types/Syntax/__tests__/RedNodeStore.test.d.ts +1 -0
- package/dist/types/Syntax/greenEdit.d.ts +64 -0
- package/dist/types/Syntax/hash.d.ts +17 -0
- package/dist/types/Syntax/index.d.ts +8 -0
- package/dist/types/Syntax/nodeAttr.d.ts +63 -0
- package/dist/types/Syntax/partition.d.ts +67 -0
- package/dist/types/Syntax/preserveNodeIds.d.ts +47 -0
- package/dist/types/Tokens/TokenResolver.d.ts +25 -0
- package/dist/types/Tokens/index.d.ts +1 -0
- package/dist/types/Transactions/Transaction.d.ts +36 -0
- package/dist/types/Transactions/UndoManager.d.ts +63 -0
- package/dist/types/Transactions/index.d.ts +3 -0
- package/dist/types/Transformers/ASTOptimizer.d.ts +34 -0
- package/dist/types/Transformers/GradientTransformer.d.ts +18 -0
- package/dist/types/Transformers/GrowTransformer.d.ts +16 -0
- package/dist/types/Transformers/RainbowTransformer.d.ts +17 -0
- package/dist/types/Transformers/SineWaveTransformer.d.ts +17 -0
- package/dist/types/Transformers/Transformer.d.ts +17 -0
- package/dist/types/Types/core.d.ts +104 -0
- package/dist/types/Types/diagnostics.d.ts +85 -0
- package/dist/types/Types/index.d.ts +11 -0
- package/dist/types/Types/operations.d.ts +109 -0
- package/dist/types/Types/queries.d.ts +67 -0
- package/dist/types/Types/symbols.d.ts +42 -0
- package/dist/types/Types/tokens.d.ts +75 -0
- package/dist/types/Utils/BBCodeGenerator.d.ts +21 -0
- package/dist/types/Utils/ColorMath.d.ts +92 -0
- package/dist/types/Utils/EffectMath.d.ts +643 -0
- package/dist/types/Utils/TagVocabulary.d.ts +104 -0
- package/dist/types/Utils/TagVocabulary.test.d.ts +1 -0
- package/dist/types/Utils/color.d.ts +29 -0
- package/dist/types/Utils/dom-to-svg.d.ts +28 -0
- package/dist/types/Utils/dom-to-svg.test.d.ts +1 -0
- package/dist/types/Utils/treeTransformers.d.ts +160 -0
- package/dist/types/Visitors/BBBlocksExporter.d.ts +27 -0
- package/dist/types/Visitors/BBCodeExporter.d.ts +90 -0
- package/dist/types/Visitors/BlockPatcher.d.ts +91 -0
- package/dist/types/Visitors/DOMMorpher.d.ts +13 -0
- package/dist/types/Visitors/HTMLRenderer.d.ts +380 -0
- package/dist/types/Visitors/JSONExporter.d.ts +42 -0
- package/dist/types/Visitors/MarkdownExporter.d.ts +28 -0
- package/dist/types/Visitors/SVGRenderer.d.ts +16 -0
- package/dist/types/Visitors/TiptapExporter.d.ts +40 -0
- package/dist/types/Visitors/Visitor.d.ts +35 -0
- package/dist/types/Visitors/index.d.ts +9 -0
- package/dist/types/Visuals/BoxDrawer.d.ts +49 -0
- package/dist/types/Visuals/index.d.ts +38 -0
- package/dist/types/index.d.ts +154 -0
- package/package.json +14 -10
- package/src/Analysis/Passes/Analysis/ColorUsageAnalyzer.ts +103 -0
- package/src/Analysis/Passes/Analysis/GradientAnalyzer.ts +294 -20
- package/src/Analysis/Passes/Analysis/SymbolAnalyzer.ts +257 -0
- package/src/Analysis/Passes/Decision/PaletteRemapDecision.ts +425 -0
- package/src/Analysis/Pipeline/Pipeline.ts +15 -2
- package/src/Analysis/index.ts +8 -2
- package/src/BBCode/BBCodeDocumentModel.ts +3 -0
- package/src/BBCode/BBCodeToGreenNode.ts +18 -12
- package/src/BBCode/Parser.ts +38 -1
- package/src/Edits/EditPlan.ts +290 -0
- package/src/Edits/Optimizer.ts +185 -0
- package/src/Edits/Rules/Rule.ts +145 -0
- package/src/Edits/Rules/dropEmptyTags.ts +110 -0
- package/src/Edits/Rules/dropRedundantNesting.ts +120 -0
- package/src/Edits/Rules/index.ts +28 -0
- package/src/Edits/Rules/mergeAdjacent.ts +224 -0
- package/src/Edits/Rules/reorderWrappers.ts +154 -0
- package/src/Edits/Rules/shortenHex.ts +79 -0
- package/src/Edits/Rules/tagValue.ts +105 -0
- package/src/Edits/Rules/unwrapInvisibleColor.ts +93 -0
- package/src/Edits/applyEdits.ts +54 -0
- package/src/Edits/index.ts +22 -0
- package/src/Events/EventBus.ts +18 -0
- package/src/HTML/HTMLToGreenNode.ts +185 -37
- package/src/Incremental/BracketIndex.ts +249 -0
- package/src/Incremental/IncrementalParser.ts +464 -41
- package/src/Lexer/BBCodeLexer.ts +25 -3
- package/src/Lexer/index.ts +1 -1
- package/src/Markdown/MarkdownAST.ts +65 -2
- package/src/Markdown/MarkdownLexer.ts +69 -14
- package/src/Markdown/MarkdownParser.ts +749 -62
- package/src/Markdown/MarkdownToGreenNode.ts +148 -27
- package/src/MilHibri/MilHibriDocumentModel.ts +56 -0
- package/src/Model/DocumentModel.ts +138 -5
- package/src/Model/TagRegistry.ts +129 -134
- package/src/Reconciler/SurgicalReconciler.ts +460 -0
- package/src/Repair/NestingRepair.ts +116 -0
- package/src/Repair/index.ts +1 -0
- package/src/Semantic/SemanticAnalyzer.ts +1802 -65
- package/src/Syntax/GreenNodePool.ts +12 -12
- package/src/Syntax/RedNode.ts +17 -3
- package/src/Syntax/RedNodeStore.ts +9 -1
- package/src/Syntax/nodeAttr.ts +172 -0
- package/src/Tokens/TokenResolver.ts +55 -0
- package/src/Tokens/index.ts +1 -0
- package/src/Types/core.ts +15 -0
- package/src/Utils/ColorMath.ts +276 -55
- package/src/Utils/EffectMath.ts +2462 -0
- package/src/Utils/TagVocabulary.ts +141 -0
- package/src/Utils/dom-to-svg.ts +28 -12
- package/src/Visitors/BBBlocksExporter.ts +15 -1
- package/src/Visitors/BBCodeExporter.ts +319 -32
- package/src/Visitors/BlockPatcher.ts +87 -11
- package/src/Visitors/DOMMorpher.ts +15 -5
- package/src/Visitors/HTMLRenderer.ts +374 -151
- package/src/Visitors/MarkdownExporter.ts +98 -41
- package/src/Visitors/TiptapExporter.ts +1 -0
- package/src/Visuals/index.ts +7 -4
- package/src/Visuals/lyne.css +117 -6
- package/src/Visuals/osu.css +36 -5
- package/src/index.ts +172 -5
- package/dist/index.d.mts +0 -4612
- package/dist/index.d.ts +0 -4612
- package/src/Analysis/Passes/Analysis/__tests__/GradientAnalyzer.test.ts +0 -135
- package/src/Analysis/Passes/Analysis/__tests__/MergeableColorAnalyzer.test.ts +0 -84
- package/src/Analysis/Passes/Analysis/__tests__/RainbowAnalyzer.test.ts +0 -99
- package/src/Analysis/Passes/Analysis/__tests__/WaveAnalyzer.test.ts +0 -119
- package/src/Analysis/Passes/Decision/__tests__/DefaultDecision.test.ts +0 -179
- package/src/Analysis/__tests__/Integration.test.ts +0 -162
- package/src/Analysis/__tests__/Pipeline.test.ts +0 -133
- package/src/Diff/__tests__/TreeDiffer.test.ts +0 -65
- package/src/Incremental/__tests__/IncrementalParser.test.ts +0 -164
- package/src/Syntax/__tests__/GreenNode.test.ts +0 -33
- package/src/Syntax/__tests__/RedNode.test.ts +0 -81
- package/src/Syntax/__tests__/RedNodeStore.test.ts +0 -104
- package/src/Tests/ASTOptimizerIdempotence.test.ts +0 -77
- package/src/Tests/BlockPatcher.test.ts +0 -437
- package/src/Tests/BlockPatcherWindowed.test.ts +0 -364
- package/src/Tests/BoxDrawer.test.ts +0 -217
- package/src/Tests/BoxRichTitle.test.ts +0 -105
- package/src/Tests/Chars500kBenchmark.test.ts +0 -151
- package/src/Tests/Chars500kEdits.test.ts +0 -321
- package/src/Tests/CollabPositions.test.ts +0 -146
- package/src/Tests/CompilerPathProfiling.test.ts +0 -186
- package/src/Tests/DOMMorpher.test.ts +0 -142
- package/src/Tests/DomPatchPerf.test.ts +0 -60
- package/src/Tests/EffectSegments.snapshot.json +0 -616
- package/src/Tests/EffectSegments.test.ts +0 -68
- package/src/Tests/FindNodeAtOffset.test.ts +0 -65
- package/src/Tests/Fuzzer.test.ts +0 -166
- package/src/Tests/GreenNodePool.test.ts +0 -153
- package/src/Tests/Lexer.test.ts +0 -238
- package/src/Tests/LyneMode.test.ts +0 -291
- package/src/Tests/ModelCoherence.test.ts +0 -180
- package/src/Tests/Partition.test.ts +0 -238
- package/src/Tests/PluginTags.test.ts +0 -150
- package/src/Tests/ProblematicSection.test.ts +0 -46
- package/src/Tests/ProblematicSectionHTML.test.ts +0 -58
- package/src/Tests/RedReuse.test.ts +0 -134
- package/src/Tests/ReproDelete20k.test.ts +0 -62
- package/src/Tests/SemanticValidators.test.ts +0 -136
- package/src/Tests/StableNodeIds.test.ts +0 -210
- package/src/Tests/StudioColorBloat.test.ts +0 -25
- package/src/Tests/StudioDebugText.test.ts +0 -27
- package/src/Tests/StudioTrailingChar.test.ts +0 -25
- package/src/Tests/StudioValidText.test.ts +0 -25
- package/src/Tests/UrlImgBug.test.ts +0 -23
- package/src/Tests/VisualBuilderFidelity.test.ts +0 -105
- package/src/Tests/referenceDocument.ts +0 -119
- package/src/Utils/dom-to-svg.test.ts +0 -86
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { RedNode } from '../Syntax/RedNode';
|
|
2
|
+
import { BBCodeExporter } from '../Visitors/BBCodeExporter';
|
|
3
|
+
import { HTMLRenderer } from '../Visitors/HTMLRenderer';
|
|
4
|
+
export interface SurgicalEdit {
|
|
5
|
+
start: number;
|
|
6
|
+
end: number;
|
|
7
|
+
text: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ReconcileResult {
|
|
10
|
+
edits: SurgicalEdit[];
|
|
11
|
+
hasChanges: boolean;
|
|
12
|
+
resultingSource: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Computes the minimal single-range text edit (common prefix + suffix diff)
|
|
16
|
+
* between two strings, ensuring Monaco only replaces the exact changed characters.
|
|
17
|
+
*/
|
|
18
|
+
export declare function computeTextDelta(original: string, updated: string): SurgicalEdit[];
|
|
19
|
+
/**
|
|
20
|
+
* Reconciles the visual DOM of a contenteditable container against the original BBCode document AST.
|
|
21
|
+
* Produces minimal, non-destructive surgical edits preserving untouched BBCode blocks and structure.
|
|
22
|
+
*/
|
|
23
|
+
export declare function reconcileVisualDOMToBBCode(originalSource: string, originalAST: RedNode | null, editorContainer: HTMLElement, exporter?: BBCodeExporter, renderer?: HTMLRenderer): ReconcileResult;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentEngine — RenderPipeline
|
|
3
|
+
*
|
|
4
|
+
* The Render Pipeline transforms a DocumentModel into renderable output.
|
|
5
|
+
* It sits between the model and the view layer.
|
|
6
|
+
*
|
|
7
|
+
* The pipeline is:
|
|
8
|
+
* DocumentModel → RenderTree → HTML/SVG/Canvas/React
|
|
9
|
+
*
|
|
10
|
+
* Plugins can intercept at any stage:
|
|
11
|
+
* - Add/transform render nodes
|
|
12
|
+
* - Provide custom renderers for custom tags
|
|
13
|
+
* - Post-process the output
|
|
14
|
+
*/
|
|
15
|
+
import { RedNode } from '../Syntax/RedNode';
|
|
16
|
+
import { type RenderNode, type RenderVariant } from './RenderTree';
|
|
17
|
+
import type { TagRegistry } from '../Model/TagRegistry';
|
|
18
|
+
export type RenderPhase = 'build' | 'transform' | 'serialize';
|
|
19
|
+
export interface RenderHook {
|
|
20
|
+
phase: RenderPhase;
|
|
21
|
+
hook: (node: RenderNode, context: RenderContext) => RenderNode | null;
|
|
22
|
+
}
|
|
23
|
+
export interface RenderContext {
|
|
24
|
+
variant: RenderVariant;
|
|
25
|
+
registry: TagRegistry;
|
|
26
|
+
source: string;
|
|
27
|
+
}
|
|
28
|
+
export declare class RenderPipeline {
|
|
29
|
+
private hooks;
|
|
30
|
+
/**
|
|
31
|
+
* Register a render hook.
|
|
32
|
+
*/
|
|
33
|
+
register(hook: RenderHook): void;
|
|
34
|
+
/**
|
|
35
|
+
* Unregister a render hook.
|
|
36
|
+
*/
|
|
37
|
+
unregister(hook: RenderHook): void;
|
|
38
|
+
/**
|
|
39
|
+
* Render a RedNode tree to a string.
|
|
40
|
+
*/
|
|
41
|
+
render(root: RedNode, variant: RenderVariant | undefined, registry: TagRegistry, source?: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Build a RenderNode tree from a RedNode tree.
|
|
44
|
+
*/
|
|
45
|
+
private buildRenderTree;
|
|
46
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentEngine — RenderTree
|
|
3
|
+
*
|
|
4
|
+
* An intermediate representation between DocumentModel and final output.
|
|
5
|
+
* The RenderTree is what the RenderPipeline processes.
|
|
6
|
+
*
|
|
7
|
+
* This abstraction allows:
|
|
8
|
+
* - Same DocumentModel → multiple render outputs (HTML, Canvas, SVG, PDF)
|
|
9
|
+
* - Plugin renderers that intercept/modify render nodes
|
|
10
|
+
* - Smooth visual transitions between document states
|
|
11
|
+
* - Partial rendering for performance
|
|
12
|
+
*/
|
|
13
|
+
import type { NodeKind } from '../Types/core';
|
|
14
|
+
export type RenderVariant = 'html' | 'canvas' | 'svg' | 'pdf' | 'react' | 'text';
|
|
15
|
+
export interface RenderNode {
|
|
16
|
+
/** Semantic kind */
|
|
17
|
+
kind: NodeKind | string;
|
|
18
|
+
/** Text content */
|
|
19
|
+
text: string;
|
|
20
|
+
/** Child render nodes */
|
|
21
|
+
children: RenderNode[];
|
|
22
|
+
/** Props/attributes for the renderer */
|
|
23
|
+
props: Record<string, unknown>;
|
|
24
|
+
/** Which render variant this node targets */
|
|
25
|
+
variant?: RenderVariant;
|
|
26
|
+
/** CSS class names */
|
|
27
|
+
className?: string;
|
|
28
|
+
/** Inline styles */
|
|
29
|
+
style?: Record<string, string | number>;
|
|
30
|
+
/** Events/handlers (for interactive renders) */
|
|
31
|
+
events?: Record<string, string>;
|
|
32
|
+
/** Metadata for renderers */
|
|
33
|
+
metadata?: Record<string, unknown>;
|
|
34
|
+
}
|
|
35
|
+
export declare class RenderTree {
|
|
36
|
+
/**
|
|
37
|
+
* Create a render tree from a document node.
|
|
38
|
+
*/
|
|
39
|
+
static fromNode(kind: NodeKind | string, text?: string, children?: RenderNode[], props?: Record<string, unknown>): RenderNode;
|
|
40
|
+
/**
|
|
41
|
+
* Create a text render node.
|
|
42
|
+
*/
|
|
43
|
+
static text(content: string): RenderNode;
|
|
44
|
+
/**
|
|
45
|
+
* Create a container render node.
|
|
46
|
+
*/
|
|
47
|
+
static container(kind: NodeKind | string, children: RenderNode[], props?: Record<string, unknown>): RenderNode;
|
|
48
|
+
/**
|
|
49
|
+
* Serialize a render tree to HTML.
|
|
50
|
+
*/
|
|
51
|
+
static toHTML(node: RenderNode): string;
|
|
52
|
+
private static kindToTag;
|
|
53
|
+
private static propsToHtml;
|
|
54
|
+
private static escapeHtml;
|
|
55
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { RedNode } from '../Syntax/RedNode';
|
|
2
|
+
import type { SurgicalEdit } from '../Reconciler/SurgicalReconciler';
|
|
3
|
+
/** A closing tag the source never opened, kept by the parser as literal text. */
|
|
4
|
+
export interface OrphanCloser {
|
|
5
|
+
/** The tag name as written, lowercased. */
|
|
6
|
+
tag: string;
|
|
7
|
+
/** Where the `[/tag]` sits in the source. */
|
|
8
|
+
range: {
|
|
9
|
+
start: number;
|
|
10
|
+
end: number;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/** An opening tag the parser had to close on the author's behalf. */
|
|
14
|
+
export interface UnclosedOpener {
|
|
15
|
+
tag: string;
|
|
16
|
+
/** Where its `[/tag]` belongs. */
|
|
17
|
+
at: number;
|
|
18
|
+
}
|
|
19
|
+
export interface NestingRepair {
|
|
20
|
+
/** Deletions for the orphans and insertions for the missing closers. */
|
|
21
|
+
edits: SurgicalEdit[];
|
|
22
|
+
orphans: OrphanCloser[];
|
|
23
|
+
unclosed: UnclosedOpener[];
|
|
24
|
+
/** The repaired source, for callers that want it whole. */
|
|
25
|
+
source: string;
|
|
26
|
+
hasChanges: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Repairs BBCode nesting without touching a byte the author wrote elsewhere.
|
|
30
|
+
*
|
|
31
|
+
* Two kinds of damage, two kinds of edit:
|
|
32
|
+
*
|
|
33
|
+
* - a closing tag with no opener is deleted, because that is what osu! does
|
|
34
|
+
* with it — Quasar renders it as literal text, which is the one place the
|
|
35
|
+
* two disagree (see `Tests/OsuNestingFidelity.test.ts`);
|
|
36
|
+
* - an opener the parser had to close silently gets its `[/tag]` written in,
|
|
37
|
+
* at the offset the parser already chose.
|
|
38
|
+
*
|
|
39
|
+
* Crossed tags need no rule of their own. `[a][b]x[/a][/b]` already parses to
|
|
40
|
+
* the same tree as `[a][b]x[/b][/a]`; removing the leftover `[/b]` is all the
|
|
41
|
+
* repair it takes.
|
|
42
|
+
*
|
|
43
|
+
* Deliberately *not* an export of the tree. Round-tripping through
|
|
44
|
+
* `BBCodeExporter` also yields balanced BBCode, but it rewrites the whole
|
|
45
|
+
* document — re-spelling attributes, collapsing spacing — and none of that is
|
|
46
|
+
* a change the author asked for. Edits keep the blast radius at the damage.
|
|
47
|
+
*/
|
|
48
|
+
export declare function repairNesting(source: string, root: RedNode | null): NestingRepair;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { repairNesting, type NestingRepair, type OrphanCloser, type UnclosedOpener } from './NestingRepair';
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentEngine — SemanticAnalyzer
|
|
3
|
+
*
|
|
4
|
+
* Walks the Red Tree and produces diagnostics by applying
|
|
5
|
+
* semantic rules to the syntax tree.
|
|
6
|
+
*
|
|
7
|
+
* This is where language-specific validation happens.
|
|
8
|
+
* The analyzer is extensible via registered validators.
|
|
9
|
+
*
|
|
10
|
+
* Inspired by Roslyn's Semantic Model and LSP diagnostics.
|
|
11
|
+
*/
|
|
12
|
+
import { RedNode } from '../Syntax/RedNode';
|
|
13
|
+
import { type BBCodeDialect } from '../BBCode/BBCodeToGreenNode';
|
|
14
|
+
import type { Diagnostic, DiagnosticSeverity, DiagnosticCollection } from '../Types/diagnostics';
|
|
15
|
+
import { type CollapsibleGradient } from '../Analysis/Passes/Analysis/GradientAnalyzer';
|
|
16
|
+
import type { SourceSpan } from '../Incremental/IncrementalParser';
|
|
17
|
+
import { type TokenResolverFn, type TokenSource } from '../Tokens';
|
|
18
|
+
export interface Validator {
|
|
19
|
+
/** Unique code for this validator (e.g. 'invalid-color') */
|
|
20
|
+
code: string;
|
|
21
|
+
/** Severity of issues found by this validator */
|
|
22
|
+
severity: DiagnosticSeverity;
|
|
23
|
+
/**
|
|
24
|
+
* Node kinds this validator can ever fire on. Omit to run on every node.
|
|
25
|
+
*
|
|
26
|
+
* Three of the five built-ins open with nothing but a kind test, so on a
|
|
27
|
+
* document of 1736 nodes they were called 1736 times each to answer a
|
|
28
|
+
* question the dispatcher can answer once. Declaring the kinds turns the
|
|
29
|
+
* call into a lookup that never happens.
|
|
30
|
+
*/
|
|
31
|
+
kinds?: readonly string[];
|
|
32
|
+
/**
|
|
33
|
+
* What a verdict on one node depends on. Default `'node'`.
|
|
34
|
+
*
|
|
35
|
+
* `'node'`: the node itself, its ancestors, its own source span, and the
|
|
36
|
+
* document-scope maps on the context (`crossings`, `unknownTags`,
|
|
37
|
+
* `orphanClosers`, `collapsibleGradients`) — everything the incremental
|
|
38
|
+
* analysis knows how to keep current. Every built-in is `'node'`-scoped.
|
|
39
|
+
*
|
|
40
|
+
* `'document'`: anything else — counting headings, comparing a node with
|
|
41
|
+
* an unrelated one, reading `allNodes`. A verdict like that can change for
|
|
42
|
+
* a node the edit never touched, which the window pass cannot see, so
|
|
43
|
+
* registering one turns every analysis into a full pass until it is
|
|
44
|
+
* unregistered. Reading `allNodes` from a `'node'`-scoped validator is
|
|
45
|
+
* treated the same way, at runtime.
|
|
46
|
+
*/
|
|
47
|
+
scope?: 'node' | 'document';
|
|
48
|
+
/** Validate a node. Return diagnostics or null */
|
|
49
|
+
validate(node: RedNode, context: AnalyzerContext): Diagnostic | Diagnostic[] | null;
|
|
50
|
+
}
|
|
51
|
+
export interface AnalyzerContext {
|
|
52
|
+
/**
|
|
53
|
+
* Every node in the tree, by id, for cross-reference validation.
|
|
54
|
+
*
|
|
55
|
+
* A getter, and deliberately: building this Map cost a second full walk of
|
|
56
|
+
* the tree plus 1736 `Map.set` calls — 23% of `analyze()` — and **no
|
|
57
|
+
* validator has ever read it**. It was built so that the caller could look up
|
|
58
|
+
* by id the node to attach each diagnostic to, which is the node the
|
|
59
|
+
* validator was looking at when it produced it. Validators that genuinely
|
|
60
|
+
* need cross-references still get it; everyone else stops paying for it.
|
|
61
|
+
*/
|
|
62
|
+
readonly allNodes: Map<string, RedNode>;
|
|
63
|
+
/**
|
|
64
|
+
* Openers whose `[/tag]` does exist but arrived too late, keyed by the
|
|
65
|
+
* opener's node id.
|
|
66
|
+
*
|
|
67
|
+
* A getter for the same reason `allNodes` is one, and asked for even more
|
|
68
|
+
* rarely: the only way to reach it is through a node that is already known
|
|
69
|
+
* to be unclosed, which on a healthy document never happens. Both validators
|
|
70
|
+
* that read it test `isUnclosedTag` first, so a document with no auto-closed
|
|
71
|
+
* tag never pays for the walk.
|
|
72
|
+
*/
|
|
73
|
+
readonly crossings: ReadonlyMap<string, CrossedTags>;
|
|
74
|
+
/**
|
|
75
|
+
* Unknown tags that were written as a PAIR, keyed by the opener's node id.
|
|
76
|
+
*
|
|
77
|
+
* Same lazy contract as `crossings`, and reached through an even tighter
|
|
78
|
+
* gate: only a text leaf whose first and last characters are brackets can
|
|
79
|
+
* be in it, which is three integer compares per text node.
|
|
80
|
+
*/
|
|
81
|
+
readonly unknownTags: ReadonlyMap<string, UnknownTag>;
|
|
82
|
+
/**
|
|
83
|
+
* Closing tags no opener claims, node id → tag name.
|
|
84
|
+
*
|
|
85
|
+
* Same walk as `unknownTags`, cached together, because the two answers are
|
|
86
|
+
* two halves of one pairing: what is left over after every unknown opener
|
|
87
|
+
* has taken its closer is a `[/tag]` that closes nothing.
|
|
88
|
+
*/
|
|
89
|
+
readonly orphanClosers: ReadonlyMap<string, string>;
|
|
90
|
+
/** Sequences of [color] tags that form a gradient, keyed by the first node's id */
|
|
91
|
+
readonly collapsibleGradients: ReadonlyMap<string, CollapsibleGradient>;
|
|
92
|
+
/** Previously collected diagnostics */
|
|
93
|
+
diagnostics: DiagnosticCollection;
|
|
94
|
+
/** Source text for position lookups */
|
|
95
|
+
source: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* How much of the tree a pass looked at.
|
|
99
|
+
*
|
|
100
|
+
* `'full'` — every node was validated afresh. `'window'` — only the nodes an
|
|
101
|
+
* edit could have changed were: the ones inside the reparse window, the
|
|
102
|
+
* ancestors on the path down to it, and any node elsewhere whose
|
|
103
|
+
* document-scope facts (a pairing, a crossing, a colour run) the edit
|
|
104
|
+
* altered. The diagnostics are complete and identical either way; the scope
|
|
105
|
+
* says how they were obtained.
|
|
106
|
+
*/
|
|
107
|
+
export type AnalyzeScope = 'full' | 'window';
|
|
108
|
+
export interface AnalyzeResult {
|
|
109
|
+
diagnostics: DiagnosticCollection;
|
|
110
|
+
/** Time taken in ms */
|
|
111
|
+
duration: number;
|
|
112
|
+
/** Number of nodes analyzed */
|
|
113
|
+
nodesAnalyzed: number;
|
|
114
|
+
/** See {@link AnalyzeScope}. */
|
|
115
|
+
scope: AnalyzeScope;
|
|
116
|
+
/** The span re-validated by a `'window'` pass; `null` for a full one. */
|
|
117
|
+
window: SourceSpan | null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* What `analyze()` actually returns: an {@link AnalyzeResult} plus the node
|
|
121
|
+
* index it had to build anyway for cross-reference lookups.
|
|
122
|
+
*
|
|
123
|
+
* Kept as a separate type, and deliberately NOT part of `AnalyzeResult`,
|
|
124
|
+
* because the index holds a strong reference to every node in the tree. A
|
|
125
|
+
* caller that stores an `AnalyzeResult` long-term (as `DocumentModel` does)
|
|
126
|
+
* must not pin an entire stale tree; one that needs the index gets it here and
|
|
127
|
+
* owns that decision explicitly.
|
|
128
|
+
*/
|
|
129
|
+
export interface IndexedAnalyzeResult extends AnalyzeResult {
|
|
130
|
+
allNodes: Map<string, RedNode>;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Whether the parser had to close this tag itself because the author never did.
|
|
134
|
+
*
|
|
135
|
+
* Exact, not heuristic. A tag the author closed ends exactly at its own
|
|
136
|
+
* `[/tag]`, because that is where the parser sets the node's end. A tag closed
|
|
137
|
+
* *for* the author ends wherever the parser gave up — at the end of the
|
|
138
|
+
* document, or at the mismatched `[/other]` that forced the issue — and the
|
|
139
|
+
* text up to that point does not end in its closing form.
|
|
140
|
+
*
|
|
141
|
+
* That single rule covers both shapes: `[b]x` (never closed) and `[b][i]x[/b]`
|
|
142
|
+
* (where `[i]` is auto-closed by the legacy nesting rules).
|
|
143
|
+
*/
|
|
144
|
+
export declare function isUnclosedTag(node: RedNode, source: string): boolean;
|
|
145
|
+
/**
|
|
146
|
+
* An opener the parser closed on the author's behalf, together with the
|
|
147
|
+
* `[/tag]` the author *did* write — just too late for it to count.
|
|
148
|
+
*/
|
|
149
|
+
export interface CrossedTags {
|
|
150
|
+
/** The tag name as written, lowercased. */
|
|
151
|
+
tag: string;
|
|
152
|
+
/** Where its closing tag belongs: the offset the parser already closed it at. */
|
|
153
|
+
at: number;
|
|
154
|
+
/** Where the ignored `[/tag]` sits in the source. */
|
|
155
|
+
closer: {
|
|
156
|
+
start: number;
|
|
157
|
+
end: number;
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* The tag name as the author actually spelled it, read back from the source.
|
|
162
|
+
*
|
|
163
|
+
* The tree cannot answer this. Several spellings collapse onto one `NodeKind`
|
|
164
|
+
* — `[strike]` and `[s]` both become `strikethrough` — and a node's `text`
|
|
165
|
+
* holds its attributes, not its name. A node's range does start at the opening
|
|
166
|
+
* bracket, so the name is the identifier immediately after it.
|
|
167
|
+
*
|
|
168
|
+
* Returns null for nodes that do not correspond to a written tag.
|
|
169
|
+
*/
|
|
170
|
+
export declare function openingTagName(node: RedNode, source: string): string | null;
|
|
171
|
+
/**
|
|
172
|
+
* The span of the *name* inside this node's closing tag, or null if the author
|
|
173
|
+
* never wrote one.
|
|
174
|
+
*
|
|
175
|
+
* A rename has to touch both ends: rewriting only the opening `[strike]` to
|
|
176
|
+
* `[s]` leaves an orphan `[/strike]` that osu! renders as literal text — worse
|
|
177
|
+
* than the deprecation it was fixing. The name sits between `[/` and `]`, so it
|
|
178
|
+
* ends one character before the node and runs back its own length.
|
|
179
|
+
*/
|
|
180
|
+
export declare function closingTagNameRange(node: RedNode, source: string, name: string): {
|
|
181
|
+
start: number;
|
|
182
|
+
end: number;
|
|
183
|
+
} | null;
|
|
184
|
+
/**
|
|
185
|
+
* An unknown tag the author wrote as a pair: `[bold]x[/bold]`.
|
|
186
|
+
*
|
|
187
|
+
* The pairing is the whole signal. An unknown tag becomes literal text on
|
|
188
|
+
* purpose — `[Gateron]` in prose has to stay visible, and a real corpus of 53
|
|
189
|
+
* userpages carries `[gb]`, `[insane]`, `[rm120]` and a dozen more of those —
|
|
190
|
+
* so a bare `[name]` is not evidence of anything. A `[name]` with a matching
|
|
191
|
+
* `[/name]` is: nobody closes a bracketed aside. That same corpus contains
|
|
192
|
+
* exactly ZERO of them, which is the false-positive budget this rule spends.
|
|
193
|
+
*/
|
|
194
|
+
export interface UnknownTag {
|
|
195
|
+
/** The name as written, lowercased. */
|
|
196
|
+
tag: string;
|
|
197
|
+
/** The `[tag]` the parser refused, kept as literal text. */
|
|
198
|
+
opener: {
|
|
199
|
+
start: number;
|
|
200
|
+
end: number;
|
|
201
|
+
};
|
|
202
|
+
/** Its `[/tag]` — what makes this a misspelling rather than prose. */
|
|
203
|
+
closer: {
|
|
204
|
+
start: number;
|
|
205
|
+
end: number;
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
export interface SemanticAnalyzerOptions {
|
|
209
|
+
dialect?: BBCodeDialect;
|
|
210
|
+
tokens?: TokenSource;
|
|
211
|
+
}
|
|
212
|
+
export declare class SemanticAnalyzer {
|
|
213
|
+
private validators;
|
|
214
|
+
/**
|
|
215
|
+
* The same validators, arranged for the walk instead of for lookup.
|
|
216
|
+
*
|
|
217
|
+
* `_always` run on every node; `_byKind` are the ones that declared their
|
|
218
|
+
* kinds. Iterating the Map itself allocated an iterator and a destructuring
|
|
219
|
+
* pair per node — 9% of `analyze()` spent on bookkeeping, not on validating.
|
|
220
|
+
*
|
|
221
|
+
* Rebuilt on register/unregister, which happen once at construction and
|
|
222
|
+
* essentially never afterwards.
|
|
223
|
+
*/
|
|
224
|
+
private _always;
|
|
225
|
+
private _byKind;
|
|
226
|
+
/** Set by register/unregister; cleared by the next `rebuildDispatch`. */
|
|
227
|
+
private _dispatchDirty;
|
|
228
|
+
/**
|
|
229
|
+
* The dialect this analyzer validates against.
|
|
230
|
+
*
|
|
231
|
+
* Only the suggestion for an unknown tag reads it — detection never needs a
|
|
232
|
+
* name list, because the parser already refused the tag. `DocumentModel`
|
|
233
|
+
* builds the analyzer before a subclass knows its dialect, so this is set
|
|
234
|
+
* afterwards rather than taken by the constructor.
|
|
235
|
+
*/
|
|
236
|
+
dialect: BBCodeDialect;
|
|
237
|
+
private _tokens?;
|
|
238
|
+
private _tokenResolver?;
|
|
239
|
+
private _validatorsVersion;
|
|
240
|
+
private _tokensVersion;
|
|
241
|
+
private _snapshot;
|
|
242
|
+
get tokens(): TokenSource | undefined;
|
|
243
|
+
set tokens(val: TokenSource | undefined);
|
|
244
|
+
get tokenResolver(): TokenResolverFn | undefined;
|
|
245
|
+
setTokens(tokens?: TokenSource): void;
|
|
246
|
+
constructor(options?: SemanticAnalyzerOptions | BBCodeDialect);
|
|
247
|
+
/**
|
|
248
|
+
* Register a validator.
|
|
249
|
+
*/
|
|
250
|
+
register(validator: Validator): void;
|
|
251
|
+
/**
|
|
252
|
+
* Remove a validator.
|
|
253
|
+
*/
|
|
254
|
+
unregister(code: string): void;
|
|
255
|
+
/** Whether any registered validator declared `'document'` scope. */
|
|
256
|
+
private hasDocumentScopedValidator;
|
|
257
|
+
/**
|
|
258
|
+
* Rebuild the kind buckets, unless they are already current.
|
|
259
|
+
*
|
|
260
|
+
* `register` used to rebuild them itself, so constructing an analyzer —
|
|
261
|
+
* which registers thirteen built-ins — rebuilt the whole table thirteen
|
|
262
|
+
* times and threw away the first twelve. A plugin registering a batch paid
|
|
263
|
+
* the same way. Registration now only marks the table stale and `analyze`
|
|
264
|
+
* rebuilds it at most once, whatever the batch size.
|
|
265
|
+
*/
|
|
266
|
+
private rebuildDispatch;
|
|
267
|
+
/**
|
|
268
|
+
* Analyze a Red Tree and produce diagnostics — every node, from scratch.
|
|
269
|
+
*
|
|
270
|
+
* Also the base a later {@link analyzeWindow} builds on: the pass remembers
|
|
271
|
+
* which nodes carry diagnostics and which ones feed the document-scope
|
|
272
|
+
* maps, so the next edit can re-validate its window alone.
|
|
273
|
+
*/
|
|
274
|
+
analyze(root: RedNode, source: string, tokensOrOptions?: TokenSource | {
|
|
275
|
+
tokens?: TokenSource;
|
|
276
|
+
}): IndexedAnalyzeResult;
|
|
277
|
+
/**
|
|
278
|
+
* Re-validate only what an edit could have changed, on top of the previous
|
|
279
|
+
* pass over this analyzer.
|
|
280
|
+
*
|
|
281
|
+
* `root` must be the tree the previous pass's root turned into through
|
|
282
|
+
* incremental reparses WITH red-subtree reuse — that is what makes every
|
|
283
|
+
* node outside `window` (the union of those reparses' windows, carried
|
|
284
|
+
* into `root`'s coordinates) the same object over the same text. The
|
|
285
|
+
* `DocumentModel` tracks exactly that and calls this only when it holds;
|
|
286
|
+
* anyone else should prefer `DocumentModel.analyzeIncremental`.
|
|
287
|
+
*
|
|
288
|
+
* Returns `null` when no window pass can be trusted: there is no previous
|
|
289
|
+
* pass, the validators or the tokens changed since it, or a validator with
|
|
290
|
+
* document scope is registered (see `Validator.scope`). The caller runs a
|
|
291
|
+
* full `analyze` then. The result's diagnostics are complete — the whole
|
|
292
|
+
* document's, identical to what a full pass would produce — and come out
|
|
293
|
+
* in document order like a full pass's do.
|
|
294
|
+
*
|
|
295
|
+
* What happens, in order:
|
|
296
|
+
* 1. descend the window (see `descendWindow`), collecting its candidates;
|
|
297
|
+
* 2. keep every previous candidate outside it that is still in the tree,
|
|
298
|
+
* at its current offsets; derive the maps from kept plus fresh;
|
|
299
|
+
* 3. diff the maps against the previous ones for nodes outside the
|
|
300
|
+
* window, and mark the nodes whose entry changed for re-validation;
|
|
301
|
+
* 4. move the kept diagnostics of displaced nodes by their displacement;
|
|
302
|
+
* 5. validate the window nodes and the marked ones;
|
|
303
|
+
* 6. assemble the collection from every diagnostic-bearing node.
|
|
304
|
+
*/
|
|
305
|
+
analyzeWindow(root: RedNode, source: string, window: SourceSpan): IndexedAnalyzeResult | null;
|
|
306
|
+
/**
|
|
307
|
+
* The context validators see. The maps are ready-made; `allNodes` is
|
|
308
|
+
* built on demand and, being the one cross-document index a validator can
|
|
309
|
+
* reach without declaring itself, its use is recorded (see
|
|
310
|
+
* `Validator.scope`).
|
|
311
|
+
*/
|
|
312
|
+
private makeContext;
|
|
313
|
+
/** Run every applicable validator over `nodes`, in order. */
|
|
314
|
+
private validateNodes;
|
|
315
|
+
private registerBuiltinValidators;
|
|
316
|
+
/**
|
|
317
|
+
* Create a validator for a specific tag/kind.
|
|
318
|
+
* Convenience method for plugin authors.
|
|
319
|
+
*/
|
|
320
|
+
createValidator(code: string, severity: DiagnosticSeverity, predicate: (node: RedNode, ctx: AnalyzerContext) => string | null): Validator;
|
|
321
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DocumentEngine — SymbolTable
|
|
3
|
+
*
|
|
4
|
+
* Tracks symbols (definitions and references) in the document.
|
|
5
|
+
* Enables IDE features like:
|
|
6
|
+
* - Go to definition
|
|
7
|
+
* - Find all references
|
|
8
|
+
* - Rename symbol
|
|
9
|
+
* - Document outline
|
|
10
|
+
*
|
|
11
|
+
* In BBCode, symbols include:
|
|
12
|
+
* - [id=hero] → Definition
|
|
13
|
+
* - [goto=hero] → Reference
|
|
14
|
+
* - Named anchors and targets
|
|
15
|
+
*/
|
|
16
|
+
import { RedNode } from '../Syntax/RedNode';
|
|
17
|
+
import type { SymbolInfo, SymbolSearchResult } from '../Types/symbols';
|
|
18
|
+
export declare class SymbolTable {
|
|
19
|
+
private symbols;
|
|
20
|
+
private nodeToSymbolId;
|
|
21
|
+
/**
|
|
22
|
+
* Build the symbol table from a RedNode tree.
|
|
23
|
+
*/
|
|
24
|
+
build(root: RedNode): void;
|
|
25
|
+
/**
|
|
26
|
+
* Get a symbol by name.
|
|
27
|
+
*/
|
|
28
|
+
get(name: string): SymbolInfo | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Get the symbol associated with a node.
|
|
31
|
+
*/
|
|
32
|
+
getSymbolForNode(nodeId: string): SymbolInfo | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Search for symbols by name.
|
|
35
|
+
*/
|
|
36
|
+
search(query: string, maxResults?: number): SymbolSearchResult[];
|
|
37
|
+
/**
|
|
38
|
+
* Get all symbols.
|
|
39
|
+
*/
|
|
40
|
+
getAll(): SymbolInfo[];
|
|
41
|
+
/**
|
|
42
|
+
* Clear all symbols.
|
|
43
|
+
*/
|
|
44
|
+
clear(): void;
|
|
45
|
+
private addSymbol;
|
|
46
|
+
private createSymbolId;
|
|
47
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SymbolTable } from './SymbolTable';
|