@changerawr/markdown 1.1.6 → 1.1.8
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/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +93 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +93 -9
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.js +93 -9
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +93 -9
- package/dist/react/index.mjs.map +1 -1
- package/dist/standalone.browser.js +116 -21
- package/dist/standalone.js +93 -9
- package/dist/standalone.js.map +1 -1
- package/dist/standalone.mjs +93 -9
- package/dist/standalone.mjs.map +1 -1
- package/package.json +1 -1
package/dist/standalone.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/standalone.ts","../src/parser.ts","../src/utils.ts","../src/renderer.ts","../src/cache.ts","../src/extensions/core/blockquote.ts","../src/extensions/core/breaks.ts","../src/extensions/core/code.ts","../src/extensions/core/emphasis.ts","../src/extensions/core/heading.ts","../src/extensions/core/hr.ts","../src/extensions/core/image.ts","../src/extensions/core/links.ts","../src/extensions/core/lists.ts","../src/extensions/core/paragraph.ts","../src/extensions/core/text.ts","../src/extensions/core/index.ts","../src/extensions/alert.ts","../src/extensions/button.ts","../src/extensions/embed.ts","../src/engine.ts"],"sourcesContent":["/**\r\n * Standalone version of Changerawr Markdown for vanilla JavaScript usage\r\n * No React dependencies - works in browser and Node.js environments\r\n */\r\n\r\nimport { ChangerawrMarkdown } from './engine';\r\nimport type { MarkdownToken, Extension, EngineConfig } from './types';\r\n\r\n// Main renderCum function for vanilla JS usage\r\nexport function renderCum(markdown: string, config?: EngineConfig): string {\r\n const engine = new ChangerawrMarkdown(config);\r\n return engine.toHtml(markdown);\r\n}\r\n\r\n// Parse-only function for getting tokens\r\nexport function parseCum(markdown: string, config?: EngineConfig): MarkdownToken[] {\r\n const engine = new ChangerawrMarkdown(config);\r\n return engine.parse(markdown);\r\n}\r\n\r\n// Create a custom engine instance\r\nexport function createCumEngine(config?: EngineConfig): ChangerawrMarkdown {\r\n return new ChangerawrMarkdown(config);\r\n}\r\n\r\n// Convenience functions with different output formats\r\nexport function renderCumToHtml(markdown: string): string {\r\n return renderCum(markdown, {\r\n renderer: { format: 'html' }\r\n });\r\n}\r\n\r\nexport function renderCumToTailwind(markdown: string): string {\r\n return renderCum(markdown, {\r\n renderer: { format: 'tailwind' }\r\n });\r\n}\r\n\r\nexport function renderCumToJson(markdown: string): MarkdownToken[] {\r\n return parseCum(markdown);\r\n}\r\n\r\n// Export for Node.js/module usage\r\nexport {\r\n ChangerawrMarkdown,\r\n type MarkdownToken,\r\n type Extension,\r\n type EngineConfig\r\n};\r\n\r\n// Default export - this is what tsup will assign to the global\r\nexport default {\r\n renderCum,\r\n parseCum,\r\n createCumEngine,\r\n renderCumToHtml,\r\n renderCumToTailwind,\r\n renderCumToJson,\r\n // Legacy aliases\r\n render: renderCum,\r\n parse: parseCum,\r\n // Include the main class\r\n ChangerawrMarkdown\r\n};","import type { MarkdownToken, ParseRule, ParserConfig } from './types';\r\n\r\nexport class MarkdownParser {\r\n private rules: ParseRule[] = [];\r\n private warnings: string[] = [];\r\n private config: ParserConfig;\r\n private compiledPatterns = new Map<ParseRule, RegExp>(); // Cache compiled regexes\r\n\r\n constructor(config?: ParserConfig) {\r\n this.config = {\r\n debugMode: false,\r\n maxIterations: 10000,\r\n validateMarkdown: false,\r\n ...config\r\n };\r\n }\r\n\r\n addRule(rule: ParseRule): void {\r\n this.rules.push(rule);\r\n // Pre-compile the regex pattern (without global flag for position-based matching)\r\n this.compiledPatterns.set(\r\n rule,\r\n new RegExp(rule.pattern.source, rule.pattern.flags.replace('g', ''))\r\n );\r\n // Sort by priority - extensions should define their own priority\r\n this.rules.sort((a, b) => {\r\n // Feature extensions first (alert, button, embed) - they have more specific patterns\r\n const aFeatureExtension = ['alert', 'button', 'embed'].includes(a.name);\r\n const bFeatureExtension = ['alert', 'button', 'embed'].includes(b.name);\r\n\r\n if (aFeatureExtension && !bFeatureExtension) return -1;\r\n if (!aFeatureExtension && bFeatureExtension) return 1;\r\n\r\n // Core extensions next\r\n const aCoreExtension = ['text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(a.name);\r\n const bCoreExtension = ['text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(b.name);\r\n\r\n if (aCoreExtension && !bCoreExtension) return -1;\r\n if (!aCoreExtension && bCoreExtension) return 1;\r\n\r\n // Within same category, specific ordering\r\n // Images before links (more specific pattern)\r\n if (a.name === 'image' && b.name === 'link') return -1;\r\n if (a.name === 'link' && b.name === 'image') return 1;\r\n\r\n // Task lists before regular lists\r\n if (a.name === 'task-item' && b.name === 'list-item') return -1;\r\n if (a.name === 'list-item' && b.name === 'task-item') return 1;\r\n\r\n // Code blocks before inline code\r\n if (a.name === 'codeblock' && b.name === 'code') return -1;\r\n if (a.name === 'code' && b.name === 'codeblock') return 1;\r\n\r\n // Bold before italic\r\n if (a.name === 'bold' && b.name === 'italic') return -1;\r\n if (a.name === 'italic' && b.name === 'bold') return 1;\r\n\r\n // Then alphabetical\r\n return a.name.localeCompare(b.name);\r\n });\r\n }\r\n\r\n hasRule(name: string): boolean {\r\n return this.rules.some(rule => rule.name === name);\r\n }\r\n\r\n parse(markdown: string): MarkdownToken[] {\r\n // Clear previous warnings\r\n this.warnings = [];\r\n\r\n if (!markdown.trim()) {\r\n return [];\r\n }\r\n\r\n // Check if we have any rules at all\r\n if (this.rules.length === 0) {\r\n this.warnings.push('No parse rules registered - consider using CoreExtensions');\r\n return [{\r\n type: 'text',\r\n content: markdown,\r\n raw: markdown\r\n }];\r\n }\r\n\r\n // Pre-process markdown to handle common issues\r\n const processedMarkdown = this.preprocessMarkdown(markdown);\r\n\r\n const tokens: MarkdownToken[] = [];\r\n let remaining = processedMarkdown;\r\n let iterationCount = 0;\r\n const maxIterations = this.config.maxIterations || 10000;\r\n\r\n while (remaining.length > 0 && iterationCount < maxIterations) {\r\n iterationCount++;\r\n let matched = false;\r\n let bestMatch: { rule: ParseRule; match: RegExpMatchArray; priority: number } | null = null;\r\n let nextBestMatchIndex: number | null = null;\r\n\r\n // Try each rule and find the best match (earliest position)\r\n for (const rule of this.rules) {\r\n try {\r\n // Use pre-compiled regex pattern\r\n const pattern = this.compiledPatterns.get(rule)!;\r\n const match = remaining.match(pattern);\r\n\r\n if (match && match.index !== undefined) {\r\n // If we found a match at position 0, use it immediately (common case)\r\n if (match.index === 0) {\r\n bestMatch = { rule, match, priority: 1000 };\r\n break; // Early exit - can't get better than position 0\r\n }\r\n\r\n // Track the closest match for chunking optimization\r\n if (nextBestMatchIndex === null || match.index < nextBestMatchIndex) {\r\n nextBestMatchIndex = match.index;\r\n }\r\n\r\n // Otherwise, consider nearby matches\r\n const priority = 1000 - match.index;\r\n\r\n if (!bestMatch || priority > bestMatch.priority ||\r\n (priority === bestMatch.priority && match.index < (bestMatch.match.index || 0))) {\r\n bestMatch = { rule, match, priority };\r\n }\r\n }\r\n } catch (error) {\r\n if (this.config.debugMode) {\r\n console.warn(`Error in rule \"${rule.name}\":`, error);\r\n }\r\n }\r\n }\r\n\r\n if (bestMatch && bestMatch.match.index !== undefined) {\r\n const { rule, match } = bestMatch;\r\n const matchIndex = match.index as number;\r\n\r\n // If match is not at the beginning, take text before it\r\n if (matchIndex > 0) {\r\n const textBefore = remaining.slice(0, matchIndex);\r\n tokens.push({\r\n type: 'text',\r\n content: textBefore,\r\n raw: textBefore\r\n });\r\n remaining = remaining.slice(matchIndex);\r\n continue;\r\n }\r\n\r\n // Process the match\r\n try {\r\n const token = rule.render(match);\r\n tokens.push({\r\n ...token,\r\n raw: match[0] || ''\r\n });\r\n\r\n remaining = remaining.slice(match[0]?.length || 0);\r\n matched = true;\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n this.warnings.push(`Failed to render ${rule.name}: ${errorMessage}`);\r\n\r\n // Fall back to treating as text\r\n const char = remaining[0];\r\n if (char) {\r\n tokens.push({\r\n type: 'text',\r\n content: char,\r\n raw: char\r\n });\r\n remaining = remaining.slice(1);\r\n }\r\n }\r\n }\r\n\r\n if (!matched) {\r\n // Use the next match index we already found during the search\r\n // This avoids a second expensive search through all rules\r\n const chunkSize = nextBestMatchIndex !== null\r\n ? nextBestMatchIndex\r\n : Math.min(remaining.length, 1000); // Take up to 1000 chars of plain text\r\n\r\n const textChunk = remaining.slice(0, chunkSize);\r\n\r\n tokens.push({\r\n type: 'text',\r\n content: textChunk,\r\n raw: textChunk\r\n });\r\n remaining = remaining.slice(chunkSize);\r\n }\r\n }\r\n\r\n if (iterationCount >= maxIterations) {\r\n this.warnings.push('Parser hit maximum iterations - possible infinite loop detected');\r\n }\r\n\r\n // Post-process tokens to merge consecutive text and validate structure\r\n const processedTokens = this.postProcessTokens(tokens);\r\n\r\n return processedTokens;\r\n }\r\n\r\n getWarnings(): string[] {\r\n return [...this.warnings];\r\n }\r\n\r\n getConfig(): ParserConfig {\r\n return { ...this.config };\r\n }\r\n\r\n updateConfig(config: Partial<ParserConfig>): void {\r\n this.config = { ...this.config, ...config };\r\n }\r\n\r\n setDebugMode(enabled: boolean): void {\r\n this.config.debugMode = enabled;\r\n }\r\n\r\n clearWarnings(): void {\r\n this.warnings = [];\r\n }\r\n\r\n private preprocessMarkdown(markdown: string): string {\r\n // Check for common markdown issues and warn about them\r\n if (this.config.validateMarkdown) {\r\n this.validateMarkdown(markdown);\r\n }\r\n\r\n // Normalize line endings\r\n return markdown.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\r\n }\r\n\r\n private validateMarkdown(markdown: string): void {\r\n // Check for unclosed bold markers\r\n const boldMatches = markdown.match(/\\*\\*/g);\r\n if (boldMatches && boldMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed bold markers (**) detected - some bold formatting may not work');\r\n }\r\n\r\n // Check for unclosed italic markers\r\n const italicMatches = markdown.match(/(?<!\\*)\\*(?!\\*)/g);\r\n if (italicMatches && italicMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed italic markers (*) detected - some italic formatting may not work');\r\n }\r\n\r\n // Check for unclosed code blocks\r\n const codeBlockMatches = markdown.match(/```/g);\r\n if (codeBlockMatches && codeBlockMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed code blocks (```) detected - some code formatting may not work');\r\n }\r\n\r\n // Check for unclosed inline code\r\n const inlineCodeMatches = markdown.match(/`/g);\r\n if (inlineCodeMatches && inlineCodeMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed inline code markers (`) detected - some code formatting may not work');\r\n }\r\n }\r\n\r\n private postProcessTokens(tokens: MarkdownToken[]): MarkdownToken[] {\r\n const processed: MarkdownToken[] = [];\r\n let i = 0;\r\n\r\n while (i < tokens.length) {\r\n const token = tokens[i];\r\n\r\n if (token && token.type === 'text') {\r\n // Collect consecutive text tokens\r\n let textContent = token.content || token.raw || '';\r\n let j = i + 1;\r\n\r\n while (j < tokens.length && tokens[j] && tokens[j]!.type === 'text') {\r\n const nextToken = tokens[j]!;\r\n textContent += nextToken.content || nextToken.raw || '';\r\n j++;\r\n }\r\n\r\n // Only create a text token if there's actual content\r\n if (textContent.trim().length > 0 || textContent.includes('\\n')) {\r\n processed.push({\r\n type: 'text',\r\n content: textContent,\r\n raw: textContent\r\n });\r\n }\r\n\r\n i = j;\r\n } else if (token) {\r\n // Recursively parse content for block-level elements\r\n const processedToken = this.recursivelyParseBlockContent(token);\r\n processed.push(processedToken);\r\n i++;\r\n } else {\r\n i++;\r\n }\r\n }\r\n\r\n return processed;\r\n }\r\n\r\n private recursivelyParseBlockContent(token: MarkdownToken): MarkdownToken {\r\n // List of token types that should have their content recursively parsed\r\n const blockTypes = ['alert', 'blockquote', 'list-item', 'task-item'];\r\n\r\n if (blockTypes.includes(token.type) && token.content && token.content.trim()) {\r\n // Recursively parse the content into child tokens\r\n const children = this.parse(token.content);\r\n\r\n return {\r\n ...token,\r\n children\r\n };\r\n }\r\n\r\n return token;\r\n }\r\n}","/**\r\n * Utility functions for Changerawr Markdown\r\n */\r\n\r\n// Import DOMPurify with SSR safety\r\nlet DOMPurify: { sanitize: (html: string, options?: Record<string, unknown>) => string } = {\r\n sanitize: (html: string) => html\r\n};\r\n\r\nif (typeof window !== 'undefined') {\r\n import('dompurify').then(module => {\r\n DOMPurify = module.default;\r\n }).catch(err => {\r\n console.error('Failed to load DOMPurify', err);\r\n });\r\n}\r\n\r\n// Allowed HTML tags and attributes for sanitization\r\nconst ALLOWED_TAGS = [\r\n // Standard HTML\r\n 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'br', 'strong', 'em', 'del', 'ins',\r\n 'a', 'img', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'table', 'thead',\r\n 'tbody', 'tr', 'th', 'td', 'div', 'span', 'sup', 'sub', 'hr', 'input',\r\n // Embeds\r\n 'iframe', 'embed', 'object', 'param', 'video', 'audio', 'source',\r\n // SVG\r\n 'svg', 'path', 'polyline', 'line', 'circle', 'rect', 'g', 'defs', 'use',\r\n // Form elements\r\n 'form', 'fieldset', 'legend', 'label', 'select', 'option', 'textarea', 'button'\r\n];\r\n\r\nconst ALLOWED_ATTR = [\r\n // Standard attributes\r\n 'href', 'title', 'alt', 'src', 'class', 'id', 'target', 'rel', 'type',\r\n 'checked', 'disabled', 'loading', 'width', 'height', 'style', 'role',\r\n // Iframe attributes\r\n 'frameborder', 'allowfullscreen', 'allow', 'sandbox', 'scrolling',\r\n 'allowtransparency', 'name', 'seamless', 'srcdoc',\r\n // Data attributes (for embeds)\r\n 'data-*',\r\n // SVG attributes\r\n 'viewBox', 'fill', 'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin',\r\n 'd', 'points', 'x1', 'y1', 'x2', 'y2', 'cx', 'cy', 'r', 'rx', 'ry',\r\n // Media attributes\r\n 'autoplay', 'controls', 'loop', 'muted', 'preload', 'poster',\r\n // Form attributes\r\n 'value', 'placeholder', 'required', 'readonly', 'maxlength', 'minlength',\r\n 'max', 'min', 'step', 'pattern', 'autocomplete', 'autofocus'\r\n];\r\n\r\n/**\r\n * Escape HTML special characters\r\n */\r\nexport function escapeHtml(text: string): string {\r\n const map: Record<string, string> = {\r\n '&': '&',\r\n '<': '<',\r\n '>': '>',\r\n '\"': '"',\r\n \"'\": '''\r\n };\r\n return text.replace(/[&<>\"']/g, char => map[char] || char);\r\n}\r\n\r\n/**\r\n * Generate URL-friendly ID from text\r\n */\r\nexport function generateId(text: string): string {\r\n return text\r\n .toLowerCase()\r\n .replace(/[^\\w\\s-]/g, '')\r\n .replace(/\\s+/g, '-')\r\n .replace(/-+/g, '-')\r\n .replace(/^-|-$/g, '')\r\n .trim();\r\n}\r\n\r\n/**\r\n * Sanitize HTML content using DOMPurify\r\n */\r\nexport function sanitizeHtml(html: string): string {\r\n try {\r\n // Skip sanitization for embed content that might be sensitive\r\n if (html.includes('codepen.io/') || html.includes('youtube.com/embed/')) {\r\n return html;\r\n }\r\n\r\n // Use DOMPurify if available\r\n if (typeof DOMPurify?.sanitize === 'function') {\r\n const sanitized = DOMPurify.sanitize(html, {\r\n ALLOWED_TAGS,\r\n ALLOWED_ATTR,\r\n ALLOW_DATA_ATTR: true,\r\n ALLOW_UNKNOWN_PROTOCOLS: false,\r\n SAFE_FOR_TEMPLATES: false,\r\n WHOLE_DOCUMENT: false,\r\n RETURN_DOM: false,\r\n RETURN_DOM_FRAGMENT: false,\r\n FORCE_BODY: false,\r\n SANITIZE_DOM: false,\r\n SANITIZE_NAMED_PROPS: false,\r\n FORBID_ATTR: ['onload', 'onerror', 'onclick', 'onmouseover', 'onmouseout', 'onfocus', 'onblur'],\r\n ADD_TAGS: ['iframe', 'embed', 'object', 'param'],\r\n ADD_ATTR: [\r\n 'allow', 'allowfullscreen', 'frameborder', 'scrolling',\r\n 'allowtransparency', 'sandbox', 'loading', 'style',\r\n 'title', 'name', 'seamless', 'srcdoc'\r\n ],\r\n ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|xxx):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i\r\n });\r\n\r\n // If too much content is lost, fall back to basic sanitization\r\n if (sanitized.length < html.length * 0.7) {\r\n return basicSanitize(html);\r\n }\r\n\r\n return sanitized;\r\n }\r\n\r\n // Fallback to basic sanitization\r\n return basicSanitize(html);\r\n } catch (error) {\r\n console.error('Sanitization failed:', error);\r\n return basicSanitize(html);\r\n }\r\n}\r\n\r\n/**\r\n * Basic HTML sanitization - removes dangerous content\r\n */\r\nexport function basicSanitize(html: string): string {\r\n return html\r\n .replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '')\r\n .replace(/on\\w+\\s*=\\s*\"[^\"]*\"/gi, '')\r\n .replace(/on\\w+\\s*=\\s*'[^']*'/gi, '')\r\n .replace(/javascript:/gi, '');\r\n}\r\n\r\n/**\r\n * Check if code is running in browser environment\r\n */\r\nexport function isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof document !== 'undefined';\r\n}\r\n\r\n/**\r\n * Check if code is running in Node.js environment\r\n */\r\nexport function isNode(): boolean {\r\n return typeof process !== 'undefined' &&\r\n process.versions != null &&\r\n process.versions.node != null;\r\n}\r\n\r\n/**\r\n * Debounce function for performance optimization\r\n */\r\nexport function debounce<T extends (...args: any[]) => any>(\r\n func: T,\r\n wait: number\r\n): (...args: Parameters<T>) => void {\r\n let timeout: NodeJS.Timeout | number;\r\n\r\n return function executedFunction(...args: Parameters<T>) {\r\n const later = () => {\r\n clearTimeout(timeout as NodeJS.Timeout);\r\n func(...args);\r\n };\r\n\r\n clearTimeout(timeout as NodeJS.Timeout);\r\n timeout = setTimeout(later, wait);\r\n };\r\n}\r\n\r\n/**\r\n * Deep merge two objects\r\n */\r\nexport function deepMerge<T extends Record<string, any>>(target: T, source: Partial<T>): T {\r\n const output = { ...target };\r\n\r\n for (const key in source) {\r\n if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {\r\n if (key in target && typeof target[key] === 'object' && !Array.isArray(target[key])) {\r\n output[key] = deepMerge(target[key], source[key] as any);\r\n } else {\r\n output[key] = source[key] as any;\r\n }\r\n } else {\r\n output[key] = source[key] as any;\r\n }\r\n }\r\n\r\n return output;\r\n}\r\n\r\n/**\r\n * Extract domain from URL\r\n */\r\nexport function extractDomain(url: string): string {\r\n try {\r\n return new URL(url).hostname;\r\n } catch {\r\n return url;\r\n }\r\n}\r\n\r\n/**\r\n * Check if URL is valid\r\n */\r\nexport function isValidUrl(url: string): boolean {\r\n try {\r\n new URL(url);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Parse options string into key-value object\r\n */\r\nexport function parseOptions(options: string): Record<string, string> {\r\n const parsed: Record<string, string> = {};\r\n if (!options) return parsed;\r\n\r\n // Parse options like \"height:400,theme:dark,autoplay:1\"\r\n options.split(',').forEach(option => {\r\n const [key, value] = option.split(':').map(s => s.trim());\r\n if (key && value) {\r\n parsed[key] = value;\r\n }\r\n });\r\n\r\n return parsed;\r\n}\r\n\r\n/**\r\n * Performance measurement utility\r\n */\r\nexport class PerformanceTimer {\r\n private startTime: number;\r\n private marks: Record<string, number> = {};\r\n\r\n constructor() {\r\n this.startTime = performance.now();\r\n }\r\n\r\n mark(name: string): void {\r\n this.marks[name] = performance.now() - this.startTime;\r\n }\r\n\r\n getTime(name?: string): number {\r\n if (name && this.marks[name] !== undefined) {\r\n return this.marks[name];\r\n }\r\n return performance.now() - this.startTime;\r\n }\r\n\r\n getAllMarks(): Record<string, number> {\r\n return { ...this.marks };\r\n }\r\n}\r\n\r\n/**\r\n * Simple logger with different levels\r\n */\r\nexport class Logger {\r\n private debugMode: boolean;\r\n\r\n constructor(debugMode = false) {\r\n this.debugMode = debugMode;\r\n }\r\n\r\n debug(...args: any[]): void {\r\n if (this.debugMode) {\r\n console.log('[DEBUG]', ...args);\r\n }\r\n }\r\n\r\n info(...args: any[]): void {\r\n console.info('[INFO]', ...args);\r\n }\r\n\r\n warn(...args: any[]): void {\r\n console.warn('[WARN]', ...args);\r\n }\r\n\r\n error(...args: any[]): void {\r\n console.error('[ERROR]', ...args);\r\n }\r\n\r\n setDebugMode(enabled: boolean): void {\r\n this.debugMode = enabled;\r\n }\r\n}","import type { MarkdownToken, RenderRule, RendererConfig } from './types';\r\nimport { sanitizeHtml, escapeHtml } from './utils';\r\n\r\nexport class MarkdownRenderer {\r\n private rules = new Map<string, RenderRule>();\r\n private warnings: string[] = [];\r\n private config: RendererConfig;\r\n\r\n constructor(config?: RendererConfig) {\r\n this.config = {\r\n format: 'tailwind',\r\n sanitize: true,\r\n allowUnsafeHtml: false,\r\n debugMode: false,\r\n ...config\r\n };\r\n }\r\n\r\n addRule(rule: RenderRule): void {\r\n this.rules.set(rule.type, rule);\r\n }\r\n\r\n hasRule(type: string): boolean {\r\n return this.rules.has(type);\r\n }\r\n\r\n render(tokens: MarkdownToken[]): string {\r\n this.warnings = [];\r\n\r\n // Inject format into each token for extensions to use\r\n const tokensWithFormat = tokens.map(token => ({\r\n ...token,\r\n attributes: {\r\n ...token.attributes,\r\n format: this.config.format\r\n }\r\n }));\r\n\r\n // Render each token using registered extensions\r\n const htmlParts = tokensWithFormat.map(token => this.renderToken(token));\r\n const combinedHtml = htmlParts.join('');\r\n\r\n // Apply sanitization if enabled\r\n if (this.config.sanitize && !this.config.allowUnsafeHtml) {\r\n return sanitizeHtml(combinedHtml);\r\n }\r\n\r\n return combinedHtml;\r\n }\r\n\r\n private renderToken(token: MarkdownToken): string {\r\n const rule = this.rules.get(token.type);\r\n\r\n if (rule) {\r\n try {\r\n // If token has children, render them and inject into attributes\r\n let tokenToRender = token;\r\n if (token.children && token.children.length > 0) {\r\n const renderedChildren = this.render(token.children);\r\n tokenToRender = {\r\n ...token,\r\n attributes: {\r\n ...token.attributes,\r\n renderedChildren // Extensions can use this instead of re-parsing\r\n }\r\n };\r\n }\r\n\r\n return rule.render(tokenToRender);\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n this.warnings.push(`Render error for ${token.type}: ${errorMessage}`);\r\n return this.createErrorBlock(`Render error for ${token.type}: ${errorMessage}`);\r\n }\r\n }\r\n\r\n // For unknown types in development, show debug info\r\n if (this.config.debugMode) {\r\n return this.createDebugBlock(token);\r\n }\r\n\r\n // Fallback: treat as text if no rule found\r\n return escapeHtml(token.content || token.raw || '');\r\n }\r\n\r\n private createErrorBlock(message: string): string {\r\n if (this.config.format === 'html') {\r\n return `<div style=\"background-color: #fee; border: 1px solid #fcc; color: #c66; padding: 8px; border-radius: 4px; margin: 8px 0; font-size: 14px;\">\r\n <strong>Render Error:</strong> ${escapeHtml(message)}\r\n </div>`;\r\n }\r\n\r\n return `<div class=\"bg-red-100 border border-red-300 text-red-800 p-2 rounded text-sm mb-2\">\r\n <strong>Render Error:</strong> ${escapeHtml(message)}\r\n </div>`;\r\n }\r\n\r\n private createDebugBlock(token: MarkdownToken): string {\r\n if (this.config.format === 'html') {\r\n return `<div style=\"background-color: #fffbf0; border: 1px solid #fed; color: #b8860b; padding: 8px; border-radius: 4px; margin: 8px 0; font-size: 14px;\">\r\n <strong>Unknown token type:</strong> ${escapeHtml(token.type)}<br>\r\n <strong>Content:</strong> ${escapeHtml(token.content || token.raw || '')}\r\n </div>`;\r\n }\r\n\r\n return `<div class=\"bg-yellow-100 border border-yellow-300 text-yellow-800 p-2 rounded text-sm mb-2\">\r\n <strong>Unknown token type:</strong> ${escapeHtml(token.type)}<br>\r\n <strong>Content:</strong> ${escapeHtml(token.content || token.raw || '')}\r\n </div>`;\r\n }\r\n\r\n getWarnings(): string[] {\r\n return [...this.warnings];\r\n }\r\n\r\n getConfig(): RendererConfig {\r\n return { ...this.config };\r\n }\r\n\r\n updateConfig(config: Partial<RendererConfig>): void {\r\n this.config = { ...this.config, ...config };\r\n }\r\n\r\n setDebugMode(enabled: boolean): void {\r\n this.config.debugMode = enabled;\r\n }\r\n\r\n clearWarnings(): void {\r\n this.warnings = [];\r\n }\r\n}","/**\n * LRU (Least Recently Used) Cache implementation for markdown rendering\n * Provides efficient caching with automatic eviction of old entries\n */\n\nexport interface CacheEntry<V> {\n value: V;\n timestamp: number;\n accessCount: number;\n}\n\nexport interface CacheStats {\n size: number;\n capacity: number;\n hits: number;\n misses: number;\n hitRate: number;\n evictions: number;\n}\n\nexport class LRUCache<K, V> {\n private cache = new Map<K, CacheEntry<V>>();\n private capacity: number;\n private hits = 0;\n private misses = 0;\n private evictions = 0;\n\n constructor(capacity = 100) {\n if (capacity <= 0) {\n throw new Error('Cache capacity must be greater than 0');\n }\n this.capacity = capacity;\n }\n\n /**\n * Get a value from the cache\n */\n get(key: K): V | undefined {\n const entry = this.cache.get(key);\n\n if (entry) {\n // Update access metadata\n entry.timestamp = Date.now();\n entry.accessCount++;\n this.hits++;\n\n // Move to end (most recently used)\n this.cache.delete(key);\n this.cache.set(key, entry);\n\n return entry.value;\n }\n\n this.misses++;\n return undefined;\n }\n\n /**\n * Set a value in the cache\n */\n set(key: K, value: V): void {\n // If key already exists, update it\n if (this.cache.has(key)) {\n this.cache.delete(key);\n }\n // If at capacity, evict least recently used\n else if (this.cache.size >= this.capacity) {\n this.evictLRU();\n }\n\n // Add new entry at end (most recently used)\n this.cache.set(key, {\n value,\n timestamp: Date.now(),\n accessCount: 0\n });\n }\n\n /**\n * Check if a key exists in the cache\n */\n has(key: K): boolean {\n return this.cache.has(key);\n }\n\n /**\n * Delete a specific key from the cache\n */\n delete(key: K): boolean {\n return this.cache.delete(key);\n }\n\n /**\n * Clear all entries from the cache\n */\n clear(): void {\n this.cache.clear();\n this.hits = 0;\n this.misses = 0;\n this.evictions = 0;\n }\n\n /**\n * Get the current size of the cache\n */\n get size(): number {\n return this.cache.size;\n }\n\n /**\n * Get cache statistics\n */\n getStats(): CacheStats {\n const totalRequests = this.hits + this.misses;\n return {\n size: this.cache.size,\n capacity: this.capacity,\n hits: this.hits,\n misses: this.misses,\n hitRate: totalRequests > 0 ? this.hits / totalRequests : 0,\n evictions: this.evictions\n };\n }\n\n /**\n * Reset cache statistics\n */\n resetStats(): void {\n this.hits = 0;\n this.misses = 0;\n this.evictions = 0;\n }\n\n /**\n * Get all keys in the cache\n */\n keys(): K[] {\n return Array.from(this.cache.keys());\n }\n\n /**\n * Get all values in the cache\n */\n values(): V[] {\n return Array.from(this.cache.values()).map(entry => entry.value);\n }\n\n /**\n * Update cache capacity and evict if necessary\n */\n setCapacity(newCapacity: number): void {\n if (newCapacity <= 0) {\n throw new Error('Cache capacity must be greater than 0');\n }\n\n this.capacity = newCapacity;\n\n // Evict entries if new capacity is smaller than current size\n while (this.cache.size > this.capacity) {\n this.evictLRU();\n }\n }\n\n /**\n * Evict the least recently used entry\n */\n private evictLRU(): void {\n // Map preserves insertion order, first entry is least recently used\n const firstKey = this.cache.keys().next().value;\n if (firstKey !== undefined) {\n this.cache.delete(firstKey);\n this.evictions++;\n }\n }\n}\n\n/**\n * Simple hash function for content\n * Uses FNV-1a algorithm for fast, decent-quality hashing\n */\nexport function hashContent(content: string): string {\n // For very large content, sample instead of hashing every character\n if (content.length > 10000) {\n // Sample: hash length + first 1000 + middle 1000 + last 1000 chars\n const start = content.slice(0, 1000);\n const middle = content.slice(Math.floor(content.length / 2) - 500, Math.floor(content.length / 2) + 500);\n const end = content.slice(-1000);\n const sample = content.length + '|' + start + middle + end;\n\n let hash = 2166136261;\n for (let i = 0; i < sample.length; i++) {\n hash ^= sample.charCodeAt(i);\n hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);\n }\n return (hash >>> 0).toString(36);\n }\n\n // For smaller content, hash normally\n let hash = 2166136261; // FNV offset basis\n for (let i = 0; i < content.length; i++) {\n hash ^= content.charCodeAt(i);\n hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);\n }\n\n return (hash >>> 0).toString(36);\n}\n\n/**\n * Create a cached version of a function\n */\nexport function memoize<T extends (...args: any[]) => any>(\n fn: T,\n options: {\n cache?: LRUCache<string, ReturnType<T>>;\n keyGenerator?: (...args: Parameters<T>) => string;\n maxSize?: number;\n } = {}\n): T & { cache: LRUCache<string, ReturnType<T>>; clearCache: () => void } {\n const cache = options.cache || new LRUCache<string, ReturnType<T>>(options.maxSize || 100);\n const keyGenerator = options.keyGenerator || ((...args: Parameters<T>) => JSON.stringify(args));\n\n const memoized = function(this: any, ...args: Parameters<T>): ReturnType<T> {\n const key = keyGenerator(...args);\n const cached = cache.get(key);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const result = fn.apply(this, args);\n cache.set(key, result);\n return result;\n } as T & { cache: LRUCache<string, ReturnType<T>>; clearCache: () => void };\n\n memoized.cache = cache;\n memoized.clearCache = () => cache.clear();\n\n return memoized;\n}\n","import {escapeHtml} from \"@/utils.ts\";\r\nimport {Extension} from \"@/types.ts\";\r\n\r\nexport const BlockquoteExtension: Extension = {\r\n name: 'blockquote',\r\n parseRules: [\r\n {\r\n name: 'blockquote',\r\n pattern: /^>\\s+(.+)$/m,\r\n render: (match) => ({\r\n type: 'blockquote',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'blockquote',\r\n render: (token) => {\r\n const format = token.attributes?.format || 'html';\r\n\r\n // Use pre-rendered children if available (new efficient approach)\r\n // Otherwise fall back to renderMarkdown callback (backwards compat) or escaped content\r\n const renderedChildren = token.attributes?.renderedChildren as string | undefined;\r\n const renderMarkdown = token.attributes?.renderMarkdown as ((md: string) => string) | undefined;\r\n const content = renderedChildren || (renderMarkdown ? renderMarkdown(token.content) : escapeHtml(token.content));\r\n\r\n if (format === 'html') {\r\n return `<blockquote style=\"border-left: 2px solid #d1d5db; padding: 8px 0 8px 16px; margin: 16px 0; font-style: italic; color: #6b7280;\">${content}</blockquote>`;\r\n }\r\n return `<blockquote class=\"pl-4 py-2 border-l-2 border-border italic text-muted-foreground my-4\">${content}</blockquote>`;\r\n }\r\n }\r\n ]\r\n};","import {Extension} from \"@/types.ts\";\r\n\r\nexport const LineBreakExtension: Extension = {\r\n name: 'line-break',\r\n parseRules: [\r\n {\r\n name: 'hard-break-backslash',\r\n pattern: /\\\\\\s*\\n/,\r\n render: (match) => ({\r\n type: 'line-break',\r\n content: '',\r\n raw: match[0] || ''\r\n })\r\n },\r\n {\r\n name: 'hard-break-spaces',\r\n pattern: / +\\n/,\r\n render: (match) => ({\r\n type: 'line-break',\r\n content: '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'line-break',\r\n render: () => '<br>'\r\n },\r\n {\r\n type: 'paragraph-break',\r\n render: () => '</p><p>'\r\n },\r\n {\r\n type: 'soft-break',\r\n render: (token) => token.content || ' '\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const InlineCodeExtension: Extension = {\r\n name: 'inline-code',\r\n parseRules: [\r\n {\r\n name: 'code',\r\n pattern: /`([^`]+)`/,\r\n render: (match) => ({\r\n type: 'code',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'code',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return `<code style=\"background-color: #f3f4f6; padding: 2px 6px; border-radius: 4px; font-family: monospace; font-size: 0.875rem;\">${content}</code>`;\r\n }\r\n // Default to Tailwind\r\n return `<code class=\"bg-muted px-1.5 py-0.5 rounded text-sm font-mono\">${content}</code>`;\r\n }\r\n }\r\n ]\r\n};\r\n\r\nexport const CodeBlockExtension: Extension = {\r\n name: 'codeblock',\r\n parseRules: [\r\n {\r\n name: 'codeblock',\r\n pattern: /```(\\w+)?\\s*\\n([\\s\\S]*?)\\n```/,\r\n render: (match) => ({\r\n type: 'codeblock',\r\n content: match[2] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n language: match[1] || 'text'\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'codeblock',\r\n render: (token) => {\r\n const language = token.attributes?.language || 'text';\r\n const escapedCode = escapeHtml(token.content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<pre style=\"background-color: #f3f4f6; padding: 16px; border-radius: 6px; overflow-x: auto; margin: 16px 0;\"><code class=\"language-${escapeHtml(language)}\">${escapedCode}</code></pre>`;\r\n }\r\n\r\n return `<pre class=\"bg-muted p-4 rounded-md overflow-x-auto my-4\"><code class=\"language-${escapeHtml(language)}\">${escapedCode}</code></pre>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const BoldExtension: Extension = {\r\n name: 'bold',\r\n parseRules: [\r\n {\r\n name: 'bold',\r\n pattern: /\\*\\*((?:(?!\\*\\*).)+)\\*\\*/,\r\n render: (match) => ({\r\n type: 'bold',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'bold',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return `<strong>${content}</strong>`;\r\n }\r\n // Default to Tailwind\r\n return `<strong class=\"font-bold\">${content}</strong>`;\r\n }\r\n }\r\n ]\r\n};\r\n\r\nexport const ItalicExtension: Extension = {\r\n name: 'italic',\r\n parseRules: [\r\n {\r\n name: 'italic',\r\n pattern: /\\*((?:(?!\\*).)+)\\*/,\r\n render: (match) => ({\r\n type: 'italic',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'italic',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return `<em>${content}</em>`;\r\n }\r\n // Default to Tailwind\r\n return `<em class=\"italic\">${content}</em>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml, generateId } from '../../utils';\r\n\r\nexport const HeadingExtension: Extension = {\r\n name: 'heading',\r\n parseRules: [\r\n {\r\n name: 'heading',\r\n pattern: /^(#{1,6})\\s+(.+)$/m,\r\n render: (match) => ({\r\n type: 'heading',\r\n content: match[2]?.trim() || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n level: String(match[1]?.length || 1)\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'heading',\r\n render: (token) => {\r\n const level = parseInt(token.attributes?.level || '1');\r\n const text = token.content;\r\n const id = generateId(text);\r\n const escapedContent = escapeHtml(text);\r\n\r\n // Default to HTML format, extensions can override\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<h${level} id=\"${id}\">${escapedContent}</h${level}>`;\r\n }\r\n\r\n // Tailwind format\r\n let headingClasses = 'group relative flex items-center gap-2';\r\n\r\n switch (level) {\r\n case 1: headingClasses += ' text-3xl font-bold mt-8 mb-4'; break;\r\n case 2: headingClasses += ' text-2xl font-semibold mt-6 mb-3'; break;\r\n case 3: headingClasses += ' text-xl font-medium mt-5 mb-3'; break;\r\n case 4: headingClasses += ' text-lg font-medium mt-4 mb-2'; break;\r\n case 5: headingClasses += ' text-base font-medium mt-3 mb-2'; break;\r\n case 6: headingClasses += ' text-sm font-medium mt-3 mb-2'; break;\r\n }\r\n\r\n return `<h${level} id=\"${id}\" class=\"${headingClasses}\">\r\n ${escapedContent}\r\n <a href=\"#${id}\" class=\"opacity-0 group-hover:opacity-100 text-muted-foreground transition-opacity\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/>\r\n <path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/>\r\n</svg>\r\n </a>\r\n </h${level}>`;\r\n }\r\n }\r\n ]\r\n};","import {Extension} from \"@/types.ts\";\r\n\r\nexport const HorizontalRuleExtension: Extension = {\r\n name: 'hr',\r\n parseRules: [\r\n {\r\n name: 'hr',\r\n pattern: /^---$/m,\r\n render: (match) => ({\r\n type: 'hr',\r\n content: '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'hr',\r\n render: (token) => {\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return '<hr style=\"margin: 24px 0; border: none; border-top: 1px solid #d1d5db;\">';\r\n }\r\n // Default to Tailwind\r\n return '<hr class=\"my-6 border-t border-border\">';\r\n }\r\n }\r\n ]\r\n};","import {escapeHtml} from \"@/utils.ts\";\r\nimport {Extension} from \"@/types.ts\";\r\n\r\nexport const ImageExtension: Extension = {\r\n name: 'image',\r\n parseRules: [\r\n {\r\n name: 'image',\r\n pattern: /!\\[([^\\]]*)\\]\\(([^)]+?)(?:\\s+\"([^\"]+)\")?\\)/,\r\n render: (match) => ({\r\n type: 'image',\r\n content: match[1] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n alt: match[1] || '',\r\n src: match[2] || '',\r\n title: match[3] || ''\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'image',\r\n render: (token) => {\r\n const src = token.attributes?.src || '';\r\n const alt = token.attributes?.alt || '';\r\n const title = token.attributes?.title || '';\r\n const titleAttr = title ? ` title=\"${escapeHtml(title)}\"` : '';\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<img src=\"${escapeHtml(src)}\" alt=\"${escapeHtml(alt)}\"${titleAttr} style=\"max-width: 100%; height: auto; border-radius: 8px; margin: 16px 0;\" loading=\"lazy\" />`;\r\n }\r\n\r\n return `<img src=\"${escapeHtml(src)}\" alt=\"${escapeHtml(alt)}\"${titleAttr} class=\"max-w-full h-auto rounded-lg my-4\" loading=\"lazy\" />`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const LinkExtension: Extension = {\r\n name: 'link',\r\n parseRules: [\r\n {\r\n name: 'link',\r\n pattern: /\\[(?!(?:button|embed):)([^\\]]+)\\]\\(([^)]+)\\)/,\r\n render: (match) => ({\r\n type: 'link',\r\n content: match[1] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n href: match[2] || ''\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'link',\r\n render: (token) => {\r\n const href = token.attributes?.href || '#';\r\n const escapedHref = escapeHtml(href);\r\n const escapedText = escapeHtml(token.content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<a href=\"${escapedHref}\" target=\"_blank\" rel=\"noopener noreferrer\">${escapedText}</a>`;\r\n }\r\n\r\n return `<a href=\"${escapedHref}\" class=\"text-primary hover:underline inline-flex items-center gap-1\" target=\"_blank\" rel=\"noopener noreferrer\">\r\n ${escapedText}\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-external-link\">\r\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"></path>\r\n <polyline points=\"15 3 21 3 21 9\"></polyline>\r\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"></line>\r\n </svg>\r\n </a>`;\r\n }\r\n }\r\n ]\r\n};","import {escapeHtml} from \"@/utils.ts\";\r\nimport {Extension} from \"@/types.ts\";\r\n\r\nexport const ListExtension: Extension = {\r\n name: 'list',\r\n parseRules: [\r\n {\r\n name: 'list-item',\r\n pattern: /^(\\s*)[-*+]\\s+(.+)$/m,\r\n render: (match) => ({\r\n type: 'list-item',\r\n content: match[2] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'list-item',\r\n render: (token) => {\r\n const format = token.attributes?.format || 'tailwind';\r\n // If children have been rendered (from recursive parsing), use them\r\n const content = token.attributes?.renderedChildren || escapeHtml(token.content);\r\n\r\n if (format === 'html') {\r\n return `<li>${content}</li>`;\r\n }\r\n // Default to Tailwind\r\n return `<li>${content}</li>`;\r\n }\r\n }\r\n ]\r\n};\r\n\r\nexport const TaskListExtension: Extension = {\r\n name: 'task-list',\r\n parseRules: [\r\n {\r\n name: 'task-item',\r\n pattern: /^(\\s*)-\\s*\\[([ xX])\\]\\s*(.+)$/m,\r\n render: (match) => ({\r\n type: 'task-item',\r\n content: match[3] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n checked: String((match[2] || '').toLowerCase() === 'x')\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'task-item',\r\n render: (token) => {\r\n const isChecked = token.attributes?.checked === 'true';\r\n // If children have been rendered (from recursive parsing), use them\r\n const content = token.attributes?.renderedChildren || escapeHtml(token.content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<div style=\"display: flex; align-items: center; gap: 8px; margin: 8px 0;\">\r\n <input type=\"checkbox\" ${isChecked ? 'checked' : ''} disabled style=\"margin: 0;\" />\r\n <span${isChecked ? ' style=\"text-decoration: line-through; color: #6b7280;\"' : ''}>${content}</span>\r\n </div>`;\r\n }\r\n\r\n return `<div class=\"flex items-center gap-2 my-2 task-list-item\">\r\n <input type=\"checkbox\" ${isChecked ? 'checked' : ''} disabled\r\n class=\"form-checkbox h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary\" />\r\n <span${isChecked ? ' class=\"line-through text-muted-foreground\"' : ''}>${content}</span>\r\n </div>`;\r\n }\r\n }\r\n ]\r\n};","import {Extension} from \"@/types.ts\";\r\nimport {escapeHtml} from \"@/utils.ts\";\r\n\r\nexport const ParagraphExtension: Extension = {\r\n name: 'paragraph',\r\n parseRules: [],\r\n renderRules: [\r\n {\r\n type: 'paragraph',\r\n render: (token) => {\r\n if (!token.content) return '';\r\n const content = token.content.trim();\r\n if (!content) return '';\r\n\r\n const processedContent = content.includes('<br>') ? content : escapeHtml(content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<p style=\"line-height: 1.75; margin-bottom: 16px;\">${processedContent}</p>`;\r\n }\r\n\r\n return `<p class=\"leading-7 mb-4\">${processedContent}</p>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const TextExtension: Extension = {\r\n name: 'text',\r\n parseRules: [],\r\n renderRules: [\r\n {\r\n type: 'text',\r\n render: (token) => {\r\n if (!token.content) return '';\r\n return escapeHtml(token.content);\r\n }\r\n }\r\n ]\r\n};","import { BlockquoteExtension } from \"./blockquote\";\r\nimport { LineBreakExtension } from \"./breaks\";\r\nimport {CodeBlockExtension, InlineCodeExtension } from \"./code\";\r\nimport { BoldExtension, ItalicExtension } from \"./emphasis\";\r\nimport { HeadingExtension } from \"./heading\";\r\nimport { HorizontalRuleExtension } from \"./hr\";\r\nimport { ImageExtension } from \"./image\";\r\nimport { LinkExtension } from \"./links\";\r\nimport { ListExtension, TaskListExtension } from \"./lists\";\r\nimport { ParagraphExtension } from \"./paragraph\";\r\nimport { TextExtension } from \"./text\";\r\n\r\nexport const CoreExtensions = [\r\n TextExtension,\r\n HeadingExtension,\r\n BoldExtension,\r\n ItalicExtension,\r\n InlineCodeExtension,\r\n CodeBlockExtension,\r\n LinkExtension,\r\n ImageExtension,\r\n ListExtension,\r\n TaskListExtension,\r\n BlockquoteExtension,\r\n HorizontalRuleExtension,\r\n ParagraphExtension,\r\n LineBreakExtension\r\n] as const;\r\n\r\nexport {\r\n TextExtension,\r\n HeadingExtension,\r\n BoldExtension,\r\n ItalicExtension,\r\n InlineCodeExtension,\r\n CodeBlockExtension,\r\n LinkExtension,\r\n ImageExtension,\r\n ListExtension,\r\n TaskListExtension,\r\n BlockquoteExtension,\r\n HorizontalRuleExtension,\r\n ParagraphExtension,\r\n LineBreakExtension\r\n};","import type { Extension } from '../types';\r\n\r\ninterface AlertTypeConfig {\r\n icon: string;\r\n classes: string;\r\n}\r\n\r\nexport const AlertExtension: Extension = {\r\n name: 'alert',\r\n parseRules: [\r\n {\r\n name: 'alert',\r\n pattern: /:::(\\w+)(?: ([^\\n]+))?\\n([\\s\\S]*?)\\n:::/,\r\n render: (match: RegExpMatchArray) => {\r\n return {\r\n type: 'alert',\r\n content: match[3]?.trim() || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n type: match[1] || 'info',\r\n title: match[2]?.trim() || ''\r\n }\r\n };\r\n }\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'alert',\r\n render: (token) => {\r\n const type = token.attributes?.type || 'info';\r\n const title = token.attributes?.title || '';\r\n\r\n const typeConfig: Record<string, AlertTypeConfig> = {\r\n info: {\r\n icon: 'ℹ️',\r\n classes: 'bg-blue-500/10 border-blue-500/30 text-blue-600 border-l-blue-500'\r\n },\r\n warning: {\r\n icon: '⚠️',\r\n classes: 'bg-amber-500/10 border-amber-500/30 text-amber-600 border-l-amber-500'\r\n },\r\n error: {\r\n icon: '❌',\r\n classes: 'bg-red-500/10 border-red-500/30 text-red-600 border-l-red-500'\r\n },\r\n success: {\r\n icon: '✅',\r\n classes: 'bg-green-500/10 border-green-500/30 text-green-600 border-l-green-500'\r\n },\r\n tip: {\r\n icon: '💡',\r\n classes: 'bg-purple-500/10 border-purple-500/30 text-purple-600 border-l-purple-500'\r\n },\r\n note: {\r\n icon: '📝',\r\n classes: 'bg-gray-500/10 border-gray-500/30 text-gray-600 border-l-gray-500'\r\n }\r\n };\r\n\r\n const config = typeConfig[type] || typeConfig.info;\r\n const baseClasses = 'border-l-4 p-4 mb-4 rounded-md transition-colors duration-200';\r\n const classes = `${baseClasses} ${config?.classes}`;\r\n\r\n // Use pre-rendered children if available (new efficient approach)\r\n // Otherwise fall back to renderMarkdown callback (backwards compat) or raw content\r\n const renderedChildren = token.attributes?.renderedChildren as string | undefined;\r\n const renderMarkdown = token.attributes?.renderMarkdown as ((md: string) => string) | undefined;\r\n const renderedContent = renderedChildren || (renderMarkdown ? renderMarkdown(token.content) : token.content);\r\n\r\n const titleHtml = title\r\n ? `<div class=\"font-medium mb-2 flex items-center gap-2\">\r\n <span class=\"text-lg\" role=\"img\" aria-label=\"${type}\">${config?.icon}</span>\r\n <span>${title}</span>\r\n </div>`\r\n : `<div class=\"font-medium mb-2 flex items-center gap-2\">\r\n <span class=\"text-lg\" role=\"img\" aria-label=\"${type}\">${config?.icon}</span>\r\n <span>${type.charAt(0).toUpperCase() + type.slice(1)}</span>\r\n </div>`;\r\n\r\n return `<div class=\"${classes}\" role=\"alert\" aria-live=\"polite\">\r\n ${titleHtml}\r\n <div class=\"leading-relaxed\">${renderedContent}</div>\r\n </div>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../types';\r\n\r\nexport const ButtonExtension: Extension = {\r\n name: 'button',\r\n parseRules: [\r\n {\r\n name: 'button',\r\n pattern: /\\[button:([^\\]]+)\\]\\(([^)]+)\\)(?:\\{([^}]+)\\})?/,\r\n render: (match) => {\r\n const options = match[3] ? match[3].split(',').map(opt => opt.trim()) : [];\r\n\r\n return {\r\n type: 'button',\r\n content: match[1] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n href: match[2] || '',\r\n style: options.find(opt =>\r\n ['default', 'primary', 'secondary', 'success', 'danger', 'outline', 'ghost'].includes(opt)\r\n ) || 'primary',\r\n size: options.find(opt => ['sm', 'md', 'lg'].includes(opt)) || 'md',\r\n disabled: String(options.includes('disabled')),\r\n target: options.includes('self') ? '_self' : '_blank'\r\n }\r\n };\r\n }\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'button',\r\n render: (token) => {\r\n const href = token.attributes?.href || '#';\r\n const style = token.attributes?.style || 'primary';\r\n const size = token.attributes?.size || 'md';\r\n const disabled = token.attributes?.disabled === 'true';\r\n const target = token.attributes?.target || '_blank';\r\n\r\n // Base classes with optical border effect\r\n const baseClasses = `\r\n inline-flex items-center justify-center font-medium rounded-lg \r\n transition-all duration-200 ease-out\r\n focus:outline-none focus:ring-2 focus:ring-offset-2\r\n disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none\r\n transform hover:scale-[1.02] active:scale-[0.98]\r\n shadow-sm hover:shadow-md active:shadow-sm\r\n border border-transparent\r\n relative overflow-hidden\r\n before:absolute before:inset-0 before:rounded-lg\r\n before:bg-gradient-to-br before:from-white/20 before:to-transparent\r\n before:opacity-0 hover:before:opacity-100 before:transition-opacity before:duration-200\r\n `.replace(/\\s+/g, ' ').trim();\r\n\r\n // Size classes\r\n const sizeClasses: Record<string, string> = {\r\n sm: 'px-3 py-1.5 text-sm gap-1.5',\r\n md: 'px-4 py-2 text-base gap-2',\r\n lg: 'px-6 py-3 text-lg gap-2.5'\r\n };\r\n\r\n // Style classes with optical borders using box-shadow\r\n const styleClasses: Record<string, string> = {\r\n default: `\r\n bg-slate-600 text-white border-slate-500\r\n hover:bg-slate-700 hover:border-slate-400\r\n focus:ring-slate-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n primary: `\r\n bg-blue-600 text-white border-blue-500\r\n hover:bg-blue-700 hover:border-blue-400\r\n focus:ring-blue-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n secondary: `\r\n bg-gray-600 text-white border-gray-500\r\n hover:bg-gray-700 hover:border-gray-400\r\n focus:ring-gray-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n success: `\r\n bg-green-600 text-white border-green-500\r\n hover:bg-green-700 hover:border-green-400\r\n focus:ring-green-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n danger: `\r\n bg-red-600 text-white border-red-500\r\n hover:bg-red-700 hover:border-red-400\r\n focus:ring-red-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n outline: `\r\n bg-transparent text-blue-600 border-blue-600\r\n hover:bg-blue-50 hover:border-blue-700 hover:text-blue-700\r\n focus:ring-blue-500\r\n shadow-[0_0_0_1px_rgba(59,130,246,0.5)_inset]\r\n hover:shadow-[0_0_0_1px_rgba(29,78,216,0.6)_inset,0_1px_2px_0_rgba(0,0,0,0.05)]\r\n `,\r\n ghost: `\r\n bg-transparent text-gray-700 border-transparent\r\n hover:bg-gray-100 hover:text-gray-900\r\n focus:ring-gray-500\r\n shadow-none\r\n hover:shadow-[0_1px_2px_0_rgba(0,0,0,0.05)]\r\n `\r\n };\r\n\r\n const classes = `\r\n ${baseClasses}\r\n ${sizeClasses[size] || sizeClasses.md}\r\n ${styleClasses[style] || styleClasses.primary}\r\n `.replace(/\\s+/g, ' ').trim();\r\n\r\n const targetAttr = target === '_blank' ? ' target=\"_blank\" rel=\"noopener noreferrer\"' :\r\n target === '_self' ? ' target=\"_self\"' : '';\r\n const disabledAttr = disabled ? ' aria-disabled=\"true\" tabindex=\"-1\"' : '';\r\n const externalIcon = target === '_blank' && !disabled ?\r\n `<svg class=\"w-4 h-4 ml-1 opacity-75\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>` : '';\r\n\r\n return `<a href=\"${href}\" class=\"${classes}\"${targetAttr}${disabledAttr}>\r\n <span class=\"relative z-10\">${token.content}</span>${externalIcon}\r\n </a>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../types';\r\nimport { parseOptions, extractDomain } from '../utils';\r\n\r\nexport const EmbedExtension: Extension = {\r\n name: 'embed',\r\n parseRules: [\r\n {\r\n name: 'embed',\r\n pattern: /\\[embed:(\\w+)\\]\\(([^)]+)\\)(?:\\{([^}]+)\\})?/,\r\n render: (match) => {\r\n return {\r\n type: 'embed',\r\n content: match[2] || '', // URL\r\n raw: match[0] || '',\r\n attributes: {\r\n provider: match[1] || 'generic',\r\n url: match[2] || '',\r\n options: match[3] || ''\r\n }\r\n };\r\n }\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'embed',\r\n render: (token) => {\r\n const provider = token.attributes?.provider || 'generic';\r\n const url = token.attributes?.url || '';\r\n const options = token.attributes?.options || '';\r\n\r\n return renderEmbed(provider, url, options);\r\n }\r\n }\r\n ]\r\n};\r\n\r\nfunction renderEmbed(provider: string, url: string, options: string): string {\r\n const baseClasses = 'rounded-lg border bg-card text-card-foreground shadow-sm mb-6 overflow-hidden';\r\n const parsedOptions = parseOptions(options);\r\n\r\n switch (provider.toLowerCase()) {\r\n case 'youtube':\r\n return renderYouTubeEmbed(url, parsedOptions, baseClasses);\r\n case 'codepen':\r\n return renderCodePenEmbed(url, parsedOptions, baseClasses);\r\n case 'figma':\r\n return renderFigmaEmbed(url, parsedOptions, baseClasses);\r\n case 'twitter':\r\n case 'tweet':\r\n return renderTwitterEmbed(url, parsedOptions, baseClasses);\r\n case 'github':\r\n return renderGitHubEmbed(url, parsedOptions, baseClasses);\r\n case 'vimeo':\r\n return renderVimeoEmbed(url, parsedOptions, baseClasses);\r\n case 'spotify':\r\n return renderSpotifyEmbed(url, parsedOptions, baseClasses);\r\n case 'codesandbox':\r\n return renderCodeSandboxEmbed(url, parsedOptions, baseClasses);\r\n default:\r\n return renderGenericEmbed(url, parsedOptions, baseClasses);\r\n }\r\n}\r\n\r\nfunction renderYouTubeEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const videoId = extractYouTubeId(url);\r\n if (!videoId) {\r\n return createErrorEmbed('Invalid YouTube URL', url, classes);\r\n }\r\n\r\n const params = new URLSearchParams();\r\n if (options.autoplay === '1') params.set('autoplay', '1');\r\n if (options.mute === '1') params.set('mute', '1');\r\n if (options.loop === '1') {\r\n params.set('loop', '1');\r\n params.set('playlist', videoId);\r\n }\r\n if (options.controls === '0') params.set('controls', '0');\r\n if (options.start) params.set('start', options.start);\r\n\r\n params.set('rel', '0');\r\n params.set('modestbranding', '1');\r\n\r\n const embedUrl = `https://www.youtube.com/embed/${videoId}?${params.toString()}`;\r\n\r\n return `<div class=\"${classes}\">\r\n <div style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\">\r\n <iframe \r\n style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;\"\r\n src=\"${embedUrl}\" \r\n title=\"YouTube video player\"\r\n frameborder=\"0\" \r\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\"\r\n allowfullscreen>\r\n </iframe>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderCodePenEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const match = url.match(/codepen\\.io\\/([^\\/]+)\\/(?:pen|embed)\\/([^\\/\\?#]+)/);\r\n\r\n if (!match) {\r\n return createErrorEmbed('Invalid CodePen URL', url, classes);\r\n }\r\n\r\n const [, user, penId] = match;\r\n const height = options.height || '400';\r\n const theme = options.theme === 'light' ? 'light' : 'dark';\r\n const defaultTab = options.tab || 'result';\r\n\r\n const embedParams = new URLSearchParams({\r\n 'default-tab': defaultTab,\r\n 'theme-id': theme,\r\n 'editable': 'true'\r\n });\r\n\r\n const embedUrl = `https://codepen.io/${user}/embed/${penId}?${embedParams.toString()}`;\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n height=\"${height}\" \r\n style=\"width: 100%; border: 0;\" \r\n scrolling=\"no\" \r\n title=\"CodePen Embed - ${penId}\" \r\n src=\"${embedUrl}\" \r\n frameborder=\"0\" \r\n loading=\"lazy\" \r\n allowtransparency=\"true\" \r\n allowfullscreen=\"true\">\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderVimeoEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const videoId = extractVimeoId(url);\r\n if (!videoId) {\r\n return createErrorEmbed('Invalid Vimeo URL', url, classes);\r\n }\r\n\r\n const params = new URLSearchParams();\r\n if (options.autoplay === '1') params.set('autoplay', '1');\r\n if (options.mute === '1') params.set('muted', '1');\r\n if (options.loop === '1') params.set('loop', '1');\r\n\r\n const embedUrl = `https://player.vimeo.com/video/${videoId}?${params.toString()}`;\r\n\r\n return `<div class=\"${classes}\">\r\n <div style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\">\r\n <iframe \r\n style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;\"\r\n src=\"${embedUrl}\" \r\n title=\"Vimeo video player\"\r\n frameborder=\"0\" \r\n allow=\"autoplay; fullscreen; picture-in-picture\"\r\n allowfullscreen>\r\n </iframe>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderSpotifyEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const embedUrl = url.replace('open.spotify.com', 'open.spotify.com/embed');\r\n const height = options.height || '380';\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n style=\"border-radius: 12px;\" \r\n src=\"${embedUrl}\" \r\n width=\"100%\" \r\n height=\"${height}\" \r\n frameborder=\"0\" \r\n allowfullscreen=\"\" \r\n allow=\"autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture\" \r\n loading=\"lazy\">\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderCodeSandboxEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n let embedUrl = url;\r\n if (url.includes('/s/')) {\r\n embedUrl = url.replace('/s/', '/embed/');\r\n }\r\n\r\n const height = options.height || '500';\r\n const view = options.view || 'preview';\r\n\r\n if (!embedUrl.includes('?')) {\r\n embedUrl += `?view=${view}`;\r\n }\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n src=\"${embedUrl}\"\r\n style=\"width: 100%; height: ${height}px; border: 0; border-radius: 4px; overflow: hidden;\"\r\n title=\"CodeSandbox Embed\"\r\n allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\r\n sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\">\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderFigmaEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const embedUrl = `https://www.figma.com/embed?embed_host=share&url=${encodeURIComponent(url)}`;\r\n const height = options.height || '450';\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n style=\"border: none;\" \r\n width=\"100%\" \r\n height=\"${height}\" \r\n src=\"${embedUrl}\" \r\n allowfullscreen>\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderTwitterEmbed(url: string, _options: Record<string, string>, classes: string): string {\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4\">\r\n <div class=\"flex items-center gap-3 mb-3\">\r\n <svg class=\"w-6 h-6 fill-current text-blue-500\" viewBox=\"0 0 24 24\">\r\n <path d=\"M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z\"/>\r\n </svg>\r\n <div>\r\n <div class=\"font-semibold text-foreground\">Twitter Post</div>\r\n <div class=\"text-sm text-muted-foreground\">External Link</div>\r\n </div>\r\n </div>\r\n <a href=\"${url}\" target=\"_blank\" \r\n class=\"inline-flex items-center gap-2 text-primary hover:text-primary/80 font-medium transition-colors\">\r\n View on Twitter\r\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>\r\n </a>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderGitHubEmbed(url: string, _options: Record<string, string>, classes: string): string {\r\n const parts = url.replace('https://github.com/', '').split('/');\r\n const owner = parts[0];\r\n const repo = parts[1];\r\n\r\n if (!owner || !repo) {\r\n return createErrorEmbed('Invalid GitHub URL', url, classes);\r\n }\r\n\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4\">\r\n <div class=\"flex items-center gap-3 mb-3\">\r\n <svg class=\"w-6 h-6 fill-current\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z\"/>\r\n </svg>\r\n <div>\r\n <div class=\"font-semibold text-foreground text-lg\">${owner}/${repo}</div>\r\n <div class=\"text-sm text-muted-foreground\">GitHub Repository</div>\r\n </div>\r\n </div>\r\n <a href=\"${url}\" target=\"_blank\" \r\n class=\"inline-flex items-center gap-2 text-primary hover:text-primary/80 font-medium transition-colors\">\r\n View on GitHub\r\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>\r\n </a>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderGenericEmbed(url: string, _options: Record<string, string>, classes: string): string {\r\n const domain = extractDomain(url);\r\n\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4\">\r\n <div class=\"flex items-center gap-3 mb-3\">\r\n <div class=\"w-10 h-10 rounded-lg bg-muted flex items-center justify-center\">\r\n <svg class=\"w-5 h-5 text-muted-foreground\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <div class=\"font-semibold text-foreground\">External Link</div>\r\n <div class=\"text-sm text-muted-foreground\">${domain}</div>\r\n </div>\r\n </div>\r\n <a href=\"${url}\" target=\"_blank\" \r\n class=\"inline-flex items-center gap-2 text-primary hover:text-primary/80 font-medium transition-colors break-all\">\r\n ${url}\r\n <svg class=\"w-4 h-4 flex-shrink-0\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>\r\n </a>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction createErrorEmbed(error: string, url: string, classes: string): string {\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4 text-destructive\">\r\n <div class=\"font-medium flex items-center gap-2\">\r\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"/>\r\n </svg>\r\n ${error}\r\n </div>\r\n <div class=\"text-sm text-muted-foreground mt-1 break-all\">${url}</div>\r\n </div>\r\n </div>`;\r\n}\r\n\r\n// Utility functions for extracting IDs\r\nfunction extractYouTubeId(url: string): string | null {\r\n const patterns = [\r\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/|youtube\\.com\\/embed\\/|youtube\\.com\\/shorts\\/)([^&\\n?#]+)/,\r\n /youtube\\.com\\/watch\\?.*v=([^&\\n?#]+)/\r\n ];\r\n\r\n for (const pattern of patterns) {\r\n const match = url.match(pattern);\r\n if (match) return match[1] || null;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction extractVimeoId(url: string): string | null {\r\n const match = url.match(/vimeo\\.com\\/(?:.*\\/)?(\\d+)/);\r\n return match?.[1] ?? null;\r\n}","import { MarkdownParser } from './parser';\r\nimport { MarkdownRenderer } from './renderer';\r\nimport { LRUCache, hashContent } from './cache';\r\nimport type {\r\n MarkdownToken,\r\n Extension,\r\n EngineConfig,\r\n ExtensionRegistration,\r\n DebugInfo,\r\n PerformanceMetrics\r\n} from './types';\r\n\r\n// Import core extensions\r\nimport { CoreExtensions } from './extensions/core';\r\n// Import feature extensions\r\nimport { AlertExtension } from './extensions/alert';\r\nimport { ButtonExtension } from './extensions/button';\r\nimport { EmbedExtension } from './extensions/embed';\r\n\r\nexport interface RenderMetrics {\r\n inputSize: number;\r\n parseTime: number;\r\n renderTime: number;\r\n totalTime: number;\r\n tokenCount: number;\r\n cacheHit: boolean;\r\n}\r\n\r\nexport class ChangerawrMarkdown {\r\n private parser: MarkdownParser;\r\n private renderer: MarkdownRenderer;\r\n private extensions = new Map<string, Extension>();\r\n\r\n // Performance & Caching\r\n private parseCache: LRUCache<string, MarkdownToken[]>;\r\n private renderCache: LRUCache<string, string>;\r\n private parseTime = 0;\r\n private renderTime = 0;\r\n private lastTokenCount = 0;\r\n\r\n constructor(config?: EngineConfig) {\r\n this.parser = new MarkdownParser(config?.parser);\r\n this.renderer = new MarkdownRenderer(config?.renderer);\r\n\r\n // Initialize caches (enabled by default)\r\n this.parseCache = new LRUCache<string, MarkdownToken[]>(100);\r\n this.renderCache = new LRUCache<string, string>(100);\r\n\r\n // Register core extensions first (for backwards compatibility)\r\n this.registerCoreExtensions();\r\n\r\n // Register feature extensions (for backwards compatibility)\r\n this.registerFeatureExtensions();\r\n\r\n // Register custom extensions if provided\r\n if (config?.extensions) {\r\n config.extensions.forEach(extension => {\r\n this.registerExtension(extension);\r\n });\r\n }\r\n\r\n // No need for default rules - everything is extension-based now!\r\n }\r\n\r\n private registerFeatureExtensions(): void {\r\n this.registerExtension(AlertExtension);\r\n this.registerExtension(ButtonExtension);\r\n this.registerExtension(EmbedExtension);\r\n }\r\n\r\n private registerCoreExtensions(): void {\r\n CoreExtensions.forEach(extension => {\r\n this.registerExtension(extension);\r\n });\r\n }\r\n\r\n registerExtension(extension: Extension): ExtensionRegistration {\r\n try {\r\n // Validate extension before registration\r\n if (!extension.name || typeof extension.name !== 'string') {\r\n throw new Error('Extension must have a valid name');\r\n }\r\n\r\n if (!Array.isArray(extension.parseRules)) {\r\n throw new Error('Extension must have parseRules array');\r\n }\r\n\r\n if (!Array.isArray(extension.renderRules)) {\r\n throw new Error('Extension must have renderRules array');\r\n }\r\n\r\n // Validate parse rules\r\n extension.parseRules.forEach((rule, index) => {\r\n if (!rule.name || typeof rule.name !== 'string') {\r\n throw new Error(`Parse rule ${index} must have a valid name`);\r\n }\r\n if (!rule.pattern || !(rule.pattern instanceof RegExp)) {\r\n throw new Error(`Parse rule ${index} must have a valid RegExp pattern`);\r\n }\r\n if (!rule.render || typeof rule.render !== 'function') {\r\n throw new Error(`Parse rule ${index} must have a valid render function`);\r\n }\r\n });\r\n\r\n // Validate render rules\r\n extension.renderRules.forEach((rule, index) => {\r\n if (!rule.type || typeof rule.type !== 'string') {\r\n throw new Error(`Render rule ${index} must have a valid type`);\r\n }\r\n if (!rule.render || typeof rule.render !== 'function') {\r\n throw new Error(`Render rule ${index} must have a valid render function`);\r\n }\r\n });\r\n\r\n // Store extension\r\n this.extensions.set(extension.name, extension);\r\n\r\n // Add rules to parser and renderer\r\n extension.parseRules.forEach(rule => {\r\n this.parser.addRule(rule);\r\n });\r\n\r\n extension.renderRules.forEach(rule => {\r\n this.renderer.addRule(rule);\r\n });\r\n\r\n return {\r\n success: true,\r\n extensionName: extension.name\r\n };\r\n\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n\r\n return {\r\n success: false,\r\n extensionName: extension.name,\r\n error: errorMessage\r\n };\r\n }\r\n }\r\n\r\n unregisterExtension(name: string): boolean {\r\n const extension = this.extensions.get(name);\r\n if (!extension) {\r\n return false;\r\n }\r\n\r\n try {\r\n // Remove extension from map\r\n this.extensions.delete(name);\r\n\r\n // Rebuild parser and renderer to remove extension rules\r\n this.rebuildParserAndRenderer();\r\n\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n parse(markdown: string): MarkdownToken[] {\r\n // Check cache first\r\n const cacheKey = hashContent(markdown);\r\n const cached = this.parseCache.get(cacheKey);\r\n if (cached) {\r\n this.lastTokenCount = cached.length;\r\n return cached;\r\n }\r\n\r\n // Parse and cache\r\n const startTime = performance.now();\r\n const tokens = this.parser.parse(markdown);\r\n this.parseTime = performance.now() - startTime;\r\n this.lastTokenCount = tokens.length;\r\n\r\n this.parseCache.set(cacheKey, tokens);\r\n return tokens;\r\n }\r\n\r\n render(tokens: MarkdownToken[], cacheKey?: string): string {\r\n // If we have a cache key (from parse), use it for render cache too\r\n if (cacheKey) {\r\n const cached = this.renderCache.get(cacheKey);\r\n if (cached) {\r\n return cached;\r\n }\r\n }\r\n\r\n // Render and cache\r\n const startTime = performance.now();\r\n const html = this.renderer.render(tokens);\r\n this.renderTime = performance.now() - startTime;\r\n\r\n if (cacheKey) {\r\n this.renderCache.set(cacheKey, html);\r\n }\r\n return html;\r\n }\r\n\r\n toHtml(markdown: string): string {\r\n const cacheKey = hashContent(markdown);\r\n\r\n // Check if we have the full HTML cached\r\n const cachedHtml = this.renderCache.get(cacheKey);\r\n if (cachedHtml) {\r\n return cachedHtml;\r\n }\r\n\r\n // Parse (may be cached)\r\n const tokens = this.parse(markdown);\r\n\r\n // Render with the same cache key\r\n return this.render(tokens, cacheKey);\r\n }\r\n\r\n /**\r\n * Render markdown with performance metrics\r\n */\r\n toHtmlWithMetrics(markdown: string): { html: string; metrics: RenderMetrics } {\r\n const startTotal = performance.now();\r\n\r\n const parseCacheKey = hashContent(markdown);\r\n const parseCacheHit = this.parseCache.has(parseCacheKey);\r\n\r\n const html = this.toHtml(markdown);\r\n const totalTime = performance.now() - startTotal;\r\n\r\n const metrics: RenderMetrics = {\r\n inputSize: markdown.length,\r\n parseTime: this.parseTime,\r\n renderTime: this.renderTime,\r\n totalTime,\r\n tokenCount: this.lastTokenCount,\r\n cacheHit: parseCacheHit\r\n };\r\n\r\n return { html, metrics };\r\n }\r\n\r\n /**\r\n * Stream-render large documents in chunks for better performance\r\n */\r\n async toHtmlStreamed(\r\n markdown: string,\r\n options: {\r\n chunkSize?: number;\r\n onChunk?: (chunk: { html: string; progress: number }) => void;\r\n } = {}\r\n ): Promise<string> {\r\n const chunkSize = options.chunkSize || 50;\r\n const tokens = this.parse(markdown);\r\n const totalTokens = tokens.length;\r\n const chunks: string[] = [];\r\n\r\n for (let i = 0; i < tokens.length; i += chunkSize) {\r\n const chunkTokens = tokens.slice(i, Math.min(i + chunkSize, tokens.length));\r\n const chunkHtml = this.render(chunkTokens);\r\n chunks.push(chunkHtml);\r\n\r\n if (options.onChunk) {\r\n options.onChunk({\r\n html: chunkHtml,\r\n progress: Math.min(i + chunkSize, tokens.length) / totalTokens\r\n });\r\n }\r\n\r\n // Yield to event loop\r\n await new Promise(resolve => setTimeout(resolve, 0));\r\n }\r\n\r\n return chunks.join('');\r\n }\r\n\r\n getExtensions(): string[] {\r\n return Array.from(this.extensions.keys());\r\n }\r\n\r\n hasExtension(name: string): boolean {\r\n return this.extensions.has(name);\r\n }\r\n\r\n getWarnings(): string[] {\r\n return [...this.parser.getWarnings(), ...this.renderer.getWarnings()];\r\n }\r\n\r\n getDebugInfo(): DebugInfo | null {\r\n return {\r\n warnings: this.getWarnings(),\r\n parseTime: this.parseTime,\r\n renderTime: this.renderTime,\r\n tokenCount: this.lastTokenCount,\r\n iterationCount: 0\r\n };\r\n }\r\n\r\n getPerformanceMetrics(): PerformanceMetrics | null {\r\n return {\r\n parseTime: this.parseTime,\r\n renderTime: this.renderTime,\r\n totalTime: this.parseTime + this.renderTime,\r\n tokenCount: this.lastTokenCount\r\n };\r\n }\r\n\r\n /**\r\n * Get cache statistics\r\n */\r\n getCacheStats() {\r\n return {\r\n parse: this.parseCache.getStats(),\r\n render: this.renderCache.getStats()\r\n };\r\n }\r\n\r\n /**\r\n * Clear all caches\r\n */\r\n clearCaches(): void {\r\n this.parseCache.clear();\r\n this.renderCache.clear();\r\n }\r\n\r\n /**\r\n * Update cache capacity\r\n */\r\n setCacheSize(size: number): void {\r\n this.parseCache.setCapacity(size);\r\n this.renderCache.setCapacity(size);\r\n }\r\n\r\n private rebuildParserAndRenderer(): void {\r\n // Get current configs\r\n const parserConfig = this.parser.getConfig();\r\n const rendererConfig = this.renderer.getConfig();\r\n\r\n // Recreate parser and renderer completely\r\n this.parser = new MarkdownParser(parserConfig);\r\n this.renderer = new MarkdownRenderer(rendererConfig);\r\n\r\n // Clear caches since we're rebuilding\r\n this.parseCache.clear();\r\n this.renderCache.clear();\r\n\r\n // Get the extensions that are still in the map (after removal)\r\n const extensionsToRegister = Array.from(this.extensions.values());\r\n\r\n // Re-register remaining extensions in the correct order\r\n // Feature extensions first\r\n const featureExtensions = extensionsToRegister.filter(ext =>\r\n ['alert', 'button', 'embed'].includes(ext.name)\r\n );\r\n\r\n // Core extensions second\r\n const coreExtensions = extensionsToRegister.filter(ext =>\r\n ['text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(ext.name)\r\n );\r\n\r\n // Custom extensions last\r\n const customExtensions = extensionsToRegister.filter(ext =>\r\n !['alert', 'button', 'embed', 'text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(ext.name)\r\n );\r\n\r\n // Register in correct order without going through the extension map\r\n [...featureExtensions, ...coreExtensions, ...customExtensions].forEach(extension => {\r\n // Add rules directly to parser and renderer\r\n extension.parseRules.forEach(rule => {\r\n this.parser.addRule(rule);\r\n });\r\n\r\n extension.renderRules.forEach(rule => {\r\n this.renderer.addRule(rule);\r\n });\r\n });\r\n }\r\n}\r\n\r\n// Factory functions for specific use cases\r\nexport function createMinimalEngine(config?: EngineConfig): ChangerawrMarkdown {\r\n // Create engine with NO default extensions\r\n const minimalConfig = {\r\n ...config,\r\n extensions: config?.extensions || []\r\n };\r\n\r\n const engine = new ChangerawrMarkdown();\r\n\r\n // Clear all default extensions\r\n const defaultExtensions = engine.getExtensions();\r\n defaultExtensions.forEach(ext => engine.unregisterExtension(ext));\r\n\r\n // Only add the ones specified in config\r\n if (minimalConfig.extensions) {\r\n minimalConfig.extensions.forEach(ext => engine.registerExtension(ext));\r\n }\r\n\r\n return engine;\r\n}\r\n\r\nexport function createCoreOnlyEngine(config?: EngineConfig): ChangerawrMarkdown {\r\n // Create engine with only core extensions (no alerts, buttons, embeds)\r\n const engine = new ChangerawrMarkdown();\r\n\r\n // Remove feature extensions, keep core\r\n engine.unregisterExtension('alert');\r\n engine.unregisterExtension('button');\r\n engine.unregisterExtension('embed');\r\n\r\n // Add any custom extensions\r\n if (config?.extensions) {\r\n config.extensions.forEach(ext => engine.registerExtension(ext));\r\n }\r\n\r\n return engine;\r\n}\r\n\r\n// Default instance for convenience functions\r\nexport const markdown = new ChangerawrMarkdown();\r\n\r\n// Convenience functions\r\nexport function parseMarkdown(content: string): MarkdownToken[] {\r\n return markdown.parse(content);\r\n}\r\n\r\nexport function renderMarkdown(content: string): string {\r\n return markdown.toHtml(content);\r\n}"],"mappings":"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","names":["markdown","module","hash","markdown","markdown"]}
|
|
1
|
+
{"version":3,"sources":["../src/standalone.ts","../src/parser.ts","../src/utils.ts","../src/renderer.ts","../src/cache.ts","../src/extensions/core/blockquote.ts","../src/extensions/core/breaks.ts","../src/extensions/core/code.ts","../src/extensions/core/emphasis.ts","../src/extensions/core/heading.ts","../src/extensions/core/hr.ts","../src/extensions/core/image.ts","../src/extensions/core/links.ts","../src/extensions/core/lists.ts","../src/extensions/core/paragraph.ts","../src/extensions/core/text.ts","../src/extensions/core/strikethrough.ts","../src/extensions/core/index.ts","../src/extensions/alert.ts","../src/extensions/button.ts","../src/extensions/embed.ts","../src/engine.ts"],"sourcesContent":["/**\r\n * Standalone version of Changerawr Markdown for vanilla JavaScript usage\r\n * No React dependencies - works in browser and Node.js environments\r\n */\r\n\r\nimport { ChangerawrMarkdown } from './engine';\r\nimport type { MarkdownToken, Extension, EngineConfig } from './types';\r\n\r\n// Main renderCum function for vanilla JS usage\r\nexport function renderCum(markdown: string, config?: EngineConfig): string {\r\n const engine = new ChangerawrMarkdown(config);\r\n return engine.toHtml(markdown);\r\n}\r\n\r\n// Parse-only function for getting tokens\r\nexport function parseCum(markdown: string, config?: EngineConfig): MarkdownToken[] {\r\n const engine = new ChangerawrMarkdown(config);\r\n return engine.parse(markdown);\r\n}\r\n\r\n// Create a custom engine instance\r\nexport function createCumEngine(config?: EngineConfig): ChangerawrMarkdown {\r\n return new ChangerawrMarkdown(config);\r\n}\r\n\r\n// Convenience functions with different output formats\r\nexport function renderCumToHtml(markdown: string): string {\r\n return renderCum(markdown, {\r\n renderer: { format: 'html' }\r\n });\r\n}\r\n\r\nexport function renderCumToTailwind(markdown: string): string {\r\n return renderCum(markdown, {\r\n renderer: { format: 'tailwind' }\r\n });\r\n}\r\n\r\nexport function renderCumToJson(markdown: string): MarkdownToken[] {\r\n return parseCum(markdown);\r\n}\r\n\r\n// Export for Node.js/module usage\r\nexport {\r\n ChangerawrMarkdown,\r\n type MarkdownToken,\r\n type Extension,\r\n type EngineConfig\r\n};\r\n\r\n// Default export - this is what tsup will assign to the global\r\nexport default {\r\n renderCum,\r\n parseCum,\r\n createCumEngine,\r\n renderCumToHtml,\r\n renderCumToTailwind,\r\n renderCumToJson,\r\n // Legacy aliases\r\n render: renderCum,\r\n parse: parseCum,\r\n // Include the main class\r\n ChangerawrMarkdown\r\n};","import type { MarkdownToken, ParseRule, ParserConfig } from './types';\r\n\r\nexport class MarkdownParser {\r\n private rules: ParseRule[] = [];\r\n private warnings: string[] = [];\r\n private config: ParserConfig;\r\n private compiledPatterns = new Map<ParseRule, RegExp>(); // Cache compiled regexes\r\n\r\n constructor(config?: ParserConfig) {\r\n this.config = {\r\n debugMode: false,\r\n maxIterations: 10000,\r\n validateMarkdown: false,\r\n ...config\r\n };\r\n }\r\n\r\n addRule(rule: ParseRule): void {\r\n this.rules.push(rule);\r\n // Pre-compile the regex pattern (without global flag for position-based matching)\r\n this.compiledPatterns.set(\r\n rule,\r\n new RegExp(rule.pattern.source, rule.pattern.flags.replace('g', ''))\r\n );\r\n // Sort by priority - extensions should define their own priority\r\n this.rules.sort((a, b) => {\r\n // Feature extensions first (alert, button, embed) - they have more specific patterns\r\n const aFeatureExtension = ['alert', 'button', 'embed'].includes(a.name);\r\n const bFeatureExtension = ['alert', 'button', 'embed'].includes(b.name);\r\n\r\n if (aFeatureExtension && !bFeatureExtension) return -1;\r\n if (!aFeatureExtension && bFeatureExtension) return 1;\r\n\r\n // Core extensions next\r\n const aCoreExtension = ['text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(a.name);\r\n const bCoreExtension = ['text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(b.name);\r\n\r\n if (aCoreExtension && !bCoreExtension) return -1;\r\n if (!aCoreExtension && bCoreExtension) return 1;\r\n\r\n // Within same category, specific ordering\r\n // Images before links (more specific pattern)\r\n if (a.name === 'image' && b.name === 'link') return -1;\r\n if (a.name === 'link' && b.name === 'image') return 1;\r\n\r\n // Task lists before regular lists\r\n if (a.name === 'task-item' && b.name === 'list-item') return -1;\r\n if (a.name === 'list-item' && b.name === 'task-item') return 1;\r\n\r\n // Code blocks before inline code\r\n if (a.name === 'codeblock' && b.name === 'code') return -1;\r\n if (a.name === 'code' && b.name === 'codeblock') return 1;\r\n\r\n // Bold before italic\r\n if (a.name === 'bold' && b.name === 'italic') return -1;\r\n if (a.name === 'italic' && b.name === 'bold') return 1;\r\n\r\n // Then alphabetical\r\n return a.name.localeCompare(b.name);\r\n });\r\n }\r\n\r\n hasRule(name: string): boolean {\r\n return this.rules.some(rule => rule.name === name);\r\n }\r\n\r\n parse(markdown: string): MarkdownToken[] {\r\n // Clear previous warnings\r\n this.warnings = [];\r\n\r\n if (!markdown.trim()) {\r\n return [];\r\n }\r\n\r\n // Check if we have any rules at all\r\n if (this.rules.length === 0) {\r\n this.warnings.push('No parse rules registered - consider using CoreExtensions');\r\n return [{\r\n type: 'text',\r\n content: markdown,\r\n raw: markdown\r\n }];\r\n }\r\n\r\n // Pre-process markdown to handle common issues\r\n const processedMarkdown = this.preprocessMarkdown(markdown);\r\n\r\n const tokens: MarkdownToken[] = [];\r\n let remaining = processedMarkdown;\r\n let iterationCount = 0;\r\n const maxIterations = this.config.maxIterations || 10000;\r\n\r\n while (remaining.length > 0 && iterationCount < maxIterations) {\r\n iterationCount++;\r\n let matched = false;\r\n let bestMatch: { rule: ParseRule; match: RegExpMatchArray; priority: number } | null = null;\r\n let nextBestMatchIndex: number | null = null;\r\n\r\n // Try each rule and find the best match (earliest position)\r\n for (const rule of this.rules) {\r\n try {\r\n // Use pre-compiled regex pattern\r\n const pattern = this.compiledPatterns.get(rule)!;\r\n const match = remaining.match(pattern);\r\n\r\n if (match && match.index !== undefined) {\r\n // If we found a match at position 0, use it immediately (common case)\r\n if (match.index === 0) {\r\n bestMatch = { rule, match, priority: 1000 };\r\n break; // Early exit - can't get better than position 0\r\n }\r\n\r\n // Track the closest match for chunking optimization\r\n if (nextBestMatchIndex === null || match.index < nextBestMatchIndex) {\r\n nextBestMatchIndex = match.index;\r\n }\r\n\r\n // Otherwise, consider nearby matches\r\n const priority = 1000 - match.index;\r\n\r\n if (!bestMatch || priority > bestMatch.priority ||\r\n (priority === bestMatch.priority && match.index < (bestMatch.match.index || 0))) {\r\n bestMatch = { rule, match, priority };\r\n }\r\n }\r\n } catch (error) {\r\n if (this.config.debugMode) {\r\n console.warn(`Error in rule \"${rule.name}\":`, error);\r\n }\r\n }\r\n }\r\n\r\n if (bestMatch && bestMatch.match.index !== undefined) {\r\n const { rule, match } = bestMatch;\r\n const matchIndex = match.index as number;\r\n\r\n // If match is not at the beginning, take text before it\r\n if (matchIndex > 0) {\r\n const textBefore = remaining.slice(0, matchIndex);\r\n tokens.push({\r\n type: 'text',\r\n content: textBefore,\r\n raw: textBefore\r\n });\r\n remaining = remaining.slice(matchIndex);\r\n continue;\r\n }\r\n\r\n // Process the match\r\n try {\r\n const token = rule.render(match);\r\n tokens.push({\r\n ...token,\r\n raw: match[0] || ''\r\n });\r\n\r\n remaining = remaining.slice(match[0]?.length || 0);\r\n matched = true;\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n this.warnings.push(`Failed to render ${rule.name}: ${errorMessage}`);\r\n\r\n // Fall back to treating as text\r\n const char = remaining[0];\r\n if (char) {\r\n tokens.push({\r\n type: 'text',\r\n content: char,\r\n raw: char\r\n });\r\n remaining = remaining.slice(1);\r\n }\r\n }\r\n }\r\n\r\n if (!matched) {\r\n // Use the next match index we already found during the search\r\n // This avoids a second expensive search through all rules\r\n const chunkSize = nextBestMatchIndex !== null\r\n ? nextBestMatchIndex\r\n : Math.min(remaining.length, 1000); // Take up to 1000 chars of plain text\r\n\r\n const textChunk = remaining.slice(0, chunkSize);\r\n\r\n tokens.push({\r\n type: 'text',\r\n content: textChunk,\r\n raw: textChunk\r\n });\r\n remaining = remaining.slice(chunkSize);\r\n }\r\n }\r\n\r\n if (iterationCount >= maxIterations) {\r\n this.warnings.push('Parser hit maximum iterations - possible infinite loop detected');\r\n }\r\n\r\n // Post-process tokens to merge consecutive text and validate structure\r\n const processedTokens = this.postProcessTokens(tokens);\r\n\r\n return processedTokens;\r\n }\r\n\r\n getWarnings(): string[] {\r\n return [...this.warnings];\r\n }\r\n\r\n getConfig(): ParserConfig {\r\n return { ...this.config };\r\n }\r\n\r\n updateConfig(config: Partial<ParserConfig>): void {\r\n this.config = { ...this.config, ...config };\r\n }\r\n\r\n setDebugMode(enabled: boolean): void {\r\n this.config.debugMode = enabled;\r\n }\r\n\r\n clearWarnings(): void {\r\n this.warnings = [];\r\n }\r\n\r\n private preprocessMarkdown(markdown: string): string {\r\n // Check for common markdown issues and warn about them\r\n if (this.config.validateMarkdown) {\r\n this.validateMarkdown(markdown);\r\n }\r\n\r\n // Normalize line endings\r\n return markdown.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\r\n }\r\n\r\n private validateMarkdown(markdown: string): void {\r\n // Check for unclosed bold markers\r\n const boldMatches = markdown.match(/\\*\\*/g);\r\n if (boldMatches && boldMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed bold markers (**) detected - some bold formatting may not work');\r\n }\r\n\r\n // Check for unclosed italic markers\r\n const italicMatches = markdown.match(/(?<!\\*)\\*(?!\\*)/g);\r\n if (italicMatches && italicMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed italic markers (*) detected - some italic formatting may not work');\r\n }\r\n\r\n // Check for unclosed code blocks\r\n const codeBlockMatches = markdown.match(/```/g);\r\n if (codeBlockMatches && codeBlockMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed code blocks (```) detected - some code formatting may not work');\r\n }\r\n\r\n // Check for unclosed inline code\r\n const inlineCodeMatches = markdown.match(/`/g);\r\n if (inlineCodeMatches && inlineCodeMatches.length % 2 !== 0) {\r\n this.warnings.push('Unclosed inline code markers (`) detected - some code formatting may not work');\r\n }\r\n }\r\n\r\n private postProcessTokens(tokens: MarkdownToken[]): MarkdownToken[] {\r\n const processed: MarkdownToken[] = [];\r\n let i = 0;\r\n\r\n while (i < tokens.length) {\r\n const token = tokens[i];\r\n\r\n if (token && token.type === 'text') {\r\n // Collect consecutive text tokens\r\n let textContent = token.content || token.raw || '';\r\n let j = i + 1;\r\n\r\n while (j < tokens.length && tokens[j] && tokens[j]!.type === 'text') {\r\n const nextToken = tokens[j]!;\r\n textContent += nextToken.content || nextToken.raw || '';\r\n j++;\r\n }\r\n\r\n // Only create a text token if there's actual content\r\n if (textContent.trim().length > 0 || textContent.includes('\\n')) {\r\n processed.push({\r\n type: 'text',\r\n content: textContent,\r\n raw: textContent\r\n });\r\n }\r\n\r\n i = j;\r\n } else if (token) {\r\n // Recursively parse content for block-level elements\r\n const processedToken = this.recursivelyParseBlockContent(token);\r\n processed.push(processedToken);\r\n i++;\r\n } else {\r\n i++;\r\n }\r\n }\r\n\r\n return processed;\r\n }\r\n\r\n private recursivelyParseBlockContent(token: MarkdownToken): MarkdownToken {\r\n // List of token types that should have their content recursively parsed\r\n const blockTypes = ['alert', 'blockquote', 'list-item', 'task-item'];\r\n\r\n if (blockTypes.includes(token.type) && token.content && token.content.trim()) {\r\n // Recursively parse the content into child tokens\r\n // For list-items and task-items, we need to exclude list rules to prevent\r\n // dashes in inline content (like \"**bold** - text\") from being treated as nested list items\r\n let children: MarkdownToken[];\r\n\r\n if ((token.type === 'list-item' || token.type === 'task-item') && this.rules.some(r => r.name === 'list-item')) {\r\n // Create a parser with the list-item rule excluded\r\n const parserWithoutListRule = new MarkdownParser(this.config);\r\n this.rules.forEach(rule => {\r\n // Skip list-item rules when parsing inside list items\r\n if (rule.name !== 'list-item' && rule.name !== 'task-item') {\r\n parserWithoutListRule.addRule(rule);\r\n }\r\n });\r\n children = parserWithoutListRule.parse(token.content);\r\n } else {\r\n children = this.parse(token.content);\r\n }\r\n\r\n return {\r\n ...token,\r\n children\r\n };\r\n }\r\n\r\n return token;\r\n }\r\n}","/**\r\n * Utility functions for Changerawr Markdown\r\n */\r\n\r\n// Import DOMPurify with SSR safety\r\nlet DOMPurify: { sanitize: (html: string, options?: Record<string, unknown>) => string } = {\r\n sanitize: (html: string) => html\r\n};\r\n\r\nif (typeof window !== 'undefined') {\r\n import('dompurify').then(module => {\r\n DOMPurify = module.default;\r\n }).catch(err => {\r\n console.error('Failed to load DOMPurify', err);\r\n });\r\n}\r\n\r\n// Allowed HTML tags and attributes for sanitization\r\nconst ALLOWED_TAGS = [\r\n // Standard HTML\r\n 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'br', 'strong', 'em', 'del', 'ins',\r\n 'a', 'img', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'table', 'thead',\r\n 'tbody', 'tr', 'th', 'td', 'div', 'span', 'sup', 'sub', 'hr', 'input',\r\n // Embeds\r\n 'iframe', 'embed', 'object', 'param', 'video', 'audio', 'source',\r\n // SVG\r\n 'svg', 'path', 'polyline', 'line', 'circle', 'rect', 'g', 'defs', 'use',\r\n // Form elements\r\n 'form', 'fieldset', 'legend', 'label', 'select', 'option', 'textarea', 'button'\r\n];\r\n\r\nconst ALLOWED_ATTR = [\r\n // Standard attributes\r\n 'href', 'title', 'alt', 'src', 'class', 'id', 'target', 'rel', 'type',\r\n 'checked', 'disabled', 'loading', 'width', 'height', 'style', 'role',\r\n // Iframe attributes\r\n 'frameborder', 'allowfullscreen', 'allow', 'sandbox', 'scrolling',\r\n 'allowtransparency', 'name', 'seamless', 'srcdoc',\r\n // Data attributes (for embeds)\r\n 'data-*',\r\n // SVG attributes\r\n 'viewBox', 'fill', 'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin',\r\n 'd', 'points', 'x1', 'y1', 'x2', 'y2', 'cx', 'cy', 'r', 'rx', 'ry',\r\n // Media attributes\r\n 'autoplay', 'controls', 'loop', 'muted', 'preload', 'poster',\r\n // Form attributes\r\n 'value', 'placeholder', 'required', 'readonly', 'maxlength', 'minlength',\r\n 'max', 'min', 'step', 'pattern', 'autocomplete', 'autofocus'\r\n];\r\n\r\n/**\r\n * Escape HTML special characters\r\n */\r\nexport function escapeHtml(text: string): string {\r\n const map: Record<string, string> = {\r\n '&': '&',\r\n '<': '<',\r\n '>': '>',\r\n '\"': '"',\r\n \"'\": '''\r\n };\r\n return text.replace(/[&<>\"']/g, char => map[char] || char);\r\n}\r\n\r\n/**\r\n * Generate URL-friendly ID from text\r\n */\r\nexport function generateId(text: string): string {\r\n return text\r\n .toLowerCase()\r\n .replace(/[^\\w\\s-]/g, '')\r\n .replace(/\\s+/g, '-')\r\n .replace(/-+/g, '-')\r\n .replace(/^-|-$/g, '')\r\n .trim();\r\n}\r\n\r\n/**\r\n * Sanitize HTML content using DOMPurify\r\n */\r\nexport function sanitizeHtml(html: string): string {\r\n try {\r\n // Skip sanitization for embed content that might be sensitive\r\n if (html.includes('codepen.io/') || html.includes('youtube.com/embed/')) {\r\n return html;\r\n }\r\n\r\n // Use DOMPurify if available\r\n if (typeof DOMPurify?.sanitize === 'function') {\r\n const sanitized = DOMPurify.sanitize(html, {\r\n ALLOWED_TAGS,\r\n ALLOWED_ATTR,\r\n ALLOW_DATA_ATTR: true,\r\n ALLOW_UNKNOWN_PROTOCOLS: false,\r\n SAFE_FOR_TEMPLATES: false,\r\n WHOLE_DOCUMENT: false,\r\n RETURN_DOM: false,\r\n RETURN_DOM_FRAGMENT: false,\r\n FORCE_BODY: false,\r\n SANITIZE_DOM: false,\r\n SANITIZE_NAMED_PROPS: false,\r\n FORBID_ATTR: ['onload', 'onerror', 'onclick', 'onmouseover', 'onmouseout', 'onfocus', 'onblur'],\r\n ADD_TAGS: ['iframe', 'embed', 'object', 'param'],\r\n ADD_ATTR: [\r\n 'allow', 'allowfullscreen', 'frameborder', 'scrolling',\r\n 'allowtransparency', 'sandbox', 'loading', 'style',\r\n 'title', 'name', 'seamless', 'srcdoc'\r\n ],\r\n ALLOWED_URI_REGEXP: /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp|xxx):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i\r\n });\r\n\r\n // If too much content is lost, fall back to basic sanitization\r\n if (sanitized.length < html.length * 0.7) {\r\n return basicSanitize(html);\r\n }\r\n\r\n return sanitized;\r\n }\r\n\r\n // Fallback to basic sanitization\r\n return basicSanitize(html);\r\n } catch (error) {\r\n console.error('Sanitization failed:', error);\r\n return basicSanitize(html);\r\n }\r\n}\r\n\r\n/**\r\n * Basic HTML sanitization - removes dangerous content\r\n */\r\nexport function basicSanitize(html: string): string {\r\n return html\r\n .replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '')\r\n .replace(/on\\w+\\s*=\\s*\"[^\"]*\"/gi, '')\r\n .replace(/on\\w+\\s*=\\s*'[^']*'/gi, '')\r\n .replace(/javascript:/gi, '');\r\n}\r\n\r\n/**\r\n * Check if code is running in browser environment\r\n */\r\nexport function isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof document !== 'undefined';\r\n}\r\n\r\n/**\r\n * Check if code is running in Node.js environment\r\n */\r\nexport function isNode(): boolean {\r\n return typeof process !== 'undefined' &&\r\n process.versions != null &&\r\n process.versions.node != null;\r\n}\r\n\r\n/**\r\n * Debounce function for performance optimization\r\n */\r\nexport function debounce<T extends (...args: any[]) => any>(\r\n func: T,\r\n wait: number\r\n): (...args: Parameters<T>) => void {\r\n let timeout: NodeJS.Timeout | number;\r\n\r\n return function executedFunction(...args: Parameters<T>) {\r\n const later = () => {\r\n clearTimeout(timeout as NodeJS.Timeout);\r\n func(...args);\r\n };\r\n\r\n clearTimeout(timeout as NodeJS.Timeout);\r\n timeout = setTimeout(later, wait);\r\n };\r\n}\r\n\r\n/**\r\n * Deep merge two objects\r\n */\r\nexport function deepMerge<T extends Record<string, any>>(target: T, source: Partial<T>): T {\r\n const output = { ...target };\r\n\r\n for (const key in source) {\r\n if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {\r\n if (key in target && typeof target[key] === 'object' && !Array.isArray(target[key])) {\r\n output[key] = deepMerge(target[key], source[key] as any);\r\n } else {\r\n output[key] = source[key] as any;\r\n }\r\n } else {\r\n output[key] = source[key] as any;\r\n }\r\n }\r\n\r\n return output;\r\n}\r\n\r\n/**\r\n * Extract domain from URL\r\n */\r\nexport function extractDomain(url: string): string {\r\n try {\r\n return new URL(url).hostname;\r\n } catch {\r\n return url;\r\n }\r\n}\r\n\r\n/**\r\n * Check if URL is valid\r\n */\r\nexport function isValidUrl(url: string): boolean {\r\n try {\r\n new URL(url);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Parse options string into key-value object\r\n */\r\nexport function parseOptions(options: string): Record<string, string> {\r\n const parsed: Record<string, string> = {};\r\n if (!options) return parsed;\r\n\r\n // Parse options like \"height:400,theme:dark,autoplay:1\"\r\n options.split(',').forEach(option => {\r\n const [key, value] = option.split(':').map(s => s.trim());\r\n if (key && value) {\r\n parsed[key] = value;\r\n }\r\n });\r\n\r\n return parsed;\r\n}\r\n\r\n/**\r\n * Performance measurement utility\r\n */\r\nexport class PerformanceTimer {\r\n private startTime: number;\r\n private marks: Record<string, number> = {};\r\n\r\n constructor() {\r\n this.startTime = performance.now();\r\n }\r\n\r\n mark(name: string): void {\r\n this.marks[name] = performance.now() - this.startTime;\r\n }\r\n\r\n getTime(name?: string): number {\r\n if (name && this.marks[name] !== undefined) {\r\n return this.marks[name];\r\n }\r\n return performance.now() - this.startTime;\r\n }\r\n\r\n getAllMarks(): Record<string, number> {\r\n return { ...this.marks };\r\n }\r\n}\r\n\r\n/**\r\n * Simple logger with different levels\r\n */\r\nexport class Logger {\r\n private debugMode: boolean;\r\n\r\n constructor(debugMode = false) {\r\n this.debugMode = debugMode;\r\n }\r\n\r\n debug(...args: any[]): void {\r\n if (this.debugMode) {\r\n console.log('[DEBUG]', ...args);\r\n }\r\n }\r\n\r\n info(...args: any[]): void {\r\n console.info('[INFO]', ...args);\r\n }\r\n\r\n warn(...args: any[]): void {\r\n console.warn('[WARN]', ...args);\r\n }\r\n\r\n error(...args: any[]): void {\r\n console.error('[ERROR]', ...args);\r\n }\r\n\r\n setDebugMode(enabled: boolean): void {\r\n this.debugMode = enabled;\r\n }\r\n}","import type { MarkdownToken, RenderRule, RendererConfig } from './types';\r\nimport { sanitizeHtml, escapeHtml } from './utils';\r\n\r\nexport class MarkdownRenderer {\r\n private rules = new Map<string, RenderRule>();\r\n private warnings: string[] = [];\r\n private config: RendererConfig;\r\n\r\n constructor(config?: RendererConfig) {\r\n this.config = {\r\n format: 'tailwind',\r\n sanitize: true,\r\n allowUnsafeHtml: false,\r\n debugMode: false,\r\n ...config\r\n };\r\n }\r\n\r\n addRule(rule: RenderRule): void {\r\n this.rules.set(rule.type, rule);\r\n }\r\n\r\n hasRule(type: string): boolean {\r\n return this.rules.has(type);\r\n }\r\n\r\n render(tokens: MarkdownToken[]): string {\r\n this.warnings = [];\r\n\r\n // Inject format into each token for extensions to use\r\n const tokensWithFormat = tokens.map(token => ({\r\n ...token,\r\n attributes: {\r\n ...token.attributes,\r\n format: this.config.format\r\n }\r\n }));\r\n\r\n // Render each token using registered extensions\r\n const htmlParts = tokensWithFormat.map(token => this.renderToken(token));\r\n const combinedHtml = htmlParts.join('');\r\n\r\n // Apply sanitization if enabled\r\n if (this.config.sanitize && !this.config.allowUnsafeHtml) {\r\n return sanitizeHtml(combinedHtml);\r\n }\r\n\r\n return combinedHtml;\r\n }\r\n\r\n private renderToken(token: MarkdownToken): string {\r\n const rule = this.rules.get(token.type);\r\n\r\n if (rule) {\r\n try {\r\n // If token has children, render them and inject into attributes\r\n let tokenToRender = token;\r\n if (token.children && token.children.length > 0) {\r\n const renderedChildren = this.render(token.children);\r\n tokenToRender = {\r\n ...token,\r\n attributes: {\r\n ...token.attributes,\r\n renderedChildren // Extensions can use this instead of re-parsing\r\n }\r\n };\r\n }\r\n\r\n return rule.render(tokenToRender);\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n this.warnings.push(`Render error for ${token.type}: ${errorMessage}`);\r\n return this.createErrorBlock(`Render error for ${token.type}: ${errorMessage}`);\r\n }\r\n }\r\n\r\n // For unknown types in development, show debug info\r\n if (this.config.debugMode) {\r\n return this.createDebugBlock(token);\r\n }\r\n\r\n // Fallback: treat as text if no rule found\r\n return escapeHtml(token.content || token.raw || '');\r\n }\r\n\r\n private createErrorBlock(message: string): string {\r\n if (this.config.format === 'html') {\r\n return `<div style=\"background-color: #fee; border: 1px solid #fcc; color: #c66; padding: 8px; border-radius: 4px; margin: 8px 0; font-size: 14px;\">\r\n <strong>Render Error:</strong> ${escapeHtml(message)}\r\n </div>`;\r\n }\r\n\r\n return `<div class=\"bg-red-100 border border-red-300 text-red-800 p-2 rounded text-sm mb-2\">\r\n <strong>Render Error:</strong> ${escapeHtml(message)}\r\n </div>`;\r\n }\r\n\r\n private createDebugBlock(token: MarkdownToken): string {\r\n if (this.config.format === 'html') {\r\n return `<div style=\"background-color: #fffbf0; border: 1px solid #fed; color: #b8860b; padding: 8px; border-radius: 4px; margin: 8px 0; font-size: 14px;\">\r\n <strong>Unknown token type:</strong> ${escapeHtml(token.type)}<br>\r\n <strong>Content:</strong> ${escapeHtml(token.content || token.raw || '')}\r\n </div>`;\r\n }\r\n\r\n return `<div class=\"bg-yellow-100 border border-yellow-300 text-yellow-800 p-2 rounded text-sm mb-2\">\r\n <strong>Unknown token type:</strong> ${escapeHtml(token.type)}<br>\r\n <strong>Content:</strong> ${escapeHtml(token.content || token.raw || '')}\r\n </div>`;\r\n }\r\n\r\n getWarnings(): string[] {\r\n return [...this.warnings];\r\n }\r\n\r\n getConfig(): RendererConfig {\r\n return { ...this.config };\r\n }\r\n\r\n updateConfig(config: Partial<RendererConfig>): void {\r\n this.config = { ...this.config, ...config };\r\n }\r\n\r\n setDebugMode(enabled: boolean): void {\r\n this.config.debugMode = enabled;\r\n }\r\n\r\n clearWarnings(): void {\r\n this.warnings = [];\r\n }\r\n}","/**\r\n * LRU (Least Recently Used) Cache implementation for markdown rendering\r\n * Provides efficient caching with automatic eviction of old entries\r\n */\r\n\r\nexport interface CacheEntry<V> {\r\n value: V;\r\n timestamp: number;\r\n accessCount: number;\r\n}\r\n\r\nexport interface CacheStats {\r\n size: number;\r\n capacity: number;\r\n hits: number;\r\n misses: number;\r\n hitRate: number;\r\n evictions: number;\r\n}\r\n\r\nexport class LRUCache<K, V> {\r\n private cache = new Map<K, CacheEntry<V>>();\r\n private capacity: number;\r\n private hits = 0;\r\n private misses = 0;\r\n private evictions = 0;\r\n\r\n constructor(capacity = 100) {\r\n if (capacity <= 0) {\r\n throw new Error('Cache capacity must be greater than 0');\r\n }\r\n this.capacity = capacity;\r\n }\r\n\r\n /**\r\n * Get a value from the cache\r\n */\r\n get(key: K): V | undefined {\r\n const entry = this.cache.get(key);\r\n\r\n if (entry) {\r\n // Update access metadata\r\n entry.timestamp = Date.now();\r\n entry.accessCount++;\r\n this.hits++;\r\n\r\n // Move to end (most recently used)\r\n this.cache.delete(key);\r\n this.cache.set(key, entry);\r\n\r\n return entry.value;\r\n }\r\n\r\n this.misses++;\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Set a value in the cache\r\n */\r\n set(key: K, value: V): void {\r\n // If key already exists, update it\r\n if (this.cache.has(key)) {\r\n this.cache.delete(key);\r\n }\r\n // If at capacity, evict least recently used\r\n else if (this.cache.size >= this.capacity) {\r\n this.evictLRU();\r\n }\r\n\r\n // Add new entry at end (most recently used)\r\n this.cache.set(key, {\r\n value,\r\n timestamp: Date.now(),\r\n accessCount: 0\r\n });\r\n }\r\n\r\n /**\r\n * Check if a key exists in the cache\r\n */\r\n has(key: K): boolean {\r\n return this.cache.has(key);\r\n }\r\n\r\n /**\r\n * Delete a specific key from the cache\r\n */\r\n delete(key: K): boolean {\r\n return this.cache.delete(key);\r\n }\r\n\r\n /**\r\n * Clear all entries from the cache\r\n */\r\n clear(): void {\r\n this.cache.clear();\r\n this.hits = 0;\r\n this.misses = 0;\r\n this.evictions = 0;\r\n }\r\n\r\n /**\r\n * Get the current size of the cache\r\n */\r\n get size(): number {\r\n return this.cache.size;\r\n }\r\n\r\n /**\r\n * Get cache statistics\r\n */\r\n getStats(): CacheStats {\r\n const totalRequests = this.hits + this.misses;\r\n return {\r\n size: this.cache.size,\r\n capacity: this.capacity,\r\n hits: this.hits,\r\n misses: this.misses,\r\n hitRate: totalRequests > 0 ? this.hits / totalRequests : 0,\r\n evictions: this.evictions\r\n };\r\n }\r\n\r\n /**\r\n * Reset cache statistics\r\n */\r\n resetStats(): void {\r\n this.hits = 0;\r\n this.misses = 0;\r\n this.evictions = 0;\r\n }\r\n\r\n /**\r\n * Get all keys in the cache\r\n */\r\n keys(): K[] {\r\n return Array.from(this.cache.keys());\r\n }\r\n\r\n /**\r\n * Get all values in the cache\r\n */\r\n values(): V[] {\r\n return Array.from(this.cache.values()).map(entry => entry.value);\r\n }\r\n\r\n /**\r\n * Update cache capacity and evict if necessary\r\n */\r\n setCapacity(newCapacity: number): void {\r\n if (newCapacity <= 0) {\r\n throw new Error('Cache capacity must be greater than 0');\r\n }\r\n\r\n this.capacity = newCapacity;\r\n\r\n // Evict entries if new capacity is smaller than current size\r\n while (this.cache.size > this.capacity) {\r\n this.evictLRU();\r\n }\r\n }\r\n\r\n /**\r\n * Evict the least recently used entry\r\n */\r\n private evictLRU(): void {\r\n // Map preserves insertion order, first entry is least recently used\r\n const firstKey = this.cache.keys().next().value;\r\n if (firstKey !== undefined) {\r\n this.cache.delete(firstKey);\r\n this.evictions++;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Simple hash function for content\r\n * Uses FNV-1a algorithm for fast, decent-quality hashing\r\n */\r\nexport function hashContent(content: string): string {\r\n // For very large content, sample instead of hashing every character\r\n if (content.length > 10000) {\r\n // Sample: hash length + first 1000 + middle 1000 + last 1000 chars\r\n const start = content.slice(0, 1000);\r\n const middle = content.slice(Math.floor(content.length / 2) - 500, Math.floor(content.length / 2) + 500);\r\n const end = content.slice(-1000);\r\n const sample = content.length + '|' + start + middle + end;\r\n\r\n let hash = 2166136261;\r\n for (let i = 0; i < sample.length; i++) {\r\n hash ^= sample.charCodeAt(i);\r\n hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);\r\n }\r\n return (hash >>> 0).toString(36);\r\n }\r\n\r\n // For smaller content, hash normally\r\n let hash = 2166136261; // FNV offset basis\r\n for (let i = 0; i < content.length; i++) {\r\n hash ^= content.charCodeAt(i);\r\n hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);\r\n }\r\n\r\n return (hash >>> 0).toString(36);\r\n}\r\n\r\n/**\r\n * Create a cached version of a function\r\n */\r\nexport function memoize<T extends (...args: any[]) => any>(\r\n fn: T,\r\n options: {\r\n cache?: LRUCache<string, ReturnType<T>>;\r\n keyGenerator?: (...args: Parameters<T>) => string;\r\n maxSize?: number;\r\n } = {}\r\n): T & { cache: LRUCache<string, ReturnType<T>>; clearCache: () => void } {\r\n const cache = options.cache || new LRUCache<string, ReturnType<T>>(options.maxSize || 100);\r\n const keyGenerator = options.keyGenerator || ((...args: Parameters<T>) => JSON.stringify(args));\r\n\r\n const memoized = function(this: any, ...args: Parameters<T>): ReturnType<T> {\r\n const key = keyGenerator(...args);\r\n const cached = cache.get(key);\r\n\r\n if (cached !== undefined) {\r\n return cached;\r\n }\r\n\r\n const result = fn.apply(this, args);\r\n cache.set(key, result);\r\n return result;\r\n } as T & { cache: LRUCache<string, ReturnType<T>>; clearCache: () => void };\r\n\r\n memoized.cache = cache;\r\n memoized.clearCache = () => cache.clear();\r\n\r\n return memoized;\r\n}\r\n","import {escapeHtml} from \"@/utils.ts\";\r\nimport {Extension} from \"@/types.ts\";\r\n\r\nexport const BlockquoteExtension: Extension = {\r\n name: 'blockquote',\r\n parseRules: [\r\n {\r\n name: 'blockquote',\r\n pattern: /^>\\s+(.+)$/m,\r\n render: (match) => ({\r\n type: 'blockquote',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'blockquote',\r\n render: (token) => {\r\n const format = token.attributes?.format || 'html';\r\n\r\n // Use pre-rendered children if available (new efficient approach)\r\n // Otherwise fall back to renderMarkdown callback (backwards compat) or escaped content\r\n const renderedChildren = token.attributes?.renderedChildren as string | undefined;\r\n const renderMarkdown = token.attributes?.renderMarkdown as ((md: string) => string) | undefined;\r\n const content = renderedChildren || (renderMarkdown ? renderMarkdown(token.content) : escapeHtml(token.content));\r\n\r\n if (format === 'html') {\r\n return `<blockquote style=\"border-left: 2px solid #d1d5db; padding: 8px 0 8px 16px; margin: 16px 0; font-style: italic; color: #6b7280;\">${content}</blockquote>`;\r\n }\r\n return `<blockquote class=\"pl-4 py-2 border-l-2 border-border italic text-muted-foreground my-4\">${content}</blockquote>`;\r\n }\r\n }\r\n ]\r\n};","import {Extension} from \"@/types.ts\";\r\n\r\nexport const LineBreakExtension: Extension = {\r\n name: 'line-break',\r\n parseRules: [\r\n {\r\n name: 'hard-break-backslash',\r\n pattern: /\\\\\\s*\\n/,\r\n render: (match) => ({\r\n type: 'line-break',\r\n content: '',\r\n raw: match[0] || ''\r\n })\r\n },\r\n {\r\n name: 'hard-break-spaces',\r\n pattern: / +\\n/,\r\n render: (match) => ({\r\n type: 'line-break',\r\n content: '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'line-break',\r\n render: () => '<br>'\r\n },\r\n {\r\n type: 'paragraph-break',\r\n render: () => '</p><p>'\r\n },\r\n {\r\n type: 'soft-break',\r\n render: (token) => token.content || ' '\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const InlineCodeExtension: Extension = {\r\n name: 'inline-code',\r\n parseRules: [\r\n {\r\n name: 'code',\r\n pattern: /`([^`]+)`/,\r\n render: (match) => ({\r\n type: 'code',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'code',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return `<code style=\"background-color: #f3f4f6; padding: 2px 6px; border-radius: 4px; font-family: monospace; font-size: 0.875rem;\">${content}</code>`;\r\n }\r\n // Default to Tailwind\r\n return `<code class=\"bg-muted px-1.5 py-0.5 rounded text-sm font-mono\">${content}</code>`;\r\n }\r\n }\r\n ]\r\n};\r\n\r\nexport const CodeBlockExtension: Extension = {\r\n name: 'codeblock',\r\n parseRules: [\r\n {\r\n name: 'codeblock',\r\n pattern: /```(\\w+)?\\s*\\n([\\s\\S]*?)\\n```/,\r\n render: (match) => ({\r\n type: 'codeblock',\r\n content: match[2] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n language: match[1] || 'text'\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'codeblock',\r\n render: (token) => {\r\n const language = token.attributes?.language || 'text';\r\n const escapedCode = escapeHtml(token.content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<pre style=\"background-color: #f3f4f6; padding: 16px; border-radius: 6px; overflow-x: auto; margin: 16px 0;\"><code class=\"language-${escapeHtml(language)}\">${escapedCode}</code></pre>`;\r\n }\r\n\r\n return `<pre class=\"bg-muted p-4 rounded-md overflow-x-auto my-4\"><code class=\"language-${escapeHtml(language)}\">${escapedCode}</code></pre>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const BoldExtension: Extension = {\r\n name: 'bold',\r\n parseRules: [\r\n {\r\n name: 'bold',\r\n pattern: /\\*\\*((?:(?!\\*\\*).)+)\\*\\*/,\r\n render: (match) => ({\r\n type: 'bold',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'bold',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return `<strong>${content}</strong>`;\r\n }\r\n // Default to Tailwind\r\n return `<strong class=\"font-bold\">${content}</strong>`;\r\n }\r\n }\r\n ]\r\n};\r\n\r\nexport const ItalicExtension: Extension = {\r\n name: 'italic',\r\n parseRules: [\r\n {\r\n name: 'italic',\r\n pattern: /\\*((?:(?!\\*).)+)\\*/,\r\n render: (match) => ({\r\n type: 'italic',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'italic',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return `<em>${content}</em>`;\r\n }\r\n // Default to Tailwind\r\n return `<em class=\"italic\">${content}</em>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml, generateId } from '../../utils';\r\n\r\nexport const HeadingExtension: Extension = {\r\n name: 'heading',\r\n parseRules: [\r\n {\r\n name: 'heading',\r\n pattern: /^(#{1,6})\\s+(.+)$/m,\r\n render: (match) => ({\r\n type: 'heading',\r\n content: match[2]?.trim() || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n level: String(match[1]?.length || 1)\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'heading',\r\n render: (token) => {\r\n const level = parseInt(token.attributes?.level || '1');\r\n const text = token.content;\r\n const id = generateId(text);\r\n const escapedContent = escapeHtml(text);\r\n\r\n // Default to HTML format, extensions can override\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<h${level} id=\"${id}\">${escapedContent}</h${level}>`;\r\n }\r\n\r\n // Tailwind format\r\n let headingClasses = 'group relative flex items-center gap-2';\r\n\r\n switch (level) {\r\n case 1: headingClasses += ' text-3xl font-bold mt-8 mb-4'; break;\r\n case 2: headingClasses += ' text-2xl font-semibold mt-6 mb-3'; break;\r\n case 3: headingClasses += ' text-xl font-medium mt-5 mb-3'; break;\r\n case 4: headingClasses += ' text-lg font-medium mt-4 mb-2'; break;\r\n case 5: headingClasses += ' text-base font-medium mt-3 mb-2'; break;\r\n case 6: headingClasses += ' text-sm font-medium mt-3 mb-2'; break;\r\n }\r\n\r\n return `<h${level} id=\"${id}\" class=\"${headingClasses}\">\r\n ${escapedContent}\r\n <a href=\"#${id}\" class=\"opacity-0 group-hover:opacity-100 text-muted-foreground transition-opacity\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/>\r\n <path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/>\r\n</svg>\r\n </a>\r\n </h${level}>`;\r\n }\r\n }\r\n ]\r\n};","import {Extension} from \"@/types.ts\";\r\n\r\nexport const HorizontalRuleExtension: Extension = {\r\n name: 'hr',\r\n parseRules: [\r\n {\r\n name: 'hr',\r\n pattern: /^---$/m,\r\n render: (match) => ({\r\n type: 'hr',\r\n content: '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'hr',\r\n render: (token) => {\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return '<hr style=\"margin: 24px 0; border: none; border-top: 1px solid #d1d5db;\">';\r\n }\r\n // Default to Tailwind\r\n return '<hr class=\"my-6 border-t border-border\">';\r\n }\r\n }\r\n ]\r\n};","import {escapeHtml} from \"@/utils.ts\";\r\nimport {Extension} from \"@/types.ts\";\r\n\r\nexport const ImageExtension: Extension = {\r\n name: 'image',\r\n parseRules: [\r\n {\r\n name: 'image',\r\n pattern: /!\\[([^\\]]*)\\]\\(([^)]+?)(?:\\s+\"([^\"]+)\")?\\)/,\r\n render: (match) => ({\r\n type: 'image',\r\n content: match[1] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n alt: match[1] || '',\r\n src: match[2] || '',\r\n caption: match[3] || '' // Renamed from 'title' to 'caption' for clarity\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'image',\r\n render: (token) => {\r\n const src = token.attributes?.src || '';\r\n const alt = token.attributes?.alt || '';\r\n const caption = token.attributes?.caption || '';\r\n const format = token.attributes?.format || 'html';\r\n\r\n // If there's a caption, render as figure with figcaption\r\n if (caption) {\r\n if (format === 'html') {\r\n return `<figure style=\"margin: 16px 0; text-align: center;\">\r\n <img src=\"${escapeHtml(src)}\" alt=\"${escapeHtml(alt)}\" style=\"max-width: 100%; height: auto; border-radius: 8px;\" loading=\"lazy\" />\r\n <figcaption style=\"margin-top: 8px; font-size: 14px; color: #6b7280; font-style: italic;\">${escapeHtml(caption)}</figcaption>\r\n </figure>`;\r\n }\r\n return `<figure class=\"my-4 text-center\">\r\n <img src=\"${escapeHtml(src)}\" alt=\"${escapeHtml(alt)}\" class=\"max-w-full h-auto rounded-lg\" loading=\"lazy\" />\r\n <figcaption class=\"mt-2 text-sm text-gray-500 italic\">${escapeHtml(caption)}</figcaption>\r\n </figure>`;\r\n }\r\n\r\n // No caption, just render the image\r\n if (format === 'html') {\r\n return `<img src=\"${escapeHtml(src)}\" alt=\"${escapeHtml(alt)}\" style=\"max-width: 100%; height: auto; border-radius: 8px; margin: 16px 0;\" loading=\"lazy\" />`;\r\n }\r\n\r\n return `<img src=\"${escapeHtml(src)}\" alt=\"${escapeHtml(alt)}\" class=\"max-w-full h-auto rounded-lg my-4\" loading=\"lazy\" />`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const LinkExtension: Extension = {\r\n name: 'link',\r\n parseRules: [\r\n {\r\n name: 'link',\r\n pattern: /\\[(?!(?:button|embed):)([^\\]]+)\\]\\(([^)]+)\\)/,\r\n render: (match) => ({\r\n type: 'link',\r\n content: match[1] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n href: match[2] || ''\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'link',\r\n render: (token) => {\r\n const href = token.attributes?.href || '#';\r\n const escapedHref = escapeHtml(href);\r\n const escapedText = escapeHtml(token.content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<a href=\"${escapedHref}\" target=\"_blank\" rel=\"noopener noreferrer\">${escapedText}</a>`;\r\n }\r\n\r\n return `<a href=\"${escapedHref}\" class=\"text-primary hover:underline inline-flex items-center gap-1\" target=\"_blank\" rel=\"noopener noreferrer\">\r\n ${escapedText}\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-external-link\">\r\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"></path>\r\n <polyline points=\"15 3 21 3 21 9\"></polyline>\r\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"></line>\r\n </svg>\r\n </a>`;\r\n }\r\n }\r\n ]\r\n};","import {escapeHtml} from \"@/utils.ts\";\r\nimport {Extension} from \"@/types.ts\";\r\n\r\nexport const ListExtension: Extension = {\r\n name: 'list',\r\n parseRules: [\r\n {\r\n name: 'unordered-list-item',\r\n pattern: /^(\\s*)[-*+]\\s+(.+)$/m,\r\n render: (match) => ({\r\n type: 'list-item',\r\n content: match[2] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n indent: match[1]?.length || 0,\r\n ordered: false,\r\n marker: match[1] ? match[0].match(/[-*+]/)?.[0] : '-'\r\n }\r\n })\r\n },\r\n {\r\n name: 'ordered-list-item',\r\n pattern: /^(\\s*)(\\d+)\\.\\s+(.+)$/m,\r\n render: (match) => ({\r\n type: 'ordered-list-item',\r\n content: match[3] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n indent: match[1]?.length || 0,\r\n ordered: true,\r\n number: parseInt(match[2] || '1')\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'list-item',\r\n render: (token) => {\r\n const format = token.attributes?.format || 'tailwind';\r\n // If children have been rendered (from recursive parsing), use them\r\n const content = token.attributes?.renderedChildren || escapeHtml(token.content);\r\n\r\n if (format === 'html') {\r\n return `<li>${content}</li>`;\r\n }\r\n // Default to Tailwind\r\n return `<li>${content}</li>`;\r\n }\r\n },\r\n {\r\n type: 'ordered-list-item',\r\n render: (token) => {\r\n const format = token.attributes?.format || 'tailwind';\r\n const content = token.attributes?.renderedChildren || escapeHtml(token.content);\r\n\r\n if (format === 'html') {\r\n return `<li>${content}</li>`;\r\n }\r\n return `<li>${content}</li>`;\r\n }\r\n }\r\n ]\r\n};\r\n\r\nexport const TaskListExtension: Extension = {\r\n name: 'task-list',\r\n parseRules: [\r\n {\r\n name: 'task-item',\r\n pattern: /^(\\s*)-\\s*\\[([ xX])\\]\\s*(.+)$/m,\r\n render: (match) => ({\r\n type: 'task-item',\r\n content: match[3] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n indent: match[1]?.length || 0,\r\n checked: String((match[2] || '').toLowerCase() === 'x')\r\n }\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'task-item',\r\n render: (token) => {\r\n const isChecked = token.attributes?.checked === 'true';\r\n // If children have been rendered (from recursive parsing), use them\r\n const content = token.attributes?.renderedChildren || escapeHtml(token.content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<div style=\"display: flex; align-items: center; gap: 8px; margin: 8px 0;\">\r\n <input type=\"checkbox\" ${isChecked ? 'checked' : ''} disabled style=\"margin: 0;\" />\r\n <span${isChecked ? ' style=\"text-decoration: line-through; color: #6b7280;\"' : ''}>${content}</span>\r\n </div>`;\r\n }\r\n\r\n return `<div class=\"flex items-center gap-2 my-2 task-list-item\">\r\n <input type=\"checkbox\" ${isChecked ? 'checked' : ''} disabled\r\n class=\"form-checkbox h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary\" />\r\n <span${isChecked ? ' class=\"line-through text-muted-foreground\"' : ''}>${content}</span>\r\n </div>`;\r\n }\r\n }\r\n ]\r\n};","import {Extension} from \"@/types.ts\";\r\nimport {escapeHtml} from \"@/utils.ts\";\r\n\r\nexport const ParagraphExtension: Extension = {\r\n name: 'paragraph',\r\n parseRules: [],\r\n renderRules: [\r\n {\r\n type: 'paragraph',\r\n render: (token) => {\r\n if (!token.content) return '';\r\n const content = token.content.trim();\r\n if (!content) return '';\r\n\r\n const processedContent = content.includes('<br>') ? content : escapeHtml(content);\r\n const format = token.attributes?.format || 'html';\r\n\r\n if (format === 'html') {\r\n return `<p style=\"line-height: 1.75; margin-bottom: 16px;\">${processedContent}</p>`;\r\n }\r\n\r\n return `<p class=\"leading-7 mb-4\">${processedContent}</p>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const TextExtension: Extension = {\r\n name: 'text',\r\n parseRules: [],\r\n renderRules: [\r\n {\r\n type: 'text',\r\n render: (token) => {\r\n if (!token.content) return '';\r\n return escapeHtml(token.content);\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../../types';\r\nimport { escapeHtml } from '../../utils';\r\n\r\nexport const StrikethroughExtension: Extension = {\r\n name: 'strikethrough',\r\n parseRules: [\r\n {\r\n name: 'strikethrough',\r\n pattern: /~~((?:(?!~~).)+)~~/,\r\n render: (match) => ({\r\n type: 'strikethrough',\r\n content: match[1] || '',\r\n raw: match[0] || ''\r\n })\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'strikethrough',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n const format = token.attributes?.format;\r\n\r\n if (format === 'html') {\r\n return `<del style=\"text-decoration: line-through; color: #6b7280;\">${content}</del>`;\r\n }\r\n // Default to Tailwind\r\n return `<del class=\"line-through text-gray-500\">${content}</del>`;\r\n }\r\n }\r\n ]\r\n};\r\n","import { BlockquoteExtension } from \"./blockquote\";\r\nimport { LineBreakExtension } from \"./breaks\";\r\nimport {CodeBlockExtension, InlineCodeExtension } from \"./code\";\r\nimport { BoldExtension, ItalicExtension } from \"./emphasis\";\r\nimport { HeadingExtension } from \"./heading\";\r\nimport { HorizontalRuleExtension } from \"./hr\";\r\nimport { ImageExtension } from \"./image\";\r\nimport { LinkExtension } from \"./links\";\r\nimport { ListExtension, TaskListExtension } from \"./lists\";\r\nimport { ParagraphExtension } from \"./paragraph\";\r\nimport { TextExtension } from \"./text\";\r\nimport { StrikethroughExtension } from \"./strikethrough\";\r\n\r\nexport const CoreExtensions = [\r\n TextExtension,\r\n HeadingExtension,\r\n BoldExtension,\r\n ItalicExtension,\r\n InlineCodeExtension,\r\n CodeBlockExtension,\r\n LinkExtension,\r\n ImageExtension,\r\n ListExtension,\r\n TaskListExtension,\r\n BlockquoteExtension,\r\n HorizontalRuleExtension,\r\n StrikethroughExtension,\r\n ParagraphExtension,\r\n LineBreakExtension\r\n] as const;\r\n\r\nexport {\r\n TextExtension,\r\n HeadingExtension,\r\n BoldExtension,\r\n ItalicExtension,\r\n InlineCodeExtension,\r\n CodeBlockExtension,\r\n LinkExtension,\r\n ImageExtension,\r\n ListExtension,\r\n TaskListExtension,\r\n BlockquoteExtension,\r\n HorizontalRuleExtension,\r\n StrikethroughExtension,\r\n ParagraphExtension,\r\n LineBreakExtension\r\n};","import type { Extension } from '../types';\r\n\r\ninterface AlertTypeConfig {\r\n icon: string;\r\n classes: string;\r\n}\r\n\r\nexport const AlertExtension: Extension = {\r\n name: 'alert',\r\n parseRules: [\r\n {\r\n name: 'alert',\r\n pattern: /:::(\\w+)(?: ([^\\n]+))?\\n([\\s\\S]*?)\\n:::/,\r\n render: (match: RegExpMatchArray) => {\r\n return {\r\n type: 'alert',\r\n content: match[3]?.trim() || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n type: match[1] || 'info',\r\n title: match[2]?.trim() || ''\r\n }\r\n };\r\n }\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'alert',\r\n render: (token) => {\r\n const type = token.attributes?.type || 'info';\r\n const title = token.attributes?.title || '';\r\n\r\n const typeConfig: Record<string, AlertTypeConfig> = {\r\n info: {\r\n icon: 'ℹ️',\r\n classes: 'bg-blue-500/10 border-blue-500/30 text-blue-600 border-l-blue-500'\r\n },\r\n warning: {\r\n icon: '⚠️',\r\n classes: 'bg-amber-500/10 border-amber-500/30 text-amber-600 border-l-amber-500'\r\n },\r\n error: {\r\n icon: '❌',\r\n classes: 'bg-red-500/10 border-red-500/30 text-red-600 border-l-red-500'\r\n },\r\n success: {\r\n icon: '✅',\r\n classes: 'bg-green-500/10 border-green-500/30 text-green-600 border-l-green-500'\r\n },\r\n tip: {\r\n icon: '💡',\r\n classes: 'bg-purple-500/10 border-purple-500/30 text-purple-600 border-l-purple-500'\r\n },\r\n note: {\r\n icon: '📝',\r\n classes: 'bg-gray-500/10 border-gray-500/30 text-gray-600 border-l-gray-500'\r\n }\r\n };\r\n\r\n const config = typeConfig[type] || typeConfig.info;\r\n const baseClasses = 'border-l-4 p-4 mb-4 rounded-md transition-colors duration-200';\r\n const classes = `${baseClasses} ${config?.classes}`;\r\n\r\n // Use pre-rendered children if available (new efficient approach)\r\n // Otherwise fall back to renderMarkdown callback (backwards compat) or raw content\r\n const renderedChildren = token.attributes?.renderedChildren as string | undefined;\r\n const renderMarkdown = token.attributes?.renderMarkdown as ((md: string) => string) | undefined;\r\n const renderedContent = renderedChildren || (renderMarkdown ? renderMarkdown(token.content) : token.content);\r\n\r\n const titleHtml = title\r\n ? `<div class=\"font-medium mb-2 flex items-center gap-2\">\r\n <span class=\"text-lg\" role=\"img\" aria-label=\"${type}\">${config?.icon}</span>\r\n <span>${title}</span>\r\n </div>`\r\n : `<div class=\"font-medium mb-2 flex items-center gap-2\">\r\n <span class=\"text-lg\" role=\"img\" aria-label=\"${type}\">${config?.icon}</span>\r\n <span>${type.charAt(0).toUpperCase() + type.slice(1)}</span>\r\n </div>`;\r\n\r\n return `<div class=\"${classes}\" role=\"alert\" aria-live=\"polite\">\r\n ${titleHtml}\r\n <div class=\"leading-relaxed\">${renderedContent}</div>\r\n </div>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../types';\r\n\r\nexport const ButtonExtension: Extension = {\r\n name: 'button',\r\n parseRules: [\r\n {\r\n name: 'button',\r\n pattern: /\\[button:([^\\]]+)\\]\\(([^)]+)\\)(?:\\{([^}]+)\\})?/,\r\n render: (match) => {\r\n const options = match[3] ? match[3].split(',').map(opt => opt.trim()) : [];\r\n\r\n return {\r\n type: 'button',\r\n content: match[1] || '',\r\n raw: match[0] || '',\r\n attributes: {\r\n href: match[2] || '',\r\n style: options.find(opt =>\r\n ['default', 'primary', 'secondary', 'success', 'danger', 'outline', 'ghost'].includes(opt)\r\n ) || 'primary',\r\n size: options.find(opt => ['sm', 'md', 'lg'].includes(opt)) || 'md',\r\n disabled: String(options.includes('disabled')),\r\n target: options.includes('self') ? '_self' : '_blank'\r\n }\r\n };\r\n }\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'button',\r\n render: (token) => {\r\n const href = token.attributes?.href || '#';\r\n const style = token.attributes?.style || 'primary';\r\n const size = token.attributes?.size || 'md';\r\n const disabled = token.attributes?.disabled === 'true';\r\n const target = token.attributes?.target || '_blank';\r\n\r\n // Base classes with optical border effect\r\n const baseClasses = `\r\n inline-flex items-center justify-center font-medium rounded-lg \r\n transition-all duration-200 ease-out\r\n focus:outline-none focus:ring-2 focus:ring-offset-2\r\n disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none\r\n transform hover:scale-[1.02] active:scale-[0.98]\r\n shadow-sm hover:shadow-md active:shadow-sm\r\n border border-transparent\r\n relative overflow-hidden\r\n before:absolute before:inset-0 before:rounded-lg\r\n before:bg-gradient-to-br before:from-white/20 before:to-transparent\r\n before:opacity-0 hover:before:opacity-100 before:transition-opacity before:duration-200\r\n `.replace(/\\s+/g, ' ').trim();\r\n\r\n // Size classes\r\n const sizeClasses: Record<string, string> = {\r\n sm: 'px-3 py-1.5 text-sm gap-1.5',\r\n md: 'px-4 py-2 text-base gap-2',\r\n lg: 'px-6 py-3 text-lg gap-2.5'\r\n };\r\n\r\n // Style classes with optical borders using box-shadow\r\n const styleClasses: Record<string, string> = {\r\n default: `\r\n bg-slate-600 text-white border-slate-500\r\n hover:bg-slate-700 hover:border-slate-400\r\n focus:ring-slate-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n primary: `\r\n bg-blue-600 text-white border-blue-500\r\n hover:bg-blue-700 hover:border-blue-400\r\n focus:ring-blue-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n secondary: `\r\n bg-gray-600 text-white border-gray-500\r\n hover:bg-gray-700 hover:border-gray-400\r\n focus:ring-gray-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n success: `\r\n bg-green-600 text-white border-green-500\r\n hover:bg-green-700 hover:border-green-400\r\n focus:ring-green-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n danger: `\r\n bg-red-600 text-white border-red-500\r\n hover:bg-red-700 hover:border-red-400\r\n focus:ring-red-500\r\n shadow-[0_1px_0_0_rgba(255,255,255,0.1)_inset,0_1px_2px_0_rgba(0,0,0,0.1)]\r\n hover:shadow-[0_1px_0_0_rgba(255,255,255,0.15)_inset,0_2px_4px_0_rgba(0,0,0,0.15)]\r\n `,\r\n outline: `\r\n bg-transparent text-blue-600 border-blue-600\r\n hover:bg-blue-50 hover:border-blue-700 hover:text-blue-700\r\n focus:ring-blue-500\r\n shadow-[0_0_0_1px_rgba(59,130,246,0.5)_inset]\r\n hover:shadow-[0_0_0_1px_rgba(29,78,216,0.6)_inset,0_1px_2px_0_rgba(0,0,0,0.05)]\r\n `,\r\n ghost: `\r\n bg-transparent text-gray-700 border-transparent\r\n hover:bg-gray-100 hover:text-gray-900\r\n focus:ring-gray-500\r\n shadow-none\r\n hover:shadow-[0_1px_2px_0_rgba(0,0,0,0.05)]\r\n `\r\n };\r\n\r\n const classes = `\r\n ${baseClasses}\r\n ${sizeClasses[size] || sizeClasses.md}\r\n ${styleClasses[style] || styleClasses.primary}\r\n `.replace(/\\s+/g, ' ').trim();\r\n\r\n const targetAttr = target === '_blank' ? ' target=\"_blank\" rel=\"noopener noreferrer\"' :\r\n target === '_self' ? ' target=\"_self\"' : '';\r\n const disabledAttr = disabled ? ' aria-disabled=\"true\" tabindex=\"-1\"' : '';\r\n const externalIcon = target === '_blank' && !disabled ?\r\n `<svg class=\"w-4 h-4 ml-1 opacity-75\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>` : '';\r\n\r\n return `<a href=\"${href}\" class=\"${classes}\"${targetAttr}${disabledAttr}>\r\n <span class=\"relative z-10\">${token.content}</span>${externalIcon}\r\n </a>`;\r\n }\r\n }\r\n ]\r\n};","import type { Extension } from '../types';\r\nimport { parseOptions, extractDomain } from '../utils';\r\n\r\nexport const EmbedExtension: Extension = {\r\n name: 'embed',\r\n parseRules: [\r\n {\r\n name: 'embed',\r\n pattern: /\\[embed:(\\w+)\\]\\(([^)]+)\\)(?:\\{([^}]+)\\})?/,\r\n render: (match) => {\r\n return {\r\n type: 'embed',\r\n content: match[2] || '', // URL\r\n raw: match[0] || '',\r\n attributes: {\r\n provider: match[1] || 'generic',\r\n url: match[2] || '',\r\n options: match[3] || ''\r\n }\r\n };\r\n }\r\n }\r\n ],\r\n renderRules: [\r\n {\r\n type: 'embed',\r\n render: (token) => {\r\n const provider = token.attributes?.provider || 'generic';\r\n const url = token.attributes?.url || '';\r\n const options = token.attributes?.options || '';\r\n\r\n return renderEmbed(provider, url, options);\r\n }\r\n }\r\n ]\r\n};\r\n\r\nfunction renderEmbed(provider: string, url: string, options: string): string {\r\n const baseClasses = 'rounded-lg border bg-card text-card-foreground shadow-sm mb-6 overflow-hidden';\r\n const parsedOptions = parseOptions(options);\r\n\r\n switch (provider.toLowerCase()) {\r\n case 'youtube':\r\n return renderYouTubeEmbed(url, parsedOptions, baseClasses);\r\n case 'codepen':\r\n return renderCodePenEmbed(url, parsedOptions, baseClasses);\r\n case 'figma':\r\n return renderFigmaEmbed(url, parsedOptions, baseClasses);\r\n case 'twitter':\r\n case 'tweet':\r\n return renderTwitterEmbed(url, parsedOptions, baseClasses);\r\n case 'github':\r\n return renderGitHubEmbed(url, parsedOptions, baseClasses);\r\n case 'vimeo':\r\n return renderVimeoEmbed(url, parsedOptions, baseClasses);\r\n case 'spotify':\r\n return renderSpotifyEmbed(url, parsedOptions, baseClasses);\r\n case 'codesandbox':\r\n return renderCodeSandboxEmbed(url, parsedOptions, baseClasses);\r\n default:\r\n return renderGenericEmbed(url, parsedOptions, baseClasses);\r\n }\r\n}\r\n\r\nfunction renderYouTubeEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const videoId = extractYouTubeId(url);\r\n if (!videoId) {\r\n return createErrorEmbed('Invalid YouTube URL', url, classes);\r\n }\r\n\r\n const params = new URLSearchParams();\r\n if (options.autoplay === '1') params.set('autoplay', '1');\r\n if (options.mute === '1') params.set('mute', '1');\r\n if (options.loop === '1') {\r\n params.set('loop', '1');\r\n params.set('playlist', videoId);\r\n }\r\n if (options.controls === '0') params.set('controls', '0');\r\n if (options.start) params.set('start', options.start);\r\n\r\n params.set('rel', '0');\r\n params.set('modestbranding', '1');\r\n\r\n const embedUrl = `https://www.youtube.com/embed/${videoId}?${params.toString()}`;\r\n\r\n return `<div class=\"${classes}\">\r\n <div style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\">\r\n <iframe \r\n style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;\"\r\n src=\"${embedUrl}\" \r\n title=\"YouTube video player\"\r\n frameborder=\"0\" \r\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\"\r\n allowfullscreen>\r\n </iframe>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderCodePenEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const match = url.match(/codepen\\.io\\/([^\\/]+)\\/(?:pen|embed)\\/([^\\/\\?#]+)/);\r\n\r\n if (!match) {\r\n return createErrorEmbed('Invalid CodePen URL', url, classes);\r\n }\r\n\r\n const [, user, penId] = match;\r\n const height = options.height || '400';\r\n const theme = options.theme === 'light' ? 'light' : 'dark';\r\n const defaultTab = options.tab || 'result';\r\n\r\n const embedParams = new URLSearchParams({\r\n 'default-tab': defaultTab,\r\n 'theme-id': theme,\r\n 'editable': 'true'\r\n });\r\n\r\n const embedUrl = `https://codepen.io/${user}/embed/${penId}?${embedParams.toString()}`;\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n height=\"${height}\" \r\n style=\"width: 100%; border: 0;\" \r\n scrolling=\"no\" \r\n title=\"CodePen Embed - ${penId}\" \r\n src=\"${embedUrl}\" \r\n frameborder=\"0\" \r\n loading=\"lazy\" \r\n allowtransparency=\"true\" \r\n allowfullscreen=\"true\">\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderVimeoEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const videoId = extractVimeoId(url);\r\n if (!videoId) {\r\n return createErrorEmbed('Invalid Vimeo URL', url, classes);\r\n }\r\n\r\n const params = new URLSearchParams();\r\n if (options.autoplay === '1') params.set('autoplay', '1');\r\n if (options.mute === '1') params.set('muted', '1');\r\n if (options.loop === '1') params.set('loop', '1');\r\n\r\n const embedUrl = `https://player.vimeo.com/video/${videoId}?${params.toString()}`;\r\n\r\n return `<div class=\"${classes}\">\r\n <div style=\"position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;\">\r\n <iframe \r\n style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0;\"\r\n src=\"${embedUrl}\" \r\n title=\"Vimeo video player\"\r\n frameborder=\"0\" \r\n allow=\"autoplay; fullscreen; picture-in-picture\"\r\n allowfullscreen>\r\n </iframe>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderSpotifyEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const embedUrl = url.replace('open.spotify.com', 'open.spotify.com/embed');\r\n const height = options.height || '380';\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n style=\"border-radius: 12px;\" \r\n src=\"${embedUrl}\" \r\n width=\"100%\" \r\n height=\"${height}\" \r\n frameborder=\"0\" \r\n allowfullscreen=\"\" \r\n allow=\"autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture\" \r\n loading=\"lazy\">\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderCodeSandboxEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n let embedUrl = url;\r\n if (url.includes('/s/')) {\r\n embedUrl = url.replace('/s/', '/embed/');\r\n }\r\n\r\n const height = options.height || '500';\r\n const view = options.view || 'preview';\r\n\r\n if (!embedUrl.includes('?')) {\r\n embedUrl += `?view=${view}`;\r\n }\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n src=\"${embedUrl}\"\r\n style=\"width: 100%; height: ${height}px; border: 0; border-radius: 4px; overflow: hidden;\"\r\n title=\"CodeSandbox Embed\"\r\n allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\r\n sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\">\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderFigmaEmbed(url: string, options: Record<string, string>, classes: string): string {\r\n const embedUrl = `https://www.figma.com/embed?embed_host=share&url=${encodeURIComponent(url)}`;\r\n const height = options.height || '450';\r\n\r\n return `<div class=\"${classes}\">\r\n <iframe \r\n style=\"border: none;\" \r\n width=\"100%\" \r\n height=\"${height}\" \r\n src=\"${embedUrl}\" \r\n allowfullscreen>\r\n </iframe>\r\n </div>`;\r\n}\r\n\r\nfunction renderTwitterEmbed(url: string, _options: Record<string, string>, classes: string): string {\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4\">\r\n <div class=\"flex items-center gap-3 mb-3\">\r\n <svg class=\"w-6 h-6 fill-current text-blue-500\" viewBox=\"0 0 24 24\">\r\n <path d=\"M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z\"/>\r\n </svg>\r\n <div>\r\n <div class=\"font-semibold text-foreground\">Twitter Post</div>\r\n <div class=\"text-sm text-muted-foreground\">External Link</div>\r\n </div>\r\n </div>\r\n <a href=\"${url}\" target=\"_blank\" \r\n class=\"inline-flex items-center gap-2 text-primary hover:text-primary/80 font-medium transition-colors\">\r\n View on Twitter\r\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>\r\n </a>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderGitHubEmbed(url: string, _options: Record<string, string>, classes: string): string {\r\n const parts = url.replace('https://github.com/', '').split('/');\r\n const owner = parts[0];\r\n const repo = parts[1];\r\n\r\n if (!owner || !repo) {\r\n return createErrorEmbed('Invalid GitHub URL', url, classes);\r\n }\r\n\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4\">\r\n <div class=\"flex items-center gap-3 mb-3\">\r\n <svg class=\"w-6 h-6 fill-current\" viewBox=\"0 0 24 24\">\r\n <path d=\"M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z\"/>\r\n </svg>\r\n <div>\r\n <div class=\"font-semibold text-foreground text-lg\">${owner}/${repo}</div>\r\n <div class=\"text-sm text-muted-foreground\">GitHub Repository</div>\r\n </div>\r\n </div>\r\n <a href=\"${url}\" target=\"_blank\" \r\n class=\"inline-flex items-center gap-2 text-primary hover:text-primary/80 font-medium transition-colors\">\r\n View on GitHub\r\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>\r\n </a>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction renderGenericEmbed(url: string, _options: Record<string, string>, classes: string): string {\r\n const domain = extractDomain(url);\r\n\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4\">\r\n <div class=\"flex items-center gap-3 mb-3\">\r\n <div class=\"w-10 h-10 rounded-lg bg-muted flex items-center justify-center\">\r\n <svg class=\"w-5 h-5 text-muted-foreground\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1\"/>\r\n </svg>\r\n </div>\r\n <div>\r\n <div class=\"font-semibold text-foreground\">External Link</div>\r\n <div class=\"text-sm text-muted-foreground\">${domain}</div>\r\n </div>\r\n </div>\r\n <a href=\"${url}\" target=\"_blank\" \r\n class=\"inline-flex items-center gap-2 text-primary hover:text-primary/80 font-medium transition-colors break-all\">\r\n ${url}\r\n <svg class=\"w-4 h-4 flex-shrink-0\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14\"/>\r\n </svg>\r\n </a>\r\n </div>\r\n </div>`;\r\n}\r\n\r\nfunction createErrorEmbed(error: string, url: string, classes: string): string {\r\n return `<div class=\"${classes}\">\r\n <div class=\"p-4 text-destructive\">\r\n <div class=\"font-medium flex items-center gap-2\">\r\n <svg class=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"/>\r\n </svg>\r\n ${error}\r\n </div>\r\n <div class=\"text-sm text-muted-foreground mt-1 break-all\">${url}</div>\r\n </div>\r\n </div>`;\r\n}\r\n\r\n// Utility functions for extracting IDs\r\nfunction extractYouTubeId(url: string): string | null {\r\n const patterns = [\r\n /(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/|youtube\\.com\\/embed\\/|youtube\\.com\\/shorts\\/)([^&\\n?#]+)/,\r\n /youtube\\.com\\/watch\\?.*v=([^&\\n?#]+)/\r\n ];\r\n\r\n for (const pattern of patterns) {\r\n const match = url.match(pattern);\r\n if (match) return match[1] || null;\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction extractVimeoId(url: string): string | null {\r\n const match = url.match(/vimeo\\.com\\/(?:.*\\/)?(\\d+)/);\r\n return match?.[1] ?? null;\r\n}","import { MarkdownParser } from './parser';\r\nimport { MarkdownRenderer } from './renderer';\r\nimport { LRUCache, hashContent } from './cache';\r\nimport type {\r\n MarkdownToken,\r\n Extension,\r\n EngineConfig,\r\n ExtensionRegistration,\r\n DebugInfo,\r\n PerformanceMetrics\r\n} from './types';\r\n\r\n// Import core extensions\r\nimport { CoreExtensions } from './extensions/core';\r\n// Import feature extensions\r\nimport { AlertExtension } from './extensions/alert';\r\nimport { ButtonExtension } from './extensions/button';\r\nimport { EmbedExtension } from './extensions/embed';\r\n\r\nexport interface RenderMetrics {\r\n inputSize: number;\r\n parseTime: number;\r\n renderTime: number;\r\n totalTime: number;\r\n tokenCount: number;\r\n cacheHit: boolean;\r\n}\r\n\r\nexport class ChangerawrMarkdown {\r\n private parser: MarkdownParser;\r\n private renderer: MarkdownRenderer;\r\n private extensions = new Map<string, Extension>();\r\n\r\n // Performance & Caching\r\n private parseCache: LRUCache<string, MarkdownToken[]>;\r\n private renderCache: LRUCache<string, string>;\r\n private parseTime = 0;\r\n private renderTime = 0;\r\n private lastTokenCount = 0;\r\n\r\n constructor(config?: EngineConfig) {\r\n this.parser = new MarkdownParser(config?.parser);\r\n this.renderer = new MarkdownRenderer(config?.renderer);\r\n\r\n // Initialize caches (enabled by default)\r\n this.parseCache = new LRUCache<string, MarkdownToken[]>(100);\r\n this.renderCache = new LRUCache<string, string>(100);\r\n\r\n // Register core extensions first (for backwards compatibility)\r\n this.registerCoreExtensions();\r\n\r\n // Register feature extensions (for backwards compatibility)\r\n this.registerFeatureExtensions();\r\n\r\n // Register custom extensions if provided\r\n if (config?.extensions) {\r\n config.extensions.forEach(extension => {\r\n this.registerExtension(extension);\r\n });\r\n }\r\n\r\n // No need for default rules - everything is extension-based now!\r\n }\r\n\r\n private registerFeatureExtensions(): void {\r\n this.registerExtension(AlertExtension);\r\n this.registerExtension(ButtonExtension);\r\n this.registerExtension(EmbedExtension);\r\n }\r\n\r\n private registerCoreExtensions(): void {\r\n CoreExtensions.forEach(extension => {\r\n this.registerExtension(extension);\r\n });\r\n }\r\n\r\n registerExtension(extension: Extension): ExtensionRegistration {\r\n try {\r\n // Validate extension before registration\r\n if (!extension.name || typeof extension.name !== 'string') {\r\n throw new Error('Extension must have a valid name');\r\n }\r\n\r\n if (!Array.isArray(extension.parseRules)) {\r\n throw new Error('Extension must have parseRules array');\r\n }\r\n\r\n if (!Array.isArray(extension.renderRules)) {\r\n throw new Error('Extension must have renderRules array');\r\n }\r\n\r\n // Validate parse rules\r\n extension.parseRules.forEach((rule, index) => {\r\n if (!rule.name || typeof rule.name !== 'string') {\r\n throw new Error(`Parse rule ${index} must have a valid name`);\r\n }\r\n if (!rule.pattern || !(rule.pattern instanceof RegExp)) {\r\n throw new Error(`Parse rule ${index} must have a valid RegExp pattern`);\r\n }\r\n if (!rule.render || typeof rule.render !== 'function') {\r\n throw new Error(`Parse rule ${index} must have a valid render function`);\r\n }\r\n });\r\n\r\n // Validate render rules\r\n extension.renderRules.forEach((rule, index) => {\r\n if (!rule.type || typeof rule.type !== 'string') {\r\n throw new Error(`Render rule ${index} must have a valid type`);\r\n }\r\n if (!rule.render || typeof rule.render !== 'function') {\r\n throw new Error(`Render rule ${index} must have a valid render function`);\r\n }\r\n });\r\n\r\n // Store extension\r\n this.extensions.set(extension.name, extension);\r\n\r\n // Add rules to parser and renderer\r\n extension.parseRules.forEach(rule => {\r\n this.parser.addRule(rule);\r\n });\r\n\r\n extension.renderRules.forEach(rule => {\r\n this.renderer.addRule(rule);\r\n });\r\n\r\n return {\r\n success: true,\r\n extensionName: extension.name\r\n };\r\n\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n\r\n return {\r\n success: false,\r\n extensionName: extension.name,\r\n error: errorMessage\r\n };\r\n }\r\n }\r\n\r\n unregisterExtension(name: string): boolean {\r\n const extension = this.extensions.get(name);\r\n if (!extension) {\r\n return false;\r\n }\r\n\r\n try {\r\n // Remove extension from map\r\n this.extensions.delete(name);\r\n\r\n // Rebuild parser and renderer to remove extension rules\r\n this.rebuildParserAndRenderer();\r\n\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n parse(markdown: string): MarkdownToken[] {\r\n // Check cache first\r\n const cacheKey = hashContent(markdown);\r\n const cached = this.parseCache.get(cacheKey);\r\n if (cached) {\r\n this.lastTokenCount = cached.length;\r\n return cached;\r\n }\r\n\r\n // Parse and cache\r\n const startTime = performance.now();\r\n const tokens = this.parser.parse(markdown);\r\n this.parseTime = performance.now() - startTime;\r\n this.lastTokenCount = tokens.length;\r\n\r\n this.parseCache.set(cacheKey, tokens);\r\n return tokens;\r\n }\r\n\r\n render(tokens: MarkdownToken[], cacheKey?: string): string {\r\n // If we have a cache key (from parse), use it for render cache too\r\n if (cacheKey) {\r\n const cached = this.renderCache.get(cacheKey);\r\n if (cached) {\r\n return cached;\r\n }\r\n }\r\n\r\n // Render and cache\r\n const startTime = performance.now();\r\n const html = this.renderer.render(tokens);\r\n this.renderTime = performance.now() - startTime;\r\n\r\n if (cacheKey) {\r\n this.renderCache.set(cacheKey, html);\r\n }\r\n return html;\r\n }\r\n\r\n toHtml(markdown: string): string {\r\n const cacheKey = hashContent(markdown);\r\n\r\n // Check if we have the full HTML cached\r\n const cachedHtml = this.renderCache.get(cacheKey);\r\n if (cachedHtml) {\r\n return cachedHtml;\r\n }\r\n\r\n // Parse (may be cached)\r\n const tokens = this.parse(markdown);\r\n\r\n // Render with the same cache key\r\n return this.render(tokens, cacheKey);\r\n }\r\n\r\n /**\r\n * Render markdown with performance metrics\r\n */\r\n toHtmlWithMetrics(markdown: string): { html: string; metrics: RenderMetrics } {\r\n const startTotal = performance.now();\r\n\r\n const parseCacheKey = hashContent(markdown);\r\n const parseCacheHit = this.parseCache.has(parseCacheKey);\r\n\r\n const html = this.toHtml(markdown);\r\n const totalTime = performance.now() - startTotal;\r\n\r\n const metrics: RenderMetrics = {\r\n inputSize: markdown.length,\r\n parseTime: this.parseTime,\r\n renderTime: this.renderTime,\r\n totalTime,\r\n tokenCount: this.lastTokenCount,\r\n cacheHit: parseCacheHit\r\n };\r\n\r\n return { html, metrics };\r\n }\r\n\r\n /**\r\n * Stream-render large documents in chunks for better performance\r\n */\r\n async toHtmlStreamed(\r\n markdown: string,\r\n options: {\r\n chunkSize?: number;\r\n onChunk?: (chunk: { html: string; progress: number }) => void;\r\n } = {}\r\n ): Promise<string> {\r\n const chunkSize = options.chunkSize || 50;\r\n const tokens = this.parse(markdown);\r\n const totalTokens = tokens.length;\r\n const chunks: string[] = [];\r\n\r\n for (let i = 0; i < tokens.length; i += chunkSize) {\r\n const chunkTokens = tokens.slice(i, Math.min(i + chunkSize, tokens.length));\r\n const chunkHtml = this.render(chunkTokens);\r\n chunks.push(chunkHtml);\r\n\r\n if (options.onChunk) {\r\n options.onChunk({\r\n html: chunkHtml,\r\n progress: Math.min(i + chunkSize, tokens.length) / totalTokens\r\n });\r\n }\r\n\r\n // Yield to event loop\r\n await new Promise(resolve => setTimeout(resolve, 0));\r\n }\r\n\r\n return chunks.join('');\r\n }\r\n\r\n getExtensions(): string[] {\r\n return Array.from(this.extensions.keys());\r\n }\r\n\r\n hasExtension(name: string): boolean {\r\n return this.extensions.has(name);\r\n }\r\n\r\n getWarnings(): string[] {\r\n return [...this.parser.getWarnings(), ...this.renderer.getWarnings()];\r\n }\r\n\r\n getDebugInfo(): DebugInfo | null {\r\n return {\r\n warnings: this.getWarnings(),\r\n parseTime: this.parseTime,\r\n renderTime: this.renderTime,\r\n tokenCount: this.lastTokenCount,\r\n iterationCount: 0\r\n };\r\n }\r\n\r\n getPerformanceMetrics(): PerformanceMetrics | null {\r\n return {\r\n parseTime: this.parseTime,\r\n renderTime: this.renderTime,\r\n totalTime: this.parseTime + this.renderTime,\r\n tokenCount: this.lastTokenCount\r\n };\r\n }\r\n\r\n /**\r\n * Get cache statistics\r\n */\r\n getCacheStats() {\r\n return {\r\n parse: this.parseCache.getStats(),\r\n render: this.renderCache.getStats()\r\n };\r\n }\r\n\r\n /**\r\n * Clear all caches\r\n */\r\n clearCaches(): void {\r\n this.parseCache.clear();\r\n this.renderCache.clear();\r\n }\r\n\r\n /**\r\n * Update cache capacity\r\n */\r\n setCacheSize(size: number): void {\r\n this.parseCache.setCapacity(size);\r\n this.renderCache.setCapacity(size);\r\n }\r\n\r\n private rebuildParserAndRenderer(): void {\r\n // Get current configs\r\n const parserConfig = this.parser.getConfig();\r\n const rendererConfig = this.renderer.getConfig();\r\n\r\n // Recreate parser and renderer completely\r\n this.parser = new MarkdownParser(parserConfig);\r\n this.renderer = new MarkdownRenderer(rendererConfig);\r\n\r\n // Clear caches since we're rebuilding\r\n this.parseCache.clear();\r\n this.renderCache.clear();\r\n\r\n // Get the extensions that are still in the map (after removal)\r\n const extensionsToRegister = Array.from(this.extensions.values());\r\n\r\n // Re-register remaining extensions in the correct order\r\n // Feature extensions first\r\n const featureExtensions = extensionsToRegister.filter(ext =>\r\n ['alert', 'button', 'embed'].includes(ext.name)\r\n );\r\n\r\n // Core extensions second\r\n const coreExtensions = extensionsToRegister.filter(ext =>\r\n ['text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(ext.name)\r\n );\r\n\r\n // Custom extensions last\r\n const customExtensions = extensionsToRegister.filter(ext =>\r\n !['alert', 'button', 'embed', 'text', 'heading', 'bold', 'italic', 'code', 'codeblock', 'link', 'image', 'list', 'task-list', 'blockquote', 'hr', 'paragraph', 'line-break'].includes(ext.name)\r\n );\r\n\r\n // Register in correct order without going through the extension map\r\n [...featureExtensions, ...coreExtensions, ...customExtensions].forEach(extension => {\r\n // Add rules directly to parser and renderer\r\n extension.parseRules.forEach(rule => {\r\n this.parser.addRule(rule);\r\n });\r\n\r\n extension.renderRules.forEach(rule => {\r\n this.renderer.addRule(rule);\r\n });\r\n });\r\n }\r\n}\r\n\r\n// Factory functions for specific use cases\r\nexport function createMinimalEngine(config?: EngineConfig): ChangerawrMarkdown {\r\n // Create engine with NO default extensions\r\n const minimalConfig = {\r\n ...config,\r\n extensions: config?.extensions || []\r\n };\r\n\r\n const engine = new ChangerawrMarkdown();\r\n\r\n // Clear all default extensions\r\n const defaultExtensions = engine.getExtensions();\r\n defaultExtensions.forEach(ext => engine.unregisterExtension(ext));\r\n\r\n // Only add the ones specified in config\r\n if (minimalConfig.extensions) {\r\n minimalConfig.extensions.forEach(ext => engine.registerExtension(ext));\r\n }\r\n\r\n return engine;\r\n}\r\n\r\nexport function createCoreOnlyEngine(config?: EngineConfig): ChangerawrMarkdown {\r\n // Create engine with only core extensions (no alerts, buttons, embeds)\r\n const engine = new ChangerawrMarkdown();\r\n\r\n // Remove feature extensions, keep core\r\n engine.unregisterExtension('alert');\r\n engine.unregisterExtension('button');\r\n engine.unregisterExtension('embed');\r\n\r\n // Add any custom extensions\r\n if (config?.extensions) {\r\n config.extensions.forEach(ext => engine.registerExtension(ext));\r\n }\r\n\r\n return engine;\r\n}\r\n\r\n// Default instance for convenience functions\r\nexport const markdown = new ChangerawrMarkdown();\r\n\r\n// Convenience functions\r\nexport function parseMarkdown(content: string): MarkdownToken[] {\r\n return markdown.parse(content);\r\n}\r\n\r\nexport function renderMarkdown(content: string): string {\r\n return markdown.toHtml(content);\r\n}"],"mappings":"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","names":["markdown","module","hash","markdown","markdown"]}
|