@seekbuddy/dsh-ui 0.0.0-stage → 0.2.0-beta.1
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/CHANGELOG.md +83 -0
- package/LICENSE +22 -0
- package/README.md +175 -2
- package/README.zh.md +176 -0
- package/THIRD_PARTY_NOTICES.md +42 -0
- package/UPSTREAM.md +59 -0
- package/dist/blocks.js +1617 -0
- package/dist/chunks/chunk-23KOEBWJ.js +104 -0
- package/dist/chunks/chunk-6SGSJ5KW.js +57 -0
- package/dist/chunks/chunk-7NH2UOZO.js +155 -0
- package/dist/chunks/chunk-7SKW4S35.js +66 -0
- package/dist/chunks/chunk-B3EEK7A2.js +408 -0
- package/dist/chunks/chunk-CEBTQO6W.js +24 -0
- package/dist/chunks/chunk-ENKPNYOB.js +26 -0
- package/dist/chunks/chunk-EWAZFWLW.js +27 -0
- package/dist/chunks/chunk-F352IICS.js +57 -0
- package/dist/chunks/chunk-FFJ6TCCF.js +31 -0
- package/dist/chunks/chunk-FZXK4LTI.js +129 -0
- package/dist/chunks/chunk-JA3XDLIA.js +1115 -0
- package/dist/chunks/chunk-L7XALG4J.js +36 -0
- package/dist/chunks/chunk-OCAQFVT3.js +3172 -0
- package/dist/chunks/chunk-RAXDA2PT.js +202 -0
- package/dist/chunks/chunk-RNVSCTW7.js +24 -0
- package/dist/chunks/chunk-RZOP2PFC.js +152 -0
- package/dist/chunks/chunk-SN6RSUWC.js +61 -0
- package/dist/chunks/chunk-SNVSQWCU.js +22 -0
- package/dist/chunks/chunk-SO3DCAWG.js +170 -0
- package/dist/chunks/chunk-UAEFKTV3.js +144 -0
- package/dist/chunks/chunk-UGEORMLD.js +89 -0
- package/dist/chunks/chunk-W6FLI3AK.js +112 -0
- package/dist/chunks/chunk-WX46TSKP.js +328 -0
- package/dist/chunks/chunk-XL33IPCV.js +261 -0
- package/dist/chunks/chunk-XW4L4ZGL.js +967 -0
- package/dist/chunks/chunk-YOBY6PSL.js +850 -0
- package/dist/chunks/chunk-ZA47FP7C.js +7 -0
- package/dist/icons.js +859 -0
- package/dist/index.js +1675 -0
- package/dist/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/dist/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/dist/katex.css +1 -0
- package/dist/katex.css.d.ts +2 -0
- package/dist/markdown.js +225 -0
- package/dist/meta.json +7575 -0
- package/dist/root-inputs.json +86 -0
- package/dist/seekbuddy-card.js +7 -0
- package/dist/seekbuddy-empty.js +8 -0
- package/dist/seekbuddy-internal/DangerButton.js +7 -0
- package/dist/seekbuddy-internal/Mark.js +7 -0
- package/dist/seekbuddy-internal/Message.js +10 -0
- package/dist/seekbuddy-internal/Pagination.js +9 -0
- package/dist/seekbuddy-internal/StatusBadge.js +7 -0
- package/dist/seekbuddy-internal/SubtleButton.js +7 -0
- package/dist/seekbuddy-internal/Switch.js +7 -0
- package/dist/seekbuddy-internal/Upload.js +7 -0
- package/dist/seekbuddy-internal/date/Calendar.js +8 -0
- package/dist/seekbuddy-internal/date/DatePicker.js +9 -0
- package/dist/seekbuddy-internal/date/DateRangePicker.js +9 -0
- package/dist/seekbuddy-internal/date/TimePicker.js +8 -0
- package/dist/seekbuddy-internal/date/fields.js +16 -0
- package/dist/seekbuddy-internal/qr/QrCode.js +7 -0
- package/dist/seekbuddy-spinner.js +7 -0
- package/dist/seekbuddy-tabs.js +7 -0
- package/dist/seekbuddy-timeline.js +8 -0
- package/dist/seekbuddy.js +89 -0
- package/dist/theme-bootstrap.js +13 -0
- package/dist/theme.js +37 -0
- package/dist/tokens.css +974 -0
- package/dist/tokens.css.d.ts +2 -0
- package/dist/types/AnimatedRows.d.ts +45 -0
- package/dist/types/Button.d.ts +18 -0
- package/dist/types/Checkbox.d.ts +19 -0
- package/dist/types/CodeFileIcon.d.ts +11 -0
- package/dist/types/CodeToolbar.d.ts +29 -0
- package/dist/types/CommandText.d.ts +15 -0
- package/dist/types/ConfigField.d.ts +32 -0
- package/dist/types/ConnectionIndicator.d.ts +25 -0
- package/dist/types/DetailDocument.d.ts +77 -0
- package/dist/types/DiffBlock.d.ts +51 -0
- package/dist/types/DisclosureRow.d.ts +37 -0
- package/dist/types/DraggableImage.d.ts +18 -0
- package/dist/types/FileTypeIcon.d.ts +42 -0
- package/dist/types/FoldToggle.d.ts +19 -0
- package/dist/types/HoverCard.d.ts +44 -0
- package/dist/types/HoverCardGroup.d.ts +24 -0
- package/dist/types/ImageLightbox.d.ts +29 -0
- package/dist/types/ImagePreview.d.ts +11 -0
- package/dist/types/InlineEditor.d.ts +22 -0
- package/dist/types/Input.d.ts +11 -0
- package/dist/types/JsonTree.d.ts +58 -0
- package/dist/types/LinkIcon.d.ts +33 -0
- package/dist/types/Menu.d.ts +163 -0
- package/dist/types/MenuGroup.d.ts +21 -0
- package/dist/types/MenuSurface.d.ts +24 -0
- package/dist/types/Modal.d.ts +43 -0
- package/dist/types/PermissionIcon.d.ts +50 -0
- package/dist/types/Pill.d.ts +12 -0
- package/dist/types/QuotePreview.d.ts +23 -0
- package/dist/types/ReadBlock.d.ts +47 -0
- package/dist/types/ReferenceIcon.d.ts +20 -0
- package/dist/types/RiskConfirmation.d.ts +19 -0
- package/dist/types/SearchBlock.d.ts +71 -0
- package/dist/types/SegmentedControl.d.ts +34 -0
- package/dist/types/SegmentedTabs.d.ts +27 -0
- package/dist/types/ShortcutKeys.d.ts +10 -0
- package/dist/types/SiteGlyph.d.ts +24 -0
- package/dist/types/StateDot.d.ts +19 -0
- package/dist/types/Switch.d.ts +19 -0
- package/dist/types/Tag.d.ts +31 -0
- package/dist/types/TerminalBlock.d.ts +85 -0
- package/dist/types/TextShimmer.d.ts +22 -0
- package/dist/types/Toast.d.ts +48 -0
- package/dist/types/Tooltip.d.ts +69 -0
- package/dist/types/UserMessageBubble.d.ts +10 -0
- package/dist/types/WebBlock.d.ts +60 -0
- package/dist/types/ZoomControls.d.ts +26 -0
- package/dist/types/ansi.d.ts +16 -0
- package/dist/types/blocks.d.ts +21 -0
- package/dist/types/clipboard.d.ts +8 -0
- package/dist/types/code-file-icon-artwork.d.ts +53 -0
- package/dist/types/code-file-types.d.ts +29 -0
- package/dist/types/code-highlighting.d.ts +11 -0
- package/dist/types/css-modules.d.ts +6 -0
- package/dist/types/darwin-desktop.d.ts +8 -0
- package/dist/types/document-zoom.d.ts +16 -0
- package/dist/types/file-drag-actions.d.ts +36 -0
- package/dist/types/file-size.d.ts +7 -0
- package/dist/types/focus.d.ts +15 -0
- package/dist/types/guide-artwork.d.ts +14 -0
- package/dist/types/head-tail-cap.d.ts +22 -0
- package/dist/types/icons/artwork.d.ts +421 -0
- package/dist/types/icons/index.d.ts +397 -0
- package/dist/types/icons/props.d.ts +8 -0
- package/dist/types/icons/shared-artwork.d.ts +36 -0
- package/dist/types/icons.d.ts +6 -0
- package/dist/types/image-drag.d.ts +16 -0
- package/dist/types/index.d.ts +71 -0
- package/dist/types/input-modality.d.ts +18 -0
- package/dist/types/keyboard-composition.d.ts +10 -0
- package/dist/types/markdown/CodeBlock.d.ts +34 -0
- package/dist/types/markdown/JsonBlock.d.ts +7 -0
- package/dist/types/markdown/MarkdownDelegate.d.ts +68 -0
- package/dist/types/markdown/MarkdownText.d.ts +54 -0
- package/dist/types/markdown/cjkFriendlyStrong.d.ts +8 -0
- package/dist/types/markdown/file-link.d.ts +22 -0
- package/dist/types/markdown/highlight.d.ts +169 -0
- package/dist/types/markdown/incremental.d.ts +79 -0
- package/dist/types/markdown/katex.d.ts +18 -0
- package/dist/types/markdown/local-image-syntax.d.ts +9 -0
- package/dist/types/markdown/mathCompatibility.d.ts +10 -0
- package/dist/types/markdown/parse.d.ts +24 -0
- package/dist/types/markdown/plain-text.d.ts +21 -0
- package/dist/types/markdown/quote-text.d.ts +7 -0
- package/dist/types/markdown/render.d.ts +145 -0
- package/dist/types/markdown/useViewportHighlighting.d.ts +10 -0
- package/dist/types/markdown/windows-path-destinations.d.ts +10 -0
- package/dist/types/markdown.d.ts +12 -0
- package/dist/types/overlay-top-margin.d.ts +14 -0
- package/dist/types/plugin-artwork.d.ts +16 -0
- package/dist/types/pointer-grace.d.ts +21 -0
- package/dist/types/rank-by-name.d.ts +21 -0
- package/dist/types/relative-time.d.ts +22 -0
- package/dist/types/seekbuddy/Card.d.ts +28 -0
- package/dist/types/seekbuddy/DangerButton.d.ts +31 -0
- package/dist/types/seekbuddy/Empty.d.ts +34 -0
- package/dist/types/seekbuddy/Mark.d.ts +27 -0
- package/dist/types/seekbuddy/Message.d.ts +52 -0
- package/dist/types/seekbuddy/Pagination.d.ts +66 -0
- package/dist/types/seekbuddy/Spinner.d.ts +20 -0
- package/dist/types/seekbuddy/StatusBadge.d.ts +33 -0
- package/dist/types/seekbuddy/SubtleButton.d.ts +30 -0
- package/dist/types/seekbuddy/Switch.d.ts +36 -0
- package/dist/types/seekbuddy/Tabs.d.ts +49 -0
- package/dist/types/seekbuddy/Timeline.d.ts +42 -0
- package/dist/types/seekbuddy/Upload.d.ts +101 -0
- package/dist/types/seekbuddy/date/Calendar.d.ts +94 -0
- package/dist/types/seekbuddy/date/DatePicker.d.ts +29 -0
- package/dist/types/seekbuddy/date/DateRangePicker.d.ts +41 -0
- package/dist/types/seekbuddy/date/TimePicker.d.ts +35 -0
- package/dist/types/seekbuddy/date/date.d.ts +79 -0
- package/dist/types/seekbuddy/date/fields.d.ts +45 -0
- package/dist/types/seekbuddy/index.d.ts +49 -0
- package/dist/types/seekbuddy/qr/QrCode.d.ts +37 -0
- package/dist/types/seekbuddy/qr/qr.d.ts +38 -0
- package/dist/types/theme-bootstrap.d.ts +3 -0
- package/dist/types/theme-core.d.ts +14 -0
- package/dist/types/theme.d.ts +4 -0
- package/dist/types/tooltip-placement.d.ts +34 -0
- package/dist/types/use-clipboard-copy.d.ts +13 -0
- package/dist/types/useAnchoredMaxHeight.d.ts +13 -0
- package/dist/types/useAnchoredPosition.d.ts +35 -0
- package/dist/types/useDismissOnOutsidePointer.d.ts +10 -0
- package/dist/types/useModalLayer.d.ts +26 -0
- package/dist/types/useRowDragPreview.d.ts +19 -0
- package/dist/types/user-text.d.ts +31 -0
- package/package.json +151 -4
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import type { FileDragActions } from '../file-drag-actions.js';
|
|
3
|
+
import type { ImageLightboxLabels } from '../ImageLightbox.js';
|
|
4
|
+
/**
|
|
5
|
+
* Handle one sanitized absolute HTTP(S) URL selected from Markdown.
|
|
6
|
+
* @param href - destination URL.
|
|
7
|
+
*/
|
|
8
|
+
export type MarkdownExternalLinkHandler = (href: string) => void;
|
|
9
|
+
/** Explicit object and viewport coordinates from the element owning a context gesture. */
|
|
10
|
+
export type MarkdownMenuTarget = {
|
|
11
|
+
kind: 'file';
|
|
12
|
+
path: string;
|
|
13
|
+
line?: number;
|
|
14
|
+
} | {
|
|
15
|
+
kind: 'url';
|
|
16
|
+
url: string;
|
|
17
|
+
} | {
|
|
18
|
+
kind: 'image';
|
|
19
|
+
url: string;
|
|
20
|
+
path?: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
mediaType?: string;
|
|
23
|
+
};
|
|
24
|
+
/** Navigation capabilities supplied by the nearest Markdown owner. */
|
|
25
|
+
export interface MarkdownDelegate {
|
|
26
|
+
/** Open an object menu without executing its normal activation. */
|
|
27
|
+
readonly getTriggerProps?: ((target: MarkdownMenuTarget) => Pick<HTMLAttributes<HTMLElement>, 'onContextMenu' | 'onKeyDown' | 'tabIndex'>) | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Image previews for decoded local paths in this owner's workspace. The renderer
|
|
30
|
+
* appends a per-mount `load` query parameter to `api/file` route URLs.
|
|
31
|
+
*/
|
|
32
|
+
readonly fileImages?: {
|
|
33
|
+
fileDrag: FileDragActions;
|
|
34
|
+
resolve: (path: string) => string | undefined;
|
|
35
|
+
resourceAddress?: ((path: string) => string) | undefined;
|
|
36
|
+
labels: ImageLightboxLabels & {
|
|
37
|
+
open: string;
|
|
38
|
+
loading: string;
|
|
39
|
+
failed: string;
|
|
40
|
+
};
|
|
41
|
+
} | undefined;
|
|
42
|
+
/** Ordinary HTTP(S) activation; absent handlers retain native anchor behavior. */
|
|
43
|
+
readonly openExternalLink?: MarkdownExternalLinkHandler | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Open a decoded local destination from settled Markdown; absent handlers leave plain text.
|
|
46
|
+
* @param path - Absolute or workspace-relative file path.
|
|
47
|
+
* @param options - First line to reveal when the destination specifies a line or range.
|
|
48
|
+
*/
|
|
49
|
+
readonly openFile?: ((path: string, options?: {
|
|
50
|
+
line?: number;
|
|
51
|
+
}) => void) | undefined;
|
|
52
|
+
}
|
|
53
|
+
/** Props for one Markdown navigation scope. */
|
|
54
|
+
export interface MarkdownDelegateProviderProps extends MarkdownDelegate {
|
|
55
|
+
readonly children: ReactNode;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Scope Markdown navigation without threading callbacks through renderers.
|
|
59
|
+
* Nested providers replace the enclosing capabilities. Handler changes reach cached links.
|
|
60
|
+
* @param props - Child tree and its file and HTTP(S) link handlers.
|
|
61
|
+
* @returns the scoped child tree.
|
|
62
|
+
*/
|
|
63
|
+
export declare function MarkdownDelegateProvider({ children, openExternalLink, openFile, fileImages, getTriggerProps, }: MarkdownDelegateProviderProps): ReactNode;
|
|
64
|
+
/**
|
|
65
|
+
* Read the nearest Markdown navigation capabilities.
|
|
66
|
+
* @returns Owner callbacks, or an empty delegate outside a provider.
|
|
67
|
+
*/
|
|
68
|
+
export declare function useMarkdownDelegate(): MarkdownDelegate;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Untrusted assistant-Markdown renderer over the direct mdast pipeline:
|
|
3
|
+
* `parse.ts` grammars, the incremental streaming parser, and `render.tsx`.
|
|
4
|
+
* While a message streams, all but the trailing two blocks freeze as cached
|
|
5
|
+
* React elements and only the source tail behind them re-parses per chunk,
|
|
6
|
+
* so per-chunk work tracks the tail size instead of the whole reply. Frozen
|
|
7
|
+
* blocks keep their source-offset keys when they cross the freeze boundary,
|
|
8
|
+
* so React reconciles instead of remounting. Known deviation while
|
|
9
|
+
* streaming: a reference-style link or footnote whose definition sits on the
|
|
10
|
+
* other side of the freeze boundary renders literally until the settled
|
|
11
|
+
* full parse self-heals it.
|
|
12
|
+
*/
|
|
13
|
+
import type { MarkdownFileMentions, MarkdownLabels, MarkdownPathImages } from './render.js';
|
|
14
|
+
export type { MarkdownCodeLabels, MarkdownFileMentions, MarkdownLabels, MarkdownPathImages } from './render.js';
|
|
15
|
+
/**
|
|
16
|
+
* Render untrusted assistant-authored Markdown as semantic React elements.
|
|
17
|
+
* @param props - Markdown source text preserved by the session projection;
|
|
18
|
+
* `streaming` parses incrementally across chunks and highlights fences as
|
|
19
|
+
* they grow (each fence re-tokenizes only appended text; TeX stays literal
|
|
20
|
+
* until the finalize swap so incomplete formulae never flash errors);
|
|
21
|
+
* `labels` forwards localized fence and footnote chrome — pass a
|
|
22
|
+
* reference-stable object (memoized per locale revision), because a new
|
|
23
|
+
* identity discards the streaming render cache mid-message. `fileMentions`
|
|
24
|
+
* links inline-code tokens its resolver recognizes as real files, and
|
|
25
|
+
* `pathImages` rewrites image destinations that are local file paths into
|
|
26
|
+
* displayable URLs its resolver vouches for. Those two vocabularies are the
|
|
27
|
+
* single streaming gate — they apply to settled renders only, because a
|
|
28
|
+
* streaming message's vocabulary is not final and frozen cached elements
|
|
29
|
+
* must not bake in handlers that could go stale. A surrounding
|
|
30
|
+
* `MarkdownDelegateProvider` can delegate ordinary HTTP(S) activation while
|
|
31
|
+
* modified clicks retain native behavior. `variant="compact"` uses secondary
|
|
32
|
+
* text sizing, uniform bold headings, and tight block spacing; the default
|
|
33
|
+
* `body` variant uses the full document typography. `omitHtml` renders raw
|
|
34
|
+
* HTML as nothing instead of literal text, for documents written for HTML
|
|
35
|
+
* renderers, such as package READMEs. `textInteractionSource` marks the
|
|
36
|
+
* existing root as a source for text selection interactions.
|
|
37
|
+
* The provider's `openFile` enables local Markdown links in settled messages,
|
|
38
|
+
* including `#L24` / `#L24-L30` fragments and `:24` / `:24-30` / `:24:5` suffixes
|
|
39
|
+
* (ranges open at their first line, columns are ignored, and invalid locations
|
|
40
|
+
* open only the file; see the README for URL/path classification).
|
|
41
|
+
* @returns A GFM document with TeX math rendered through KaTeX; raw HTML never
|
|
42
|
+
* renders as markup, and unsafe protocols are disabled. Local links without an opener remain text;
|
|
43
|
+
* absolute HTTP(S) images render directly.
|
|
44
|
+
*/
|
|
45
|
+
export declare const MarkdownText: import("react").MemoExoticComponent<({ text, streaming, labels, fileMentions, pathImages, variant, omitHtml, textInteractionSource, }: {
|
|
46
|
+
text: string;
|
|
47
|
+
streaming?: boolean;
|
|
48
|
+
labels: MarkdownLabels;
|
|
49
|
+
fileMentions?: MarkdownFileMentions | undefined;
|
|
50
|
+
pathImages?: MarkdownPathImages | undefined;
|
|
51
|
+
variant?: 'body' | 'compact';
|
|
52
|
+
omitHtml?: boolean;
|
|
53
|
+
textInteractionSource?: boolean;
|
|
54
|
+
}) => import("react").JSX.Element>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Let asterisk strong emphasis close after punctuation when CJK prose continues without whitespace. */
|
|
2
|
+
import type { Extension } from 'micromark-util-types';
|
|
3
|
+
/**
|
|
4
|
+
* Extend CommonMark asterisk strong emphasis for punctuation-delimited CJK
|
|
5
|
+
* prose, as a micromark syntax extension for `fromMarkdown`.
|
|
6
|
+
* @returns The micromark syntax extension.
|
|
7
|
+
*/
|
|
8
|
+
export declare function cjkFriendlyStrong(): Extension;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Local Markdown destinations accepted by the file-preview callback. */
|
|
2
|
+
/**
|
|
3
|
+
* Recognize a relative, rooted, or absolute Windows path before URL parsing.
|
|
4
|
+
* @param value - A decoded or URI-normalized destination.
|
|
5
|
+
* @returns Whether a filesystem prefix makes the destination unambiguous.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isExplicitFilePath(value: string): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Decode a file destination with a fragment, line range, or line/column suffix.
|
|
10
|
+
* Explicit relative, slash/backslash-rooted, and Windows drive paths take
|
|
11
|
+
* precedence over URLs. Other parseable absolute URLs are not file links.
|
|
12
|
+
* Fragments take precedence over colon suffixes; invalid locations open the
|
|
13
|
+
* file without selecting a line. Columns are consumed but not selected.
|
|
14
|
+
* Percent-encode literal `?`, `#`, and numeric colon suffixes in filenames.
|
|
15
|
+
* @param value - Parsed Markdown link destination.
|
|
16
|
+
* @returns A local path and optional first line, or undefined for URLs,
|
|
17
|
+
* fragment-only links, queries, malformed escapes, or control characters.
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseFileLink(value: string): {
|
|
20
|
+
path: string;
|
|
21
|
+
line?: number;
|
|
22
|
+
} | undefined;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The client's ONE syntax highlighter: a synchronous fine-grained shiki core
|
|
3
|
+
* (JavaScript regex engine — no oniguruma WASM, bundle-friendly) with an
|
|
4
|
+
* explicit grammar allowlist and a CSS-variables theme. Colors live in the
|
|
5
|
+
* theme package's token sheets as `--shiki-*` custom properties (light and
|
|
6
|
+
* dark blocks), never here — the repo's tokens-only styling rule.
|
|
7
|
+
*
|
|
8
|
+
* Only the three markdown-fence and `run_code` grammars (TypeScript, shell,
|
|
9
|
+
* JSON) load into the singleton at boot — the set every session renders. Every
|
|
10
|
+
* other language in the shared extension table
|
|
11
|
+
* (`@deepseek-ai/dsh-util-code-language`: python, rust, yaml, markup, …) is
|
|
12
|
+
* imported lazily and registered the first time such a language is requested,
|
|
13
|
+
* so a session that never opens a code surface in one of those languages pays
|
|
14
|
+
* neither the grammar modules nor their synchronous init. The first render of a
|
|
15
|
+
* lazy language falls back to plain text while its grammar loads, then
|
|
16
|
+
* {@link onGrammarLoaded} notifies subscribers to re-render with highlighting.
|
|
17
|
+
* An unknown or absent language falls back to plain text (no highlighting, still
|
|
18
|
+
* monospace) — never an error.
|
|
19
|
+
*/
|
|
20
|
+
import langTs from '@shikijs/langs/typescript';
|
|
21
|
+
import type { CSSProperties } from 'react';
|
|
22
|
+
/** A shiki grammar module's default export (a `LanguageRegistration[]`), taken
|
|
23
|
+
* from a boot grammar so no direct `@shikijs/types` dependency is needed. */
|
|
24
|
+
type LangModule = {
|
|
25
|
+
default: typeof langTs;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Replace the Go grammar's repeated one-line struct-field rule with the rule
|
|
29
|
+
* worlpaker/go-syntax merged in 4a9b120a52c (https://github.com/worlpaker/go-syntax/pull/25):
|
|
30
|
+
* the repeated rule backtracks exponentially on lines such as a brace-bearing
|
|
31
|
+
* comment after `struct {`. Delete this patch once `@shikijs/langs` ships that
|
|
32
|
+
* commit; 4.5.0 does not. The rule is located as the only rule in
|
|
33
|
+
* `struct_variables_types_fields` containing the field-token literal below,
|
|
34
|
+
* taken from `@shikijs/langs` 4.4.3.
|
|
35
|
+
* @param grammars - the `@shikijs/langs/go` default export, left unmodified.
|
|
36
|
+
* @returns copies of `grammars` with that rule's match replaced in the `go` grammar.
|
|
37
|
+
* @throws When the module has no `go` grammar, the grammar lacks
|
|
38
|
+
* `struct_variables_types_fields`, or that entry has no or several such rules.
|
|
39
|
+
* The lazy load then rejects unhandled and Go code renders as plain text.
|
|
40
|
+
*/
|
|
41
|
+
export declare function patchGoGrammar(grammars: LangModule['default']): LangModule['default'];
|
|
42
|
+
/**
|
|
43
|
+
* Resolve a language hint to the grammar id {@link LANG_ALIASES} selects.
|
|
44
|
+
* @param lang - Language hint from a code surface: a canonical grammar id or the read card's persisted short id.
|
|
45
|
+
* @returns The resolved grammar id, or `undefined` when the table aliases no grammar.
|
|
46
|
+
*/
|
|
47
|
+
export declare function grammarForHint(lang: string | undefined): string | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Whether a language hint can use the shared syntax highlighter.
|
|
50
|
+
* @param lang - Language hint from a code surface.
|
|
51
|
+
* @returns Whether the hint resolves to a supported grammar.
|
|
52
|
+
*/
|
|
53
|
+
export declare function supportsHighlighting(lang: string | undefined): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Subscribe to lazy-grammar load completions; `listener` fires after a
|
|
56
|
+
* {@link LAZY_GRAMMARS} grammar finishes registering on the singleton, so a
|
|
57
|
+
* caller that rendered its plain fallback while the grammar loaded can
|
|
58
|
+
* re-highlight. Uses the `useSyncExternalStore` subscribe signature; pair it with
|
|
59
|
+
* {@link grammarLoadCount} as the snapshot. Returns an unsubscribe function.
|
|
60
|
+
* @param listener - invoked (no args) on each grammar-load completion.
|
|
61
|
+
* @returns a disposer that removes the listener.
|
|
62
|
+
*/
|
|
63
|
+
export declare function subscribeGrammarLoaded(listener: () => void): () => void;
|
|
64
|
+
/**
|
|
65
|
+
* The lazy-grammar load counter — a value that changes on every load, so a
|
|
66
|
+
* `useSyncExternalStore` snapshot re-renders the subscriber when a grammar
|
|
67
|
+
* registers. Opaque: only its identity across renders matters.
|
|
68
|
+
* @returns the current load count.
|
|
69
|
+
*/
|
|
70
|
+
export declare function grammarLoadCount(): number;
|
|
71
|
+
/**
|
|
72
|
+
* Highlight `code` into shiki's HTML (a single `<pre class="shiki">` tree)
|
|
73
|
+
* when `lang` maps to a registered grammar; `undefined` means the caller
|
|
74
|
+
* renders its plain fallback. A lazy grammar not yet loaded returns `undefined`
|
|
75
|
+
* for this call and loads in the background; subscribe with
|
|
76
|
+
* {@link onGrammarLoaded} to re-highlight once it registers.
|
|
77
|
+
* @param code - the source text.
|
|
78
|
+
* @param lang - the language hint (a markdown fence info string or a fixed caller id).
|
|
79
|
+
* @returns the highlighted HTML, or `undefined` for unknown or not-yet-loaded languages.
|
|
80
|
+
*/
|
|
81
|
+
export declare function highlightToHtml(code: string, lang: string | undefined): string | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* One highlighted run of a line: the text and the inline style shiki assigned
|
|
84
|
+
* it. The css-variables theme colors every run through a `--shiki-*` custom
|
|
85
|
+
* property, so `style.color` is always present; it is held as a style object
|
|
86
|
+
* rather than a bare color so a run spreads onto a `<span style>` uniformly.
|
|
87
|
+
*/
|
|
88
|
+
export interface HighlightSpan {
|
|
89
|
+
text: string;
|
|
90
|
+
style: CSSProperties;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Incremental highlighter for one growing streaming fence. TextMate
|
|
94
|
+
* tokenization is line-based and forward-only — a line's tokens depend only on
|
|
95
|
+
* its own text and the grammar state entering it — so appended text never
|
|
96
|
+
* changes a completed line's tokens. The session caches the spans of every
|
|
97
|
+
* completed line together with the grammar state after them;
|
|
98
|
+
* {@link updateFrame} reports only newly completed lines plus the still-growing
|
|
99
|
+
* last line, while {@link update} materializes the complete compatibility
|
|
100
|
+
* result. Per-call tokenization cost therefore excludes the completed prefix,
|
|
101
|
+
* and the result equals a from-scratch tokenization of the same code.
|
|
102
|
+
* Non-append input and a change of resolved grammar reset the cache and
|
|
103
|
+
* re-tokenize fully, so any input stays correct.
|
|
104
|
+
*/
|
|
105
|
+
export declare class StreamingHighlightSession {
|
|
106
|
+
/** Grammar id the cache was built with; a different resolution resets it. */
|
|
107
|
+
private resolved;
|
|
108
|
+
/** Newline-terminated source prefix covered by {@link spans}. */
|
|
109
|
+
private prefix;
|
|
110
|
+
/** Cached spans, one entry per completed line of {@link prefix}. */
|
|
111
|
+
private spans;
|
|
112
|
+
/** Grammar state after {@link prefix}; undefined = the grammar's initial state. */
|
|
113
|
+
private state;
|
|
114
|
+
private lastCode;
|
|
115
|
+
private lastLang;
|
|
116
|
+
private lastResult;
|
|
117
|
+
private generation;
|
|
118
|
+
private lastFrame;
|
|
119
|
+
private reset;
|
|
120
|
+
/** Tokenize `text` with `resolved`, resuming from the cached grammar state when one exists. */
|
|
121
|
+
private tokenize;
|
|
122
|
+
/**
|
|
123
|
+
* Tokenize one update as a delta for a retained renderer.
|
|
124
|
+
* @param code - the fence text accumulated so far.
|
|
125
|
+
* @param lang - the language hint.
|
|
126
|
+
* @returns Newly completed lines plus the current tail, or `undefined` for the plain arm.
|
|
127
|
+
*/
|
|
128
|
+
updateFrame(code: string, lang: string | undefined): StreamingHighlightFrame | undefined;
|
|
129
|
+
/**
|
|
130
|
+
* Tokenize the fence's current text into per-line highlighted runs;
|
|
131
|
+
* `undefined` means the caller renders its plain fallback. Idempotent per
|
|
132
|
+
* (`code`, `lang`) input — repeated calls return the identical result array —
|
|
133
|
+
* and a retained line keeps its span-array identity across growing calls, so
|
|
134
|
+
* a React caller can reuse cached line elements. A lazy grammar not yet
|
|
135
|
+
* loaded returns `undefined` and loads in the background exactly as
|
|
136
|
+
* {@link highlightToHtml} does; the next call after it registers highlights.
|
|
137
|
+
* @param code - the fence text accumulated so far (display-trimmed, no synthetic trailing newline).
|
|
138
|
+
* @param lang - the language hint (a markdown fence info string).
|
|
139
|
+
* @returns one entry per line of `code` (each an array of runs), or `undefined` for unknown or not-yet-loaded languages.
|
|
140
|
+
*/
|
|
141
|
+
update(code: string, lang: string | undefined): readonly HighlightSpan[][] | undefined;
|
|
142
|
+
}
|
|
143
|
+
/** One retained-renderer update from {@link StreamingHighlightSession.updateFrame}. */
|
|
144
|
+
export interface StreamingHighlightFrame {
|
|
145
|
+
/** Changes whenever prior completed lines must be discarded. */
|
|
146
|
+
readonly generation: number;
|
|
147
|
+
/** Completed lines added since the preceding frame in this generation. */
|
|
148
|
+
readonly appended: readonly HighlightSpan[][];
|
|
149
|
+
/** The still-growing final line or lines, replaced by the next frame. */
|
|
150
|
+
readonly tail: readonly HighlightSpan[][];
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Tokenize `code` into per-line highlighted runs when `lang` maps to a
|
|
154
|
+
* registered grammar; `undefined` means the caller renders its plain fallback.
|
|
155
|
+
* A line-numbered view needs the token runs split per line (one gutter number
|
|
156
|
+
* per line), which the single-`<pre>` {@link highlightToHtml} does not expose,
|
|
157
|
+
* so this returns shiki's own 2D line/token structure narrowed to what a run
|
|
158
|
+
* renders. Each run's color is a `--shiki-*` custom property, keeping token
|
|
159
|
+
* colors on the theme package's sheets exactly as the HTML path does; the
|
|
160
|
+
* markup font-style bits the theme lets through (bold/italic/underline in
|
|
161
|
+
* markdown scopes) are dropped — the line-numbered file view renders
|
|
162
|
+
* color-only runs. The trailing newline shiki appends as a final empty line
|
|
163
|
+
* is dropped so the run count matches the caller's own line array.
|
|
164
|
+
* @param code - the source text.
|
|
165
|
+
* @param lang - the language hint (a file-extension-derived language id).
|
|
166
|
+
* @returns one entry per source line (each an array of runs), or `undefined` for unknown or not-yet-loaded languages.
|
|
167
|
+
*/
|
|
168
|
+
export declare function highlightLines(code: string, lang: string | undefined): HighlightSpan[][] | undefined;
|
|
169
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Incremental block-level markdown parsing for an append-only text stream.
|
|
3
|
+
*
|
|
4
|
+
* Re-parsing the whole accumulated document on every streaming chunk is
|
|
5
|
+
* quadratic in the final reply length. CommonMark block parsing is line-based
|
|
6
|
+
* and appended text can only reshape the parse frontier — the last top-level
|
|
7
|
+
* block (a paragraph becoming a setext heading or a table, or a list
|
|
8
|
+
* continuing after a blank line) — so earlier blocks are final. This parser
|
|
9
|
+
* therefore freezes all but the trailing {@link UNSTABLE_TAIL_BLOCKS} blocks
|
|
10
|
+
* and re-parses only the source tail behind them. A final unclosed top-level
|
|
11
|
+
* fence cannot freeze as a block, so its completed content lines use a second
|
|
12
|
+
* frontier: only the last completed line and current partial line return
|
|
13
|
+
* through the caller's grammar. Each source region is therefore parsed a
|
|
14
|
+
* bounded number of times over the stream instead of once per chunk.
|
|
15
|
+
*
|
|
16
|
+
* The block freeze boundary comes from the parser's own `position` offsets.
|
|
17
|
+
* The cut sits at the *end offset* of the last frozen block (not the next
|
|
18
|
+
* block's start): a following block's start offset excludes up to three spaces
|
|
19
|
+
* of insignificant leading indentation, which is harmless to drop, but
|
|
20
|
+
* cutting at the previous end also keeps the inter-block blank lines in the
|
|
21
|
+
* tail so the sliced source stays verbatim. Fence scanning only recognizes a
|
|
22
|
+
* parser-confirmed code node and closing delimiter; ambiguous input returns to
|
|
23
|
+
* the normal tail parse.
|
|
24
|
+
*
|
|
25
|
+
* Known deviation, shared with any prefix-freeze scheme: micromark resolves
|
|
26
|
+
* reference-style links and footnotes document-wide at parse time, so a
|
|
27
|
+
* reference whose definition lands on the other side of the freeze boundary
|
|
28
|
+
* renders literally until the settled full parse self-heals it.
|
|
29
|
+
*/
|
|
30
|
+
import type { Root, RootContent } from 'mdast';
|
|
31
|
+
/** A top-level mdast block plus a render key that is stable across chunks. */
|
|
32
|
+
export interface PositionedBlock {
|
|
33
|
+
/** The parsed block. Positions inside it are relative to its parse slice. */
|
|
34
|
+
readonly node: RootContent;
|
|
35
|
+
/**
|
|
36
|
+
* The block's start offset in the full source text. Stable from the frame
|
|
37
|
+
* a block first appears through freezing, so React reconciles rather than
|
|
38
|
+
* remounts when a block crosses the freeze boundary.
|
|
39
|
+
*/
|
|
40
|
+
readonly key: number;
|
|
41
|
+
}
|
|
42
|
+
/** One {@link IncrementalMarkdownParser.update} result. */
|
|
43
|
+
export interface IncrementalBlocks {
|
|
44
|
+
/** Blocks that can no longer change; grows monotonically per generation. */
|
|
45
|
+
readonly frozen: readonly PositionedBlock[];
|
|
46
|
+
/** The re-parsed unstable tail (at most {@link UNSTABLE_TAIL_BLOCKS} blocks plus growth). */
|
|
47
|
+
readonly tail: readonly PositionedBlock[];
|
|
48
|
+
/** Bumped whenever non-append input discards the frozen prefix; callers drop caches keyed on it. */
|
|
49
|
+
readonly generation: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Append-only incremental parser over a caller-supplied grammar. One instance
|
|
53
|
+
* accumulates one streaming document; non-append input resets it.
|
|
54
|
+
*/
|
|
55
|
+
export declare class IncrementalMarkdownParser {
|
|
56
|
+
private readonly parse;
|
|
57
|
+
private prevText;
|
|
58
|
+
private tailStart;
|
|
59
|
+
private frozen;
|
|
60
|
+
private generation;
|
|
61
|
+
private cached;
|
|
62
|
+
private openFence;
|
|
63
|
+
/** @param parse - Grammar shared with whatever renders the blocks, so boundaries agree. */
|
|
64
|
+
constructor(parse: (text: string) => Root);
|
|
65
|
+
/** Parse one unclosed-fence content slice through the caller's grammar. */
|
|
66
|
+
private fenceValue;
|
|
67
|
+
/** Recognize the parsed tail's final unclosed fence and prepare its incremental content frontier. */
|
|
68
|
+
private openFenceState;
|
|
69
|
+
/** Extend a recognized unclosed fence without parsing its completed content prefix again. */
|
|
70
|
+
private updateOpenFence;
|
|
71
|
+
/**
|
|
72
|
+
* Fold the current accumulated text and return the frozen/tail split.
|
|
73
|
+
* Idempotent for identical input (the previous result is returned as-is),
|
|
74
|
+
* so callers may invoke it from render paths that re-execute.
|
|
75
|
+
* @param text - The full accumulated markdown source.
|
|
76
|
+
* @returns Frozen and tail blocks with stream-stable render keys.
|
|
77
|
+
*/
|
|
78
|
+
update(text: string): IncrementalBlocks;
|
|
79
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TeX-to-React via KaTeX, replicating the rehype-katex pipeline this renderer
|
|
3
|
+
* replaced: the same three-arm error chain (strict render, `strict: 'ignore'`
|
|
4
|
+
* retry, error span). KaTeX emits a static span/MathML/SVG vocabulary with no
|
|
5
|
+
* raw user HTML, the same trusted innerHTML path shiki uses in CodeBlock. The
|
|
6
|
+
* stable wrapper keeps server rendering and hydration identical without a
|
|
7
|
+
* browser-only DOMParser dependency.
|
|
8
|
+
*/
|
|
9
|
+
import type { ReactNode } from 'react';
|
|
10
|
+
/**
|
|
11
|
+
* Render TeX source to React elements through KaTeX.
|
|
12
|
+
* @param value - The TeX source (math node value; fenced `math` blocks append
|
|
13
|
+
* their trailing newline to match the replaced pipeline's text extraction).
|
|
14
|
+
* @param displayMode - Display (block) versus inline rendering.
|
|
15
|
+
* @returns KaTeX's element tree, or the error span when the source does not
|
|
16
|
+
* parse (colored with KaTeX's stock `errorColor`, matching rehype-katex).
|
|
17
|
+
*/
|
|
18
|
+
export declare function renderTexToReact(value: string, displayMode: boolean): ReactNode;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Recover standalone local image references with bare spaces without changing code or source offsets. */
|
|
2
|
+
import type { Root } from 'mdast';
|
|
3
|
+
/**
|
|
4
|
+
* Recover only unambiguous, unescaped image-only paragraphs containing a local path with spaces.
|
|
5
|
+
* @param root - Parsed Markdown tree, modified in place.
|
|
6
|
+
* @param source - Original source used to distinguish authored syntax from escaped examples.
|
|
7
|
+
* @returns The same root with recovered image nodes.
|
|
8
|
+
*/
|
|
9
|
+
export declare function recoverLocalImages(root: Root, source: string): Root;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Extend upstream dollar-only math syntax with TeX delimiters while reusing its token vocabulary. */
|
|
2
|
+
import type { Extension } from 'micromark-util-types';
|
|
3
|
+
/**
|
|
4
|
+
* TeX backslash delimiters and same-line display-dollar blocks as a micromark
|
|
5
|
+
* syntax extension reusing `micromark-extension-math`'s token vocabulary; the
|
|
6
|
+
* caller must also register `math()` on the same parse so the emitted tokens
|
|
7
|
+
* compile to standard math nodes.
|
|
8
|
+
* @returns The micromark syntax extension.
|
|
9
|
+
*/
|
|
10
|
+
export declare function mathCompatibility(): Extension;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The markdown renderer's two mdast grammars, one per rendering arm. Each
|
|
3
|
+
* arm is internally consistent — the incremental tail parses, the one-shot
|
|
4
|
+
* parses, and the plain-text projection of a given grammar always agree on
|
|
5
|
+
* where blocks start and end — and the settled grammar is the streaming one
|
|
6
|
+
* plus the math extensions, so the arms differ only where TeX delimiters
|
|
7
|
+
* begin a math construct (a `$$` block is a paragraph while streaming and a
|
|
8
|
+
* math block once settled, by design).
|
|
9
|
+
*/
|
|
10
|
+
import type { Root } from 'mdast';
|
|
11
|
+
/**
|
|
12
|
+
* Parse GFM markdown (the streaming arm's grammar: no math, so incomplete
|
|
13
|
+
* TeX never flashes KaTeX errors mid-stream).
|
|
14
|
+
* @param text - Markdown source.
|
|
15
|
+
* @returns The mdast root.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseGfm(text: string): Root;
|
|
18
|
+
/**
|
|
19
|
+
* Parse GFM markdown plus TeX math with the compatibility delimiters
|
|
20
|
+
* (the settled arm's grammar).
|
|
21
|
+
* @param text - Markdown source.
|
|
22
|
+
* @returns The mdast root.
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseGfmWithMath(text: string): Root;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown-to-plain-text projection for compact summaries and labels.
|
|
3
|
+
* Parsing shares the renderer's streaming GFM grammar ({@link parseGfm}), so
|
|
4
|
+
* the projection strips exactly the markup the renderer would draw; raw HTML
|
|
5
|
+
* stays literal, links keep their labels, images keep alt text, and code
|
|
6
|
+
* keeps its source text.
|
|
7
|
+
*/
|
|
8
|
+
/** Amount of parsed Markdown content returned by the extractor. */
|
|
9
|
+
export type MarkdownPlainTextMode = 'all' | 'first-line' | 'first-paragraph';
|
|
10
|
+
/** Options for {@link extractMarkdownPlainText}. */
|
|
11
|
+
export interface MarkdownPlainTextOptions {
|
|
12
|
+
/** Projection boundary; defaults to the complete document. */
|
|
13
|
+
mode?: MarkdownPlainTextMode;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Parse GFM Markdown, remove its presentation markup, and preserve raw HTML literally.
|
|
17
|
+
* @param markdown - Markdown source.
|
|
18
|
+
* @param options - Optional extraction boundary.
|
|
19
|
+
* @returns Plain text for the whole document, first visible line, or first semantic paragraph.
|
|
20
|
+
*/
|
|
21
|
+
export declare function extractMarkdownPlainText(markdown: string, options?: MarkdownPlainTextOptions): string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Shared Markdown blockquote formatting for browser text. */
|
|
2
|
+
/**
|
|
3
|
+
* Project selected visible text as an ordinary Markdown blockquote.
|
|
4
|
+
* @param text - selected visible text without quote markers.
|
|
5
|
+
* @returns one `> `-prefixed line per normalized input line.
|
|
6
|
+
*/
|
|
7
|
+
export declare function formatQuoteText(text: string): string;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direct mdast→React markdown renderer. Replaces the react-markdown /
|
|
3
|
+
* remark-rehype pipeline with one switch over parsed nodes so streaming can
|
|
4
|
+
* cache frozen blocks as React elements; the rendered DOM is pinned
|
|
5
|
+
* byte-for-byte by `tests/fixtures/markdown-dom` and must not drift.
|
|
6
|
+
*
|
|
7
|
+
* External links reject executable and embedded-document protocols; settled
|
|
8
|
+
* local file links use an explicit owner callback. Images additionally require
|
|
9
|
+
* absolute HTTP(S), raw HTML renders as literal text (no HTML enters the
|
|
10
|
+
* DOM), and KaTeX runs without trusted commands. Fragment-only URLs are not
|
|
11
|
+
* absolute, so footnote references and back-references render as plain
|
|
12
|
+
* text rather than in-page links.
|
|
13
|
+
*
|
|
14
|
+
* Merge-extensible node unions fall through the documented default (render
|
|
15
|
+
* nothing) rather than ending in assertNever: grammars registered elsewhere
|
|
16
|
+
* may add node types this renderer has no mapping for.
|
|
17
|
+
*/
|
|
18
|
+
import type { HTMLAttributes } from 'react';
|
|
19
|
+
import type { ReactNode } from 'react';
|
|
20
|
+
import type * as Md from 'mdast';
|
|
21
|
+
import type { CodeToolbarLabels } from '../CodeToolbar.js';
|
|
22
|
+
import type { PositionedBlock } from './incremental.js';
|
|
23
|
+
/** Copy-button labels forwarded to fence CodeBlocks (this package is cordis-free, so copy arrives via props). */
|
|
24
|
+
export interface MarkdownCodeLabels {
|
|
25
|
+
/** Copy-button idle label. */
|
|
26
|
+
copyLabel: string;
|
|
27
|
+
/** Copy-button label during the post-copy confirmation window. */
|
|
28
|
+
copiedLabel: string;
|
|
29
|
+
/** Shared card controls; omitted for custom toolbar layouts. */
|
|
30
|
+
toolbarLabels?: CodeToolbarLabels | undefined;
|
|
31
|
+
}
|
|
32
|
+
/** Localized chrome for a Markdown document. */
|
|
33
|
+
export interface MarkdownLabels {
|
|
34
|
+
code: MarkdownCodeLabels;
|
|
35
|
+
footnotes: string;
|
|
36
|
+
}
|
|
37
|
+
/** Link/image reference targets collected from a document (first definition per identifier wins, as in CommonMark). */
|
|
38
|
+
export interface ReferenceTargets {
|
|
39
|
+
/** Link/image definitions keyed by upper-cased identifier. */
|
|
40
|
+
definitions: Map<string, Md.Definition>;
|
|
41
|
+
/** Footnote definitions keyed by upper-cased identifier. */
|
|
42
|
+
footnotes: Map<string, Md.FootnoteDefinition>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create an empty {@link ReferenceTargets}.
|
|
46
|
+
* @returns Fresh empty maps.
|
|
47
|
+
*/
|
|
48
|
+
export declare function createReferenceTargets(): ReferenceTargets;
|
|
49
|
+
/**
|
|
50
|
+
* Record every definition and footnote definition under `nodes` into
|
|
51
|
+
* `targets`, depth-first, keeping the first definition per identifier.
|
|
52
|
+
* @param nodes - Subtrees to walk (top-level blocks or any nested children).
|
|
53
|
+
* @param targets - Accumulator, typically shared across incremental segments.
|
|
54
|
+
*/
|
|
55
|
+
export declare function collectReferenceTargets(nodes: readonly Md.RootContent[], targets: ReferenceTargets): void;
|
|
56
|
+
/**
|
|
57
|
+
* Local-path image vocabulary for image destinations: the owner maps an
|
|
58
|
+
* authored destination that fails the remote-URL allowlist (an absolute local
|
|
59
|
+
* file path, for example) to a displayable URL it can vouch for. Absent
|
|
60
|
+
* wherever no such vocabulary exists, authored local destinations keep their
|
|
61
|
+
* documented fallback (the image's alt text). Rewritten destinations must be
|
|
62
|
+
* absolute; the renderer re-checks their protocol before emitting them.
|
|
63
|
+
*/
|
|
64
|
+
export interface MarkdownPathImages {
|
|
65
|
+
/**
|
|
66
|
+
* Resolve one authored image destination.
|
|
67
|
+
* @param value - The destination exactly as the markdown author wrote it.
|
|
68
|
+
* @returns A displayable absolute URL, or undefined when the destination
|
|
69
|
+
* names no displayable image — it then stays inert alt text. The renderer
|
|
70
|
+
* appends a per-mount `load` query parameter to `api/file` route results.
|
|
71
|
+
*/
|
|
72
|
+
resolve(value: string): string | undefined;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* File-mention affordance for inline code: the owner resolves an authored
|
|
76
|
+
* token to the file it names, using its own vocabulary of real files — the
|
|
77
|
+
* renderer never guesses at what looks like a path.
|
|
78
|
+
*/
|
|
79
|
+
export interface MarkdownFileMentions {
|
|
80
|
+
/**
|
|
81
|
+
* Resolve one inline-code token.
|
|
82
|
+
* @param value - The authored token, exactly as written.
|
|
83
|
+
* @returns The opener with its accessible label and full-path title, or
|
|
84
|
+
* undefined when the token names no known file — it then stays inert code.
|
|
85
|
+
*/
|
|
86
|
+
resolve(value: string): {
|
|
87
|
+
open: () => void;
|
|
88
|
+
contextMenuProps?: Pick<HTMLAttributes<HTMLElement>, 'onContextMenu' | 'onKeyDown' | 'tabIndex'>;
|
|
89
|
+
label: string;
|
|
90
|
+
title: string;
|
|
91
|
+
} | undefined;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* One render pass's state: immutable options and targets plus the footnote
|
|
95
|
+
* numbering accumulated in document order while references render.
|
|
96
|
+
*/
|
|
97
|
+
export interface MarkdownRenderContext {
|
|
98
|
+
/** Streaming arm: fences highlight incrementally as they grow; TeX (including ```math fences) stays literal until the settled pass. */
|
|
99
|
+
readonly streaming: boolean;
|
|
100
|
+
/** Localized fence copy-button labels. */
|
|
101
|
+
readonly labels: MarkdownLabels;
|
|
102
|
+
/** Inside a blockquote's children: tables there always fill the quote's width. */
|
|
103
|
+
readonly inBlockquote?: boolean;
|
|
104
|
+
/** Inline-code file mentions; absent wherever no opener vocabulary exists. */
|
|
105
|
+
readonly fileMentions: MarkdownFileMentions | undefined;
|
|
106
|
+
/** Local-path image vocabulary; absent wherever no rewriting owner exists. */
|
|
107
|
+
readonly pathImages: MarkdownPathImages | undefined;
|
|
108
|
+
/** Raw HTML renders nothing instead of literal text. */
|
|
109
|
+
readonly omitHtml: boolean;
|
|
110
|
+
/** Inside an anchor's children: interactive mentions must not nest there. */
|
|
111
|
+
readonly inLink?: boolean;
|
|
112
|
+
/** Reference targets visible to this pass. */
|
|
113
|
+
readonly targets: ReferenceTargets;
|
|
114
|
+
/** Footnote identifiers in first-reference order; a footnote's number is its 1-based index here. */
|
|
115
|
+
readonly footnoteOrder: string[];
|
|
116
|
+
/** References rendered per identifier; drives the section's back-reference count. */
|
|
117
|
+
readonly footnoteCounts: Map<string, number>;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Render top-level blocks. Nodes that render nothing (definitions, unmapped
|
|
121
|
+
* types) are dropped rather than kept as null placeholders, matching the
|
|
122
|
+
* replaced pipeline's child lists so separator newlines land identically.
|
|
123
|
+
* @param blocks - Blocks with their stream-stable render keys.
|
|
124
|
+
* @param context - The pass state; footnote numbering mutates in document order.
|
|
125
|
+
* @returns One React node per rendered block.
|
|
126
|
+
*/
|
|
127
|
+
export declare function renderBlocks(blocks: readonly PositionedBlock[], context: MarkdownRenderContext): ReactNode[];
|
|
128
|
+
/**
|
|
129
|
+
* Interleave the newline text nodes the replaced pipeline emitted between
|
|
130
|
+
* block-level children. They are invisible between elements but coalesce
|
|
131
|
+
* into adjacent literal raw-HTML text, where the DOM parity fixtures pin
|
|
132
|
+
* them.
|
|
133
|
+
* @param elements - Rendered block children with empty renders already dropped.
|
|
134
|
+
* @param edges - Also emit the leading and trailing newline (hast's loose wrap).
|
|
135
|
+
* @returns The interleaved children.
|
|
136
|
+
*/
|
|
137
|
+
export declare function wrapBlockChildren(elements: readonly ReactNode[], edges: boolean): ReactNode[];
|
|
138
|
+
/**
|
|
139
|
+
* Render the trailing footnote section for every footnote referenced during
|
|
140
|
+
* the pass, in first-reference order, with one plain-text back-reference
|
|
141
|
+
* marker per rendered reference.
|
|
142
|
+
* @param context - The pass state after all blocks rendered.
|
|
143
|
+
* @returns The section, or null when no referenced footnote has a definition.
|
|
144
|
+
*/
|
|
145
|
+
export declare function renderFootnoteSection(context: MarkdownRenderContext): ReactNode | null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RefObject } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Activate one supported code surface when it first intersects the viewport.
|
|
4
|
+
* Activation lasts for the component lifetime; browsers without
|
|
5
|
+
* IntersectionObserver activate immediately.
|
|
6
|
+
* @param target - Code surface whose plain rendering reserves its geometry.
|
|
7
|
+
* @param lang - Optional language hint.
|
|
8
|
+
* @returns Whether this component may build highlighted output.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useViewportHighlighting(target: RefObject<Element | null>, lang: string | undefined): boolean;
|