Download tools/ui/src/lib/components/app/content/MarkdownContent/markdown-utils.ts from Parakon/parakon-runtime: direct link, hf CLI and curl.
- Browser
- Download file 2.73 kB
-
https://huggingface.co/Parakon/parakon-runtime/resolve/main/tools/ui/src/lib/components/app/content/MarkdownContent/markdown-utils.ts
- Command line
-
hf download hf://Parakon/parakon-runtime/tools/ui/src/lib/components/app/content/MarkdownContent/markdown-utils.ts
-
curl -L -o markdown-utils.ts https://huggingface.co/Parakon/parakon-runtime/resolve/main/tools/ui/src/lib/components/app/content/MarkdownContent/markdown-utils.ts
2.73 kB
| /** | |
| * Utility functions for markdown processing in MarkdownContent component. | |
| */ | |
| import { MARKDOWN_DATA_ATTRS } from '$lib/constants'; | |
| import type { RootContent as HastRootContent } from 'hast'; | |
| /** | |
| * Generates a unique identifier for a HAST node based on its position. | |
| * Used for stable block identification during incremental rendering. | |
| * @param node - The HAST root content node | |
| * @param indexFallback - Fallback index if position is unavailable | |
| * @returns Unique string identifier for the node | |
| */ | |
| export function getHastNodeId(node: HastRootContent, indexFallback: number): string { | |
| const position = node.position; | |
| if (position?.start?.offset != null && position?.end?.offset != null) { | |
| return `hast-${position.start.offset}-${position.end.offset}`; | |
| } | |
| return `${node.type}-${indexFallback}`; | |
| } | |
| /** | |
| * Generates a hash for MDAST node based on its position. | |
| * Used for cache lookup during incremental rendering. | |
| */ | |
| export function getMdastNodeHash(node: unknown, index: number): string { | |
| const n = node as { | |
| type?: string; | |
| position?: { start?: { offset?: number }; end?: { offset?: number } }; | |
| }; | |
| if (n.position?.start?.offset != null && n.position?.end?.offset != null) { | |
| return `${n.type}-${n.position.start.offset}-${n.position.end.offset}`; | |
| } | |
| return `${n.type}-idx${index}`; | |
| } | |
| /** | |
| * Determines if the new content is an append (new content added to existing blocks). | |
| * This is used to optimize cache reuse during streaming updates. | |
| * | |
| * @param newContent - The new markdown content | |
| * @param previousContent - The previous markdown content to check against | |
| * @returns true if the content appears to be an append operation | |
| */ | |
| export function isAppendMode(newContent: string, previousContent: string): boolean { | |
| return previousContent.length > 0 && newContent.startsWith(previousContent); | |
| } | |
| export interface CodeInfo { | |
| rawCode: string; | |
| language: string; | |
| } | |
| /** | |
| * Extracts code information from a button click target within a code block. | |
| * @param target - The clicked button element | |
| * @returns Object with rawCode and language, or null if extraction fails | |
| */ | |
| export function getCodeInfoFromTarget(target: HTMLElement): CodeInfo | null { | |
| const wrapper = target.closest('.code-block-wrapper'); | |
| if (!wrapper) { | |
| console.error('No wrapper found'); | |
| return null; | |
| } | |
| const codeElement = wrapper.querySelector<HTMLElement>(`code[${MARKDOWN_DATA_ATTRS.CODE_ID}]`); | |
| if (!codeElement) { | |
| console.error('No code element found in wrapper'); | |
| return null; | |
| } | |
| const rawCode = codeElement.textContent ?? ''; | |
| const languageLabel = wrapper.querySelector<HTMLElement>('.code-language'); | |
| const language = languageLabel?.textContent?.trim() || 'text'; | |
| return { language, rawCode }; | |
| } | |