@analogjs/content 2.5.0-beta.4 → 2.5.0-beta.40
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/fesm2022/analogjs-content-prism-highlighter.mjs.map +1 -1
- package/fesm2022/analogjs-content-resources.mjs +19 -6
- package/fesm2022/analogjs-content-resources.mjs.map +1 -1
- package/fesm2022/analogjs-content.mjs +116 -8
- package/fesm2022/analogjs-content.mjs.map +1 -1
- package/package.json +1 -1
- package/types/analogjs-content-prism-highlighter.d.ts +2 -2
- package/types/analogjs-content.d.ts +68 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analogjs-content-prism-highlighter.mjs","sources":["../../../../packages/content/prism-highlighter/src/lib/prism-highlighter.ts","../../../../packages/content/prism-highlighter/src/lib/prism/angular.js","../../../../packages/content/prism-highlighter/src/index.ts","../../../../packages/content/prism-highlighter/src/analogjs-content-prism-highlighter.ts"],"sourcesContent":["import { MarkedContentHighlighter } from '@analogjs/content';\nimport { Injectable } from '@angular/core';\nimport { markedHighlight } from 'marked-highlight';\n\ndeclare const Prism: typeof import('prismjs');\n\n@Injectable()\nexport class PrismHighlighter extends MarkedContentHighlighter {\n override augmentCodeBlock(code: string, lang: string): string {\n const classes =\n lang.startsWith('diff') && Prism.languages['diff']\n ? `language-${lang} diff-highlight`\n : `language-${lang.replace('diff-', '')}`;\n return `<pre class=\"${classes}\"><code class=\"${classes}\">${code}</code></pre>`;\n }\n\n override getHighlightExtension() {\n return markedHighlight({\n async: true,\n highlight: (code: string, lang: string) => {\n let diff = lang?.startsWith('diff-');\n lang = diff ? lang.replace('diff-', '') : lang || 'typescript';\n\n if (diff && !Prism.languages['diff']) {\n diff = false;\n console.warn(`Notice:\n ---------------------------------------------------------------------------------------\n The \\`diff\\` language and plugin are not available in the provided setup.\n To enable it, add the following imports your \\`app.config.ts\\`:\n import 'prismjs/components/prism-diff';\n import 'prismjs/plugins/diff-highlight/prism-diff-highlight';\n ---------------------------------------------------------------------------------------\n `);\n }\n\n if (!Prism.languages[lang]) {\n if (lang !== 'mermaid') {\n console.warn(`Notice:\n ---------------------------------------------------------------------------------------\n The requested language '${lang}' is not available in the provided setup.\n To enable it, add the following import your \\`app.config.ts\\`:\n import 'prismjs/components/prism-${lang}';\n ---------------------------------------------------------------------------------------\n `);\n }\n return code;\n }\n return Prism.highlight(\n code,\n diff ? Prism.languages['diff'] : Prism.languages[lang],\n lang,\n );\n },\n });\n }\n}\n","(function () {\n if (typeof Prism === 'undefined') {\n return;\n }\n\n Prism.languages.angular = Prism.languages.extend('markup', {\n keyword:\n /(?:@if|@for|@switch|@defer|@loading|@error|@placeholder|prefetch)\\b/,\n operator: /\\b(?:on|when)\\b/,\n number: {\n pattern: /\\b(minimum|after)\\s+\\d+(?:s|ms|)/gi,\n lookbehind: true,\n },\n builtin: {\n pattern:\n /\\b(?:viewport|timer|minimum|after|hover|idle|immediate|interaction)/,\n },\n function:\n /#?(?!\\s)[_$a-zA-Z\\xA0-\\uFFFF](?:(?!\\s)[$\\w\\xA0-\\uFFFF])*(?=\\s*(?:\\.\\s*(?:apply|bind|call)\\s*)?\\()/,\n });\n\n Prism.languages.ng = Prism.languages.angular;\n})();\n","import { ContentRenderer, NoopContentRenderer } from '@analogjs/content';\nimport { Provider } from '@angular/core';\nimport { PrismHighlighter } from './lib/prism-highlighter';\n\nimport 'prismjs';\nimport 'prismjs/plugins/toolbar/prism-toolbar';\nimport 'prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard';\nimport './lib/prism/angular';\n\nexport { PrismHighlighter };\n\nexport function withPrismHighlighter(): Provider[] {\n return [{ provide: ContentRenderer, useClass: NoopContentRenderer }];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"analogjs-content-prism-highlighter.mjs","sources":["../../../../packages/content/prism-highlighter/src/lib/prism-highlighter.ts","../../../../packages/content/prism-highlighter/src/lib/prism/angular.js","../../../../packages/content/prism-highlighter/src/index.ts","../../../../packages/content/prism-highlighter/src/analogjs-content-prism-highlighter.ts"],"sourcesContent":["import { MarkedContentHighlighter } from '@analogjs/content';\nimport { Injectable } from '@angular/core';\nimport { markedHighlight } from 'marked-highlight';\n\ndeclare const Prism: typeof import('prismjs');\n\ntype HighlightExtension = ReturnType<\n MarkedContentHighlighter['getHighlightExtension']\n>;\n\n@Injectable()\nexport class PrismHighlighter extends MarkedContentHighlighter {\n override augmentCodeBlock(code: string, lang: string): string {\n const classes =\n lang.startsWith('diff') && Prism.languages['diff']\n ? `language-${lang} diff-highlight`\n : `language-${lang.replace('diff-', '')}`;\n return `<pre class=\"${classes}\"><code class=\"${classes}\">${code}</code></pre>`;\n }\n\n override getHighlightExtension(): HighlightExtension {\n return markedHighlight({\n async: true,\n highlight: (code: string, lang: string) => {\n let diff = lang?.startsWith('diff-');\n lang = diff ? lang.replace('diff-', '') : lang || 'typescript';\n\n if (diff && !Prism.languages['diff']) {\n diff = false;\n console.warn(`Notice:\n ---------------------------------------------------------------------------------------\n The \\`diff\\` language and plugin are not available in the provided setup.\n To enable it, add the following imports your \\`app.config.ts\\`:\n import 'prismjs/components/prism-diff';\n import 'prismjs/plugins/diff-highlight/prism-diff-highlight';\n ---------------------------------------------------------------------------------------\n `);\n }\n\n if (!Prism.languages[lang]) {\n if (lang !== 'mermaid') {\n console.warn(`Notice:\n ---------------------------------------------------------------------------------------\n The requested language '${lang}' is not available in the provided setup.\n To enable it, add the following import your \\`app.config.ts\\`:\n import 'prismjs/components/prism-${lang}';\n ---------------------------------------------------------------------------------------\n `);\n }\n return code;\n }\n return Prism.highlight(\n code,\n diff ? Prism.languages['diff'] : Prism.languages[lang],\n lang,\n );\n },\n }) as HighlightExtension;\n }\n}\n","(function () {\n if (typeof Prism === 'undefined') {\n return;\n }\n\n Prism.languages.angular = Prism.languages.extend('markup', {\n keyword:\n /(?:@if|@for|@switch|@defer|@loading|@error|@placeholder|prefetch)\\b/,\n operator: /\\b(?:on|when)\\b/,\n number: {\n pattern: /\\b(minimum|after)\\s+\\d+(?:s|ms|)/gi,\n lookbehind: true,\n },\n builtin: {\n pattern:\n /\\b(?:viewport|timer|minimum|after|hover|idle|immediate|interaction)/,\n },\n function:\n /#?(?!\\s)[_$a-zA-Z\\xA0-\\uFFFF](?:(?!\\s)[$\\w\\xA0-\\uFFFF])*(?=\\s*(?:\\.\\s*(?:apply|bind|call)\\s*)?\\()/,\n });\n\n Prism.languages.ng = Prism.languages.angular;\n})();\n","import { ContentRenderer, NoopContentRenderer } from '@analogjs/content';\nimport { Provider } from '@angular/core';\nimport { PrismHighlighter } from './lib/prism-highlighter';\n\nimport 'prismjs';\nimport 'prismjs/plugins/toolbar/prism-toolbar';\nimport 'prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard';\nimport './lib/prism/angular';\n\nexport { PrismHighlighter };\n\nexport function withPrismHighlighter(): Provider[] {\n return [{ provide: ContentRenderer, useClass: NoopContentRenderer }];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;AAWM,MAAO,gBAAiB,SAAQ,wBAAwB,CAAA;IACnD,gBAAgB,CAAC,IAAY,EAAE,IAAY,EAAA;AAClD,QAAA,MAAM,OAAO,GACX,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM;cAC7C,CAAA,SAAA,EAAY,IAAI,CAAA,eAAA;cAChB,CAAA,SAAA,EAAY,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA,CAAE;AAC7C,QAAA,OAAO,eAAe,OAAO,CAAA,eAAA,EAAkB,OAAO,CAAA,EAAA,EAAK,IAAI,eAAe;IAChF;IAES,qBAAqB,GAAA;AAC5B,QAAA,OAAO,eAAe,CAAC;AACrB,YAAA,KAAK,EAAE,IAAI;AACX,YAAA,SAAS,EAAE,CAAC,IAAY,EAAE,IAAY,KAAI;gBACxC,IAAI,IAAI,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC;AACpC,gBAAA,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,YAAY;gBAE9D,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;oBACpC,IAAI,GAAG,KAAK;oBACZ,OAAO,CAAC,IAAI,CAAC,CAAA;;;;;;;AAOV,YAAA,CAAA,CAAC;gBACN;gBAEA,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE;AAC1B,oBAAA,IAAI,IAAI,KAAK,SAAS,EAAE;wBACtB,OAAO,CAAC,IAAI,CAAC,CAAA;;8BAEK,IAAI,CAAA;;yCAEO,IAAI,CAAA;;AAE9B,cAAA,CAAA,CAAC;oBACN;AACA,oBAAA,OAAO,IAAI;gBACb;AACA,gBAAA,OAAO,KAAK,CAAC,SAAS,CACpB,IAAI,EACJ,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EACtD,IAAI,CACL;YACH,CAAC;AACF,SAAA,CAAuB;IAC1B;8GA/CW,gBAAgB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;kHAAhB,gBAAgB,EAAA,CAAA,CAAA;;2FAAhB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B;;;;ACVD,CAAC,YAAA;AACC,IAAA,IAAI,OAAO,KAAK,KAAK,WAAW,EAAE;QAChC;IACF;AAEA,IAAA,KAAK,CAAC,SAAS,CAAC,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE;AACzD,QAAA,OAAO,EACL,qEAAqE;AACvE,QAAA,QAAQ,EAAE,iBAAiB;AAC3B,QAAA,MAAM,EAAE;AACN,YAAA,OAAO,EAAE,oCAAoC;AAC7C,YAAA,UAAU,EAAE,IAAI;AACjB,SAAA;AACD,QAAA,OAAO,EAAE;AACP,YAAA,OAAO,EACL,qEAAqE;AACxE,SAAA;AACD,QAAA,QAAQ,EACN,mGAAmG;AACtG,KAAA,CAAC;IAEF,KAAK,CAAC,SAAS,CAAC,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO;AAC9C,CAAC,GAAG;;SCXY,oBAAoB,GAAA;IAClC,OAAO,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,mBAAmB,EAAE,CAAC;AACtE;;ACbA;;AAEG;;;;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resource, inject, computed } from '@angular/core';
|
|
2
|
-
import { injectContentListLoader, parseRawContentFile, injectContentFileLoader, ContentRenderer } from '@analogjs/content';
|
|
2
|
+
import { injectContentListLoader, injectContentLocale, filterByLocale, parseRawContentFile, injectContentFileLoader, ContentRenderer } from '@analogjs/content';
|
|
3
3
|
import { ActivatedRoute } from '@angular/router';
|
|
4
4
|
import { toSignal } from '@angular/core/rxjs-interop';
|
|
5
5
|
import { from } from 'rxjs';
|
|
@@ -7,13 +7,20 @@ import { map } from 'rxjs/operators';
|
|
|
7
7
|
|
|
8
8
|
function contentFilesResource(filterFn) {
|
|
9
9
|
const contentListLoader = injectContentListLoader();
|
|
10
|
-
const
|
|
10
|
+
const locale = injectContentLocale();
|
|
11
|
+
const contentList = contentListLoader().then((items) => {
|
|
12
|
+
let results = locale ? filterByLocale(items, locale) : items;
|
|
13
|
+
if (filterFn) {
|
|
14
|
+
results = results.filter(filterFn);
|
|
15
|
+
}
|
|
16
|
+
return results;
|
|
17
|
+
});
|
|
11
18
|
return resource({
|
|
12
19
|
loader: () => contentList,
|
|
13
20
|
});
|
|
14
21
|
}
|
|
15
22
|
|
|
16
|
-
async function getContentFile(contentFiles, slug, fallback) {
|
|
23
|
+
async function getContentFile(contentFiles, slug, fallback, locale) {
|
|
17
24
|
// Normalize file keys so both "/src/content/..." and "/<project>/src/content/..." resolve.
|
|
18
25
|
// This mirrors normalization used elsewhere in the content pipeline.
|
|
19
26
|
const normalizedFiles = {};
|
|
@@ -43,7 +50,12 @@ async function getContentFile(contentFiles, slug, fallback) {
|
|
|
43
50
|
`${base}/index.md`,
|
|
44
51
|
`${base}/index.agx`,
|
|
45
52
|
];
|
|
46
|
-
|
|
53
|
+
// Try locale-prefixed paths first, then fall back to unprefixed, then bare slug via stem
|
|
54
|
+
const localeCandidates = locale
|
|
55
|
+
? candidates.map((c) => c.replace('/src/content/', `/src/content/${locale}/`))
|
|
56
|
+
: [];
|
|
57
|
+
const allCandidates = [...localeCandidates, ...candidates];
|
|
58
|
+
const matchKey = allCandidates.find((k) => k in normalizedFiles) ?? stemToKey[slug];
|
|
47
59
|
const contentFile = matchKey ? normalizedFiles[matchKey] : undefined;
|
|
48
60
|
if (!contentFile) {
|
|
49
61
|
return {
|
|
@@ -82,6 +94,7 @@ async function getContentFile(contentFiles, slug, fallback) {
|
|
|
82
94
|
function contentFileResource(params, fallback = 'No Content Found') {
|
|
83
95
|
const loaderPromise = injectContentFileLoader();
|
|
84
96
|
const contentRenderer = inject(ContentRenderer);
|
|
97
|
+
const locale = injectContentLocale();
|
|
85
98
|
const contentFilesMap = toSignal(from(loaderPromise()));
|
|
86
99
|
const input = params ||
|
|
87
100
|
toSignal(inject(ActivatedRoute).paramMap.pipe(map((params) => params.get('slug'))), { requireSync: true });
|
|
@@ -91,7 +104,7 @@ function contentFileResource(params, fallback = 'No Content Found') {
|
|
|
91
104
|
const { input: param, files } = params;
|
|
92
105
|
if (typeof param === 'string') {
|
|
93
106
|
if (param) {
|
|
94
|
-
const file = await getContentFile(files, param, fallback);
|
|
107
|
+
const file = await getContentFile(files, param, fallback, locale);
|
|
95
108
|
if (typeof file.content === 'string') {
|
|
96
109
|
const rendered = (await contentRenderer.render(file.content));
|
|
97
110
|
return {
|
|
@@ -113,7 +126,7 @@ function contentFileResource(params, fallback = 'No Content Found') {
|
|
|
113
126
|
};
|
|
114
127
|
}
|
|
115
128
|
else {
|
|
116
|
-
const file = await getContentFile(files, param.customFilename, fallback);
|
|
129
|
+
const file = await getContentFile(files, param.customFilename, fallback, locale);
|
|
117
130
|
if (typeof file.content === 'string') {
|
|
118
131
|
const rendered = (await contentRenderer.render(file.content));
|
|
119
132
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analogjs-content-resources.mjs","sources":["../../../../packages/content/resources/src/content-files-resource.ts","../../../../packages/content/resources/src/content-file-resource.ts","../../../../packages/content/resources/src/analogjs-content-resources.ts"],"sourcesContent":["import { resource } from '@angular/core';\nimport {\n injectContentListLoader,\n InjectContentFilesFilterFunction,\n} from '@analogjs/content';\n\nexport function contentFilesResource<Attributes extends Record<string, any>>(\n filterFn?: InjectContentFilesFilterFunction<Attributes> | undefined,\n) {\n const contentListLoader = injectContentListLoader<Attributes>();\n const contentList = contentListLoader().then((items) =>\n filterFn ? items.filter(filterFn) : items,\n );\n\n return resource({\n loader: () => contentList,\n });\n}\n","import { computed, inject, resource, Signal } from '@angular/core';\nimport {\n ContentFile,\n ContentRenderer,\n parseRawContentFile,\n injectContentFileLoader,\n} from '@analogjs/content';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { from } from 'rxjs';\nimport { map } from 'rxjs/operators';\n\ntype ContentFileParams = Signal<\n | string\n | {\n customFilename: string;\n }\n>;\n\nasync function getContentFile<\n Attributes extends Record<string, any> = Record<string, any>,\n>(\n contentFiles: Record<string, () => Promise<string>>,\n slug: string,\n fallback: string,\n): Promise<ContentFile<Attributes | Record<string, never>>> {\n // Normalize file keys so both \"/src/content/...\" and \"/<project>/src/content/...\" resolve.\n // This mirrors normalization used elsewhere in the content pipeline.\n const normalizedFiles: Record<string, () => Promise<string>> = {};\n const stemToKey: Record<string, string> = {};\n for (const [key, resolver] of Object.entries(contentFiles)) {\n const normalizedKey = key\n // replace any prefix up to the content directory with /src/content\n // use a non-greedy match so nested paths containing \"/content\" are preserved\n .replace(/^(?:.*?)\\/content(?=\\/)/, '/src/content')\n // normalize duplicate slashes\n .replace(/\\/{2,}/g, '/');\n normalizedFiles[normalizedKey] = resolver;\n // Index by bare filename stem so slug-only lookups work\n const stem = normalizedKey\n .split('/')\n .pop()\n ?.replace(/\\.[^.]+$/, '');\n if (stem && !stemToKey[stem]) {\n stemToKey[stem] = normalizedKey;\n }\n }\n\n // Try direct file first, then directory index variants, then bare slug via stem\n const base = `/src/content/${slug}`.replace(/\\/{2,}/g, '/');\n const candidates = [\n `${base}.md`,\n `${base}.agx`,\n `${base}/index.md`,\n `${base}/index.agx`,\n ];\n\n const matchKey =\n candidates.find((k) => k in normalizedFiles) ?? stemToKey[slug];\n const contentFile = matchKey ? normalizedFiles[matchKey] : undefined;\n\n if (!contentFile) {\n return {\n filename: base,\n attributes: {},\n slug: '',\n content: fallback,\n } as ContentFile<Attributes | Record<string, never>>;\n }\n\n const resolvedBase = matchKey!.replace(/\\.(md|agx)$/, '');\n\n return contentFile().then(\n (contentFile: string | { default: any; metadata: any }) => {\n if (typeof contentFile === 'string') {\n const { content, attributes } =\n parseRawContentFile<Attributes>(contentFile);\n\n return {\n filename: resolvedBase,\n slug,\n attributes,\n content,\n } as ContentFile<Attributes | Record<string, never>>;\n }\n\n return {\n filename: resolvedBase,\n slug,\n attributes: contentFile.metadata,\n content: contentFile.default,\n } as ContentFile<Attributes | Record<string, never>>;\n },\n );\n}\n\n/**\n * Resource for requesting an individual content file\n *\n * @param params\n * @param fallback\n * @returns\n */\nexport function contentFileResource<\n Attributes extends Record<string, any> = Record<string, any>,\n>(params?: ContentFileParams, fallback = 'No Content Found') {\n const loaderPromise = injectContentFileLoader();\n const contentRenderer = inject(ContentRenderer);\n const contentFilesMap = toSignal(from(loaderPromise()));\n const input =\n params ||\n toSignal(\n inject(ActivatedRoute).paramMap.pipe(\n map((params) => params.get('slug') as string),\n ),\n { requireSync: true },\n );\n\n return resource({\n params: computed(() => ({ input: input(), files: contentFilesMap() })),\n loader: async ({ params }) => {\n const { input: param, files } = params;\n\n if (typeof param === 'string') {\n if (param) {\n const file = await getContentFile<Attributes>(\n files!,\n param,\n fallback,\n );\n if (typeof file.content === 'string') {\n const rendered = (await contentRenderer.render(file.content)) as {\n toc?: Array<{ id: string; level: number; text: string }>;\n };\n return {\n ...file,\n toc: rendered.toc ?? [],\n };\n }\n return {\n ...file,\n toc: [],\n };\n }\n\n return {\n filename: '',\n slug: '',\n attributes: {},\n content: fallback,\n toc: [],\n } as ContentFile<Attributes | Record<string, never>>;\n } else {\n const file = await getContentFile<Attributes>(\n files!,\n param.customFilename,\n fallback,\n );\n if (typeof file.content === 'string') {\n const rendered = (await contentRenderer.render(file.content)) as {\n toc?: Array<{ id: string; level: number; text: string }>;\n };\n return {\n ...file,\n toc: rendered.toc ?? [],\n };\n }\n return {\n ...file,\n toc: [],\n };\n }\n },\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"analogjs-content-resources.mjs","sources":["../../../../packages/content/resources/src/content-files-resource.ts","../../../../packages/content/resources/src/content-file-resource.ts","../../../../packages/content/resources/src/analogjs-content-resources.ts"],"sourcesContent":["import { resource } from '@angular/core';\nimport {\n injectContentListLoader,\n InjectContentFilesFilterFunction,\n filterByLocale,\n injectContentLocale,\n} from '@analogjs/content';\n\nexport function contentFilesResource<Attributes extends Record<string, any>>(\n filterFn?: InjectContentFilesFilterFunction<Attributes> | undefined,\n) {\n const contentListLoader = injectContentListLoader<Attributes>();\n const locale = injectContentLocale();\n const contentList = contentListLoader().then((items) => {\n let results = locale ? filterByLocale(items, locale) : items;\n if (filterFn) {\n results = results.filter(filterFn);\n }\n return results;\n });\n\n return resource({\n loader: () => contentList,\n });\n}\n","import { computed, inject, resource, Signal } from '@angular/core';\nimport {\n ContentFile,\n ContentRenderer,\n parseRawContentFile,\n injectContentFileLoader,\n injectContentLocale,\n} from '@analogjs/content';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { from } from 'rxjs';\nimport { map } from 'rxjs/operators';\n\ntype ContentFileParams = Signal<\n | string\n | {\n customFilename: string;\n }\n>;\n\nasync function getContentFile<\n Attributes extends Record<string, any> = Record<string, any>,\n>(\n contentFiles: Record<string, () => Promise<string>>,\n slug: string,\n fallback: string,\n locale?: string | null,\n): Promise<ContentFile<Attributes | Record<string, never>>> {\n // Normalize file keys so both \"/src/content/...\" and \"/<project>/src/content/...\" resolve.\n // This mirrors normalization used elsewhere in the content pipeline.\n const normalizedFiles: Record<string, () => Promise<string>> = {};\n const stemToKey: Record<string, string> = {};\n for (const [key, resolver] of Object.entries(contentFiles)) {\n const normalizedKey = key\n // replace any prefix up to the content directory with /src/content\n // use a non-greedy match so nested paths containing \"/content\" are preserved\n .replace(/^(?:.*?)\\/content(?=\\/)/, '/src/content')\n // normalize duplicate slashes\n .replace(/\\/{2,}/g, '/');\n normalizedFiles[normalizedKey] = resolver;\n // Index by bare filename stem so slug-only lookups work\n const stem = normalizedKey\n .split('/')\n .pop()\n ?.replace(/\\.[^.]+$/, '');\n if (stem && !stemToKey[stem]) {\n stemToKey[stem] = normalizedKey;\n }\n }\n\n // Try direct file first, then directory index variants, then bare slug via stem\n const base = `/src/content/${slug}`.replace(/\\/{2,}/g, '/');\n const candidates = [\n `${base}.md`,\n `${base}.agx`,\n `${base}/index.md`,\n `${base}/index.agx`,\n ];\n\n // Try locale-prefixed paths first, then fall back to unprefixed, then bare slug via stem\n const localeCandidates = locale\n ? candidates.map((c) =>\n c.replace('/src/content/', `/src/content/${locale}/`),\n )\n : [];\n const allCandidates = [...localeCandidates, ...candidates];\n const matchKey =\n allCandidates.find((k) => k in normalizedFiles) ?? stemToKey[slug];\n const contentFile = matchKey ? normalizedFiles[matchKey] : undefined;\n\n if (!contentFile) {\n return {\n filename: base,\n attributes: {},\n slug: '',\n content: fallback,\n } as ContentFile<Attributes | Record<string, never>>;\n }\n\n const resolvedBase = matchKey!.replace(/\\.(md|agx)$/, '');\n\n return contentFile().then(\n (contentFile: string | { default: any; metadata: any }) => {\n if (typeof contentFile === 'string') {\n const { content, attributes } =\n parseRawContentFile<Attributes>(contentFile);\n\n return {\n filename: resolvedBase,\n slug,\n attributes,\n content,\n } as ContentFile<Attributes | Record<string, never>>;\n }\n\n return {\n filename: resolvedBase,\n slug,\n attributes: contentFile.metadata,\n content: contentFile.default,\n } as ContentFile<Attributes | Record<string, never>>;\n },\n );\n}\n\n/**\n * Resource for requesting an individual content file\n *\n * @param params\n * @param fallback\n * @returns\n */\nexport function contentFileResource<\n Attributes extends Record<string, any> = Record<string, any>,\n>(params?: ContentFileParams, fallback = 'No Content Found') {\n const loaderPromise = injectContentFileLoader();\n const contentRenderer = inject(ContentRenderer);\n const locale = injectContentLocale();\n const contentFilesMap = toSignal(from(loaderPromise()));\n const input =\n params ||\n toSignal(\n inject(ActivatedRoute).paramMap.pipe(\n map((params) => params.get('slug') as string),\n ),\n { requireSync: true },\n );\n\n return resource({\n params: computed(() => ({ input: input(), files: contentFilesMap() })),\n loader: async ({ params }) => {\n const { input: param, files } = params;\n\n if (typeof param === 'string') {\n if (param) {\n const file = await getContentFile<Attributes>(\n files!,\n param,\n fallback,\n locale,\n );\n if (typeof file.content === 'string') {\n const rendered = (await contentRenderer.render(file.content)) as {\n toc?: Array<{ id: string; level: number; text: string }>;\n };\n return {\n ...file,\n toc: rendered.toc ?? [],\n };\n }\n return {\n ...file,\n toc: [],\n };\n }\n\n return {\n filename: '',\n slug: '',\n attributes: {},\n content: fallback,\n toc: [],\n } as ContentFile<Attributes | Record<string, never>>;\n } else {\n const file = await getContentFile<Attributes>(\n files!,\n param.customFilename,\n fallback,\n locale,\n );\n if (typeof file.content === 'string') {\n const rendered = (await contentRenderer.render(file.content)) as {\n toc?: Array<{ id: string; level: number; text: string }>;\n };\n return {\n ...file,\n toc: rendered.toc ?? [],\n };\n }\n return {\n ...file,\n toc: [],\n };\n }\n },\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -172,6 +172,108 @@ class NoopContentRenderer {
|
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
/**
|
|
176
|
+
* Token for the active content locale.
|
|
177
|
+
* Provided via `withLocale()` in `provideContent()`.
|
|
178
|
+
*
|
|
179
|
+
* When set, `injectContentFiles()` filters to content matching this locale,
|
|
180
|
+
* and `injectContent()` resolves locale-prefixed content paths first.
|
|
181
|
+
*/
|
|
182
|
+
const CONTENT_LOCALE = new InjectionToken('@analogjs/content Locale');
|
|
183
|
+
/**
|
|
184
|
+
* Injects the content locale, returning null if not configured.
|
|
185
|
+
*/
|
|
186
|
+
function injectContentLocale() {
|
|
187
|
+
return inject(CONTENT_LOCALE, { optional: true });
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Content feature that sets the active locale for content resolution.
|
|
191
|
+
*
|
|
192
|
+
* When provided, content APIs become locale-aware:
|
|
193
|
+
* - `injectContentFiles()` filters to files in the locale subdirectory
|
|
194
|
+
* or with a matching `locale` frontmatter attribute.
|
|
195
|
+
* - `injectContent()` tries locale-prefixed paths first
|
|
196
|
+
* (e.g., `content/fr/blog/post.md` before `content/blog/post.md`).
|
|
197
|
+
*
|
|
198
|
+
* Usage:
|
|
199
|
+
* ```typescript
|
|
200
|
+
* // With loader — runs in injection context
|
|
201
|
+
* provideContent(
|
|
202
|
+
* withMarkdownRenderer(),
|
|
203
|
+
* withLocale({ loadLocale: injectLocale }),
|
|
204
|
+
* )
|
|
205
|
+
*
|
|
206
|
+
* // Static locale
|
|
207
|
+
* provideContent(
|
|
208
|
+
* withMarkdownRenderer(),
|
|
209
|
+
* withLocale('fr'),
|
|
210
|
+
* )
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
function withLocale(locale) {
|
|
214
|
+
if (typeof locale === 'string') {
|
|
215
|
+
return { provide: CONTENT_LOCALE, useValue: locale };
|
|
216
|
+
}
|
|
217
|
+
return { provide: CONTENT_LOCALE, useFactory: locale.loadLocale };
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Filters content files by locale using map-based key lookup.
|
|
221
|
+
*
|
|
222
|
+
* Matching rules:
|
|
223
|
+
* 1. Frontmatter `locale` attribute matches the active locale.
|
|
224
|
+
* 2. File is in the active locale subdirectory (e.g., `/content/fr/blog/post`).
|
|
225
|
+
* 3. File has no locale marker and no localized variant exists — included as universal content.
|
|
226
|
+
*
|
|
227
|
+
* Files in a different locale's subdirectory are always excluded.
|
|
228
|
+
*/
|
|
229
|
+
function filterByLocale(files, locale) {
|
|
230
|
+
const localePrefix = `/content/${locale}/`;
|
|
231
|
+
// Collect all locale prefixes present in the file set
|
|
232
|
+
const allLocalePrefixes = new Set();
|
|
233
|
+
for (const file of files) {
|
|
234
|
+
const match = file.filename.match(/\/content\/([a-z]{2}(?:-[a-zA-Z]+)?)\//);
|
|
235
|
+
if (match) {
|
|
236
|
+
allLocalePrefixes.add(`/content/${match[1]}/`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Build set of base paths that have a localized variant for the active locale
|
|
240
|
+
const localizedBasePaths = new Set();
|
|
241
|
+
for (const file of files) {
|
|
242
|
+
if (file.filename.includes(localePrefix)) {
|
|
243
|
+
localizedBasePaths.add(file.filename.replace(localePrefix, '/content/'));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return files.filter((file) => {
|
|
247
|
+
// Frontmatter locale attribute takes priority
|
|
248
|
+
if (file.attributes['locale']) {
|
|
249
|
+
return file.attributes['locale'] === locale;
|
|
250
|
+
}
|
|
251
|
+
// File is in the active locale subdirectory — include
|
|
252
|
+
if (file.filename.includes(localePrefix)) {
|
|
253
|
+
return true;
|
|
254
|
+
}
|
|
255
|
+
// File is in a different locale's subdirectory — exclude
|
|
256
|
+
for (const prefix of allLocalePrefixes) {
|
|
257
|
+
if (prefix !== localePrefix && file.filename.includes(prefix)) {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// Universal content — include only if no localized variant exists
|
|
262
|
+
return !localizedBasePaths.has(file.filename);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Prepends locale-prefixed candidates before the standard candidates
|
|
267
|
+
* for content file map key lookup.
|
|
268
|
+
*/
|
|
269
|
+
function withLocaleCandidates(candidates, locale) {
|
|
270
|
+
if (!locale) {
|
|
271
|
+
return candidates;
|
|
272
|
+
}
|
|
273
|
+
const localeCandidates = candidates.map((c) => c.replace('/src/content/', `/src/content/${locale}/`));
|
|
274
|
+
return [...localeCandidates, ...candidates];
|
|
275
|
+
}
|
|
276
|
+
|
|
175
277
|
/**
|
|
176
278
|
* Returns the list of content files by filename with ?analog-content-list=true.
|
|
177
279
|
* We use the query param to transform the return into an array of
|
|
@@ -303,7 +405,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
|
|
|
303
405
|
}] });
|
|
304
406
|
|
|
305
407
|
/// <reference types="vite/client" />
|
|
306
|
-
function getContentFile(contentFiles, prefix, slug, fallback, renderTaskService, contentRenderer) {
|
|
408
|
+
function getContentFile(contentFiles, prefix, slug, fallback, renderTaskService, contentRenderer, locale) {
|
|
307
409
|
// Normalize file keys so both "/src/content/..." and "/<project>/src/content/..." resolve.
|
|
308
410
|
const normalizedFiles = {};
|
|
309
411
|
for (const [key, resolver] of Object.entries(contentFiles)) {
|
|
@@ -319,7 +421,8 @@ function getContentFile(contentFiles, prefix, slug, fallback, renderTaskService,
|
|
|
319
421
|
`${base}/index.md`,
|
|
320
422
|
`${base}/index.agx`,
|
|
321
423
|
];
|
|
322
|
-
const
|
|
424
|
+
const allCandidates = withLocaleCandidates(candidates, locale);
|
|
425
|
+
const matchKey = allCandidates.find((k) => k in normalizedFiles);
|
|
323
426
|
const contentFile = matchKey ? normalizedFiles[matchKey] : undefined;
|
|
324
427
|
const resolvedBase = (matchKey || `${base}.md`).replace(/\.(md|agx)$/, '');
|
|
325
428
|
if (!contentFile) {
|
|
@@ -377,6 +480,7 @@ function injectContent(param = 'slug', fallback = 'No Content Found') {
|
|
|
377
480
|
const contentFiles = inject(CONTENT_FILES_TOKEN);
|
|
378
481
|
const contentRenderer = inject(ContentRenderer);
|
|
379
482
|
const renderTaskService = inject(RenderTaskService);
|
|
483
|
+
const locale = inject(CONTENT_LOCALE, { optional: true });
|
|
380
484
|
const task = renderTaskService.addRenderTask();
|
|
381
485
|
if (typeof param === 'string' || 'param' in param) {
|
|
382
486
|
const prefix = typeof param === 'string' ? '' : `${param.subdirectory}/`;
|
|
@@ -384,7 +488,7 @@ function injectContent(param = 'slug', fallback = 'No Content Found') {
|
|
|
384
488
|
const paramKey = typeof param === 'string' ? param : param.param;
|
|
385
489
|
return route.paramMap.pipe(map((params) => params.get(paramKey)), switchMap((slug) => {
|
|
386
490
|
if (slug) {
|
|
387
|
-
return getContentFile(contentFiles, prefix, slug, fallback, renderTaskService, contentRenderer);
|
|
491
|
+
return getContentFile(contentFiles, prefix, slug, fallback, renderTaskService, contentRenderer, locale);
|
|
388
492
|
}
|
|
389
493
|
return of({
|
|
390
494
|
filename: '',
|
|
@@ -396,7 +500,7 @@ function injectContent(param = 'slug', fallback = 'No Content Found') {
|
|
|
396
500
|
}), tap(() => renderTaskService.clearRenderTask(task)));
|
|
397
501
|
}
|
|
398
502
|
else {
|
|
399
|
-
return getContentFile(contentFiles, '', param.customFilename, fallback, renderTaskService, contentRenderer).pipe(tap(() => renderTaskService.clearRenderTask(task)));
|
|
503
|
+
return getContentFile(contentFiles, '', param.customFilename, fallback, renderTaskService, contentRenderer, locale).pipe(tap(() => renderTaskService.clearRenderTask(task)));
|
|
400
504
|
}
|
|
401
505
|
}
|
|
402
506
|
|
|
@@ -404,12 +508,16 @@ function injectContentFiles(filterFn) {
|
|
|
404
508
|
const renderTaskService = inject(RenderTaskService);
|
|
405
509
|
const task = renderTaskService.addRenderTask();
|
|
406
510
|
const allContentFiles = inject(CONTENT_FILES_LIST_TOKEN);
|
|
511
|
+
const locale = inject(CONTENT_LOCALE, { optional: true });
|
|
407
512
|
renderTaskService.clearRenderTask(task);
|
|
513
|
+
let results = allContentFiles;
|
|
514
|
+
if (locale) {
|
|
515
|
+
results = filterByLocale(results, locale);
|
|
516
|
+
}
|
|
408
517
|
if (filterFn) {
|
|
409
|
-
|
|
410
|
-
return filteredContentFiles;
|
|
518
|
+
results = results.filter(filterFn);
|
|
411
519
|
}
|
|
412
|
-
return
|
|
520
|
+
return results;
|
|
413
521
|
}
|
|
414
522
|
function injectContentFilesMap() {
|
|
415
523
|
return inject(CONTENT_FILES_TOKEN);
|
|
@@ -656,5 +764,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImpor
|
|
|
656
764
|
* Generated bundle index. Do not edit.
|
|
657
765
|
*/
|
|
658
766
|
|
|
659
|
-
export { AnchorNavigationDirective, CONTENT_FILE_LOADER, CONTENT_LIST_LOADER, ContentRenderer, MERMAID_IMPORT_TOKEN, AnalogMarkdownComponent as MarkdownComponent, MarkdownContentRendererService, AnalogMarkdownRouteComponent as MarkdownRouteComponent, MarkedContentHighlighter, MarkedSetupService, NoopContentRenderer, injectContent, injectContentFileLoader, injectContentFiles, injectContentFilesMap, injectContentListLoader, parseRawContentFile, provideContent, withContentFileLoader, withContentListLoader, withHighlighter, withMarkdownRenderer };
|
|
767
|
+
export { AnchorNavigationDirective, CONTENT_FILE_LOADER, CONTENT_LIST_LOADER, CONTENT_LOCALE, ContentRenderer, MERMAID_IMPORT_TOKEN, AnalogMarkdownComponent as MarkdownComponent, MarkdownContentRendererService, AnalogMarkdownRouteComponent as MarkdownRouteComponent, MarkedContentHighlighter, MarkedSetupService, NoopContentRenderer, filterByLocale, injectContent, injectContentFileLoader, injectContentFiles, injectContentFilesMap, injectContentListLoader, injectContentLocale, parseRawContentFile, provideContent, withContentFileLoader, withContentListLoader, withHighlighter, withLocale, withLocaleCandidates, withMarkdownRenderer };
|
|
660
768
|
//# sourceMappingURL=analogjs-content.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analogjs-content.mjs","sources":["../../../../packages/content/src/lib/anchor-navigation.directive.ts","../../../../packages/content/src/lib/content-renderer.ts","../../../../packages/content/src/lib/get-content-files.ts","../../../../packages/content/src/lib/content-files-list-token.ts","../../../../packages/content/src/lib/content-files-token.ts","../../../../packages/content/src/lib/parse-raw-content-file.ts","../../../../packages/content/src/lib/utils/zone-wait-for.ts","../../../../packages/content/src/lib/render-task.service.ts","../../../../packages/content/src/lib/content.ts","../../../../packages/content/src/lib/inject-content-files.ts","../../../../packages/content/src/lib/marked-content-highlighter.ts","../../../../packages/content/src/lib/marked-setup.service.ts","../../../../packages/content/src/lib/markdown-content-renderer.service.ts","../../../../packages/content/src/lib/content-file-loader.ts","../../../../packages/content/src/lib/content-list-loader.ts","../../../../packages/content/src/lib/provide-content.ts","../../../../packages/content/src/lib/markdown-route.component.ts","../../../../packages/content/src/lib/markdown.component.ts","../../../../packages/content/src/analogjs-content.ts"],"sourcesContent":["import { Directive, HostListener, inject } from '@angular/core';\nimport { DOCUMENT, Location } from '@angular/common';\nimport { Router } from '@angular/router';\n\n@Directive({\n selector: '[analogAnchorNavigation]',\n standalone: true,\n})\nexport class AnchorNavigationDirective {\n private readonly document = inject(DOCUMENT);\n private readonly location = inject(Location);\n private readonly router = inject(Router);\n\n @HostListener('click', ['$event.target'])\n handleNavigation(element: EventTarget | null): boolean {\n if (\n element instanceof HTMLAnchorElement &&\n isInternalUrl(element, this.document) &&\n hasTargetSelf(element) &&\n !hasDownloadAttribute(element)\n ) {\n const { pathname, search, hash } = element;\n const url = this.location.normalize(`${pathname}${search}${hash}`);\n this.router.navigateByUrl(url);\n\n return false;\n }\n\n return true;\n }\n}\n\nfunction hasDownloadAttribute(anchorElement: HTMLAnchorElement): boolean {\n return anchorElement.getAttribute('download') !== null;\n}\n\nfunction hasTargetSelf(anchorElement: HTMLAnchorElement): boolean {\n return !anchorElement.target || anchorElement.target === '_self';\n}\n\nfunction isInternalUrl(\n anchorElement: HTMLAnchorElement,\n document: Document,\n): boolean {\n return (\n anchorElement.host === document.location.host &&\n anchorElement.protocol === document.location.protocol\n );\n}\n","/// <reference types=\"vite/client\" />\n\nimport { Injectable, TransferState, inject, makeStateKey } from '@angular/core';\n\nexport type TableOfContentItem = {\n id: string;\n level: number; // starts at 1\n text: string;\n};\n\nexport type RenderedContent = {\n content: string;\n toc: TableOfContentItem[];\n};\n\n@Injectable()\nexport abstract class ContentRenderer {\n async render(content: string): Promise<RenderedContent> {\n return { content, toc: [] };\n }\n\n // Backward-compatible API for consumers that read headings directly.\n getContentHeadings(_content: string): TableOfContentItem[] {\n return [];\n }\n\n // eslint-disable-next-line\n enhance() {}\n}\n\nexport class NoopContentRenderer implements ContentRenderer {\n private readonly transferState = inject(TransferState);\n private contentId = 0;\n\n /**\n * Generates a hash from the content string\n * to be used with the transfer state\n */\n private generateHash(str: string) {\n let hash = 0;\n for (let i = 0, len = str.length; i < len; i++) {\n let chr = str.charCodeAt(i);\n hash = (hash << 5) - hash + chr;\n hash |= 0; // Convert to 32bit integer\n }\n return hash;\n }\n\n async render(content: string): Promise<RenderedContent> {\n this.contentId = this.generateHash(content);\n const toc = this.getContentHeadings(content);\n const key = makeStateKey<TableOfContentItem[]>(\n `content-headings-${this.contentId}`,\n );\n\n if (import.meta.env.SSR === true) {\n this.transferState.set(key, toc);\n return { content, toc };\n }\n\n return {\n content,\n toc: this.transferState.get(key, toc),\n };\n }\n enhance() {}\n\n getContentHeadings(content: string): TableOfContentItem[] {\n return this.extractHeadings(content);\n }\n\n private extractHeadings(content: string): TableOfContentItem[] {\n const markdownHeadings = this.extractHeadingsFromMarkdown(content);\n if (markdownHeadings.length > 0) {\n return markdownHeadings;\n }\n\n const htmlHeadings = this.extractHeadingsFromHtml(content);\n return htmlHeadings;\n }\n\n private extractHeadingsFromMarkdown(content: string): TableOfContentItem[] {\n const lines = content.split('\\n');\n const toc: TableOfContentItem[] = [];\n const slugCounts = new Map<string, number>();\n\n for (const line of lines) {\n const match = /^(#{1,6})\\s+(.+?)\\s*$/.exec(line);\n if (!match) {\n continue;\n }\n\n const level = match[1].length;\n const text = match[2].trim();\n if (!text) {\n continue;\n }\n\n const baseSlug = text\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .trim()\n .replace(/\\s+/g, '-');\n const count = slugCounts.get(baseSlug) ?? 0;\n slugCounts.set(baseSlug, count + 1);\n const id = count === 0 ? baseSlug : `${baseSlug}-${count}`;\n\n toc.push({ id, level, text });\n }\n\n return toc;\n }\n\n private extractHeadingsFromHtml(content: string): TableOfContentItem[] {\n const toc: TableOfContentItem[] = [];\n const slugCounts = new Map<string, number>();\n const headingRegex = /<h([1-6])([^>]*)>([\\s\\S]*?)<\\/h\\1>/gi;\n\n for (const match of content.matchAll(headingRegex)) {\n const level = Number(match[1]);\n const attrs = match[2] ?? '';\n const rawInner = match[3] ?? '';\n const text = rawInner.replace(/<[^>]+>/g, '').trim();\n if (!text) {\n continue;\n }\n\n const idMatch =\n /\\sid=(['\"])(.*?)\\1/i.exec(attrs) ?? /\\sid=([^\\s>]+)/i.exec(attrs);\n let id = idMatch?.[2] ?? idMatch?.[1] ?? '';\n if (!id) {\n id = this.makeSlug(text, slugCounts);\n }\n\n toc.push({ id, level, text });\n }\n\n return toc;\n }\n\n private makeSlug(text: string, slugCounts: Map<string, number>): string {\n const baseSlug = text\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .trim()\n .replace(/\\s+/g, '-');\n const count = slugCounts.get(baseSlug) ?? 0;\n slugCounts.set(baseSlug, count + 1);\n return count === 0 ? baseSlug : `${baseSlug}-${count}`;\n }\n}\n","/**\n * Returns the list of content files by filename with ?analog-content-list=true.\n * We use the query param to transform the return into an array of\n * just front matter attributes.\n *\n * @returns\n */\nexport const getContentFilesList = () => {\n let ANALOG_CONTENT_FILE_LIST = {};\n\n return ANALOG_CONTENT_FILE_LIST as Record<string, Record<string, any>>;\n};\n\n/**\n * Returns the lazy loaded content files for lookups.\n *\n * @returns\n */\nexport const getContentFiles = () => {\n let ANALOG_CONTENT_ROUTE_FILES = {};\n\n return ANALOG_CONTENT_ROUTE_FILES;\n};\n","import { InjectionToken } from '@angular/core';\nimport { ContentFile } from './content-file';\nimport { getContentFilesList } from './get-content-files';\n\nfunction getSlug(filename: string) {\n // Extract the last path segment without its extension.\n // Handles names with dots like [[...slug]].md by stripping only the final extension.\n const lastSegment = (filename.split(/[/\\\\]/).pop() || '').trim();\n const base = lastSegment.replace(/\\.[^./\\\\]+$/, ''); // strip only the final extension\n // Treat index.md as index route => empty slug\n return base === 'index' ? '' : base;\n}\n\nexport const CONTENT_FILES_LIST_TOKEN = new InjectionToken<ContentFile[]>(\n '@analogjs/content Content Files List',\n {\n providedIn: 'root',\n factory() {\n const contentFiles = getContentFilesList();\n\n return Object.keys(contentFiles).map((filename) => {\n const attributes = contentFiles[filename];\n const slug = attributes['slug'];\n\n return {\n filename,\n attributes,\n slug: slug ? encodeURI(slug) : encodeURI(getSlug(filename)),\n };\n });\n },\n },\n);\n","import { InjectionToken, Signal, inject, signal } from '@angular/core';\n\nimport { getContentFiles } from './get-content-files';\nimport { CONTENT_FILES_LIST_TOKEN } from './content-files-list-token';\n\nexport const CONTENT_FILES_TOKEN = new InjectionToken<\n Record<string, () => Promise<string>>\n>('@analogjs/content Content Files', {\n providedIn: 'root',\n factory() {\n const contentFiles = getContentFiles();\n const allFiles = { ...contentFiles };\n const contentFilesList = inject(CONTENT_FILES_LIST_TOKEN);\n\n const lookup: Record<string, string> = {};\n contentFilesList.forEach((item) => {\n const contentFilename = item.filename.replace(\n /(.*?)\\/content/,\n '/src/content',\n );\n const fileParts = contentFilename.split('/');\n const filePath = fileParts.slice(0, fileParts.length - 1).join('/');\n const fileNameParts = fileParts[fileParts.length - 1].split('.');\n const ext = fileNameParts[fileNameParts.length - 1];\n let slug = (item.slug ?? '') as string;\n // Default empty slug to 'index'\n if (slug === '') {\n slug = 'index';\n }\n // If slug contains path separators, treat it as root-relative to /src/content\n const newBase = slug.includes('/')\n ? `/src/content/${slug}`\n : `${filePath}/${slug}`;\n lookup[contentFilename] = `${newBase}.${ext}`.replace(/\\/{2,}/g, '/');\n });\n\n const objectUsingSlugAttribute: Record<string, () => Promise<string>> = {};\n Object.entries(allFiles).forEach((entry) => {\n const filename = entry[0];\n const value = entry[1];\n const strippedFilename = filename.replace(\n /^\\/(.*?)\\/content/,\n '/src/content',\n );\n\n const newFilename = lookup[strippedFilename];\n if (newFilename !== undefined) {\n const objectFilename = newFilename.replace(\n /^\\/(.*?)\\/content/,\n '/src/content',\n );\n objectUsingSlugAttribute[objectFilename] =\n value as () => Promise<string>;\n }\n });\n\n return objectUsingSlugAttribute;\n },\n});\n\nexport const CONTENT_FILES_MAP_TOKEN = new InjectionToken<\n Signal<Record<string, () => Promise<string>>>\n>('@analogjs/content Content Files', {\n providedIn: 'root',\n factory() {\n return signal(inject(CONTENT_FILES_TOKEN));\n },\n});\n","import fm from 'front-matter';\n\nexport function parseRawContentFile<Attributes extends Record<string, any>>(\n rawContentFile: string,\n): { content: string; attributes: Attributes } {\n const { body, attributes } = fm<Attributes>(rawContentFile);\n return { content: body, attributes };\n}\n","import { firstValueFrom, isObservable, Observable } from 'rxjs';\n\ndeclare const Zone: any;\n\nexport async function waitFor<T>(prom: Promise<T> | Observable<T>): Promise<T> {\n if (isObservable(prom)) {\n prom = firstValueFrom(prom);\n }\n\n if (typeof Zone === 'undefined') {\n return prom;\n }\n\n const macroTask = Zone.current.scheduleMacroTask(\n `AnalogContentResolve-${Math.random()}`,\n () => {},\n {},\n () => {},\n );\n return prom.then((p: T) => {\n macroTask.invoke();\n return p;\n });\n}\n","import { Injectable, inject } from '@angular/core';\nimport { ɵPendingTasksInternal as ɵPendingTasks } from '@angular/core';\n\n@Injectable()\nexport class RenderTaskService {\n #pendingTasks = inject(ɵPendingTasks);\n\n addRenderTask() {\n return this.#pendingTasks.add();\n }\n\n clearRenderTask(clear: number | Function) {\n if (typeof clear === 'function') {\n clear();\n } else if (typeof (this.#pendingTasks as any).remove === 'function') {\n (this.#pendingTasks as any).remove(clear);\n }\n }\n}\n","/// <reference types=\"vite/client\" />\n\nimport { inject } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { from, Observable, of } from 'rxjs';\nimport { map, switchMap, tap } from 'rxjs/operators';\n\nimport { ContentFile } from './content-file';\nimport { ContentRenderer } from './content-renderer';\nimport { CONTENT_FILES_TOKEN } from './content-files-token';\nimport { parseRawContentFile } from './parse-raw-content-file';\nimport { waitFor } from './utils/zone-wait-for';\nimport { RenderTaskService } from './render-task.service';\n\nfunction getContentFile<\n Attributes extends Record<string, any> = Record<string, any>,\n>(\n contentFiles: Record<string, () => Promise<string>>,\n prefix: string,\n slug: string,\n fallback: string,\n renderTaskService: RenderTaskService,\n contentRenderer: ContentRenderer,\n): Observable<ContentFile<Attributes | Record<string, never>>> {\n // Normalize file keys so both \"/src/content/...\" and \"/<project>/src/content/...\" resolve.\n const normalizedFiles: Record<string, () => Promise<string>> = {};\n for (const [key, resolver] of Object.entries(contentFiles)) {\n const normalizedKey = key\n .replace(/^(?:.*)\\/content/, '/src/content')\n .replace(/\\/{2,}/g, '/');\n normalizedFiles[normalizedKey] = resolver as () => Promise<string>;\n }\n\n const base = `/src/content/${prefix}${slug}`.replace(/\\/{2,}/g, '/');\n const candidates = [\n `${base}.md`,\n `${base}.agx`,\n `${base}/index.md`,\n `${base}/index.agx`,\n ];\n\n const matchKey = candidates.find((k) => k in normalizedFiles);\n const contentFile = matchKey ? normalizedFiles[matchKey] : undefined;\n const resolvedBase = (matchKey || `${base}.md`).replace(/\\.(md|agx)$/, '');\n\n if (!contentFile) {\n return of({\n filename: resolvedBase,\n attributes: {},\n slug: '',\n content: fallback,\n toc: [],\n });\n }\n\n const contentTask = renderTaskService.addRenderTask();\n return new Observable<string | { default: any; metadata: any }>(\n (observer) => {\n const contentResolver = contentFile();\n\n if (import.meta.env.SSR === true) {\n waitFor(contentResolver).then((content) => {\n observer.next(content);\n observer.complete();\n\n setTimeout(() => renderTaskService.clearRenderTask(contentTask), 10);\n });\n } else {\n contentResolver.then((content) => {\n observer.next(content);\n observer.complete();\n });\n }\n },\n ).pipe(\n switchMap((contentFile) => {\n if (typeof contentFile === 'string') {\n const { content, attributes } =\n parseRawContentFile<Attributes>(contentFile);\n return from(contentRenderer.render(content)).pipe(\n map((rendered) => ({\n filename: resolvedBase,\n slug,\n attributes,\n content,\n toc: rendered.toc ?? [],\n })),\n );\n }\n return of({\n filename: resolvedBase,\n slug,\n attributes: contentFile.metadata,\n content: contentFile.default,\n toc: [],\n });\n }),\n );\n}\n\n/**\n * Retrieves the static content using the provided param and/or prefix.\n *\n * @param param route parameter (default: 'slug')\n * @param fallback fallback text if content file is not found (default: 'No Content Found')\n */\nexport function injectContent<\n Attributes extends Record<string, any> = Record<string, any>,\n>(\n param:\n | string\n | {\n param: string;\n subdirectory: string;\n }\n | {\n customFilename: string;\n } = 'slug',\n fallback = 'No Content Found',\n): Observable<ContentFile<Attributes | Record<string, never>>> {\n const contentFiles = inject(CONTENT_FILES_TOKEN);\n const contentRenderer = inject(ContentRenderer);\n const renderTaskService = inject(RenderTaskService);\n const task = renderTaskService.addRenderTask();\n\n if (typeof param === 'string' || 'param' in param) {\n const prefix = typeof param === 'string' ? '' : `${param.subdirectory}/`;\n const route = inject(ActivatedRoute);\n const paramKey = typeof param === 'string' ? param : param.param;\n return route.paramMap.pipe(\n map((params) => params.get(paramKey)),\n switchMap((slug) => {\n if (slug) {\n return getContentFile<Attributes>(\n contentFiles,\n prefix,\n slug,\n fallback,\n renderTaskService,\n contentRenderer,\n );\n }\n return of({\n filename: '',\n slug: '',\n attributes: {},\n content: fallback,\n toc: [],\n });\n }),\n tap(() => renderTaskService.clearRenderTask(task)),\n );\n } else {\n return getContentFile<Attributes>(\n contentFiles,\n '',\n param.customFilename,\n fallback,\n renderTaskService,\n contentRenderer,\n ).pipe(tap(() => renderTaskService.clearRenderTask(task)));\n }\n}\n","import { inject } from '@angular/core';\n\nimport { ContentFile } from './content-file';\nimport { CONTENT_FILES_LIST_TOKEN } from './content-files-list-token';\nimport { CONTENT_FILES_TOKEN } from './content-files-token';\nimport { RenderTaskService } from './render-task.service';\n\nexport function injectContentFiles<Attributes extends Record<string, any>>(\n filterFn?: InjectContentFilesFilterFunction<Attributes>,\n): ContentFile<Attributes>[] {\n const renderTaskService = inject(RenderTaskService);\n const task = renderTaskService.addRenderTask();\n const allContentFiles = inject(\n CONTENT_FILES_LIST_TOKEN,\n ) as ContentFile<Attributes>[];\n renderTaskService.clearRenderTask(task);\n\n if (filterFn) {\n const filteredContentFiles = allContentFiles.filter(filterFn);\n\n return filteredContentFiles;\n }\n\n return allContentFiles;\n}\n\nexport type InjectContentFilesFilterFunction<T extends Record<string, any>> = (\n value: ContentFile<T>,\n index: number,\n array: ContentFile<T>[],\n) => boolean;\n\nexport function injectContentFilesMap() {\n return inject(CONTENT_FILES_TOKEN);\n}\n","import {\n AbstractType,\n Injectable,\n Provider,\n ProviderToken,\n Type,\n} from '@angular/core';\n\nexport interface MarkedContentHighlighter {\n augmentCodeBlock?(code: string, lang: string): string;\n}\n\n@Injectable()\nexport abstract class MarkedContentHighlighter {\n abstract getHighlightExtension(): import('marked').MarkedExtension;\n}\n\nexport function withHighlighter(\n provider: (\n | { useValue: MarkedContentHighlighter }\n | {\n useClass:\n | Type<MarkedContentHighlighter>\n | AbstractType<MarkedContentHighlighter>;\n }\n | { useFactory: (...deps: any[]) => MarkedContentHighlighter }\n ) & { deps?: ProviderToken<any>[] },\n): Provider {\n return { provide: MarkedContentHighlighter, ...provider } as Provider;\n}\n","/**\n * Credit goes to Scully for original implementation\n * https://github.com/scullyio/scully/blob/main/libs/scully/src/lib/fileHanderPlugins/markdown.ts\n */\nimport { inject, Injectable } from '@angular/core';\nimport { marked } from 'marked';\nimport { gfmHeadingId } from 'marked-gfm-heading-id';\nimport { mangle } from 'marked-mangle';\nimport { MarkedContentHighlighter } from './marked-content-highlighter';\n\n@Injectable()\nexport class MarkedSetupService {\n private readonly marked: typeof marked;\n private readonly highlighter = inject(MarkedContentHighlighter, {\n optional: true,\n });\n\n constructor() {\n const renderer = new marked.Renderer();\n renderer.code = ({ text, lang }) => {\n // Let's do a language based detection like on GitHub\n // So we can still have non-interpreted mermaid code\n if (lang === 'mermaid') {\n return '<pre class=\"mermaid\">' + text + '</pre>';\n }\n\n if (!lang) {\n return '<pre><code>' + text + '</code></pre>';\n }\n\n if (this.highlighter?.augmentCodeBlock) {\n return this.highlighter?.augmentCodeBlock(text, lang);\n }\n\n return `<pre class=\"language-${lang}\"><code class=\"language-${lang}\">${text}</code></pre>`;\n };\n\n const extensions = [gfmHeadingId(), mangle()];\n\n if (this.highlighter) {\n extensions.push(this.highlighter.getHighlightExtension());\n }\n\n marked.use(...extensions, {\n renderer,\n pedantic: false,\n gfm: true,\n breaks: false,\n });\n\n this.marked = marked;\n }\n\n getMarkedInstance(): typeof marked {\n return this.marked;\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { getHeadingList } from 'marked-gfm-heading-id';\n\nimport {\n ContentRenderer,\n RenderedContent,\n TableOfContentItem,\n} from './content-renderer';\nimport { MarkedSetupService } from './marked-setup.service';\n\n@Injectable()\nexport class MarkdownContentRendererService implements ContentRenderer {\n #marked = inject(MarkedSetupService, { self: true });\n\n async render(content: string): Promise<RenderedContent> {\n const renderedContent = await this.#marked\n .getMarkedInstance()\n .parse(content);\n return {\n content: renderedContent,\n toc: getHeadingList(),\n };\n }\n\n getContentHeadings(content: string): TableOfContentItem[] {\n return [...content.matchAll(/^(#{1,6})\\s+(.+?)\\s*$/gm)].map((match) => ({\n id: match[2]\n .trim()\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/\\s+/g, '-'),\n level: match[1].length,\n text: match[2].trim(),\n }));\n }\n\n // eslint-disable-next-line\n enhance() {}\n}\n","import { InjectionToken, Provider } from '@angular/core';\nimport { inject } from '@angular/core';\n\nimport { injectContentFilesMap } from './inject-content-files';\n\ntype ContentFileLoaderFunction = () => Promise<\n Record<string, () => Promise<string>>\n>;\n\nexport const CONTENT_FILE_LOADER =\n new InjectionToken<ContentFileLoaderFunction>(\n '@analogjs/content/resource File Loader',\n );\n\nexport function injectContentFileLoader() {\n return inject(CONTENT_FILE_LOADER) as ContentFileLoaderFunction;\n}\n\nexport function withContentFileLoader(): Provider {\n return {\n provide: CONTENT_FILE_LOADER,\n useFactory() {\n return async () => injectContentFilesMap();\n },\n };\n}\n","import { InjectionToken, Provider } from '@angular/core';\nimport { inject } from '@angular/core';\n\nimport { ContentFile } from './content-file';\nimport { injectContentFiles } from './inject-content-files';\n\ntype ContentListLoaderFunction<Attributes extends Record<string, any>> =\n () => Promise<ContentFile<Attributes>[]>;\n\nexport const CONTENT_LIST_LOADER = new InjectionToken<\n ContentListLoaderFunction<any>\n>('@analogjs/content/resource List Loader');\n\nexport function injectContentListLoader<\n Attributes extends Record<string, any>,\n>() {\n return inject(CONTENT_LIST_LOADER) as ContentListLoaderFunction<Attributes>;\n}\n\nexport function withContentListLoader(): Provider {\n return {\n provide: CONTENT_LIST_LOADER,\n useFactory() {\n return async () => injectContentFiles();\n },\n };\n}\n","import { Provider, InjectionToken } from '@angular/core';\nimport { ContentRenderer, NoopContentRenderer } from './content-renderer';\nimport { RenderTaskService } from './render-task.service';\nimport { withContentFileLoader } from './content-file-loader';\nimport { withContentListLoader } from './content-list-loader';\n\nexport interface MarkdownRendererOptions {\n loadMermaid?: () => Promise<typeof import('mermaid')>;\n}\n\nconst CONTENT_RENDERER_PROVIDERS: Provider[] = [\n {\n provide: ContentRenderer,\n useClass: NoopContentRenderer,\n },\n withContentFileLoader(),\n withContentListLoader(),\n];\n\nexport function withMarkdownRenderer(\n options?: MarkdownRendererOptions,\n): Provider {\n return [\n CONTENT_RENDERER_PROVIDERS,\n options?.loadMermaid\n ? [\n {\n provide: MERMAID_IMPORT_TOKEN,\n useFactory: options.loadMermaid,\n },\n ]\n : [],\n ];\n}\n\nexport function provideContent(...features: Provider[]) {\n return [\n { provide: RenderTaskService, useClass: RenderTaskService },\n ...features,\n ];\n}\n\nexport const MERMAID_IMPORT_TOKEN = new InjectionToken<\n Promise<typeof import('mermaid')>\n>('mermaid_import');\n","import { AsyncPipe } from '@angular/common';\nimport {\n AfterViewChecked,\n Component,\n inject,\n Input,\n ViewEncapsulation,\n} from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { ContentRenderer } from './content-renderer';\nimport { AnchorNavigationDirective } from './anchor-navigation.directive';\n\n@Component({\n selector: 'analog-markdown-route',\n standalone: true,\n imports: [AsyncPipe],\n hostDirectives: [AnchorNavigationDirective],\n preserveWhitespaces: true,\n encapsulation: ViewEncapsulation.None,\n template: `<div [innerHTML]=\"content\" [class]=\"classes\"></div>`,\n})\nexport default class AnalogMarkdownRouteComponent implements AfterViewChecked {\n private sanitizer = inject(DomSanitizer);\n private route = inject(ActivatedRoute);\n contentRenderer = inject(ContentRenderer);\n\n protected content: SafeHtml = this.sanitizer.bypassSecurityTrustHtml(\n this.route.snapshot.data['renderedAnalogContent'],\n );\n\n @Input() classes = 'analog-markdown-route';\n\n ngAfterViewChecked() {\n this.contentRenderer.enhance();\n }\n}\n","import { isPlatformBrowser } from '@angular/common';\nimport {\n AfterViewChecked,\n Component,\n NgZone,\n PLATFORM_ID,\n Signal,\n ViewEncapsulation,\n computed,\n inject,\n input,\n} from '@angular/core';\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { ActivatedRoute, Data } from '@angular/router';\nimport { from, of } from 'rxjs';\nimport { catchError, map, switchMap } from 'rxjs/operators';\n\nimport { AnchorNavigationDirective } from './anchor-navigation.directive';\nimport { ContentRenderer } from './content-renderer';\nimport { MERMAID_IMPORT_TOKEN } from './provide-content';\n\n@Component({\n selector: 'analog-markdown',\n standalone: true,\n hostDirectives: [AnchorNavigationDirective],\n preserveWhitespaces: true,\n encapsulation: ViewEncapsulation.None,\n template: ` <div [innerHTML]=\"htmlContent()\" [class]=\"classes()\"></div> `,\n})\nexport default class AnalogMarkdownComponent implements AfterViewChecked {\n private sanitizer = inject(DomSanitizer);\n private route = inject(ActivatedRoute);\n private zone = inject(NgZone);\n private readonly platformId = inject(PLATFORM_ID);\n private readonly mermaidImport = inject(MERMAID_IMPORT_TOKEN, {\n optional: true,\n });\n private mermaid: typeof import('mermaid') | undefined;\n\n private contentSource: Signal<SafeHtml | string | undefined> = toSignal(\n this.getContentSource(),\n );\n readonly htmlContent = computed(() => {\n const inputContent = this.content();\n\n if (inputContent) {\n return this.sanitizer.bypassSecurityTrustHtml(inputContent as string);\n }\n\n return this.contentSource();\n });\n readonly content = input<string | object | null>();\n readonly classes = input('analog-markdown');\n\n contentRenderer = inject(ContentRenderer);\n\n constructor() {\n if (isPlatformBrowser(this.platformId) && this.mermaidImport) {\n // Mermaid can only be loaded on client side\n this.loadMermaid(this.mermaidImport);\n }\n }\n\n getContentSource() {\n return this.route.data.pipe(\n map<Data, string>((data) => data['_analogContent'] ?? ''),\n switchMap((contentString) => this.renderContent(contentString)),\n map((content) => this.sanitizer.bypassSecurityTrustHtml(content)),\n catchError((e) => of(`There was an error ${e}`)),\n );\n }\n\n async renderContent(content: string): Promise<string> {\n const rendered = await this.contentRenderer.render(content);\n return rendered.content;\n }\n\n ngAfterViewChecked() {\n this.contentRenderer.enhance();\n this.zone.runOutsideAngular(() => this.mermaid?.default.run());\n }\n\n private loadMermaid(mermaidImport: Promise<typeof import('mermaid')>) {\n this.zone.runOutsideAngular(() =>\n // Wrap into an observable to avoid redundant initialization once\n // the markdown component is destroyed before the promise is resolved.\n from(mermaidImport)\n .pipe(takeUntilDestroyed())\n .subscribe((mermaid) => {\n this.mermaid = mermaid;\n this.mermaid.default.initialize({ startOnLoad: false });\n // Explicitly running mermaid as ngAfterViewChecked\n // has probably already been called\n this.mermaid?.default.run();\n }),\n );\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["ɵPendingTasks"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"analogjs-content.mjs","sources":["../../../../packages/content/src/lib/anchor-navigation.directive.ts","../../../../packages/content/src/lib/content-renderer.ts","../../../../packages/content/src/lib/content-locale.ts","../../../../packages/content/src/lib/get-content-files.ts","../../../../packages/content/src/lib/content-files-list-token.ts","../../../../packages/content/src/lib/content-files-token.ts","../../../../packages/content/src/lib/parse-raw-content-file.ts","../../../../packages/content/src/lib/utils/zone-wait-for.ts","../../../../packages/content/src/lib/render-task.service.ts","../../../../packages/content/src/lib/content.ts","../../../../packages/content/src/lib/inject-content-files.ts","../../../../packages/content/src/lib/marked-content-highlighter.ts","../../../../packages/content/src/lib/marked-setup.service.ts","../../../../packages/content/src/lib/markdown-content-renderer.service.ts","../../../../packages/content/src/lib/content-file-loader.ts","../../../../packages/content/src/lib/content-list-loader.ts","../../../../packages/content/src/lib/provide-content.ts","../../../../packages/content/src/lib/markdown-route.component.ts","../../../../packages/content/src/lib/markdown.component.ts","../../../../packages/content/src/analogjs-content.ts"],"sourcesContent":["import { Directive, HostListener, inject } from '@angular/core';\nimport { DOCUMENT, Location } from '@angular/common';\nimport { Router } from '@angular/router';\n\n@Directive({\n selector: '[analogAnchorNavigation]',\n standalone: true,\n})\nexport class AnchorNavigationDirective {\n private readonly document = inject(DOCUMENT);\n private readonly location = inject(Location);\n private readonly router = inject(Router);\n\n @HostListener('click', ['$event.target'])\n handleNavigation(element: EventTarget | null): boolean {\n if (\n element instanceof HTMLAnchorElement &&\n isInternalUrl(element, this.document) &&\n hasTargetSelf(element) &&\n !hasDownloadAttribute(element)\n ) {\n const { pathname, search, hash } = element;\n const url = this.location.normalize(`${pathname}${search}${hash}`);\n this.router.navigateByUrl(url);\n\n return false;\n }\n\n return true;\n }\n}\n\nfunction hasDownloadAttribute(anchorElement: HTMLAnchorElement): boolean {\n return anchorElement.getAttribute('download') !== null;\n}\n\nfunction hasTargetSelf(anchorElement: HTMLAnchorElement): boolean {\n return !anchorElement.target || anchorElement.target === '_self';\n}\n\nfunction isInternalUrl(\n anchorElement: HTMLAnchorElement,\n document: Document,\n): boolean {\n return (\n anchorElement.host === document.location.host &&\n anchorElement.protocol === document.location.protocol\n );\n}\n","/// <reference types=\"vite/client\" />\n\nimport { Injectable, TransferState, inject, makeStateKey } from '@angular/core';\n\nexport type TableOfContentItem = {\n id: string;\n level: number; // starts at 1\n text: string;\n};\n\nexport type RenderedContent = {\n content: string;\n toc: TableOfContentItem[];\n};\n\n@Injectable()\nexport abstract class ContentRenderer {\n async render(content: string): Promise<RenderedContent> {\n return { content, toc: [] };\n }\n\n // Backward-compatible API for consumers that read headings directly.\n getContentHeadings(_content: string): TableOfContentItem[] {\n return [];\n }\n\n // eslint-disable-next-line\n enhance() {}\n}\n\nexport class NoopContentRenderer implements ContentRenderer {\n private readonly transferState = inject(TransferState);\n private contentId = 0;\n\n /**\n * Generates a hash from the content string\n * to be used with the transfer state\n */\n private generateHash(str: string) {\n let hash = 0;\n for (let i = 0, len = str.length; i < len; i++) {\n let chr = str.charCodeAt(i);\n hash = (hash << 5) - hash + chr;\n hash |= 0; // Convert to 32bit integer\n }\n return hash;\n }\n\n async render(content: string): Promise<RenderedContent> {\n this.contentId = this.generateHash(content);\n const toc = this.getContentHeadings(content);\n const key = makeStateKey<TableOfContentItem[]>(\n `content-headings-${this.contentId}`,\n );\n\n if (import.meta.env.SSR === true) {\n this.transferState.set(key, toc);\n return { content, toc };\n }\n\n return {\n content,\n toc: this.transferState.get(key, toc),\n };\n }\n enhance() {}\n\n getContentHeadings(content: string): TableOfContentItem[] {\n return this.extractHeadings(content);\n }\n\n private extractHeadings(content: string): TableOfContentItem[] {\n const markdownHeadings = this.extractHeadingsFromMarkdown(content);\n if (markdownHeadings.length > 0) {\n return markdownHeadings;\n }\n\n const htmlHeadings = this.extractHeadingsFromHtml(content);\n return htmlHeadings;\n }\n\n private extractHeadingsFromMarkdown(content: string): TableOfContentItem[] {\n const lines = content.split('\\n');\n const toc: TableOfContentItem[] = [];\n const slugCounts = new Map<string, number>();\n\n for (const line of lines) {\n const match = /^(#{1,6})\\s+(.+?)\\s*$/.exec(line);\n if (!match) {\n continue;\n }\n\n const level = match[1].length;\n const text = match[2].trim();\n if (!text) {\n continue;\n }\n\n const baseSlug = text\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .trim()\n .replace(/\\s+/g, '-');\n const count = slugCounts.get(baseSlug) ?? 0;\n slugCounts.set(baseSlug, count + 1);\n const id = count === 0 ? baseSlug : `${baseSlug}-${count}`;\n\n toc.push({ id, level, text });\n }\n\n return toc;\n }\n\n private extractHeadingsFromHtml(content: string): TableOfContentItem[] {\n const toc: TableOfContentItem[] = [];\n const slugCounts = new Map<string, number>();\n const headingRegex = /<h([1-6])([^>]*)>([\\s\\S]*?)<\\/h\\1>/gi;\n\n for (const match of content.matchAll(headingRegex)) {\n const level = Number(match[1]);\n const attrs = match[2] ?? '';\n const rawInner = match[3] ?? '';\n const text = rawInner.replace(/<[^>]+>/g, '').trim();\n if (!text) {\n continue;\n }\n\n const idMatch =\n /\\sid=(['\"])(.*?)\\1/i.exec(attrs) ?? /\\sid=([^\\s>]+)/i.exec(attrs);\n let id = idMatch?.[2] ?? idMatch?.[1] ?? '';\n if (!id) {\n id = this.makeSlug(text, slugCounts);\n }\n\n toc.push({ id, level, text });\n }\n\n return toc;\n }\n\n private makeSlug(text: string, slugCounts: Map<string, number>): string {\n const baseSlug = text\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .trim()\n .replace(/\\s+/g, '-');\n const count = slugCounts.get(baseSlug) ?? 0;\n slugCounts.set(baseSlug, count + 1);\n return count === 0 ? baseSlug : `${baseSlug}-${count}`;\n }\n}\n","import { InjectionToken, inject, Provider } from '@angular/core';\n\nimport { ContentFile } from './content-file';\n\n/**\n * Token for the active content locale.\n * Provided via `withLocale()` in `provideContent()`.\n *\n * When set, `injectContentFiles()` filters to content matching this locale,\n * and `injectContent()` resolves locale-prefixed content paths first.\n */\nexport const CONTENT_LOCALE = new InjectionToken<string>(\n '@analogjs/content Locale',\n);\n\n/**\n * Injects the content locale, returning null if not configured.\n */\nexport function injectContentLocale(): string | null {\n return inject(CONTENT_LOCALE, { optional: true });\n}\n\nexport interface ContentLocaleOptions {\n /**\n * Function that returns the active locale.\n * Runs in injection context so `inject()` can be used to read\n * from other tokens (e.g., a LOCALE token from a router package).\n *\n * ```typescript\n * withLocale({ loadLocale: injectLocale })\n * withLocale({ loadLocale: () => navigator.language.split('-')[0] })\n * ```\n */\n loadLocale: () => string | null;\n}\n\n/**\n * Content feature that sets the active locale for content resolution.\n *\n * When provided, content APIs become locale-aware:\n * - `injectContentFiles()` filters to files in the locale subdirectory\n * or with a matching `locale` frontmatter attribute.\n * - `injectContent()` tries locale-prefixed paths first\n * (e.g., `content/fr/blog/post.md` before `content/blog/post.md`).\n *\n * Usage:\n * ```typescript\n * // With loader — runs in injection context\n * provideContent(\n * withMarkdownRenderer(),\n * withLocale({ loadLocale: injectLocale }),\n * )\n *\n * // Static locale\n * provideContent(\n * withMarkdownRenderer(),\n * withLocale('fr'),\n * )\n * ```\n */\nexport function withLocale(locale: string | ContentLocaleOptions): Provider {\n if (typeof locale === 'string') {\n return { provide: CONTENT_LOCALE, useValue: locale };\n }\n\n return { provide: CONTENT_LOCALE, useFactory: locale.loadLocale };\n}\n\n/**\n * Filters content files by locale using map-based key lookup.\n *\n * Matching rules:\n * 1. Frontmatter `locale` attribute matches the active locale.\n * 2. File is in the active locale subdirectory (e.g., `/content/fr/blog/post`).\n * 3. File has no locale marker and no localized variant exists — included as universal content.\n *\n * Files in a different locale's subdirectory are always excluded.\n */\nexport function filterByLocale<T extends Record<string, any>>(\n files: ContentFile<T>[],\n locale: string,\n): ContentFile<T>[] {\n const localePrefix = `/content/${locale}/`;\n\n // Collect all locale prefixes present in the file set\n const allLocalePrefixes = new Set<string>();\n for (const file of files) {\n const match = file.filename.match(/\\/content\\/([a-z]{2}(?:-[a-zA-Z]+)?)\\//);\n if (match) {\n allLocalePrefixes.add(`/content/${match[1]}/`);\n }\n }\n\n // Build set of base paths that have a localized variant for the active locale\n const localizedBasePaths = new Set<string>();\n for (const file of files) {\n if (file.filename.includes(localePrefix)) {\n localizedBasePaths.add(file.filename.replace(localePrefix, '/content/'));\n }\n }\n\n return files.filter((file) => {\n // Frontmatter locale attribute takes priority\n if (file.attributes['locale']) {\n return file.attributes['locale'] === locale;\n }\n // File is in the active locale subdirectory — include\n if (file.filename.includes(localePrefix)) {\n return true;\n }\n // File is in a different locale's subdirectory — exclude\n for (const prefix of allLocalePrefixes) {\n if (prefix !== localePrefix && file.filename.includes(prefix)) {\n return false;\n }\n }\n // Universal content — include only if no localized variant exists\n return !localizedBasePaths.has(file.filename);\n });\n}\n\n/**\n * Prepends locale-prefixed candidates before the standard candidates\n * for content file map key lookup.\n */\nexport function withLocaleCandidates(\n candidates: string[],\n locale: string | null | undefined,\n): string[] {\n if (!locale) {\n return candidates;\n }\n const localeCandidates = candidates.map((c) =>\n c.replace('/src/content/', `/src/content/${locale}/`),\n );\n return [...localeCandidates, ...candidates];\n}\n","/**\n * Returns the list of content files by filename with ?analog-content-list=true.\n * We use the query param to transform the return into an array of\n * just front matter attributes.\n *\n * @returns\n */\nexport const getContentFilesList = () => {\n let ANALOG_CONTENT_FILE_LIST = {};\n\n return ANALOG_CONTENT_FILE_LIST as Record<string, Record<string, any>>;\n};\n\n/**\n * Returns the lazy loaded content files for lookups.\n *\n * @returns\n */\nexport const getContentFiles = () => {\n let ANALOG_CONTENT_ROUTE_FILES = {};\n\n return ANALOG_CONTENT_ROUTE_FILES;\n};\n","import { InjectionToken } from '@angular/core';\nimport { ContentFile } from './content-file';\nimport { getContentFilesList } from './get-content-files';\n\nfunction getSlug(filename: string) {\n // Extract the last path segment without its extension.\n // Handles names with dots like [[...slug]].md by stripping only the final extension.\n const lastSegment = (filename.split(/[/\\\\]/).pop() || '').trim();\n const base = lastSegment.replace(/\\.[^./\\\\]+$/, ''); // strip only the final extension\n // Treat index.md as index route => empty slug\n return base === 'index' ? '' : base;\n}\n\nexport const CONTENT_FILES_LIST_TOKEN = new InjectionToken<ContentFile[]>(\n '@analogjs/content Content Files List',\n {\n providedIn: 'root',\n factory() {\n const contentFiles = getContentFilesList();\n\n return Object.keys(contentFiles).map((filename) => {\n const attributes = contentFiles[filename];\n const slug = attributes['slug'];\n\n return {\n filename,\n attributes,\n slug: slug ? encodeURI(slug) : encodeURI(getSlug(filename)),\n };\n });\n },\n },\n);\n","import { InjectionToken, Signal, inject, signal } from '@angular/core';\n\nimport { getContentFiles } from './get-content-files';\nimport { CONTENT_FILES_LIST_TOKEN } from './content-files-list-token';\n\nexport const CONTENT_FILES_TOKEN = new InjectionToken<\n Record<string, () => Promise<string>>\n>('@analogjs/content Content Files', {\n providedIn: 'root',\n factory() {\n const contentFiles = getContentFiles();\n const allFiles = { ...contentFiles };\n const contentFilesList = inject(CONTENT_FILES_LIST_TOKEN);\n\n const lookup: Record<string, string> = {};\n contentFilesList.forEach((item) => {\n const contentFilename = item.filename.replace(\n /(.*?)\\/content/,\n '/src/content',\n );\n const fileParts = contentFilename.split('/');\n const filePath = fileParts.slice(0, fileParts.length - 1).join('/');\n const fileNameParts = fileParts[fileParts.length - 1].split('.');\n const ext = fileNameParts[fileNameParts.length - 1];\n let slug = (item.slug ?? '') as string;\n // Default empty slug to 'index'\n if (slug === '') {\n slug = 'index';\n }\n // If slug contains path separators, treat it as root-relative to /src/content\n const newBase = slug.includes('/')\n ? `/src/content/${slug}`\n : `${filePath}/${slug}`;\n lookup[contentFilename] = `${newBase}.${ext}`.replace(/\\/{2,}/g, '/');\n });\n\n const objectUsingSlugAttribute: Record<string, () => Promise<string>> = {};\n Object.entries(allFiles).forEach((entry) => {\n const filename = entry[0];\n const value = entry[1];\n const strippedFilename = filename.replace(\n /^\\/(.*?)\\/content/,\n '/src/content',\n );\n\n const newFilename = lookup[strippedFilename];\n if (newFilename !== undefined) {\n const objectFilename = newFilename.replace(\n /^\\/(.*?)\\/content/,\n '/src/content',\n );\n objectUsingSlugAttribute[objectFilename] =\n value as () => Promise<string>;\n }\n });\n\n return objectUsingSlugAttribute;\n },\n});\n\nexport const CONTENT_FILES_MAP_TOKEN = new InjectionToken<\n Signal<Record<string, () => Promise<string>>>\n>('@analogjs/content Content Files', {\n providedIn: 'root',\n factory() {\n return signal(inject(CONTENT_FILES_TOKEN));\n },\n});\n","import fm from 'front-matter';\n\nexport function parseRawContentFile<Attributes extends Record<string, any>>(\n rawContentFile: string,\n): { content: string; attributes: Attributes } {\n const { body, attributes } = fm<Attributes>(rawContentFile);\n return { content: body, attributes };\n}\n","import { firstValueFrom, isObservable, Observable } from 'rxjs';\n\ndeclare const Zone: any;\n\nexport async function waitFor<T>(prom: Promise<T> | Observable<T>): Promise<T> {\n if (isObservable(prom)) {\n prom = firstValueFrom(prom);\n }\n\n if (typeof Zone === 'undefined') {\n return prom;\n }\n\n const macroTask = Zone.current.scheduleMacroTask(\n `AnalogContentResolve-${Math.random()}`,\n () => {},\n {},\n () => {},\n );\n return prom.then((p: T) => {\n macroTask.invoke();\n return p;\n });\n}\n","import { Injectable, inject } from '@angular/core';\nimport { ɵPendingTasksInternal as ɵPendingTasks } from '@angular/core';\n\n@Injectable()\nexport class RenderTaskService {\n #pendingTasks = inject(ɵPendingTasks);\n\n addRenderTask() {\n return this.#pendingTasks.add();\n }\n\n clearRenderTask(clear: number | Function) {\n if (typeof clear === 'function') {\n clear();\n } else if (typeof (this.#pendingTasks as any).remove === 'function') {\n (this.#pendingTasks as any).remove(clear);\n }\n }\n}\n","/// <reference types=\"vite/client\" />\n\nimport { inject } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { from, Observable, of } from 'rxjs';\nimport { map, switchMap, tap } from 'rxjs/operators';\n\nimport { ContentFile } from './content-file';\nimport { ContentRenderer } from './content-renderer';\nimport { CONTENT_LOCALE, withLocaleCandidates } from './content-locale';\nimport { CONTENT_FILES_TOKEN } from './content-files-token';\nimport { parseRawContentFile } from './parse-raw-content-file';\nimport { waitFor } from './utils/zone-wait-for';\nimport { RenderTaskService } from './render-task.service';\n\nfunction getContentFile<\n Attributes extends Record<string, any> = Record<string, any>,\n>(\n contentFiles: Record<string, () => Promise<string>>,\n prefix: string,\n slug: string,\n fallback: string,\n renderTaskService: RenderTaskService,\n contentRenderer: ContentRenderer,\n locale?: string | null,\n): Observable<ContentFile<Attributes | Record<string, never>>> {\n // Normalize file keys so both \"/src/content/...\" and \"/<project>/src/content/...\" resolve.\n const normalizedFiles: Record<string, () => Promise<string>> = {};\n for (const [key, resolver] of Object.entries(contentFiles)) {\n const normalizedKey = key\n .replace(/^(?:.*)\\/content/, '/src/content')\n .replace(/\\/{2,}/g, '/');\n normalizedFiles[normalizedKey] = resolver as () => Promise<string>;\n }\n\n const base = `/src/content/${prefix}${slug}`.replace(/\\/{2,}/g, '/');\n const candidates = [\n `${base}.md`,\n `${base}.agx`,\n `${base}/index.md`,\n `${base}/index.agx`,\n ];\n\n const allCandidates = withLocaleCandidates(candidates, locale);\n const matchKey = allCandidates.find((k) => k in normalizedFiles);\n const contentFile = matchKey ? normalizedFiles[matchKey] : undefined;\n const resolvedBase = (matchKey || `${base}.md`).replace(/\\.(md|agx)$/, '');\n\n if (!contentFile) {\n return of({\n filename: resolvedBase,\n attributes: {},\n slug: '',\n content: fallback,\n toc: [],\n });\n }\n\n const contentTask = renderTaskService.addRenderTask();\n return new Observable<string | { default: any; metadata: any }>(\n (observer) => {\n const contentResolver = contentFile();\n\n if (import.meta.env.SSR === true) {\n waitFor(contentResolver).then((content) => {\n observer.next(content);\n observer.complete();\n\n setTimeout(() => renderTaskService.clearRenderTask(contentTask), 10);\n });\n } else {\n contentResolver.then((content) => {\n observer.next(content);\n observer.complete();\n });\n }\n },\n ).pipe(\n switchMap((contentFile) => {\n if (typeof contentFile === 'string') {\n const { content, attributes } =\n parseRawContentFile<Attributes>(contentFile);\n return from(contentRenderer.render(content)).pipe(\n map((rendered) => ({\n filename: resolvedBase,\n slug,\n attributes,\n content,\n toc: rendered.toc ?? [],\n })),\n );\n }\n return of({\n filename: resolvedBase,\n slug,\n attributes: contentFile.metadata,\n content: contentFile.default,\n toc: [],\n });\n }),\n );\n}\n\n/**\n * Retrieves the static content using the provided param and/or prefix.\n *\n * @param param route parameter (default: 'slug')\n * @param fallback fallback text if content file is not found (default: 'No Content Found')\n */\nexport function injectContent<\n Attributes extends Record<string, any> = Record<string, any>,\n>(\n param:\n | string\n | {\n param: string;\n subdirectory: string;\n }\n | {\n customFilename: string;\n } = 'slug',\n fallback = 'No Content Found',\n): Observable<ContentFile<Attributes | Record<string, never>>> {\n const contentFiles = inject(CONTENT_FILES_TOKEN);\n const contentRenderer = inject(ContentRenderer);\n const renderTaskService = inject(RenderTaskService);\n const locale = inject(CONTENT_LOCALE, { optional: true });\n const task = renderTaskService.addRenderTask();\n\n if (typeof param === 'string' || 'param' in param) {\n const prefix = typeof param === 'string' ? '' : `${param.subdirectory}/`;\n const route = inject(ActivatedRoute);\n const paramKey = typeof param === 'string' ? param : param.param;\n return route.paramMap.pipe(\n map((params) => params.get(paramKey)),\n switchMap((slug) => {\n if (slug) {\n return getContentFile<Attributes>(\n contentFiles,\n prefix,\n slug,\n fallback,\n renderTaskService,\n contentRenderer,\n locale,\n );\n }\n return of({\n filename: '',\n slug: '',\n attributes: {},\n content: fallback,\n toc: [],\n });\n }),\n tap(() => renderTaskService.clearRenderTask(task)),\n );\n } else {\n return getContentFile<Attributes>(\n contentFiles,\n '',\n param.customFilename,\n fallback,\n renderTaskService,\n contentRenderer,\n locale,\n ).pipe(tap(() => renderTaskService.clearRenderTask(task)));\n }\n}\n","import { inject } from '@angular/core';\n\nimport { ContentFile } from './content-file';\nimport { CONTENT_FILES_LIST_TOKEN } from './content-files-list-token';\nimport { CONTENT_FILES_TOKEN } from './content-files-token';\nimport { CONTENT_LOCALE, filterByLocale } from './content-locale';\nimport { RenderTaskService } from './render-task.service';\n\nexport function injectContentFiles<Attributes extends Record<string, any>>(\n filterFn?: InjectContentFilesFilterFunction<Attributes>,\n): ContentFile<Attributes>[] {\n const renderTaskService = inject(RenderTaskService);\n const task = renderTaskService.addRenderTask();\n const allContentFiles = inject(\n CONTENT_FILES_LIST_TOKEN,\n ) as ContentFile<Attributes>[];\n const locale = inject(CONTENT_LOCALE, { optional: true });\n renderTaskService.clearRenderTask(task);\n\n let results = allContentFiles;\n\n if (locale) {\n results = filterByLocale(results, locale);\n }\n\n if (filterFn) {\n results = results.filter(filterFn);\n }\n\n return results;\n}\n\nexport type InjectContentFilesFilterFunction<T extends Record<string, any>> = (\n value: ContentFile<T>,\n index: number,\n array: ContentFile<T>[],\n) => boolean;\n\nexport function injectContentFilesMap() {\n return inject(CONTENT_FILES_TOKEN);\n}\n","import {\n AbstractType,\n Injectable,\n Provider,\n ProviderToken,\n Type,\n} from '@angular/core';\n\nexport interface MarkedContentHighlighter {\n augmentCodeBlock?(code: string, lang: string): string;\n}\n\n@Injectable()\nexport abstract class MarkedContentHighlighter {\n abstract getHighlightExtension(): import('marked').MarkedExtension;\n}\n\nexport function withHighlighter(\n provider: (\n | { useValue: MarkedContentHighlighter }\n | {\n useClass:\n | Type<MarkedContentHighlighter>\n | AbstractType<MarkedContentHighlighter>;\n }\n | { useFactory: (...deps: any[]) => MarkedContentHighlighter }\n ) & { deps?: ProviderToken<any>[] },\n): Provider {\n return { provide: MarkedContentHighlighter, ...provider } as Provider;\n}\n","/**\n * Credit goes to Scully for original implementation\n * https://github.com/scullyio/scully/blob/main/libs/scully/src/lib/fileHanderPlugins/markdown.ts\n */\nimport { inject, Injectable } from '@angular/core';\nimport { marked } from 'marked';\nimport { gfmHeadingId } from 'marked-gfm-heading-id';\nimport { mangle } from 'marked-mangle';\nimport { MarkedContentHighlighter } from './marked-content-highlighter';\n\n@Injectable()\nexport class MarkedSetupService {\n private readonly marked: typeof marked;\n private readonly highlighter = inject(MarkedContentHighlighter, {\n optional: true,\n });\n\n constructor() {\n const renderer = new marked.Renderer();\n renderer.code = ({ text, lang }) => {\n // Let's do a language based detection like on GitHub\n // So we can still have non-interpreted mermaid code\n if (lang === 'mermaid') {\n return '<pre class=\"mermaid\">' + text + '</pre>';\n }\n\n if (!lang) {\n return '<pre><code>' + text + '</code></pre>';\n }\n\n if (this.highlighter?.augmentCodeBlock) {\n return this.highlighter?.augmentCodeBlock(text, lang);\n }\n\n return `<pre class=\"language-${lang}\"><code class=\"language-${lang}\">${text}</code></pre>`;\n };\n\n const extensions = [gfmHeadingId(), mangle()];\n\n if (this.highlighter) {\n extensions.push(this.highlighter.getHighlightExtension());\n }\n\n marked.use(...extensions, {\n renderer,\n pedantic: false,\n gfm: true,\n breaks: false,\n });\n\n this.marked = marked;\n }\n\n getMarkedInstance(): typeof marked {\n return this.marked;\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { getHeadingList } from 'marked-gfm-heading-id';\n\nimport {\n ContentRenderer,\n RenderedContent,\n TableOfContentItem,\n} from './content-renderer';\nimport { MarkedSetupService } from './marked-setup.service';\n\n@Injectable()\nexport class MarkdownContentRendererService implements ContentRenderer {\n #marked = inject(MarkedSetupService, { self: true });\n\n async render(content: string): Promise<RenderedContent> {\n const renderedContent = await this.#marked\n .getMarkedInstance()\n .parse(content);\n return {\n content: renderedContent,\n toc: getHeadingList(),\n };\n }\n\n getContentHeadings(content: string): TableOfContentItem[] {\n return [...content.matchAll(/^(#{1,6})\\s+(.+?)\\s*$/gm)].map((match) => ({\n id: match[2]\n .trim()\n .toLowerCase()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/\\s+/g, '-'),\n level: match[1].length,\n text: match[2].trim(),\n }));\n }\n\n // eslint-disable-next-line\n enhance() {}\n}\n","import { InjectionToken, Provider } from '@angular/core';\nimport { inject } from '@angular/core';\n\nimport { injectContentFilesMap } from './inject-content-files';\n\ntype ContentFileLoaderFunction = () => Promise<\n Record<string, () => Promise<string>>\n>;\n\nexport const CONTENT_FILE_LOADER =\n new InjectionToken<ContentFileLoaderFunction>(\n '@analogjs/content/resource File Loader',\n );\n\nexport function injectContentFileLoader() {\n return inject(CONTENT_FILE_LOADER) as ContentFileLoaderFunction;\n}\n\nexport function withContentFileLoader(): Provider {\n return {\n provide: CONTENT_FILE_LOADER,\n useFactory() {\n return async () => injectContentFilesMap();\n },\n };\n}\n","import { InjectionToken, Provider } from '@angular/core';\nimport { inject } from '@angular/core';\n\nimport { ContentFile } from './content-file';\nimport { injectContentFiles } from './inject-content-files';\n\ntype ContentListLoaderFunction<Attributes extends Record<string, any>> =\n () => Promise<ContentFile<Attributes>[]>;\n\nexport const CONTENT_LIST_LOADER = new InjectionToken<\n ContentListLoaderFunction<any>\n>('@analogjs/content/resource List Loader');\n\nexport function injectContentListLoader<\n Attributes extends Record<string, any>,\n>() {\n return inject(CONTENT_LIST_LOADER) as ContentListLoaderFunction<Attributes>;\n}\n\nexport function withContentListLoader(): Provider {\n return {\n provide: CONTENT_LIST_LOADER,\n useFactory() {\n return async () => injectContentFiles();\n },\n };\n}\n","import { Provider, InjectionToken } from '@angular/core';\nimport { ContentRenderer, NoopContentRenderer } from './content-renderer';\nimport { RenderTaskService } from './render-task.service';\nimport { withContentFileLoader } from './content-file-loader';\nimport { withContentListLoader } from './content-list-loader';\n\nexport interface MarkdownRendererOptions {\n loadMermaid?: () => Promise<typeof import('mermaid')>;\n}\n\nconst CONTENT_RENDERER_PROVIDERS: Provider[] = [\n {\n provide: ContentRenderer,\n useClass: NoopContentRenderer,\n },\n withContentFileLoader(),\n withContentListLoader(),\n];\n\nexport function withMarkdownRenderer(\n options?: MarkdownRendererOptions,\n): Provider {\n return [\n CONTENT_RENDERER_PROVIDERS,\n options?.loadMermaid\n ? [\n {\n provide: MERMAID_IMPORT_TOKEN,\n useFactory: options.loadMermaid,\n },\n ]\n : [],\n ];\n}\n\nexport function provideContent(...features: Provider[]) {\n return [\n { provide: RenderTaskService, useClass: RenderTaskService },\n ...features,\n ];\n}\n\nexport const MERMAID_IMPORT_TOKEN = new InjectionToken<\n Promise<typeof import('mermaid')>\n>('mermaid_import');\n","import { AsyncPipe } from '@angular/common';\nimport {\n AfterViewChecked,\n Component,\n inject,\n Input,\n ViewEncapsulation,\n} from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { ActivatedRoute } from '@angular/router';\n\nimport { ContentRenderer } from './content-renderer';\nimport { AnchorNavigationDirective } from './anchor-navigation.directive';\n\n@Component({\n selector: 'analog-markdown-route',\n standalone: true,\n imports: [AsyncPipe],\n hostDirectives: [AnchorNavigationDirective],\n preserveWhitespaces: true,\n encapsulation: ViewEncapsulation.None,\n template: `<div [innerHTML]=\"content\" [class]=\"classes\"></div>`,\n})\nexport default class AnalogMarkdownRouteComponent implements AfterViewChecked {\n private sanitizer = inject(DomSanitizer);\n private route = inject(ActivatedRoute);\n contentRenderer = inject(ContentRenderer);\n\n protected content: SafeHtml = this.sanitizer.bypassSecurityTrustHtml(\n this.route.snapshot.data['renderedAnalogContent'],\n );\n\n @Input() classes = 'analog-markdown-route';\n\n ngAfterViewChecked() {\n this.contentRenderer.enhance();\n }\n}\n","import { isPlatformBrowser } from '@angular/common';\nimport {\n AfterViewChecked,\n Component,\n NgZone,\n PLATFORM_ID,\n Signal,\n ViewEncapsulation,\n computed,\n inject,\n input,\n} from '@angular/core';\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { ActivatedRoute, Data } from '@angular/router';\nimport { from, of } from 'rxjs';\nimport { catchError, map, switchMap } from 'rxjs/operators';\n\nimport { AnchorNavigationDirective } from './anchor-navigation.directive';\nimport { ContentRenderer } from './content-renderer';\nimport { MERMAID_IMPORT_TOKEN } from './provide-content';\n\n@Component({\n selector: 'analog-markdown',\n standalone: true,\n hostDirectives: [AnchorNavigationDirective],\n preserveWhitespaces: true,\n encapsulation: ViewEncapsulation.None,\n template: ` <div [innerHTML]=\"htmlContent()\" [class]=\"classes()\"></div> `,\n})\nexport default class AnalogMarkdownComponent implements AfterViewChecked {\n private sanitizer = inject(DomSanitizer);\n private route = inject(ActivatedRoute);\n private zone = inject(NgZone);\n private readonly platformId = inject(PLATFORM_ID);\n private readonly mermaidImport = inject(MERMAID_IMPORT_TOKEN, {\n optional: true,\n });\n private mermaid: typeof import('mermaid') | undefined;\n\n private contentSource: Signal<SafeHtml | string | undefined> = toSignal(\n this.getContentSource(),\n );\n readonly htmlContent = computed(() => {\n const inputContent = this.content();\n\n if (inputContent) {\n return this.sanitizer.bypassSecurityTrustHtml(inputContent as string);\n }\n\n return this.contentSource();\n });\n readonly content = input<string | object | null>();\n readonly classes = input('analog-markdown');\n\n contentRenderer = inject(ContentRenderer);\n\n constructor() {\n if (isPlatformBrowser(this.platformId) && this.mermaidImport) {\n // Mermaid can only be loaded on client side\n this.loadMermaid(this.mermaidImport);\n }\n }\n\n getContentSource() {\n return this.route.data.pipe(\n map<Data, string>((data) => data['_analogContent'] ?? ''),\n switchMap((contentString) => this.renderContent(contentString)),\n map((content) => this.sanitizer.bypassSecurityTrustHtml(content)),\n catchError((e) => of(`There was an error ${e}`)),\n );\n }\n\n async renderContent(content: string): Promise<string> {\n const rendered = await this.contentRenderer.render(content);\n return rendered.content;\n }\n\n ngAfterViewChecked() {\n this.contentRenderer.enhance();\n this.zone.runOutsideAngular(() => this.mermaid?.default.run());\n }\n\n private loadMermaid(mermaidImport: Promise<typeof import('mermaid')>) {\n this.zone.runOutsideAngular(() =>\n // Wrap into an observable to avoid redundant initialization once\n // the markdown component is destroyed before the promise is resolved.\n from(mermaidImport)\n .pipe(takeUntilDestroyed())\n .subscribe((mermaid) => {\n this.mermaid = mermaid;\n this.mermaid.default.initialize({ startOnLoad: false });\n // Explicitly running mermaid as ngAfterViewChecked\n // has probably already been called\n this.mermaid?.default.run();\n }),\n );\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["ɵPendingTasks"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Provider } from '@angular/core';
|
|
3
|
-
import * as marked from 'marked';
|
|
4
3
|
import { MarkedContentHighlighter } from '@analogjs/content';
|
|
5
4
|
|
|
5
|
+
type HighlightExtension = ReturnType<MarkedContentHighlighter['getHighlightExtension']>;
|
|
6
6
|
declare class PrismHighlighter extends MarkedContentHighlighter {
|
|
7
7
|
augmentCodeBlock(code: string, lang: string): string;
|
|
8
|
-
getHighlightExtension():
|
|
8
|
+
getHighlightExtension(): HighlightExtension;
|
|
9
9
|
static ɵfac: i0.ɵɵFactoryDeclaration<PrismHighlighter, never>;
|
|
10
10
|
static ɵprov: i0.ɵɵInjectableDeclaration<PrismHighlighter>;
|
|
11
11
|
}
|
|
@@ -164,5 +164,72 @@ declare const CONTENT_FILE_LOADER: InjectionToken<ContentFileLoaderFunction>;
|
|
|
164
164
|
declare function injectContentFileLoader(): ContentFileLoaderFunction;
|
|
165
165
|
declare function withContentFileLoader(): Provider;
|
|
166
166
|
|
|
167
|
-
|
|
167
|
+
/**
|
|
168
|
+
* Token for the active content locale.
|
|
169
|
+
* Provided via `withLocale()` in `provideContent()`.
|
|
170
|
+
*
|
|
171
|
+
* When set, `injectContentFiles()` filters to content matching this locale,
|
|
172
|
+
* and `injectContent()` resolves locale-prefixed content paths first.
|
|
173
|
+
*/
|
|
174
|
+
declare const CONTENT_LOCALE: InjectionToken<string>;
|
|
175
|
+
/**
|
|
176
|
+
* Injects the content locale, returning null if not configured.
|
|
177
|
+
*/
|
|
178
|
+
declare function injectContentLocale(): string | null;
|
|
179
|
+
interface ContentLocaleOptions {
|
|
180
|
+
/**
|
|
181
|
+
* Function that returns the active locale.
|
|
182
|
+
* Runs in injection context so `inject()` can be used to read
|
|
183
|
+
* from other tokens (e.g., a LOCALE token from a router package).
|
|
184
|
+
*
|
|
185
|
+
* ```typescript
|
|
186
|
+
* withLocale({ loadLocale: injectLocale })
|
|
187
|
+
* withLocale({ loadLocale: () => navigator.language.split('-')[0] })
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
loadLocale: () => string | null;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Content feature that sets the active locale for content resolution.
|
|
194
|
+
*
|
|
195
|
+
* When provided, content APIs become locale-aware:
|
|
196
|
+
* - `injectContentFiles()` filters to files in the locale subdirectory
|
|
197
|
+
* or with a matching `locale` frontmatter attribute.
|
|
198
|
+
* - `injectContent()` tries locale-prefixed paths first
|
|
199
|
+
* (e.g., `content/fr/blog/post.md` before `content/blog/post.md`).
|
|
200
|
+
*
|
|
201
|
+
* Usage:
|
|
202
|
+
* ```typescript
|
|
203
|
+
* // With loader — runs in injection context
|
|
204
|
+
* provideContent(
|
|
205
|
+
* withMarkdownRenderer(),
|
|
206
|
+
* withLocale({ loadLocale: injectLocale }),
|
|
207
|
+
* )
|
|
208
|
+
*
|
|
209
|
+
* // Static locale
|
|
210
|
+
* provideContent(
|
|
211
|
+
* withMarkdownRenderer(),
|
|
212
|
+
* withLocale('fr'),
|
|
213
|
+
* )
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
declare function withLocale(locale: string | ContentLocaleOptions): Provider;
|
|
217
|
+
/**
|
|
218
|
+
* Filters content files by locale using map-based key lookup.
|
|
219
|
+
*
|
|
220
|
+
* Matching rules:
|
|
221
|
+
* 1. Frontmatter `locale` attribute matches the active locale.
|
|
222
|
+
* 2. File is in the active locale subdirectory (e.g., `/content/fr/blog/post`).
|
|
223
|
+
* 3. File has no locale marker and no localized variant exists — included as universal content.
|
|
224
|
+
*
|
|
225
|
+
* Files in a different locale's subdirectory are always excluded.
|
|
226
|
+
*/
|
|
227
|
+
declare function filterByLocale<T extends Record<string, any>>(files: ContentFile<T>[], locale: string): ContentFile<T>[];
|
|
228
|
+
/**
|
|
229
|
+
* Prepends locale-prefixed candidates before the standard candidates
|
|
230
|
+
* for content file map key lookup.
|
|
231
|
+
*/
|
|
232
|
+
declare function withLocaleCandidates(candidates: string[], locale: string | null | undefined): string[];
|
|
233
|
+
|
|
234
|
+
export { AnchorNavigationDirective, CONTENT_FILE_LOADER, CONTENT_LIST_LOADER, CONTENT_LOCALE, ContentRenderer, MERMAID_IMPORT_TOKEN, AnalogMarkdownComponent as MarkdownComponent, MarkdownContentRendererService, AnalogMarkdownRouteComponent as MarkdownRouteComponent, MarkedContentHighlighter, MarkedSetupService, NoopContentRenderer, filterByLocale, injectContent, injectContentFileLoader, injectContentFiles, injectContentFilesMap, injectContentListLoader, injectContentLocale, parseRawContentFile, provideContent, withContentFileLoader, withContentListLoader, withHighlighter, withLocale, withLocaleCandidates, withMarkdownRenderer };
|
|
168
235
|
export type { ContentFile, InjectContentFilesFilterFunction };
|