@memberjunction/ng-markdown
A feature-rich Angular component for rendering Markdown content with syntax highlighting, Mermaid diagrams, collapsible sections, GitHub-style alerts, and SVG rendering.
Installation
Section titled “Installation”npm install @memberjunction/ng-markdownOverview
Section titled “Overview”The Markdown component replaces ngx-markdown with a MemberJunction-native implementation. It uses marked for parsing, Prism.js for syntax highlighting, and Mermaid for diagram rendering. The module does not use forRoot() — simply import MarkdownModule wherever needed.
flowchart LR
subgraph Input["Markdown Source"]
A["Raw Markdown String"]
end
subgraph Parser["Parsing Pipeline"]
B["marked parser"]
B --> C["marked-highlight (Prism.js)"]
B --> D["marked-alert (GitHub alerts)"]
B --> E["marked-smartypants (typography)"]
end
subgraph Render["Rendering"]
C --> F["Syntax-highlighted code blocks"]
D --> G["Alert blockquotes"]
B --> H["Mermaid diagrams"]
B --> I["SVG code blocks"]
end
A --> B
style Input fill:#2d6a9f,stroke:#1a4971,color:#fff
style Parser fill:#7c5295,stroke:#563a6b,color:#fff
style Render fill:#2d8659,stroke:#1a5c3a,color:#fff
Module Import
Section titled “Module Import”import { MarkdownModule } from '@memberjunction/ng-markdown';
@NgModule({ imports: [MarkdownModule] // No forRoot() needed})export class YourModule {}Basic Usage
Section titled “Basic Usage”<mj-markdown [data]="markdownContent"></mj-markdown>Full Configuration
Section titled “Full Configuration”<mj-markdown [data]="content" [enableMermaid]="true" [enableCollapsibleHeadings]="true" [collapsibleHeadingLevel]="2" [autoExpandLevels]="[2]" [enableCodeCopy]="true" [enableAlerts]="true" [enableSmartypants]="true" [enableSvgRenderer]="true" [enableHtml]="false" [mermaidTheme]="'default'" (rendered)="onRendered($event)" (headingClick)="onHeadingClick($event)" (codeCopied)="onCodeCopied($event)"></mj-markdown>Key Features
Section titled “Key Features”| Feature | Default | Description |
|---|---|---|
| Syntax highlighting | Enabled | Prism.js with Okaidia theme |
| Mermaid diagrams | Enabled | Render mermaid code blocks as diagrams |
| Math | Enabled | TeX ($…$ / \(…\) inline, $$…$$ / \[…\] display), typeset as MathML by KaTeX (loaded on first use), and MathML markup, including JATS-style <mml:math> |
| Code copy button | Enabled | Copy-to-clipboard on hover |
| GitHub-style alerts | Enabled | [!NOTE], [!TIP], [!WARNING] blockquotes |
| Smartypants typography | Enabled | Curly quotes, em/en dashes, ellipsis |
| SVG rendering | Enabled | Render SVG code blocks as images |
| Collapsible headings | Disabled | Expand/collapse heading sections |
| HTML passthrough | Disabled | Raw HTML rendering (security-sensitive) |
| JavaScript | Disabled | Allow JS in HTML (use only for trusted content) |
Configuration Inputs
Section titled “Configuration Inputs”| Input | Type | Default | Description |
|---|---|---|---|
data | string | '' | Markdown content to render |
enableHighlight | boolean | true | Prism.js syntax highlighting |
enableMermaid | boolean | true | Mermaid diagram rendering |
EnableMath | boolean | true | TeX math, and keeping markdown out of MathML markup (<mml:math> needs it; unprefixed <math> renders either way, since the sanitizer allows MathML). Single dollars follow Pandoc’s rule, so $5 and $10 stays text; \$ is a literal dollar. PascalCase only: unlike the older inputs above, it has no lowercase alias |
enableCodeCopy | boolean | true | Copy button on code blocks |
enableCollapsibleHeadings | boolean | false | Collapsible heading sections |
collapsibleHeadingLevel | 1-6 | 2 | Heading level to start collapsing |
collapsibleDefaultExpanded | boolean | true | Default expansion state |
autoExpandLevels | number[] | undefined | Specific levels to auto-expand |
enableAlerts | boolean | true | GitHub-style alerts |
enableSmartypants | boolean | true | Typography improvements |
enableSvgRenderer | boolean | true | SVG code block rendering |
enableHtml | boolean | false | Raw HTML passthrough |
enableJavaScript | boolean | false | Allow JS in HTML |
enableHeadingIds | boolean | true | Generate heading IDs for anchors |
headingIdPrefix | string | '' | Prefix for heading IDs |
enableLineNumbers | boolean | false | Show line numbers in code blocks |
containerClass | string | '' | Custom CSS class for container |
mermaidTheme | string | 'default' | Mermaid theme (default/dark/forest/neutral/base) |
sanitize | boolean | true | Sanitize HTML output |
OpenLinksInNewTab | boolean | false | Open rendered HTML links (external and relative/same-origin URLs, whether bare https://... autolinks or [text](url) links) in a new browser tab (target="_blank" with rel="noopener noreferrer"). In-page fragment links (#heading), mailto: / tel: / sms: links, and raw HTML links with an explicit target keep their behaviour. PascalCase only |
Outputs
Section titled “Outputs”| Event | Type | Description |
|---|---|---|
rendered | MarkdownRenderEvent | Emitted when rendering completes |
headingClick | HeadingInfo | Emitted when a heading is clicked |
codeCopied | string | Emitted when code is copied to clipboard |
ImageClicked | ImageClickedEventArgs | Emitted when a rendered image (not one inside a link) is clicked or activated by keyboard; images react only while this is bound |
Tall images can be capped by the host with the --mj-markdown-image-max-height CSS custom property (unset: no cap), for example --mj-markdown-image-max-height: 360px on a chat column.
Migration from ngx-markdown
Section titled “Migration from ngx-markdown”- Replace imports:
'ngx-markdown'to'@memberjunction/ng-markdown' - Remove
forRoot()from module imports - Update selectors:
<markdown>to<mj-markdown> - The
elementproperty is preserved for backward compatibility
Dependencies
Section titled “Dependencies”marked— Markdown parsermarked-alert— GitHub-style alertsmarked-highlight— Syntax highlighting integrationmarked-smartypants— Typography improvementsprismjs— Syntax highlightingmermaid— Diagram renderingkatex— TeX math typesetting (MathML output, so no KaTeX stylesheet or fonts are needed)