Converts Markdown source to plain text with two output modes: structured article text (preserving paragraph breaks) and collapsed single-line preview text. ## Key Components ### `MarkdownToPlainOptions` Configuration interface with two optional properties: - `mode`: `'article'` (default) preserves `\n\n` paragraph structure; `'preview'` collapses all whitespace to a single line - `maxChars`: Optional character cap — truncates without ellipsis (caller decides truncation presentation) ### `stripInlineMarkdown(s: string): string` Shared utility that strips inline Markdown markers from a string: - `[text](url)` → `text` - `**bold**` → `bold` - `*italic*` → `italic` - `` `inline code` `` → `inline code` All patterns use negated character classes to avoid catastrophic backtracking. ### `markdownToPlainText(markdown, options): string` Main conversion function. Processing order matters — fenced code blocks and images are stripped first (before inline backtick stripping could interfere), then `stripInlineMarkdown` runs, followed by heading markers and list bullets. Final pass applies mode-specific whitespace normalization and optional character truncation. ## Usage Example ```typescript import { markdownToPlainText, stripInlineMarkdown } from './markdown-to-plain' // Article mode — preserves paragraph breaks (e.g. JSON-LD body echo) const articleText = markdownToPlainText(` # Getting Started Install with **npm** or \`yarn\`. - Clone the repo - Run \`npm install\` `) // → "Getting Started\nInstall with npm or yarn.\n\nClone the repo\nRun npm install" // Preview mode — single line for chat cards / OG snippets const preview = markdownToPlainText(markdownSource, { mode: 'preview', maxChars: 160, }) // Standalone inline strip (e.g. inside extractSections) const clean = stripInlineMarkdown('**Bold** and [a link](https://example.com)') // → "Bold and a link" ``` ## Source [`markdown-to-plain.ts`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/markdown-to-plain.ts)