ngx-markdown-pages 0.0.1

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.
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # ngx-markdown-pages
2
+
3
+ An Angular library for rendering markdown files as routable pages. Built on top of [ngx-markdown](https://github.com/jfcere/ngx-markdown).
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install ngx-markdown-pages ngx-markdown marked
9
+ ```
10
+
11
+ ## Setup
12
+
13
+ Call `provideMarkdownPages()` in your application providers:
14
+
15
+ ```typescript
16
+ import { provideMarkdownPages } from 'ngx-markdown-pages';
17
+
18
+ bootstrapApplication(AppComponent, {
19
+ providers: [
20
+ provideMarkdownPages(),
21
+ ],
22
+ });
23
+ ```
24
+
25
+ To enable the clipboard copy button on code blocks:
26
+
27
+ ```typescript
28
+ provideMarkdownPages({ clipboard: true })
29
+ ```
30
+
31
+ ## Routing
32
+
33
+ Define your markdown pages with `markdownPageRoutes()`:
34
+
35
+ ```typescript
36
+ import { markdownPageRoutes } from 'ngx-markdown-pages';
37
+
38
+ const routes: Routes = [
39
+ ...markdownPageRoutes([
40
+ { path: 'getting-started', markdownFile: 'assets/docs/getting-started.md' },
41
+ { path: 'api-reference', markdownFile: 'assets/docs/api-reference.md' },
42
+ ]),
43
+ ];
44
+ ```
45
+
46
+ Each route renders a `MarkdownPageComponent` that loads and displays the specified markdown file. Heading anchor links with smooth scrolling are handled automatically.
@@ -0,0 +1,81 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, inject, ElementRef, Component } from '@angular/core';
3
+ import { provideMarkdown, MARKED_OPTIONS, MarkdownComponent } from 'ngx-markdown';
4
+ import { Renderer } from 'marked';
5
+ import { ActivatedRoute, Router } from '@angular/router';
6
+ import { toSignal } from '@angular/core/rxjs-interop';
7
+ import { map } from 'rxjs';
8
+
9
+ const MARKDOWN_PAGES_OPTIONS = new InjectionToken('MARKDOWN_PAGES_OPTIONS', { factory: () => ({}) });
10
+ function provideMarkdownPages(options) {
11
+ return [
12
+ { provide: MARKDOWN_PAGES_OPTIONS, useValue: options ?? {} },
13
+ ...provideMarkdown({
14
+ markedOptions: {
15
+ provide: MARKED_OPTIONS,
16
+ useFactory: () => {
17
+ const renderer = new Renderer();
18
+ renderer.heading = ({ text, depth }) => {
19
+ const slug = text
20
+ .toLowerCase()
21
+ .replace(/<[^>]*>/g, '')
22
+ .replace(/[^\w\s-]/g, '')
23
+ .replace(/\s+/g, '-');
24
+ return `<h${depth} id="${slug}">${text}</h${depth}>`;
25
+ };
26
+ return { renderer };
27
+ },
28
+ },
29
+ }),
30
+ ];
31
+ }
32
+
33
+ class MarkdownPageComponent {
34
+ route = inject(ActivatedRoute);
35
+ router = inject(Router);
36
+ el = inject((ElementRef));
37
+ options = inject(MARKDOWN_PAGES_OPTIONS);
38
+ markdownSrc = toSignal(this.route.data.pipe(map((data) => data['markdownFile'])), { initialValue: '' });
39
+ onClick(event) {
40
+ const anchor = event.target.closest('a');
41
+ const href = anchor?.getAttribute('href');
42
+ if (!href?.startsWith('#'))
43
+ return;
44
+ event.preventDefault();
45
+ const fragment = href.substring(1);
46
+ this.router.navigate([], { relativeTo: this.route, fragment }).then(() => {
47
+ document.getElementById(fragment)?.scrollIntoView({ behavior: 'smooth' });
48
+ });
49
+ }
50
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: MarkdownPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
51
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.19", type: MarkdownPageComponent, isStandalone: true, selector: "mdp-markdown-page", host: { listeners: { "click": "onClick($event)" } }, ngImport: i0, template: `<markdown [src]="markdownSrc()" [disableSanitizer]="true" [clipboard]="options.clipboard ?? false" />`, isInline: true, dependencies: [{ kind: "component", type: MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "disableSanitizer", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }] });
52
+ }
53
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.19", ngImport: i0, type: MarkdownPageComponent, decorators: [{
54
+ type: Component,
55
+ args: [{
56
+ selector: 'mdp-markdown-page',
57
+ standalone: true,
58
+ imports: [MarkdownComponent],
59
+ template: `<markdown [src]="markdownSrc()" [disableSanitizer]="true" [clipboard]="options.clipboard ?? false" />`,
60
+ host: { '(click)': 'onClick($event)' },
61
+ }]
62
+ }] });
63
+
64
+ function markdownPageRoutes(config) {
65
+ return config.map(({ path, markdownFile }) => ({
66
+ path,
67
+ component: MarkdownPageComponent,
68
+ data: { markdownFile },
69
+ }));
70
+ }
71
+
72
+ /*
73
+ * Public API Surface of ngx-markdown-pages
74
+ */
75
+
76
+ /**
77
+ * Generated bundle index. Do not edit.
78
+ */
79
+
80
+ export { MarkdownPageComponent, markdownPageRoutes, provideMarkdownPages };
81
+ //# sourceMappingURL=ngx-markdown-pages.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngx-markdown-pages.mjs","sources":["../../src/lib/markdown-pages.config.ts","../../src/lib/markdown-page.component.ts","../../src/lib/markdown-pages.routes.ts","../../src/public-api.ts","../../src/ngx-markdown-pages.ts"],"sourcesContent":["import { InjectionToken, Provider } from '@angular/core';\nimport { provideMarkdown, MARKED_OPTIONS } from 'ngx-markdown';\nimport { Renderer } from 'marked';\n\nexport interface MarkdownPageConfig {\n path: string;\n markdownFile: string;\n}\n\nexport interface MarkdownPagesOptions {\n clipboard?: boolean;\n}\n\nexport const MARKDOWN_PAGES_OPTIONS = new InjectionToken<MarkdownPagesOptions>(\n 'MARKDOWN_PAGES_OPTIONS',\n { factory: () => ({}) }\n);\n\nexport function provideMarkdownPages(options?: MarkdownPagesOptions): Provider[] {\n return [\n { provide: MARKDOWN_PAGES_OPTIONS, useValue: options ?? {} },\n ...provideMarkdown({\n markedOptions: {\n provide: MARKED_OPTIONS,\n useFactory: () => {\n const renderer = new Renderer();\n renderer.heading = ({ text, depth }) => {\n const slug = text\n .toLowerCase()\n .replace(/<[^>]*>/g, '')\n .replace(/[^\\w\\s-]/g, '')\n .replace(/\\s+/g, '-');\n return `<h${depth} id=\"${slug}\">${text}</h${depth}>`;\n };\n return { renderer };\n },\n },\n }),\n ];\n}\n","import { Component, ElementRef, inject } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { map } from 'rxjs';\nimport { MarkdownComponent } from 'ngx-markdown';\nimport { MARKDOWN_PAGES_OPTIONS } from './markdown-pages.config';\n\n@Component({\n selector: 'mdp-markdown-page',\n standalone: true,\n imports: [MarkdownComponent],\n template: `<markdown [src]=\"markdownSrc()\" [disableSanitizer]=\"true\" [clipboard]=\"options.clipboard ?? false\" />`,\n host: { '(click)': 'onClick($event)' },\n})\nexport class MarkdownPageComponent {\n private route = inject(ActivatedRoute);\n private router = inject(Router);\n private el = inject(ElementRef<HTMLElement>);\n protected options = inject(MARKDOWN_PAGES_OPTIONS);\n\n markdownSrc = toSignal(\n this.route.data.pipe(map((data) => data['markdownFile'] as string)),\n { initialValue: '' }\n );\n\n onClick(event: MouseEvent) {\n const anchor = (event.target as HTMLElement).closest('a');\n const href = anchor?.getAttribute('href');\n if (!href?.startsWith('#')) return;\n\n event.preventDefault();\n const fragment = href.substring(1);\n this.router.navigate([], { relativeTo: this.route, fragment }).then(() => {\n document.getElementById(fragment)?.scrollIntoView({ behavior: 'smooth' });\n });\n }\n}\n","import { Route } from '@angular/router';\nimport { MarkdownPageComponent } from './markdown-page.component';\nimport { MarkdownPageConfig } from './markdown-pages.config';\n\nexport function markdownPageRoutes(config: MarkdownPageConfig[]): Route[] {\n return config.map(({ path, markdownFile }) => ({\n path,\n component: MarkdownPageComponent,\n data: { markdownFile },\n }));\n}\n","/*\n * Public API Surface of ngx-markdown-pages\n */\n\nexport type { MarkdownPageConfig, MarkdownPagesOptions } from './lib/markdown-pages.config';\nexport { provideMarkdownPages } from './lib/markdown-pages.config';\nexport { MarkdownPageComponent } from './lib/markdown-page.component';\nexport { markdownPageRoutes } from './lib/markdown-pages.routes';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ /// <amd-module name="ngx-markdown-pages" />
5
+ export * from './public-api';
@@ -0,0 +1,11 @@
1
+ import * as i0 from "@angular/core";
2
+ export declare class MarkdownPageComponent {
3
+ private route;
4
+ private router;
5
+ private el;
6
+ protected options: import("./markdown-pages.config").MarkdownPagesOptions;
7
+ markdownSrc: import("@angular/core").Signal<string>;
8
+ onClick(event: MouseEvent): void;
9
+ static ɵfac: i0.ɵɵFactoryDeclaration<MarkdownPageComponent, never>;
10
+ static ɵcmp: i0.ɵɵComponentDeclaration<MarkdownPageComponent, "mdp-markdown-page", never, {}, {}, never, never, true, never>;
11
+ }
@@ -0,0 +1,10 @@
1
+ import { InjectionToken, Provider } from '@angular/core';
2
+ export interface MarkdownPageConfig {
3
+ path: string;
4
+ markdownFile: string;
5
+ }
6
+ export interface MarkdownPagesOptions {
7
+ clipboard?: boolean;
8
+ }
9
+ export declare const MARKDOWN_PAGES_OPTIONS: InjectionToken<MarkdownPagesOptions>;
10
+ export declare function provideMarkdownPages(options?: MarkdownPagesOptions): Provider[];
@@ -0,0 +1,3 @@
1
+ import { Route } from '@angular/router';
2
+ import { MarkdownPageConfig } from './markdown-pages.config';
3
+ export declare function markdownPageRoutes(config: MarkdownPageConfig[]): Route[];
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "ngx-markdown-pages",
3
+ "version": "0.0.1",
4
+ "peerDependencies": {
5
+ "@angular/common": "^19.2.0",
6
+ "@angular/core": "^19.2.0",
7
+ "@angular/router": "^19.2.0",
8
+ "ngx-markdown": "^19.0.0",
9
+ "marked": "^15.0.0"
10
+ },
11
+ "dependencies": {
12
+ "tslib": "^2.3.0"
13
+ },
14
+ "sideEffects": false,
15
+ "module": "fesm2022/ngx-markdown-pages.mjs",
16
+ "typings": "index.d.ts",
17
+ "exports": {
18
+ "./package.json": {
19
+ "default": "./package.json"
20
+ },
21
+ ".": {
22
+ "types": "./index.d.ts",
23
+ "default": "./fesm2022/ngx-markdown-pages.mjs"
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,4 @@
1
+ export type { MarkdownPageConfig, MarkdownPagesOptions } from './lib/markdown-pages.config';
2
+ export { provideMarkdownPages } from './lib/markdown-pages.config';
3
+ export { MarkdownPageComponent } from './lib/markdown-page.component';
4
+ export { markdownPageRoutes } from './lib/markdown-pages.routes';