{"_id":"@jonahschulte/rtf-toolkit","_rev":"5-0e1db272dffafe3688f51d4fbfa21e04","name":"@jonahschulte/rtf-toolkit","dist-tags":{"latest":"0.5.0"},"versions":{"0.1.0":{"name":"@jonahschulte/rtf-toolkit","version":"0.1.0","keywords":["rtf","rich-text-format","parser","converter","track-changes","html-to-rtf","rtf-to-html","document","wysiwyg","typescript"],"author":{"name":"Jonah Schulte"},"license":"MIT","_id":"@jonahschulte/rtf-toolkit@0.1.0","maintainers":[{"name":"jonahschulte","email":"jonah@jonahschulte.com"}],"homepage":"https://github.com/jonahschulte/rtf-toolkit#readme","bugs":{"url":"https://github.com/jonahschulte/rtf-toolkit/issues"},"dist":{"shasum":"279125d2fad91e7a926813ebc78d48b9ee0117d5","tarball":"https://registry.npmjs.org/@jonahschulte/rtf-toolkit/-/rtf-toolkit-0.1.0.tgz","fileCount":47,"integrity":"sha512-jU86/E1DshNMke7YHGF45RfoEDSV2HHkRFwuzEWoy2SOpZ7ZFVBzVrdWsl/vguCQSC3LUXy0hTzMfyjvYPFY0w==","signatures":[{"sig":"MEUCIQCiLRnFmxa3sXX2OoILId+bSAQKfLgWyPDEDlqaYn+8GQIgSH2hYVY4+2ZYX+tzXUnDNdxcV3NBJ0JY1Oh6fxGa7Wc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120174},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react/index.d.ts","import":"./dist/react/index.js"}},"gitHead":"e6d9bbf63517623f9f2d863679d323e548616a23","scripts":{"dev":"tsc --watch","lint":"eslint src --ext .ts,.tsx","test":"vitest","build":"tsc","format":"prettier --write \"src/**/*.{ts,tsx}\"","lint:fix":"eslint src --ext .ts,.tsx --fix","test:run":"vitest run","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test:run"},"_npmUser":{"name":"jonahschulte","email":"jonah@jonahschulte.com"},"repository":{"url":"git+https://github.com/jonahschulte/rtf-toolkit.git","type":"git"},"_npmVersion":"10.9.4","description":"Modern TypeScript RTF parser with track changes support - Full RTF 1.9.1 spec compliance","directories":{},"_nodeVersion":"22.21.1","_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.57.1","vitest":"^1.6.1","prettier":"^3.7.4","typescript":"^5.9.3","@types/node":"^20.19.27","@types/react":"^18.2.0","@vitest/coverage-v8":"^1.6.1","@typescript-eslint/parser":"^6.21.0","@typescript-eslint/eslint-plugin":"^6.21.0"},"peerDependencies":{"react":"^18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/rtf-toolkit_0.1.0_1767152420968_0.1287890537167209","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@jonahschulte/rtf-toolkit","version":"0.2.0","keywords":["rtf","rich-text-format","parser","converter","track-changes","html-to-rtf","rtf-to-html","document","wysiwyg","typescript"],"author":{"name":"Jonah Schulte"},"license":"MIT","_id":"@jonahschulte/rtf-toolkit@0.2.0","maintainers":[{"name":"jonahschulte","email":"jonah@jonahschulte.com"}],"homepage":"https://github.com/jonahschulte/rtf-toolkit#readme","bugs":{"url":"https://github.com/jonahschulte/rtf-toolkit/issues"},"dist":{"shasum":"bc291776b3adfd7bc9d10c32d160a9a6e8a45bb4","tarball":"https://registry.npmjs.org/@jonahschulte/rtf-toolkit/-/rtf-toolkit-0.2.0.tgz","fileCount":49,"integrity":"sha512-WVw7JVR45lFTI7kbX7WqDN3krMhKY1SELiruCer6y9ZJ2HTn0G3FupSV0JmKK0+CFWXWEegE7vAxiXTH75uVvQ==","signatures":[{"sig":"MEQCIDuYV+S3p9MW3Q2jNMmWNJ/82i+hMQQU2bm7ZSUW5L5qAiA+Jum4fCI0AxdspdQGXVdnKqZwUHO9LrpDzvB8dzqhBw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":129730},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react/index.d.ts","import":"./dist/react/index.js"}},"gitHead":"8212a5596682f8389fd01b3c013e289e7ee920b9","scripts":{"dev":"tsc --watch","lint":"eslint src --ext .ts,.tsx","test":"vitest","build":"tsc","format":"prettier --write \"src/**/*.{ts,tsx}\"","lint:fix":"eslint src --ext .ts,.tsx --fix","test:run":"vitest run","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test:run"},"_npmUser":{"name":"jonahschulte","email":"jonah@jonahschulte.com"},"repository":{"url":"git+https://github.com/jonahschulte/rtf-toolkit.git","type":"git"},"_npmVersion":"10.9.4","description":"Modern TypeScript RTF parser with track changes support - Full RTF 1.9.1 spec compliance","directories":{},"_nodeVersion":"22.21.1","_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.57.1","vitest":"^1.6.1","prettier":"^3.7.4","typescript":"^5.9.3","@types/node":"^20.19.27","@types/react":"^18.2.0","@vitest/coverage-v8":"^1.6.1","@typescript-eslint/parser":"^6.21.0","@typescript-eslint/eslint-plugin":"^6.21.0"},"peerDependencies":{"react":"^18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/rtf-toolkit_0.2.0_1767156500201_0.009225545806506696","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@jonahschulte/rtf-toolkit","version":"0.3.0","keywords":["rtf","rich-text-format","parser","converter","track-changes","html-to-rtf","rtf-to-html","document","wysiwyg","typescript"],"author":{"name":"Jonah Schulte"},"license":"MIT","_id":"@jonahschulte/rtf-toolkit@0.3.0","maintainers":[{"name":"jonahschulte","email":"jonah@jonahschulte.com"}],"homepage":"https://github.com/jonahschulte/rtf-toolkit#readme","bugs":{"url":"https://github.com/jonahschulte/rtf-toolkit/issues"},"dist":{"shasum":"d19fe7540b60f0320e19e71f0e10c24ae5cdb8d2","tarball":"https://registry.npmjs.org/@jonahschulte/rtf-toolkit/-/rtf-toolkit-0.3.0.tgz","fileCount":49,"integrity":"sha512-KtiCVR3DFIpQBAr1x6u03T4ve99fc+pXFMoZ9xK5GTiT4CKYAWfE1yZJpYkjc7OhKqClnwGz5O/afwDnNRKRpg==","signatures":[{"sig":"MEQCIEsmFxywa+5dAJGAkYmuJGRD+MGAKCs7MApxA3KsTJXgAiAZpCwS0muhkFaRcryku+HWNm5O3bHRzU0iPErylfjy3w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":137938},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react/index.d.ts","import":"./dist/react/index.js"}},"gitHead":"1725a1d382ac0742a283ef6fc42458cce7317937","scripts":{"dev":"tsc --watch","lint":"eslint src --ext .ts,.tsx","test":"vitest","build":"tsc","format":"prettier --write \"src/**/*.{ts,tsx}\"","lint:fix":"eslint src --ext .ts,.tsx --fix","test:run":"vitest run","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test:run"},"_npmUser":{"name":"jonahschulte","email":"jonah@jonahschulte.com"},"repository":{"url":"git+https://github.com/jonahschulte/rtf-toolkit.git","type":"git"},"_npmVersion":"10.9.4","description":"Modern TypeScript RTF parser with track changes support - Full RTF 1.9.1 spec compliance","directories":{},"_nodeVersion":"22.21.1","_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.57.1","vitest":"^1.6.1","prettier":"^3.7.4","typescript":"^5.9.3","@types/node":"^20.19.27","@types/react":"^18.2.0","@vitest/coverage-v8":"^1.6.1","@typescript-eslint/parser":"^6.21.0","@typescript-eslint/eslint-plugin":"^6.21.0"},"peerDependencies":{"react":"^18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/rtf-toolkit_0.3.0_1767161454224_0.2859048781052629","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@jonahschulte/rtf-toolkit","version":"0.4.0","keywords":["rtf","rich-text-format","parser","converter","track-changes","html-to-rtf","rtf-to-html","document","wysiwyg","typescript"],"author":{"name":"Jonah Schulte"},"license":"MIT","_id":"@jonahschulte/rtf-toolkit@0.4.0","maintainers":[{"name":"jonahschulte","email":"jonah@jonahschulte.com"}],"homepage":"https://github.com/jonahschulte/rtf-toolkit#readme","bugs":{"url":"https://github.com/jonahschulte/rtf-toolkit/issues"},"dist":{"shasum":"62fb947c03130e34193246e454f0f4ea285fd30b","tarball":"https://registry.npmjs.org/@jonahschulte/rtf-toolkit/-/rtf-toolkit-0.4.0.tgz","fileCount":49,"integrity":"sha512-+Rm3rjdVi9FvSK0RJp8tzaEo6BF8I8PnsI2WNAtH5FvZvRQLvJ8UALFKN97B6hXH69s7BOOIECO9GZqhWWoA4w==","signatures":[{"sig":"MEUCIH6q3aV+vaG9cbsZRba88i/hZHA3loPWeQOt1DX/JWatAiEA2ZTofOXDR6keXR3F7+onAnrs1QkyQM96lrLq6a3yDTs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":166767},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react/index.d.ts","import":"./dist/react/index.js"}},"gitHead":"032c0be5a807e573ca04272adcec059e55f570ab","scripts":{"dev":"tsc --watch","lint":"eslint src --ext .ts,.tsx","test":"vitest","build":"tsc","format":"prettier --write \"src/**/*.{ts,tsx}\"","lint:fix":"eslint src --ext .ts,.tsx --fix","test:run":"vitest run","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test:run"},"_npmUser":{"name":"jonahschulte","email":"jonah@jonahschulte.com"},"repository":{"url":"git+https://github.com/jonahschulte/rtf-toolkit.git","type":"git"},"_npmVersion":"10.9.4","description":"Modern TypeScript RTF parser with track changes support - Full RTF 1.9.1 spec compliance","directories":{},"_nodeVersion":"22.21.1","_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.57.1","vitest":"^1.6.1","prettier":"^3.7.4","typescript":"^5.9.3","@types/node":"^20.19.27","@types/react":"^18.2.0","@vitest/coverage-v8":"^1.6.1","@typescript-eslint/parser":"^6.21.0","@typescript-eslint/eslint-plugin":"^6.21.0"},"peerDependencies":{"react":"^18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/rtf-toolkit_0.4.0_1767317646690_0.0031330351514309296","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@jonahschulte/rtf-toolkit","version":"0.5.0","description":"Modern TypeScript RTF parser with track changes support - Full RTF 1.9.1 spec compliance","keywords":["rtf","rich-text-format","parser","converter","track-changes","html-to-rtf","rtf-to-html","document","wysiwyg","typescript"],"author":{"name":"Jonah Schulte"},"license":"MIT","type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react/index.d.ts","import":"./dist/react/index.js"}},"scripts":{"build":"tsc","dev":"tsc --watch","test":"vitest","test:run":"vitest run","test:coverage":"vitest run --coverage","lint":"eslint src --ext .ts,.tsx","lint:fix":"eslint src --ext .ts,.tsx --fix","format":"prettier --write \"src/**/*.{ts,tsx}\"","prepublishOnly":"npm run build && npm run test:run"},"devDependencies":{"@types/node":"^20.19.27","@types/react":"^18.2.0","@typescript-eslint/eslint-plugin":"^6.21.0","@typescript-eslint/parser":"^6.21.0","@vitest/coverage-v8":"^1.6.1","eslint":"^8.57.1","prettier":"^3.7.4","typescript":"^5.9.3","vitest":"^1.6.1"},"peerDependencies":{"react":"^18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"repository":{"type":"git","url":"git+https://github.com/jonahschulte/rtf-toolkit.git"},"bugs":{"url":"https://github.com/jonahschulte/rtf-toolkit/issues"},"homepage":"https://github.com/jonahschulte/rtf-toolkit#readme","_id":"@jonahschulte/rtf-toolkit@0.5.0","gitHead":"6af77a69179e6408d0590cb56f3882a4a397d8cb","_nodeVersion":"22.21.1","_npmVersion":"10.9.4","dist":{"integrity":"sha512-yVVih2sC3OzkEEcTK1K/jqJll7Il0EP3hx0fDWHX2Kd5ceHenljYiHLxls1npquHnYQ9DthitBCGZ3GoHfYg7Q==","shasum":"0fe0e3861d4334e8e6427d9882f3c0ea308acec1","tarball":"https://registry.npmjs.org/@jonahschulte/rtf-toolkit/-/rtf-toolkit-0.5.0.tgz","fileCount":49,"unpackedSize":171598,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEudCmMgGWvqnuzMiV/btbJH2MLlsX1hm96Sro3FZv9vAiAj00+ShFaYxpvoLWR1+9YvggY38kqhE7ADsNxUv3dbrA=="}]},"_npmUser":{"name":"jonahschulte","email":"jonah@jonahschulte.com"},"directories":{},"maintainers":[{"name":"jonahschulte","email":"jonah@jonahschulte.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/rtf-toolkit_0.5.0_1767333911973_0.782520215768989"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-31T03:40:20.857Z","modified":"2026-01-02T06:05:12.337Z","0.1.0":"2025-12-31T03:40:21.108Z","0.2.0":"2025-12-31T04:48:20.357Z","0.3.0":"2025-12-31T06:10:54.370Z","0.4.0":"2026-01-02T01:34:06.837Z","0.5.0":"2026-01-02T06:05:12.129Z"},"bugs":{"url":"https://github.com/jonahschulte/rtf-toolkit/issues"},"author":{"name":"Jonah Schulte"},"license":"MIT","homepage":"https://github.com/jonahschulte/rtf-toolkit#readme","keywords":["rtf","rich-text-format","parser","converter","track-changes","html-to-rtf","rtf-to-html","document","wysiwyg","typescript"],"repository":{"type":"git","url":"git+https://github.com/jonahschulte/rtf-toolkit.git"},"description":"Modern TypeScript RTF parser with track changes support - Full RTF 1.9.1 spec compliance","maintainers":[{"name":"jonahschulte","email":"jonah@jonahschulte.com"}],"readme":"# @jonahschulte/rtf-toolkit\n\n> Modern TypeScript RTF parser with track changes support\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue.svg)](https://www.typescriptlang.org/)\n[![Tests](https://img.shields.io/badge/tests-119%20passing-brightgreen.svg)]()\n\nA production-grade RTF parsing library for JavaScript/TypeScript with comprehensive track changes support. Perfect for government contracts, legal documents, and any application requiring RTF document analysis.\n\n## ✨ Features\n\n- ✅ **Full RTF Parsing** - Handles RTF 1.9.1 specification\n- ✅ **Track Changes Support** - Parse insertions, deletions, and author metadata\n- ✅ **HTML Conversion** - Clean, semantic HTML output\n- ✅ **TypeScript First** - Full type safety and IntelliSense\n- ✅ **Zero Dependencies** - Lightweight core library\n- ✅ **100% Tested** - 94 comprehensive unit tests\n- ✅ **Visual Track Changes** - HTML rendering with color-coded changes\n\n## Installation\n\n```bash\nnpm install @jonahschulte/rtf-toolkit\n```\n\n## Quick Start\n\n### Basic RTF to HTML Conversion\n\n```typescript\nimport { parseRTF, toHTML } from '@jonahschulte/rtf-toolkit';\n\n// Parse RTF\nconst rtf = '{\\\\rtf1\\\\b Bold\\\\b0 and \\\\i italic\\\\i0 text}';\nconst doc = parseRTF(rtf);\n\n// Convert to HTML\nconst html = toHTML(doc);\nconsole.log(html);\n// Output: <div class=\"rtf-content\">\n//           <p><strong>Bold</strong> and <em>italic</em> text</p>\n//         </div>\n```\n\n### Track Changes (Revisions)\n\n```typescript\nimport { parseRTF, getTrackChanges, getTrackChangeMetadata } from '@jonahschulte/rtf-toolkit';\n\n// Parse RTF with track changes\nconst rtf = `{\\\\rtf1\n{\\\\*\\\\revtbl{Unknown;}{John Doe;}{Jane Smith;}}\nOriginal text {\\\\revised\\\\revauth1 inserted by John} more text.\n{\\\\deleted\\\\revauth2 removed by Jane} final text.}`;\n\nconst doc = parseRTF(rtf);\n\n// Get all track changes\nconst changes = getTrackChanges(doc);\nchanges.forEach((change) => {\n  console.log(`${change.type}: \"${change.text}\" by ${change.author}`);\n});\n// Output:\n// insertion: \"inserted by John\" by John Doe\n// deletion: \"removed by Jane\" by Jane Smith\n\n// Get summary metadata\nconst metadata = getTrackChangeMetadata(doc);\nconsole.log(`${metadata.totalChanges} changes by ${metadata.authors.length} authors`);\n// Output: 2 changes by 2 authors\n```\n\n### HTML with Track Changes Visualization\n\n```typescript\nimport { parseRTF, toHTML } from '@jonahschulte/rtf-toolkit';\n\nconst rtfWithChanges = `{\\\\rtf1\n{\\\\*\\\\revtbl{Unknown;}{Editor;}}\nText with {\\\\revised\\\\revauth1 new content} here.}`;\n\nconst doc = parseRTF(rtfWithChanges);\nconst html = toHTML(doc);\n\nconsole.log(html);\n// Output includes:\n// <span class=\"rtf-revision-inserted\"\n//       style=\"background-color: #d4edda; border-bottom: 2px solid #28a745;\"\n//       data-revision-type=\"insertion\"\n//       data-author=\"Editor\">new content</span>\n```\n\n## API Reference\n\n### Parsing\n\n#### `parseRTF(rtf: string): RTFDocument`\n\nParse an RTF string into an Abstract Syntax Tree (AST).\n\n```typescript\nconst doc = parseRTF(rtfString);\nconsole.log(doc.rtfVersion); // 1\nconsole.log(doc.charset); // 'ansi'\nconsole.log(doc.fontTable); // Array of fonts\nconsole.log(doc.colorTable); // Array of colors\nconsole.log(doc.content); // Array of paragraphs\n```\n\n### Rendering\n\n#### `toHTML(doc: RTFDocument, options?: HTMLOptions): string`\n\nConvert RTF document AST to HTML.\n\n```typescript\nconst html = toHTML(doc, {\n  includeWrapper: true, // Wrap in <div class=\"rtf-content\">\n});\n```\n\n**HTMLOptions:**\n- `includeWrapper?: boolean` - Wrap output in container div (default: true)\n- `useClasses?: boolean` - Use CSS classes instead of inline styles\n- `classPrefix?: string` - Custom CSS class prefix\n\n### Track Changes\n\n#### `getTrackChanges(doc: RTFDocument): TrackChange[]`\n\nExtract all track changes from the document.\n\n```typescript\nconst changes = getTrackChanges(doc);\n\nchanges.forEach((change) => {\n  console.log(change.id); // Unique identifier\n  console.log(change.type); // 'insertion' | 'deletion' | 'formatting'\n  console.log(change.author); // Author name\n  console.log(change.authorIndex); // Author index in revision table\n  console.log(change.text); // Change content\n  console.log(change.timestamp); // Date object\n  console.log(change.position); // { paragraphIndex, characterOffset }\n});\n```\n\n#### `getTrackChangeMetadata(doc: RTFDocument): TrackChangeMetadata`\n\nGet summary statistics about track changes.\n\n```typescript\nconst metadata = getTrackChangeMetadata(doc);\n\nconsole.log(metadata.totalChanges); // Total number of changes\nconsole.log(metadata.insertions); // Number of insertions\nconsole.log(metadata.deletions); // Number of deletions\nconsole.log(metadata.authors); // Array of unique author names\nconsole.log(metadata.hasRevisions); // Boolean flag\n```\n\n## RTF Features Supported\n\n### Document Structure\n- ✅ RTF header (`\\rtf1`, `\\ansi`, `\\deff`)\n- ✅ Font table (`\\fonttbl`) with font families\n- ✅ Color table (`\\colortbl`) with RGB values\n- ✅ Revision table (`\\revtbl`) with author names\n\n### Character Formatting\n- ✅ Bold (`\\b`)\n- ✅ Italic (`\\i`)\n- ✅ Underline (`\\ul`)\n- ✅ Font size (`\\fs`)\n- ✅ Font family (`\\f`)\n- ✅ Text color (`\\cf`)\n- ✅ Background color (`\\cb`)\n\n### Paragraph Formatting\n- ✅ Alignment (`\\qc`, `\\qr`, `\\ql`, `\\qj`)\n- ✅ Spacing before/after (`\\sb`, `\\sa`)\n- ✅ Indentation (`\\li`, `\\ri`, `\\fi`)\n- ✅ Paragraph breaks (`\\par`)\n\n### Track Changes\n- ✅ Revision table parsing\n- ✅ Insertions (`\\revised`)\n- ✅ Deletions (`\\deleted`)\n- ✅ Author tracking (`\\revauth`)\n- ✅ Timestamps (`\\revdttm`)\n- ✅ Visual HTML rendering\n\n### Special Characters\n- ✅ Hex escapes (`\\'XX`)\n- ✅ Unicode characters (`\\u`)\n- ✅ Control symbols (`\\~`, `\\-`, `\\_`)\n- ✅ Literal escapes (`\\\\`, `\\{`, `\\}`)\n\n## Use Cases\n\n### Government Contracts & Legal Documents\n```typescript\n// Parse contract with redlines\nconst contract = parseRTF(governmentContractRTF);\nconst changes = getTrackChanges(contract);\n\n// Review all changes\nchanges.forEach((change) => {\n  console.log(`${change.author} ${change.type}d: \"${change.text}\"`);\n});\n\n// Generate HTML for review\nconst html = toHTML(contract);\n// Insertions shown in green, deletions in red with strikethrough\n```\n\n### Document Review Workflows\n```typescript\n// Get summary for review dashboard\nconst metadata = getTrackChangeMetadata(doc);\n\nconsole.log(`Pending Review: ${metadata.totalChanges} changes`);\nconsole.log(`Contributors: ${metadata.authors.join(', ')}`);\n```\n\n### Content Migration\n```typescript\n// Extract clean text without markup\nconst doc = parseRTF(rtfString);\nconst html = toHTML(doc);\n\n// Use in modern CMS or web application\n```\n\n## Examples\n\nSee the `examples/` directory for complete demonstrations:\n- `basic-usage.ts` - Basic parsing and HTML conversion\n- `track-changes-demo.ts` - Track changes extraction and visualization\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Run tests\nnpm test\n\n# Build\nnpm run build\n\n# Run examples\nnpm run build && node examples/track-changes-demo.js\n```\n\n## TypeScript Support\n\nFull TypeScript definitions included:\n\n```typescript\nimport type {\n  RTFDocument,\n  ParagraphNode,\n  TextNode,\n  RevisionNode,\n  TrackChange,\n  TrackChangeMetadata,\n} from '@jonahschulte/rtf-toolkit';\n\n// Fully typed API with IntelliSense support\n```\n\n## Browser Support\n\nWorks in all modern browsers and Node.js:\n- ✅ Chrome/Edge (latest)\n- ✅ Firefox (latest)\n- ✅ Safari (latest)\n- ✅ Node.js 18+\n\n## Performance\n\nOptimized for real-world documents:\n- Typical documents (<100KB): <100ms parsing\n- Large documents (1MB+): <1s parsing\n- Efficient memory usage\n- Streaming capable (future)\n\n## License\n\nMIT © 2025 Jonah Schulte\n\n## Credits\n\nBuilt to solve real-world government contract NDA management needs.\n\nOpen-sourced to help the community deal with legacy RTF systems.\n\n## Acknowledgments\n\n- RTF 1.9.1 Specification by Microsoft\n- Inspired by the limitations of existing RTF libraries\n\n## Contributing\n\nIssues and PRs welcome! See [GitHub Issues](https://github.com/jonahschulte/rtf-toolkit/issues).\n\n**Star this repo** if you find it useful! ⭐\n","readmeFilename":"README.md"}