# MarkdownViewerComponent Selector: `app-markdown-viewer` Module: `AppSharedModule` (already exported — no extra import needed) A generic, self-contained markdown renderer. Handles parsing, heading-based section splitting, Mermaid diagrams, inline video embeds, syntax-highlighted find-in-page, and emits a table-of-contents item list for the host to render wherever it likes. --- ## Inputs | Input | Type | Default | Description | |---|---|---|---| | `src` | `string` | `undefined` | URL of a remote `.md` file to fetch and render. Mutually exclusive with `markdown`. | | `markdown` | `string` | `undefined` | Raw markdown string to render inline. Takes precedence over `src` if both are set. | | `showFindBar` | `boolean` | `false` | Show the find-in-page bar above the content. | --- ## Outputs | Output | Payload | Description | |---|---|---| | `tocItemsChange` | `{ label: string; anchorId: string }[]` | Emitted after content loads. Each item corresponds to a top-level heading in the document. Use this to render a Table of Contents outside the component. | --- ## Public Methods | Method | Signature | Description | |---|---|---| | `scrollToId` | `(anchorId: string) => void` | Scrolls the content area to the element with the given id. Use in conjunction with `tocItemsChange` to implement external TOC navigation. | --- ## Usage Examples ### Render a remote file ```html ``` ### Render an inline string ```html ``` ### With find-in-page bar ```html ``` ### With an external Table of Contents The component emits TOC items but does **not** render a TOC sidebar itself. The host component is responsible for displaying the list and wiring up scroll navigation. **Template:** ```html ``` **Component:** ```typescript import { ViewChild } from '@angular/core'; import { MarkdownViewerComponent } from '../shared/markdown-viewer/markdown-viewer.component'; export class MyComponent { @ViewChild(MarkdownViewerComponent) viewer?: MarkdownViewerComponent; tocItems: { label: string; anchorId: string }[] = []; content = '# Hello\n\nSome text.\n\n## Section Two\n\nMore text.'; scrollToHeading(event: MouseEvent, anchorId: string): void { event.preventDefault(); this.viewer?.scrollToId(anchorId); } } ``` --- ## Content Features ### Mermaid diagrams Fenced code blocks with language `mermaid` are automatically rendered as SVG diagrams: ````markdown ```mermaid graph TD A --> B ``` ```` ### Inline video embeds Use the custom `!video[title](url)` syntax to embed video files (`.mp4`, `.webm`, `.ogg`) or iframes (YouTube, Vimeo, etc.): ```markdown !video[Demo walkthrough](https://example.com/demo.mp4) !video[YouTube video](https://www.youtube.com/embed/abc123) ``` ### Tables Standard markdown tables are styled with borders and alternating row colours automatically. --- ## Notes - Content is split into sections at every heading. The text before the first heading becomes an "intro" block. - `src` and `markdown` are mutually exclusive. If both are provided, `markdown` wins. - `scrollToId` is a no-op if the component has not yet rendered or the anchor does not exist in the current content. - The component is part of `AppSharedModule` and does not need to be imported separately in feature modules that already import `AppSharedModule`.