@changerawr/markdown 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,585 @@
1
+ interface MarkdownToken {
2
+ type: string;
3
+ content: string;
4
+ raw: string;
5
+ attributes?: Record<string, string>;
6
+ }
7
+ interface ParseRule {
8
+ name: string;
9
+ pattern: RegExp;
10
+ render: (match: RegExpMatchArray) => MarkdownToken;
11
+ }
12
+ interface RenderRule {
13
+ type: string;
14
+ render: (token: MarkdownToken) => string;
15
+ }
16
+ interface Extension {
17
+ name: string;
18
+ parseRules: ParseRule[];
19
+ renderRules: RenderRule[];
20
+ }
21
+ type OutputFormat = 'html' | 'tailwind' | 'json';
22
+ interface RendererConfig {
23
+ format: OutputFormat;
24
+ sanitize?: boolean;
25
+ allowUnsafeHtml?: boolean;
26
+ customClasses?: Record<string, string>;
27
+ debugMode?: boolean;
28
+ }
29
+ interface ParserConfig {
30
+ debugMode?: boolean;
31
+ maxIterations?: number;
32
+ validateMarkdown?: boolean;
33
+ }
34
+ interface EngineConfig {
35
+ parser?: ParserConfig;
36
+ renderer?: RendererConfig;
37
+ extensions?: Extension[];
38
+ }
39
+ interface DebugInfo {
40
+ warnings: string[];
41
+ parseTime: number;
42
+ renderTime: number;
43
+ tokenCount: number;
44
+ iterationCount: number;
45
+ }
46
+ interface JsonAstNode {
47
+ type: string;
48
+ content: string;
49
+ attributes?: Record<string, string>;
50
+ children?: JsonAstNode[];
51
+ }
52
+ interface PerformanceMetrics {
53
+ parseTime: number;
54
+ renderTime: number;
55
+ totalTime: number;
56
+ tokenCount: number;
57
+ memoryUsed?: number;
58
+ }
59
+ declare class MarkdownParseError extends Error {
60
+ readonly position?: number | undefined;
61
+ readonly rule?: string | undefined;
62
+ constructor(message: string, position?: number | undefined, rule?: string | undefined);
63
+ }
64
+ declare class MarkdownRenderError extends Error {
65
+ readonly tokenType?: string | undefined;
66
+ readonly token?: MarkdownToken | undefined;
67
+ constructor(message: string, tokenType?: string | undefined, token?: MarkdownToken | undefined);
68
+ }
69
+ declare class ExtensionError extends Error {
70
+ readonly extensionName?: string | undefined;
71
+ constructor(message: string, extensionName?: string | undefined);
72
+ }
73
+ type TokenType = 'text' | 'heading' | 'bold' | 'italic' | 'code' | 'codeblock' | 'link' | 'image' | 'list-item' | 'task-item' | 'blockquote' | 'hr' | 'line-break' | 'paragraph-break' | 'soft-break' | 'paragraph' | 'alert' | 'button' | 'embed' | string;
74
+ interface EngineEvents {
75
+ onParseStart?: (content: string) => void;
76
+ onParseComplete?: (tokens: MarkdownToken[], metrics: PerformanceMetrics) => void;
77
+ onRenderStart?: (tokens: MarkdownToken[]) => void;
78
+ onRenderComplete?: (html: string, metrics: PerformanceMetrics) => void;
79
+ onError?: (error: Error) => void;
80
+ onWarning?: (warning: string) => void;
81
+ }
82
+ interface ExtensionRegistration {
83
+ success: boolean;
84
+ extensionName: string;
85
+ error?: string;
86
+ conflictingRules?: string[];
87
+ }
88
+
89
+ declare class ChangerawrMarkdown {
90
+ private parser;
91
+ private renderer;
92
+ private extensions;
93
+ constructor(config?: EngineConfig);
94
+ /**
95
+ * Register a custom extension
96
+ */
97
+ registerExtension(extension: Extension): ExtensionRegistration;
98
+ /**
99
+ * Unregister an extension
100
+ */
101
+ unregisterExtension(name: string): boolean;
102
+ /**
103
+ * Parse markdown content into tokens
104
+ */
105
+ parse(markdown: string): MarkdownToken[];
106
+ /**
107
+ * Render tokens to HTML
108
+ */
109
+ render(tokens: MarkdownToken[]): string;
110
+ /**
111
+ * Parse and render markdown to HTML in one step
112
+ */
113
+ toHtml(markdown: string): string;
114
+ /**
115
+ * Get list of registered extensions
116
+ */
117
+ getExtensions(): string[];
118
+ /**
119
+ * Check if extension is registered
120
+ */
121
+ hasExtension(name: string): boolean;
122
+ /**
123
+ * Get parser warnings
124
+ */
125
+ getWarnings(): string[];
126
+ /**
127
+ * Get debug information from last render
128
+ */
129
+ getDebugInfo(): DebugInfo | null;
130
+ /**
131
+ * Get performance metrics for the last operation
132
+ */
133
+ getPerformanceMetrics(): PerformanceMetrics | null;
134
+ /**
135
+ * Register built-in extensions
136
+ */
137
+ private registerBuiltInExtensions;
138
+ /**
139
+ * Rebuild parser and renderer with current extensions
140
+ */
141
+ private rebuildParserAndRenderer;
142
+ }
143
+ declare function parseMarkdown(content: string): MarkdownToken[];
144
+ declare function renderMarkdown(content: string): string;
145
+
146
+ /**
147
+ * Plain HTML output renderer - no CSS framework classes
148
+ */
149
+
150
+ /**
151
+ * Render markdown to plain HTML without CSS framework classes
152
+ */
153
+ declare function renderToHTML(markdown: string, config?: Omit<EngineConfig, 'renderer'>): string;
154
+ /**
155
+ * Parse markdown and render to HTML with custom configuration
156
+ */
157
+ declare function renderToHTMLWithConfig(markdown: string, rendererConfig: {
158
+ sanitize?: boolean;
159
+ allowUnsafeHtml?: boolean;
160
+ debugMode?: boolean;
161
+ }): string;
162
+ /**
163
+ * Render markdown to HTML without any sanitization (use with caution)
164
+ */
165
+ declare function renderToHTMLUnsafe(markdown: string): string;
166
+
167
+ /**
168
+ * JSON AST output renderer - returns structured token data
169
+ */
170
+
171
+ /**
172
+ * Parse markdown and return the token array as JSON
173
+ */
174
+ declare function renderToJSON(markdown: string, config?: Omit<EngineConfig, 'renderer'>): MarkdownToken[];
175
+ /**
176
+ * Parse markdown and return a hierarchical AST structure
177
+ */
178
+ declare function renderToAST(markdown: string, config?: Omit<EngineConfig, 'renderer'>): JsonAstNode[];
179
+ /**
180
+ * Convert flat token array to hierarchical AST
181
+ */
182
+ declare function tokensToAST(tokens: MarkdownToken[]): JsonAstNode[];
183
+ /**
184
+ * Convert AST back to flat tokens
185
+ */
186
+ declare function astToTokens(ast: JsonAstNode[]): MarkdownToken[];
187
+ /**
188
+ * Serialize tokens to JSON string with formatting
189
+ */
190
+ declare function tokensToJSONString(tokens: MarkdownToken[], pretty?: boolean): string;
191
+ /**
192
+ * Serialize AST to JSON string with formatting
193
+ */
194
+ declare function astToJSONString(ast: JsonAstNode[], pretty?: boolean): string;
195
+ /**
196
+ * Parse JSON string back to tokens
197
+ */
198
+ declare function parseTokensFromJSON(jsonString: string): MarkdownToken[];
199
+ /**
200
+ * Parse JSON string back to AST
201
+ */
202
+ declare function parseASTFromJSON(jsonString: string): JsonAstNode[];
203
+ /**
204
+ * Get comprehensive statistics from parsed tokens
205
+ */
206
+ declare function getTokenStats(tokens: MarkdownToken[]): TokenStatistics;
207
+ /**
208
+ * Get AST-specific statistics
209
+ */
210
+ declare function getASTStats(ast: JsonAstNode[]): ASTStatistics;
211
+ /**
212
+ * Compare two token arrays for differences
213
+ */
214
+ declare function compareTokens(tokensA: MarkdownToken[], tokensB: MarkdownToken[]): TokenComparison;
215
+ interface TokenStatistics {
216
+ totalTokens: number;
217
+ tokenTypes: Record<string, number>;
218
+ extensionTokens: Record<string, number>;
219
+ totalContent: number;
220
+ totalRaw: number;
221
+ tokensWithAttributes: number;
222
+ averageContentLength: number;
223
+ averageRawLength: number;
224
+ attributeUsageRate: number;
225
+ }
226
+ interface ASTStatistics {
227
+ totalNodes: number;
228
+ maxDepth: number;
229
+ nodesWithChildren: number;
230
+ totalChildren: number;
231
+ nodeTypes: Record<string, number>;
232
+ averageChildrenPerParent: number;
233
+ hierarchyComplexity: number;
234
+ }
235
+ interface TokenDifference {
236
+ index: number;
237
+ type: 'added' | 'removed' | 'modified';
238
+ tokenA?: MarkdownToken;
239
+ tokenB?: MarkdownToken;
240
+ }
241
+ interface TokenComparison {
242
+ identical: boolean;
243
+ differences: TokenDifference[];
244
+ addedCount: number;
245
+ removedCount: number;
246
+ modifiedCount: number;
247
+ }
248
+
249
+ /**
250
+ * Tailwind CSS output renderer - HTML with Tailwind CSS classes
251
+ */
252
+
253
+ /**
254
+ * Render markdown to HTML with Tailwind CSS classes (default behavior)
255
+ */
256
+ declare function renderToTailwind(markdown: string, config?: Omit<EngineConfig, 'renderer'>): string;
257
+ /**
258
+ * Render markdown with custom Tailwind classes
259
+ */
260
+ declare function renderToTailwindWithClasses(markdown: string, customClasses?: Record<string, string>): string;
261
+ /**
262
+ * Render markdown to Tailwind HTML with custom configuration
263
+ */
264
+ declare function renderToTailwindWithConfig(markdown: string, rendererConfig: {
265
+ sanitize?: boolean;
266
+ allowUnsafeHtml?: boolean;
267
+ customClasses?: Record<string, string>;
268
+ debugMode?: boolean;
269
+ }): string;
270
+ /**
271
+ * Default Tailwind configuration for common use cases
272
+ */
273
+ declare const defaultTailwindClasses: {
274
+ 'heading-1': string;
275
+ 'heading-2': string;
276
+ 'heading-3': string;
277
+ 'heading-4': string;
278
+ 'heading-5': string;
279
+ 'heading-6': string;
280
+ paragraph: string;
281
+ blockquote: string;
282
+ 'code-inline': string;
283
+ 'code-block': string;
284
+ link: string;
285
+ button: string;
286
+ list: string;
287
+ 'list-item': string;
288
+ image: string;
289
+ embed: string;
290
+ alert: string;
291
+ 'alert-info': string;
292
+ 'alert-warning': string;
293
+ 'alert-error': string;
294
+ 'alert-success': string;
295
+ };
296
+ /**
297
+ * Prose-friendly Tailwind classes for blog/article content
298
+ */
299
+ declare const proseClasses: {
300
+ 'heading-1': string;
301
+ 'heading-2': string;
302
+ 'heading-3': string;
303
+ paragraph: string;
304
+ blockquote: string;
305
+ 'code-inline': string;
306
+ 'code-block': string;
307
+ link: string;
308
+ };
309
+ /**
310
+ * Minimal Tailwind classes for clean, simple styling
311
+ */
312
+ declare const minimalClasses: {
313
+ 'heading-1': string;
314
+ 'heading-2': string;
315
+ 'heading-3': string;
316
+ paragraph: string;
317
+ blockquote: string;
318
+ 'code-inline': string;
319
+ 'code-block': string;
320
+ link: string;
321
+ };
322
+
323
+ /**
324
+ * Standalone version of Changerawr Markdown for vanilla JavaScript usage
325
+ * No React dependencies - works in browser and Node.js environments
326
+ */
327
+
328
+ declare function renderCum(markdown: string, config?: EngineConfig): string;
329
+ declare function parseCum(markdown: string, config?: EngineConfig): MarkdownToken[];
330
+ declare function createCumEngine(config?: EngineConfig): ChangerawrMarkdown;
331
+ declare function renderCumToHtml(markdown: string): string;
332
+ declare function renderCumToTailwind(markdown: string): string;
333
+ declare function renderCumToJson(markdown: string): MarkdownToken[];
334
+
335
+ /**
336
+ * Utility functions for Changerawr Markdown
337
+ */
338
+ /**
339
+ * Escape HTML special characters
340
+ */
341
+ declare function escapeHtml(text: string): string;
342
+ /**
343
+ * Generate URL-friendly ID from text
344
+ */
345
+ declare function generateId(text: string): string;
346
+ /**
347
+ * Sanitize HTML content using DOMPurify
348
+ */
349
+ declare function sanitizeHtml(html: string): string;
350
+ /**
351
+ * Basic HTML sanitization - removes dangerous content
352
+ */
353
+ declare function basicSanitize(html: string): string;
354
+ /**
355
+ * Check if code is running in browser environment
356
+ */
357
+ declare function isBrowser(): boolean;
358
+ /**
359
+ * Check if code is running in Node.js environment
360
+ */
361
+ declare function isNode(): boolean;
362
+ /**
363
+ * Debounce function for performance optimization
364
+ */
365
+ declare function debounce<T extends (...args: any[]) => any>(func: T, wait: number): (...args: Parameters<T>) => void;
366
+ /**
367
+ * Deep merge two objects
368
+ */
369
+ declare function deepMerge<T extends Record<string, any>>(target: T, source: Partial<T>): T;
370
+ /**
371
+ * Extract domain from URL
372
+ */
373
+ declare function extractDomain(url: string): string;
374
+ /**
375
+ * Check if URL is valid
376
+ */
377
+ declare function isValidUrl(url: string): boolean;
378
+ /**
379
+ * Parse options string into key-value object
380
+ */
381
+ declare function parseOptions(options: string): Record<string, string>;
382
+ /**
383
+ * Performance measurement utility
384
+ */
385
+ declare class PerformanceTimer {
386
+ private startTime;
387
+ private marks;
388
+ constructor();
389
+ mark(name: string): void;
390
+ getTime(name?: string): number;
391
+ getAllMarks(): Record<string, number>;
392
+ }
393
+ /**
394
+ * Simple logger with different levels
395
+ */
396
+ declare class Logger {
397
+ private debugMode;
398
+ constructor(debugMode?: boolean);
399
+ debug(...args: any[]): void;
400
+ info(...args: any[]): void;
401
+ warn(...args: any[]): void;
402
+ error(...args: any[]): void;
403
+ setDebugMode(enabled: boolean): void;
404
+ }
405
+
406
+ declare class MarkdownParser {
407
+ private rules;
408
+ private warnings;
409
+ private config;
410
+ constructor(config?: ParserConfig);
411
+ addRule(rule: ParseRule): void;
412
+ setupDefaultRulesIfEmpty(): void;
413
+ hasRule(name: string): boolean;
414
+ parse(markdown: string): MarkdownToken[];
415
+ getWarnings(): string[];
416
+ getConfig(): ParserConfig;
417
+ updateConfig(config: Partial<ParserConfig>): void;
418
+ setDebugMode(enabled: boolean): void;
419
+ clearWarnings(): void;
420
+ getIterationCount(): number;
421
+ private preprocessMarkdown;
422
+ private validateMarkdown;
423
+ private postProcessTokens;
424
+ private setupDefaultRules;
425
+ }
426
+
427
+ declare class MarkdownRenderer {
428
+ private rules;
429
+ private warnings;
430
+ private config;
431
+ constructor(config?: RendererConfig);
432
+ addRule(rule: RenderRule): void;
433
+ hasRule(type: string): boolean;
434
+ render(tokens: MarkdownToken[]): string;
435
+ getWarnings(): string[];
436
+ getConfig(): RendererConfig;
437
+ updateConfig(config: Partial<RendererConfig>): void;
438
+ setDebugMode(enabled: boolean): void;
439
+ clearWarnings(): void;
440
+ private renderToken;
441
+ private createErrorBlock;
442
+ private createDebugBlock;
443
+ private setupDefaultRules;
444
+ }
445
+
446
+ declare const AlertExtension: Extension;
447
+
448
+ declare const ButtonExtension: Extension;
449
+
450
+ declare const EmbedExtension: Extension;
451
+
452
+ /**
453
+ * @changerawr/markdown - Main package exports
454
+ *
455
+ * Powerful markdown renderer with custom extensions
456
+ * Supports HTML, Tailwind CSS, and JSON outputs
457
+ */
458
+
459
+ /**
460
+ * Create a general-purpose markdown engine with default settings
461
+ */
462
+ declare function createEngine(config?: EngineConfig): ChangerawrMarkdown;
463
+ /**
464
+ * Create an engine optimized for HTML output (no CSS classes)
465
+ */
466
+ declare function createHTMLEngine(config?: Omit<EngineConfig, 'renderer'>): ChangerawrMarkdown;
467
+ /**
468
+ * Create an engine optimized for Tailwind CSS output
469
+ */
470
+ declare function createTailwindEngine(config?: Omit<EngineConfig, 'renderer'>): ChangerawrMarkdown;
471
+ /**
472
+ * Create an engine with debug mode enabled
473
+ */
474
+ declare function createDebugEngine(config?: EngineConfig): ChangerawrMarkdown;
475
+ /**
476
+ * Create an engine without built-in extensions (minimal setup)
477
+ */
478
+ declare function createMinimalEngine(config?: EngineConfig): ChangerawrMarkdown;
479
+ /**
480
+ * Create an engine with custom extensions only
481
+ */
482
+ declare function createCustomEngine(extensions: Extension[], config?: Omit<EngineConfig, 'extensions'>): ChangerawrMarkdown;
483
+ /**
484
+ * Quick access object with common functions
485
+ * Useful for destructuring: const { render, parse, toHtml } = markdown;
486
+ */
487
+ declare const markdown: {
488
+ readonly render: typeof renderMarkdown;
489
+ readonly parse: typeof parseMarkdown;
490
+ readonly toHtml: typeof renderToHTML;
491
+ readonly toTailwind: typeof renderToTailwind;
492
+ readonly toJson: typeof renderToJSON;
493
+ readonly toAst: typeof renderToAST;
494
+ readonly createEngine: typeof createEngine;
495
+ readonly createHTMLEngine: typeof createHTMLEngine;
496
+ readonly createTailwindEngine: typeof createTailwindEngine;
497
+ readonly createDebugEngine: typeof createDebugEngine;
498
+ readonly createMinimalEngine: typeof createMinimalEngine;
499
+ readonly createCustomEngine: typeof createCustomEngine;
500
+ readonly renderCum: typeof renderCum;
501
+ readonly parseCum: typeof parseCum;
502
+ readonly ChangerawrMarkdown: typeof ChangerawrMarkdown;
503
+ readonly extensions: {
504
+ readonly Alert: Extension;
505
+ readonly Button: Extension;
506
+ readonly Embed: Extension;
507
+ };
508
+ readonly utils: {
509
+ readonly escapeHtml: typeof escapeHtml;
510
+ readonly generateId: typeof generateId;
511
+ readonly sanitizeHtml: typeof sanitizeHtml;
512
+ readonly extractDomain: typeof extractDomain;
513
+ readonly parseOptions: typeof parseOptions;
514
+ readonly PerformanceTimer: typeof PerformanceTimer;
515
+ readonly Logger: typeof Logger;
516
+ };
517
+ };
518
+
519
+ /**
520
+ * Preset configurations for common use cases
521
+ */
522
+ declare const presets: {
523
+ /**
524
+ * Blog/article preset with prose-friendly styling
525
+ */
526
+ readonly blog: {
527
+ readonly renderer: {
528
+ readonly format: "tailwind";
529
+ readonly customClasses: {
530
+ readonly 'heading-1': "text-4xl font-bold tracking-tight mt-10 mb-6";
531
+ readonly 'heading-2': "text-3xl font-semibold tracking-tight mt-8 mb-4";
532
+ readonly 'heading-3': "text-2xl font-medium tracking-tight mt-6 mb-3";
533
+ readonly paragraph: "text-lg leading-8 mb-6";
534
+ readonly blockquote: "border-l-4 border-gray-300 pl-6 py-2 italic text-gray-700 my-6";
535
+ readonly 'code-inline': "bg-gray-100 text-gray-800 px-2 py-1 rounded text-sm font-mono";
536
+ readonly 'code-block': "bg-gray-900 text-gray-100 p-6 rounded-lg overflow-x-auto my-6 text-sm";
537
+ };
538
+ };
539
+ };
540
+ /**
541
+ * Documentation preset with clean, technical styling
542
+ */
543
+ readonly docs: {
544
+ readonly renderer: {
545
+ readonly format: "tailwind";
546
+ readonly customClasses: {
547
+ readonly 'heading-1': "text-3xl font-bold border-b border-gray-200 pb-2 mb-6";
548
+ readonly 'heading-2': "text-2xl font-semibold mt-8 mb-4";
549
+ readonly 'heading-3': "text-xl font-medium mt-6 mb-3";
550
+ readonly paragraph: "leading-7 mb-4";
551
+ readonly 'code-inline': "bg-blue-50 text-blue-800 px-2 py-1 rounded text-sm font-mono";
552
+ readonly 'code-block': "bg-gray-50 border border-gray-200 p-4 rounded-lg overflow-x-auto my-4 text-sm";
553
+ readonly alert: "border border-blue-200 bg-blue-50 text-blue-800 p-4 rounded-lg mb-4";
554
+ };
555
+ };
556
+ };
557
+ /**
558
+ * Minimal preset with basic styling
559
+ */
560
+ readonly minimal: {
561
+ readonly renderer: {
562
+ readonly format: "html";
563
+ readonly sanitize: true;
564
+ };
565
+ };
566
+ /**
567
+ * Performance preset with minimal processing
568
+ */
569
+ readonly fast: {
570
+ readonly parser: {
571
+ readonly validateMarkdown: false;
572
+ readonly maxIterations: 1000;
573
+ };
574
+ readonly renderer: {
575
+ readonly format: "html";
576
+ readonly sanitize: false;
577
+ };
578
+ };
579
+ };
580
+ /**
581
+ * Create engine with preset configuration
582
+ */
583
+ declare function createEngineWithPreset(presetName: keyof typeof presets, additionalConfig?: EngineConfig): ChangerawrMarkdown;
584
+
585
+ export { type ASTStatistics, AlertExtension, ButtonExtension, ChangerawrMarkdown, type DebugInfo, EmbedExtension, type EngineConfig, type EngineEvents, type Extension, ExtensionError, type Extension as ExtensionInterface, type ExtensionRegistration, type JsonAstNode, Logger, MarkdownParseError, MarkdownParser, MarkdownRenderError, MarkdownRenderer, type MarkdownToken, type OutputFormat, type ParseRule, type ParserConfig, type PerformanceMetrics, PerformanceTimer, type RenderRule, type RendererConfig, type TokenComparison, type TokenDifference, type TokenStatistics, type TokenType, astToJSONString, astToTokens, basicSanitize, compareTokens, createCumEngine, createCustomEngine, createDebugEngine, createEngine, createEngineWithPreset, createHTMLEngine, createMinimalEngine, createTailwindEngine, debounce, deepMerge, markdown as default, defaultTailwindClasses, escapeHtml, extractDomain, generateId, getASTStats, getTokenStats, isBrowser, isNode, isValidUrl, markdown, minimalClasses, parseASTFromJSON, parseCum, parseMarkdown, parseOptions, parseTokensFromJSON, presets, proseClasses, renderCum, renderCumToHtml, renderCumToJson, renderCumToTailwind, renderMarkdown, renderToAST, renderToHTML, renderToHTMLUnsafe, renderToHTMLWithConfig, renderToJSON, renderToTailwind, renderToTailwindWithClasses, renderToTailwindWithConfig, sanitizeHtml, tokensToAST, tokensToJSONString };