@changerawr/markdown 1.0.1 → 1.0.3
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 +8 -233
- package/dist/index.d.ts +8 -233
- package/dist/index.js +35 -481
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +34 -454
- package/dist/index.mjs.map +1 -1
- package/dist/standalone.d.mts +3 -2
- package/dist/standalone.d.ts +3 -2
- package/dist/standalone.js +1 -8
- package/dist/standalone.js.map +1 -1
- package/dist/standalone.mjs +1 -8
- package/dist/standalone.mjs.map +1 -1
- package/package.json +1 -1
package/dist/standalone.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/parser.ts","../src/utils.ts","../src/renderer.ts","../src/extensions/alert.ts","../src/extensions/button.ts","../src/extensions/embed.ts","../src/engine.ts","../src/standalone.ts"],"sourcesContent":["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\r\n constructor(config?: ParserConfig) {\r\n this.config = config || {};\r\n }\r\n\r\n addRule(rule: ParseRule): void {\r\n this.rules.push(rule);\r\n // Sort by priority - put specific patterns first\r\n this.rules.sort((a, b) => {\r\n // CUM extensions first (alert, embed, button)\r\n if (a.name.includes('alert') || a.name.includes('embed') || a.name.includes('button')) return -1;\r\n if (b.name.includes('alert') || b.name.includes('embed') || b.name.includes('button')) return 1;\r\n\r\n // Task lists before regular lists\r\n if (a.name === 'task-list') return -1;\r\n if (b.name === 'task-list') return 1;\r\n if (a.name === 'list' && b.name === 'task-list') return 1;\r\n if (b.name === 'list' && a.name === 'task-list') return -1;\r\n\r\n // Then other rules\r\n return a.name.localeCompare(b.name);\r\n });\r\n }\r\n\r\n setupDefaultRulesIfEmpty(): void {\r\n // Check if we have any default rules (not just extension rules)\r\n const hasDefaultRules = this.rules.some(rule =>\r\n !['alert', 'button', 'embed'].includes(rule.name)\r\n );\r\n\r\n if (!hasDefaultRules) {\r\n this.setupDefaultRules();\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 // Ensure we have some rules\r\n this.setupDefaultRulesIfEmpty();\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 || (markdown.length * 2);\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\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 // Create a fresh regex without global flag for position-based matching\r\n const pattern = new RegExp(rule.pattern.source, rule.pattern.flags.replace('g', ''));\r\n const match = remaining.match(pattern);\r\n\r\n if (match && match.index !== undefined) {\r\n // Prioritize matches at position 0, but also consider nearby matches\r\n const priority = match.index === 0 ? 1000 : (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 // Take one character and continue\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 (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 getIterationCount(): number {\r\n // Return last iteration count for debugging\r\n return 0; // Simplified for now\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 processed.push(token);\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 setupDefaultRules(): void {\r\n // Headers (most specific first)\r\n this.addRule({\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 // Code blocks (before inline code)\r\n this.addRule({\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 // Hard line breaks - backslash at end of line\r\n this.addRule({\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 // Hard line breaks - two spaces at end of line\r\n this.addRule({\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 // Paragraph breaks - double newlines\r\n this.addRule({\r\n name: 'paragraph-break',\r\n pattern: /\\n\\s*\\n/,\r\n render: (match) => ({\r\n type: 'paragraph-break',\r\n content: '',\r\n raw: match[0] || ''\r\n })\r\n });\r\n\r\n // Bold (before italic to avoid conflicts)\r\n this.addRule({\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 // Italic\r\n this.addRule({\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 // Inline code\r\n this.addRule({\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 // Images (before links to avoid conflicts)\r\n this.addRule({\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 // Links\r\n this.addRule({\r\n name: 'link',\r\n pattern: /\\[([^\\]]+)\\]\\(([^)]+)\\)/,\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 // Task lists (before regular lists)\r\n this.addRule({\r\n name: 'task-list',\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 // Lists (after task lists)\r\n this.addRule({\r\n name: 'list',\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 // Blockquotes\r\n this.addRule({\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 // Horizontal rules\r\n this.addRule({\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 // Single newlines (soft line breaks) - handled last\r\n this.addRule({\r\n name: 'soft-break',\r\n pattern: /\\n/,\r\n render: (match) => ({\r\n type: 'soft-break',\r\n content: ' ', // Convert to space for inline text\r\n raw: match[0] || ''\r\n })\r\n });\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, generateId } 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 this.setupDefaultRules();\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 // Render each token\r\n const htmlParts = tokens.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 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 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 return rule.render(token);\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 text tokens, just return the content\r\n if (token.type === 'text') {\r\n return escapeHtml(token.content || token.raw || '');\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 // In production, return the content safely - this might be the issue\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 private setupDefaultRules(): void {\r\n this.addRule({\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 if (this.config.format === 'html') {\r\n return `<h${level} id=\"${id}\">${escapedContent}</h${level}>`;\r\n }\r\n\r\n let headingClasses = 'group relative flex items-center gap-2';\r\n\r\n switch (level) {\r\n case 1:\r\n headingClasses += ' text-3xl font-bold mt-8 mb-4';\r\n break;\r\n case 2:\r\n headingClasses += ' text-2xl font-semibold mt-6 mb-3';\r\n break;\r\n case 3:\r\n headingClasses += ' text-xl font-medium mt-5 mb-3';\r\n break;\r\n case 4:\r\n headingClasses += ' text-lg font-medium mt-4 mb-2';\r\n break;\r\n case 5:\r\n headingClasses += ' text-base font-medium mt-3 mb-2';\r\n break;\r\n case 6:\r\n headingClasses += ' text-sm font-medium mt-3 mb-2';\r\n 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 16 16\" fill=\"currentColor\">\r\n <path d=\"M7.5 4H5.75A3.75 3.75 0 002 7.75v.5a3.75 3.75 0 003.75 3.75h1.5m-1.5-4h3m1.5-4h1.75A3.75 3.75 0 0114 7.75v.5a3.75 3.75 0 01-3.75 3.75H8.5\"/>\r\n </svg>\r\n </a>\r\n </h${level}>`;\r\n }\r\n });\r\n\r\n this.addRule({\r\n type: 'bold',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n if (this.config.format === 'html') {\r\n return `<strong>${content}</strong>`;\r\n }\r\n return `<strong class=\"font-bold\">${content}</strong>`;\r\n }\r\n });\r\n\r\n this.addRule({\r\n type: 'italic',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n if (this.config.format === 'html') {\r\n return `<em>${content}</em>`;\r\n }\r\n return `<em class=\"italic\">${content}</em>`;\r\n }\r\n });\r\n\r\n this.addRule({\r\n type: 'code',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n if (this.config.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 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 this.addRule({\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\r\n if (this.config.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 this.addRule({\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\r\n if (this.config.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 this.addRule({\r\n type: 'list-item',\r\n render: (token) => `<li>${escapeHtml(token.content)}</li>`\r\n });\r\n\r\n this.addRule({\r\n type: 'blockquote',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n if (this.config.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 this.addRule({\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 this.addRule({\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\r\n if (this.config.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 this.addRule({\r\n type: 'task-item',\r\n render: (token) => {\r\n const isChecked = token.attributes?.checked === 'true';\r\n const escapedContent = escapeHtml(token.content);\r\n\r\n if (this.config.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;\"' : ''}>${escapedContent}</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\"' : ''}>${escapedContent}</span>\r\n </div>`;\r\n }\r\n });\r\n\r\n this.addRule({\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\r\n if (this.config.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 this.addRule({\r\n type: 'hr',\r\n render: () => {\r\n if (this.config.format === 'html') {\r\n return '<hr style=\"margin: 24px 0; border: none; border-top: 1px solid #d1d5db;\">';\r\n }\r\n return '<hr class=\"my-6 border-t border-border\">';\r\n }\r\n });\r\n\r\n // Line break handling\r\n this.addRule({\r\n type: 'line-break',\r\n render: () => '<br>'\r\n });\r\n\r\n this.addRule({\r\n type: 'paragraph-break',\r\n render: () => '</p><p>'\r\n });\r\n\r\n this.addRule({\r\n type: 'soft-break',\r\n render: (token) => token.content || ' '\r\n });\r\n }\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+)(?:\\s+(.*?))?\\s*\\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] || ''\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 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\">${token.content}</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 text = match[1] || '';\r\n const href = match[2] || '';\r\n const optionsString = match[3] || '';\r\n\r\n // Parse options\r\n const options = optionsString.split(',').map(opt => opt.trim()).filter(Boolean);\r\n\r\n // Determine style\r\n const styleOptions = ['default', 'primary', 'secondary', 'success', 'danger', 'outline', 'ghost'];\r\n const style = options.find(opt => styleOptions.includes(opt)) || 'primary';\r\n\r\n // Determine size\r\n const sizeOptions = ['sm', 'md', 'lg'];\r\n const size = options.find(opt => sizeOptions.includes(opt)) || 'md';\r\n\r\n // Determine other options\r\n const disabled = options.includes('disabled');\r\n const target = options.includes('self') ? '_self' : '_blank';\r\n\r\n return {\r\n type: 'button',\r\n content: text,\r\n raw: match[0] || '',\r\n attributes: {\r\n href,\r\n style,\r\n size,\r\n disabled: disabled.toString(),\r\n target\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 const text = token.content;\r\n\r\n // Build CSS classes\r\n const classes = buildButtonClasses(style, size);\r\n\r\n // Build attributes\r\n const targetAttr = target === '_blank'\r\n ? ' target=\"_blank\" rel=\"noopener noreferrer\"'\r\n : target === '_self'\r\n ? ' target=\"_self\"'\r\n : '';\r\n const disabledAttr = disabled ? ' aria-disabled=\"true\" tabindex=\"-1\"' : '';\r\n\r\n // Add external link icon only for _blank targets that aren't disabled\r\n const externalIcon = target === '_blank' && !disabled\r\n ? '<svg class=\"w-4 h-4 ml-1\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><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\"/></svg>'\r\n : '';\r\n\r\n return `<a href=\"${href}\" class=\"${classes}\"${targetAttr}${disabledAttr}>\r\n ${text}${externalIcon}\r\n </a>`;\r\n }\r\n }\r\n ]\r\n};\r\n\r\nfunction buildButtonClasses(style: string, size: string): string {\r\n // Base classes\r\n const base = [\r\n 'inline-flex',\r\n 'items-center',\r\n 'justify-center',\r\n 'font-medium',\r\n 'rounded-lg',\r\n 'transition-colors',\r\n 'focus:outline-none',\r\n 'focus:ring-2',\r\n 'focus:ring-offset-2',\r\n 'disabled:opacity-50',\r\n 'disabled:cursor-not-allowed'\r\n ];\r\n\r\n // Size classes\r\n const sizes: Record<string, string[]> = {\r\n sm: ['px-3', 'py-1.5', 'text-sm'],\r\n md: ['px-4', 'py-2', 'text-base'],\r\n lg: ['px-6', 'py-3', 'text-lg']\r\n };\r\n\r\n // Style classes\r\n const styles: Record<string, string[]> = {\r\n default: ['bg-slate-600', 'text-white', 'hover:bg-slate-700', 'focus:ring-slate-500'],\r\n primary: ['bg-blue-600', 'text-white', 'hover:bg-blue-700', 'focus:ring-blue-500'],\r\n secondary: ['bg-gray-600', 'text-white', 'hover:bg-gray-700', 'focus:ring-gray-500'],\r\n success: ['bg-green-600', 'text-white', 'hover:bg-green-700', 'focus:ring-green-500'],\r\n danger: ['bg-red-600', 'text-white', 'hover:bg-red-700', 'focus:ring-red-500'],\r\n outline: ['border', 'border-blue-600', 'text-blue-600', 'hover:bg-blue-50', 'focus:ring-blue-500'],\r\n ghost: ['text-gray-700', 'hover:bg-gray-100', 'focus:ring-gray-500']\r\n };\r\n\r\n // Combine all classes\r\n const allClasses = [\r\n ...base,\r\n ...(sizes[size] ?? sizes.md ?? []),\r\n ...(styles[style] ?? styles.primary ?? [])\r\n ];\r\n\r\n return allClasses.join(' ');\r\n}\r\n\r\n// Usage examples:\r\n// [button:Click Me](https://example.com){primary}\r\n// [button:Download](./file.pdf){success,lg}\r\n// [button:Cancel](javascript:void(0)){outline,sm}\r\n// [button:Disabled Button](#){danger,disabled}\r\n// [button:Same Tab](https://example.com){primary,self}\r\n// [button:Ghost Button](#){ghost,md}","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 `\r\n <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 `\r\n <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 `\r\n <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 `\r\n <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 `\r\n <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 `\r\n <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 `\r\n <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 `\r\n <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 `\r\n <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 `\r\n <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 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// Built-in extensions\r\nimport { AlertExtension } from './extensions/alert';\r\nimport { ButtonExtension } from './extensions/button';\r\nimport { EmbedExtension } from './extensions/embed';\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 constructor(config?: EngineConfig) {\r\n this.parser = new MarkdownParser(config?.parser);\r\n this.renderer = new MarkdownRenderer(config?.renderer);\r\n\r\n // Register built-in extensions first\r\n this.registerBuiltInExtensions();\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 // Ensure default rules are setup after extensions\r\n this.parser.setupDefaultRulesIfEmpty();\r\n }\r\n\r\n /**\r\n * Register a custom extension\r\n */\r\n registerExtension(extension: Extension): ExtensionRegistration {\r\n try {\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 /**\r\n * Unregister an extension\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 /**\r\n * Parse markdown content into tokens\r\n */\r\n parse(markdown: string): MarkdownToken[] {\r\n return this.parser.parse(markdown);\r\n }\r\n\r\n /**\r\n * Render tokens to HTML\r\n */\r\n render(tokens: MarkdownToken[]): string {\r\n return this.renderer.render(tokens);\r\n }\r\n\r\n /**\r\n * Parse and render markdown to HTML in one step\r\n */\r\n toHtml(markdown: string): string {\r\n const tokens = this.parse(markdown);\r\n return this.render(tokens);\r\n }\r\n\r\n /**\r\n * Get list of registered extensions\r\n */\r\n getExtensions(): string[] {\r\n return Array.from(this.extensions.keys());\r\n }\r\n\r\n /**\r\n * Check if extension is registered\r\n */\r\n hasExtension(name: string): boolean {\r\n return this.extensions.has(name);\r\n }\r\n\r\n /**\r\n * Get parser warnings\r\n */\r\n getWarnings(): string[] {\r\n return [...this.parser.getWarnings(), ...this.renderer.getWarnings()];\r\n }\r\n\r\n /**\r\n * Get debug information from last render\r\n */\r\n getDebugInfo(): DebugInfo | null {\r\n return {\r\n warnings: this.getWarnings(),\r\n parseTime: 0,\r\n renderTime: 0,\r\n tokenCount: 0,\r\n iterationCount: 0\r\n };\r\n }\r\n\r\n /**\r\n * Get performance metrics for the last operation\r\n */\r\n getPerformanceMetrics(): PerformanceMetrics | null {\r\n return {\r\n parseTime: 0,\r\n renderTime: 0,\r\n totalTime: 0,\r\n tokenCount: 0\r\n };\r\n }\r\n\r\n /**\r\n * Register built-in extensions\r\n */\r\n private registerBuiltInExtensions(): void {\r\n this.registerExtension(AlertExtension);\r\n this.registerExtension(ButtonExtension);\r\n this.registerExtension(EmbedExtension);\r\n }\r\n\r\n /**\r\n * Rebuild parser and renderer with current extensions\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\r\n this.parser = new MarkdownParser(parserConfig);\r\n this.renderer = new MarkdownRenderer(rendererConfig);\r\n\r\n // Re-register only the extensions that are still in the map\r\n const extensionsToRegister = Array.from(this.extensions.values());\r\n\r\n // Clear the map and re-register from scratch\r\n this.extensions.clear();\r\n\r\n // Register remaining extensions\r\n extensionsToRegister.forEach(extension => {\r\n this.registerExtension(extension);\r\n });\r\n\r\n // Ensure default rules are setup\r\n this.parser.setupDefaultRulesIfEmpty();\r\n }\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}","/**\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// Create the global API object\r\nconst globalAPI = {\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};\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 for easier imports\r\nexport default globalAPI;\r\n\r\n// Browser global assignment (will be executed when the script loads)\r\nif (typeof window !== 'undefined') {\r\n (window as any).ChangerawrMarkdown = globalAPI;\r\n}\r\n\r\n// Also assign to global scope for different environments\r\nif (typeof globalThis !== 'undefined') {\r\n (globalThis as any).ChangerawrMarkdown = globalAPI;\r\n}"],"mappings":"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","names":["markdown","markdown","markdown"]}
|
|
1
|
+
{"version":3,"sources":["../src/parser.ts","../src/utils.ts","../src/renderer.ts","../src/extensions/alert.ts","../src/extensions/button.ts","../src/extensions/embed.ts","../src/engine.ts","../src/standalone.ts"],"sourcesContent":["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\r\n constructor(config?: ParserConfig) {\r\n this.config = config || {};\r\n }\r\n\r\n addRule(rule: ParseRule): void {\r\n this.rules.push(rule);\r\n // Sort by priority - put specific patterns first\r\n this.rules.sort((a, b) => {\r\n // CUM extensions first (alert, embed, button)\r\n if (a.name.includes('alert') || a.name.includes('embed') || a.name.includes('button')) return -1;\r\n if (b.name.includes('alert') || b.name.includes('embed') || b.name.includes('button')) return 1;\r\n\r\n // Task lists before regular lists\r\n if (a.name === 'task-list') return -1;\r\n if (b.name === 'task-list') return 1;\r\n if (a.name === 'list' && b.name === 'task-list') return 1;\r\n if (b.name === 'list' && a.name === 'task-list') return -1;\r\n\r\n // Then other rules\r\n return a.name.localeCompare(b.name);\r\n });\r\n }\r\n\r\n setupDefaultRulesIfEmpty(): void {\r\n // Check if we have any default rules (not just extension rules)\r\n const hasDefaultRules = this.rules.some(rule =>\r\n !['alert', 'button', 'embed'].includes(rule.name)\r\n );\r\n\r\n if (!hasDefaultRules) {\r\n this.setupDefaultRules();\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 // Ensure we have some rules\r\n this.setupDefaultRulesIfEmpty();\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 || (markdown.length * 2);\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\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 // Create a fresh regex without global flag for position-based matching\r\n const pattern = new RegExp(rule.pattern.source, rule.pattern.flags.replace('g', ''));\r\n const match = remaining.match(pattern);\r\n\r\n if (match && match.index !== undefined) {\r\n // Prioritize matches at position 0, but also consider nearby matches\r\n const priority = match.index === 0 ? 1000 : (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 // Take one character and continue\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 (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 getIterationCount(): number {\r\n // Return last iteration count for debugging\r\n return 0; // Simplified for now\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 processed.push(token);\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 setupDefaultRules(): void {\r\n // Headers (most specific first)\r\n this.addRule({\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 // Code blocks (before inline code)\r\n this.addRule({\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 // Hard line breaks - backslash at end of line\r\n this.addRule({\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 // Hard line breaks - two spaces at end of line\r\n this.addRule({\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 // Paragraph breaks - double newlines\r\n this.addRule({\r\n name: 'paragraph-break',\r\n pattern: /\\n\\s*\\n/,\r\n render: (match) => ({\r\n type: 'paragraph-break',\r\n content: '',\r\n raw: match[0] || ''\r\n })\r\n });\r\n\r\n // Bold (before italic to avoid conflicts)\r\n this.addRule({\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 // Italic\r\n this.addRule({\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 // Inline code\r\n this.addRule({\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 // Images (before links to avoid conflicts)\r\n this.addRule({\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 // Links\r\n this.addRule({\r\n name: 'link',\r\n pattern: /\\[([^\\]]+)\\]\\(([^)]+)\\)/,\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 // Task lists (before regular lists)\r\n this.addRule({\r\n name: 'task-list',\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 // Lists (after task lists)\r\n this.addRule({\r\n name: 'list',\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 // Blockquotes\r\n this.addRule({\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 // Horizontal rules\r\n this.addRule({\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 // Single newlines (soft line breaks) - handled last\r\n this.addRule({\r\n name: 'soft-break',\r\n pattern: /\\n/,\r\n render: (match) => ({\r\n type: 'soft-break',\r\n content: ' ', // Convert to space for inline text\r\n raw: match[0] || ''\r\n })\r\n });\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, generateId } 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 this.setupDefaultRules();\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 // Render each token\r\n const htmlParts = tokens.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 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 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 return rule.render(token);\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 text tokens, just return the content\r\n if (token.type === 'text') {\r\n return escapeHtml(token.content || token.raw || '');\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 // In production, return the content safely - this might be the issue\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 private setupDefaultRules(): void {\r\n this.addRule({\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 if (this.config.format === 'html') {\r\n return `<h${level} id=\"${id}\">${escapedContent}</h${level}>`;\r\n }\r\n\r\n let headingClasses = 'group relative flex items-center gap-2';\r\n\r\n switch (level) {\r\n case 1:\r\n headingClasses += ' text-3xl font-bold mt-8 mb-4';\r\n break;\r\n case 2:\r\n headingClasses += ' text-2xl font-semibold mt-6 mb-3';\r\n break;\r\n case 3:\r\n headingClasses += ' text-xl font-medium mt-5 mb-3';\r\n break;\r\n case 4:\r\n headingClasses += ' text-lg font-medium mt-4 mb-2';\r\n break;\r\n case 5:\r\n headingClasses += ' text-base font-medium mt-3 mb-2';\r\n break;\r\n case 6:\r\n headingClasses += ' text-sm font-medium mt-3 mb-2';\r\n 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 16 16\" fill=\"currentColor\">\r\n <path d=\"M7.5 4H5.75A3.75 3.75 0 002 7.75v.5a3.75 3.75 0 003.75 3.75h1.5m-1.5-4h3m1.5-4h1.75A3.75 3.75 0 0114 7.75v.5a3.75 3.75 0 01-3.75 3.75H8.5\"/>\r\n </svg>\r\n </a>\r\n </h${level}>`;\r\n }\r\n });\r\n\r\n this.addRule({\r\n type: 'bold',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n if (this.config.format === 'html') {\r\n return `<strong>${content}</strong>`;\r\n }\r\n return `<strong class=\"font-bold\">${content}</strong>`;\r\n }\r\n });\r\n\r\n this.addRule({\r\n type: 'italic',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n if (this.config.format === 'html') {\r\n return `<em>${content}</em>`;\r\n }\r\n return `<em class=\"italic\">${content}</em>`;\r\n }\r\n });\r\n\r\n this.addRule({\r\n type: 'code',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n if (this.config.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 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 this.addRule({\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\r\n if (this.config.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 this.addRule({\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\r\n if (this.config.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 this.addRule({\r\n type: 'list-item',\r\n render: (token) => `<li>${escapeHtml(token.content)}</li>`\r\n });\r\n\r\n this.addRule({\r\n type: 'blockquote',\r\n render: (token) => {\r\n const content = escapeHtml(token.content);\r\n if (this.config.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 this.addRule({\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 this.addRule({\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\r\n if (this.config.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 this.addRule({\r\n type: 'task-item',\r\n render: (token) => {\r\n const isChecked = token.attributes?.checked === 'true';\r\n const escapedContent = escapeHtml(token.content);\r\n\r\n if (this.config.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;\"' : ''}>${escapedContent}</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\"' : ''}>${escapedContent}</span>\r\n </div>`;\r\n }\r\n });\r\n\r\n this.addRule({\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\r\n if (this.config.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 this.addRule({\r\n type: 'hr',\r\n render: () => {\r\n if (this.config.format === 'html') {\r\n return '<hr style=\"margin: 24px 0; border: none; border-top: 1px solid #d1d5db;\">';\r\n }\r\n return '<hr class=\"my-6 border-t border-border\">';\r\n }\r\n });\r\n\r\n // Line break handling\r\n this.addRule({\r\n type: 'line-break',\r\n render: () => '<br>'\r\n });\r\n\r\n this.addRule({\r\n type: 'paragraph-break',\r\n render: () => '</p><p>'\r\n });\r\n\r\n this.addRule({\r\n type: 'soft-break',\r\n render: (token) => token.content || ' '\r\n });\r\n }\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+)(?:\\s+(.*?))?\\s*\\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] || ''\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 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\">${token.content}</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 text = match[1] || '';\r\n const href = match[2] || '';\r\n const optionsString = match[3] || '';\r\n\r\n // Parse options\r\n const options = optionsString.split(',').map(opt => opt.trim()).filter(Boolean);\r\n\r\n // Determine style\r\n const styleOptions = ['default', 'primary', 'secondary', 'success', 'danger', 'outline', 'ghost'];\r\n const style = options.find(opt => styleOptions.includes(opt)) || 'primary';\r\n\r\n // Determine size\r\n const sizeOptions = ['sm', 'md', 'lg'];\r\n const size = options.find(opt => sizeOptions.includes(opt)) || 'md';\r\n\r\n // Determine other options\r\n const disabled = options.includes('disabled');\r\n const target = options.includes('self') ? '_self' : '_blank';\r\n\r\n return {\r\n type: 'button',\r\n content: text,\r\n raw: match[0] || '',\r\n attributes: {\r\n href,\r\n style,\r\n size,\r\n disabled: disabled.toString(),\r\n target\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 const text = token.content;\r\n\r\n // Build CSS classes\r\n const classes = buildButtonClasses(style, size);\r\n\r\n // Build attributes\r\n const targetAttr = target === '_blank'\r\n ? ' target=\"_blank\" rel=\"noopener noreferrer\"'\r\n : target === '_self'\r\n ? ' target=\"_self\"'\r\n : '';\r\n const disabledAttr = disabled ? ' aria-disabled=\"true\" tabindex=\"-1\"' : '';\r\n\r\n // Add external link icon only for _blank targets that aren't disabled\r\n const externalIcon = target === '_blank' && !disabled\r\n ? '<svg class=\"w-4 h-4 ml-1\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><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\"/></svg>'\r\n : '';\r\n\r\n return `<a href=\"${href}\" class=\"${classes}\"${targetAttr}${disabledAttr}>\r\n ${text}${externalIcon}\r\n </a>`;\r\n }\r\n }\r\n ]\r\n};\r\n\r\nfunction buildButtonClasses(style: string, size: string): string {\r\n // Base classes\r\n const base = [\r\n 'inline-flex',\r\n 'items-center',\r\n 'justify-center',\r\n 'font-medium',\r\n 'rounded-lg',\r\n 'transition-colors',\r\n 'focus:outline-none',\r\n 'focus:ring-2',\r\n 'focus:ring-offset-2',\r\n 'disabled:opacity-50',\r\n 'disabled:cursor-not-allowed'\r\n ];\r\n\r\n // Size classes\r\n const sizes: Record<string, string[]> = {\r\n sm: ['px-3', 'py-1.5', 'text-sm'],\r\n md: ['px-4', 'py-2', 'text-base'],\r\n lg: ['px-6', 'py-3', 'text-lg']\r\n };\r\n\r\n // Style classes\r\n const styles: Record<string, string[]> = {\r\n default: ['bg-slate-600', 'text-white', 'hover:bg-slate-700', 'focus:ring-slate-500'],\r\n primary: ['bg-blue-600', 'text-white', 'hover:bg-blue-700', 'focus:ring-blue-500'],\r\n secondary: ['bg-gray-600', 'text-white', 'hover:bg-gray-700', 'focus:ring-gray-500'],\r\n success: ['bg-green-600', 'text-white', 'hover:bg-green-700', 'focus:ring-green-500'],\r\n danger: ['bg-red-600', 'text-white', 'hover:bg-red-700', 'focus:ring-red-500'],\r\n outline: ['border', 'border-blue-600', 'text-blue-600', 'hover:bg-blue-50', 'focus:ring-blue-500'],\r\n ghost: ['text-gray-700', 'hover:bg-gray-100', 'focus:ring-gray-500']\r\n };\r\n\r\n // Combine all classes\r\n const allClasses = [\r\n ...base,\r\n ...(sizes[size] ?? sizes.md ?? []),\r\n ...(styles[style] ?? styles.primary ?? [])\r\n ];\r\n\r\n return allClasses.join(' ');\r\n}\r\n\r\n// Usage examples:\r\n// [button:Click Me](https://example.com){primary}\r\n// [button:Download](./file.pdf){success,lg}\r\n// [button:Cancel](javascript:void(0)){outline,sm}\r\n// [button:Disabled Button](#){danger,disabled}\r\n// [button:Same Tab](https://example.com){primary,self}\r\n// [button:Ghost Button](#){ghost,md}","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 `\r\n <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 `\r\n <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 `\r\n <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 `\r\n <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 `\r\n <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 `\r\n <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 `\r\n <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 `\r\n <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 `\r\n <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 `\r\n <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 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// Built-in extensions\r\nimport { AlertExtension } from './extensions/alert';\r\nimport { ButtonExtension } from './extensions/button';\r\nimport { EmbedExtension } from './extensions/embed';\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 constructor(config?: EngineConfig) {\r\n this.parser = new MarkdownParser(config?.parser);\r\n this.renderer = new MarkdownRenderer(config?.renderer);\r\n\r\n // Register built-in extensions first\r\n this.registerBuiltInExtensions();\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 // Ensure default rules are setup after extensions\r\n this.parser.setupDefaultRulesIfEmpty();\r\n }\r\n\r\n /**\r\n * Register a custom extension\r\n */\r\n registerExtension(extension: Extension): ExtensionRegistration {\r\n try {\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 /**\r\n * Unregister an extension\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 /**\r\n * Parse markdown content into tokens\r\n */\r\n parse(markdown: string): MarkdownToken[] {\r\n return this.parser.parse(markdown);\r\n }\r\n\r\n /**\r\n * Render tokens to HTML\r\n */\r\n render(tokens: MarkdownToken[]): string {\r\n return this.renderer.render(tokens);\r\n }\r\n\r\n /**\r\n * Parse and render markdown to HTML in one step\r\n */\r\n toHtml(markdown: string): string {\r\n const tokens = this.parse(markdown);\r\n return this.render(tokens);\r\n }\r\n\r\n /**\r\n * Get list of registered extensions\r\n */\r\n getExtensions(): string[] {\r\n return Array.from(this.extensions.keys());\r\n }\r\n\r\n /**\r\n * Check if extension is registered\r\n */\r\n hasExtension(name: string): boolean {\r\n return this.extensions.has(name);\r\n }\r\n\r\n /**\r\n * Get parser warnings\r\n */\r\n getWarnings(): string[] {\r\n return [...this.parser.getWarnings(), ...this.renderer.getWarnings()];\r\n }\r\n\r\n /**\r\n * Get debug information from last render\r\n */\r\n getDebugInfo(): DebugInfo | null {\r\n return {\r\n warnings: this.getWarnings(),\r\n parseTime: 0,\r\n renderTime: 0,\r\n tokenCount: 0,\r\n iterationCount: 0\r\n };\r\n }\r\n\r\n /**\r\n * Get performance metrics for the last operation\r\n */\r\n getPerformanceMetrics(): PerformanceMetrics | null {\r\n return {\r\n parseTime: 0,\r\n renderTime: 0,\r\n totalTime: 0,\r\n tokenCount: 0\r\n };\r\n }\r\n\r\n /**\r\n * Register built-in extensions\r\n */\r\n private registerBuiltInExtensions(): void {\r\n this.registerExtension(AlertExtension);\r\n this.registerExtension(ButtonExtension);\r\n this.registerExtension(EmbedExtension);\r\n }\r\n\r\n /**\r\n * Rebuild parser and renderer with current extensions\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\r\n this.parser = new MarkdownParser(parserConfig);\r\n this.renderer = new MarkdownRenderer(rendererConfig);\r\n\r\n // Re-register only the extensions that are still in the map\r\n const extensionsToRegister = Array.from(this.extensions.values());\r\n\r\n // Clear the map and re-register from scratch\r\n this.extensions.clear();\r\n\r\n // Register remaining extensions\r\n extensionsToRegister.forEach(extension => {\r\n this.registerExtension(extension);\r\n });\r\n\r\n // Ensure default rules are setup\r\n this.parser.setupDefaultRulesIfEmpty();\r\n }\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}","/**\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};"],"mappings":"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","names":["markdown","markdown","markdown"]}
|