Refactor routing in App component to enhance navigation and improve error handling by integrating dynamic routes and updating the NotFound route.
This commit is contained in:
6
node_modules/@astrojs/markdown-remark/dist/frontmatter-injection.d.ts
generated
vendored
Normal file
6
node_modules/@astrojs/markdown-remark/dist/frontmatter-injection.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { VFileData as Data, VFile } from 'vfile';
|
||||
import type { MarkdownAstroData } from './types.js';
|
||||
export declare class InvalidAstroDataError extends TypeError {
|
||||
}
|
||||
export declare function safelyGetAstroData(vfileData: Data): MarkdownAstroData | InvalidAstroDataError;
|
||||
export declare function setVfileFrontmatter(vfile: VFile, frontmatter: Record<string, any>): void;
|
31
node_modules/@astrojs/markdown-remark/dist/frontmatter-injection.js
generated
vendored
Normal file
31
node_modules/@astrojs/markdown-remark/dist/frontmatter-injection.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
function isValidAstroData(obj) {
|
||||
if (typeof obj === "object" && obj !== null && obj.hasOwnProperty("frontmatter")) {
|
||||
const { frontmatter } = obj;
|
||||
try {
|
||||
JSON.stringify(frontmatter);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
return typeof frontmatter === "object" && frontmatter !== null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
class InvalidAstroDataError extends TypeError {
|
||||
}
|
||||
function safelyGetAstroData(vfileData) {
|
||||
const { astro } = vfileData;
|
||||
if (!astro || !isValidAstroData(astro)) {
|
||||
return new InvalidAstroDataError();
|
||||
}
|
||||
return astro;
|
||||
}
|
||||
function setVfileFrontmatter(vfile, frontmatter) {
|
||||
vfile.data ??= {};
|
||||
vfile.data.astro ??= {};
|
||||
vfile.data.astro.frontmatter = frontmatter;
|
||||
}
|
||||
export {
|
||||
InvalidAstroDataError,
|
||||
safelyGetAstroData,
|
||||
setVfileFrontmatter
|
||||
};
|
15
node_modules/@astrojs/markdown-remark/dist/highlight.d.ts
generated
vendored
Normal file
15
node_modules/@astrojs/markdown-remark/dist/highlight.d.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import type { Root } from 'hast';
|
||||
type Highlighter = (code: string, language: string, options?: {
|
||||
meta?: string;
|
||||
}) => Promise<string>;
|
||||
/**
|
||||
* A hast utility to syntax highlight code blocks with a given syntax highlighter.
|
||||
*
|
||||
* @param tree
|
||||
* The hast tree in which to syntax highlight code blocks.
|
||||
* @param highlighter
|
||||
* A function which receives the code and language, and returns the HTML of a syntax
|
||||
* highlighted `<pre>` element.
|
||||
*/
|
||||
export declare function highlightCodeBlocks(tree: Root, highlighter: Highlighter): Promise<void>;
|
||||
export {};
|
53
node_modules/@astrojs/markdown-remark/dist/highlight.js
generated
vendored
Normal file
53
node_modules/@astrojs/markdown-remark/dist/highlight.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
import { fromHtml } from "hast-util-from-html";
|
||||
import { toText } from "hast-util-to-text";
|
||||
import { removePosition } from "unist-util-remove-position";
|
||||
import { visitParents } from "unist-util-visit-parents";
|
||||
const languagePattern = /\blanguage-(\S+)\b/;
|
||||
async function highlightCodeBlocks(tree, highlighter) {
|
||||
const nodes = [];
|
||||
visitParents(tree, { type: "element", tagName: "code" }, (node, ancestors) => {
|
||||
const parent = ancestors.at(-1);
|
||||
if (parent?.type !== "element" || parent.tagName !== "pre") {
|
||||
return;
|
||||
}
|
||||
if (parent.children.length !== 1) {
|
||||
return;
|
||||
}
|
||||
let languageMatch;
|
||||
let { className } = node.properties;
|
||||
if (typeof className === "string") {
|
||||
languageMatch = languagePattern.exec(className);
|
||||
} else if (Array.isArray(className)) {
|
||||
for (const cls of className) {
|
||||
if (typeof cls !== "string") {
|
||||
continue;
|
||||
}
|
||||
languageMatch = languagePattern.exec(cls);
|
||||
if (languageMatch) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (languageMatch?.[1] === "math") {
|
||||
return;
|
||||
}
|
||||
nodes.push({
|
||||
node,
|
||||
language: languageMatch?.[1] || "plaintext",
|
||||
parent,
|
||||
grandParent: ancestors.at(-2)
|
||||
});
|
||||
});
|
||||
for (const { node, language, grandParent, parent } of nodes) {
|
||||
const meta = node.data?.meta ?? node.properties.metastring ?? void 0;
|
||||
const code = toText(node, { whitespace: "pre" });
|
||||
const html = await highlighter(code, language, { meta });
|
||||
const replacement = fromHtml(html, { fragment: true }).children[0];
|
||||
removePosition(replacement);
|
||||
const index = grandParent.children.indexOf(parent);
|
||||
grandParent.children[index] = replacement;
|
||||
}
|
||||
}
|
||||
export {
|
||||
highlightCodeBlocks
|
||||
};
|
2
node_modules/@astrojs/markdown-remark/dist/import-plugin-browser.d.ts
generated
vendored
Normal file
2
node_modules/@astrojs/markdown-remark/dist/import-plugin-browser.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type * as unified from 'unified';
|
||||
export declare function importPlugin(p: string): Promise<unified.Plugin>;
|
7
node_modules/@astrojs/markdown-remark/dist/import-plugin-browser.js
generated
vendored
Normal file
7
node_modules/@astrojs/markdown-remark/dist/import-plugin-browser.js
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
async function importPlugin(p) {
|
||||
const importResult = await import(p);
|
||||
return importResult.default;
|
||||
}
|
||||
export {
|
||||
importPlugin
|
||||
};
|
2
node_modules/@astrojs/markdown-remark/dist/import-plugin-default.d.ts
generated
vendored
Normal file
2
node_modules/@astrojs/markdown-remark/dist/import-plugin-default.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type * as unified from 'unified';
|
||||
export declare function importPlugin(p: string): Promise<unified.Plugin>;
|
18
node_modules/@astrojs/markdown-remark/dist/import-plugin-default.js
generated
vendored
Normal file
18
node_modules/@astrojs/markdown-remark/dist/import-plugin-default.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import path from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { resolve as importMetaResolve } from "import-meta-resolve";
|
||||
let cwdUrlStr;
|
||||
async function importPlugin(p) {
|
||||
try {
|
||||
const importResult2 = await import(p);
|
||||
return importResult2.default;
|
||||
} catch {
|
||||
}
|
||||
cwdUrlStr ??= pathToFileURL(path.join(process.cwd(), "package.json")).toString();
|
||||
const resolved = importMetaResolve(p, cwdUrlStr);
|
||||
const importResult = await import(resolved);
|
||||
return importResult.default;
|
||||
}
|
||||
export {
|
||||
importPlugin
|
||||
};
|
13
node_modules/@astrojs/markdown-remark/dist/index.d.ts
generated
vendored
Normal file
13
node_modules/@astrojs/markdown-remark/dist/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { AstroMarkdownOptions, MarkdownProcessor } from './types.js';
|
||||
export { InvalidAstroDataError, setVfileFrontmatter } from './frontmatter-injection.js';
|
||||
export { rehypeHeadingIds } from './rehype-collect-headings.js';
|
||||
export { remarkCollectImages } from './remark-collect-images.js';
|
||||
export { rehypePrism } from './rehype-prism.js';
|
||||
export { rehypeShiki } from './rehype-shiki.js';
|
||||
export { createShikiHighlighter, type ShikiHighlighter } from './shiki.js';
|
||||
export * from './types.js';
|
||||
export declare const markdownConfigDefaults: Required<AstroMarkdownOptions>;
|
||||
/**
|
||||
* Create a markdown preprocessor to render multiple markdown files
|
||||
*/
|
||||
export declare function createMarkdownProcessor(opts?: AstroMarkdownOptions): Promise<MarkdownProcessor>;
|
142
node_modules/@astrojs/markdown-remark/dist/index.js
generated
vendored
Normal file
142
node_modules/@astrojs/markdown-remark/dist/index.js
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
import {
|
||||
InvalidAstroDataError,
|
||||
safelyGetAstroData,
|
||||
setVfileFrontmatter
|
||||
} from "./frontmatter-injection.js";
|
||||
import { loadPlugins } from "./load-plugins.js";
|
||||
import { rehypeHeadingIds } from "./rehype-collect-headings.js";
|
||||
import { rehypePrism } from "./rehype-prism.js";
|
||||
import { rehypeShiki } from "./rehype-shiki.js";
|
||||
import { remarkCollectImages } from "./remark-collect-images.js";
|
||||
import rehypeRaw from "rehype-raw";
|
||||
import rehypeStringify from "rehype-stringify";
|
||||
import remarkGfm from "remark-gfm";
|
||||
import remarkParse from "remark-parse";
|
||||
import remarkRehype from "remark-rehype";
|
||||
import remarkSmartypants from "remark-smartypants";
|
||||
import { unified } from "unified";
|
||||
import { VFile } from "vfile";
|
||||
import { rehypeImages } from "./rehype-images.js";
|
||||
import { InvalidAstroDataError as InvalidAstroDataError2, setVfileFrontmatter as setVfileFrontmatter2 } from "./frontmatter-injection.js";
|
||||
import { rehypeHeadingIds as rehypeHeadingIds2 } from "./rehype-collect-headings.js";
|
||||
import { remarkCollectImages as remarkCollectImages2 } from "./remark-collect-images.js";
|
||||
import { rehypePrism as rehypePrism2 } from "./rehype-prism.js";
|
||||
import { rehypeShiki as rehypeShiki2 } from "./rehype-shiki.js";
|
||||
import { createShikiHighlighter } from "./shiki.js";
|
||||
export * from "./types.js";
|
||||
const markdownConfigDefaults = {
|
||||
syntaxHighlight: "shiki",
|
||||
shikiConfig: {
|
||||
langs: [],
|
||||
theme: "github-dark",
|
||||
themes: {},
|
||||
wrap: false,
|
||||
transformers: [],
|
||||
langAlias: {}
|
||||
},
|
||||
remarkPlugins: [],
|
||||
rehypePlugins: [],
|
||||
remarkRehype: {},
|
||||
gfm: true,
|
||||
smartypants: true
|
||||
};
|
||||
const isPerformanceBenchmark = Boolean(process.env.ASTRO_PERFORMANCE_BENCHMARK);
|
||||
async function createMarkdownProcessor(opts) {
|
||||
const {
|
||||
syntaxHighlight = markdownConfigDefaults.syntaxHighlight,
|
||||
shikiConfig = markdownConfigDefaults.shikiConfig,
|
||||
remarkPlugins = markdownConfigDefaults.remarkPlugins,
|
||||
rehypePlugins = markdownConfigDefaults.rehypePlugins,
|
||||
remarkRehype: remarkRehypeOptions = markdownConfigDefaults.remarkRehype,
|
||||
gfm = markdownConfigDefaults.gfm,
|
||||
smartypants = markdownConfigDefaults.smartypants
|
||||
} = opts ?? {};
|
||||
const loadedRemarkPlugins = await Promise.all(loadPlugins(remarkPlugins));
|
||||
const loadedRehypePlugins = await Promise.all(loadPlugins(rehypePlugins));
|
||||
const parser = unified().use(remarkParse);
|
||||
if (!isPerformanceBenchmark) {
|
||||
if (gfm) {
|
||||
parser.use(remarkGfm);
|
||||
}
|
||||
if (smartypants) {
|
||||
parser.use(remarkSmartypants);
|
||||
}
|
||||
}
|
||||
for (const [plugin, pluginOpts] of loadedRemarkPlugins) {
|
||||
parser.use(plugin, pluginOpts);
|
||||
}
|
||||
if (!isPerformanceBenchmark) {
|
||||
parser.use(remarkCollectImages);
|
||||
}
|
||||
parser.use(remarkRehype, {
|
||||
allowDangerousHtml: true,
|
||||
passThrough: [],
|
||||
...remarkRehypeOptions
|
||||
});
|
||||
if (!isPerformanceBenchmark) {
|
||||
if (syntaxHighlight === "shiki") {
|
||||
parser.use(rehypeShiki, shikiConfig);
|
||||
} else if (syntaxHighlight === "prism") {
|
||||
parser.use(rehypePrism);
|
||||
}
|
||||
}
|
||||
for (const [plugin, pluginOpts] of loadedRehypePlugins) {
|
||||
parser.use(plugin, pluginOpts);
|
||||
}
|
||||
parser.use(rehypeImages());
|
||||
if (!isPerformanceBenchmark) {
|
||||
parser.use(rehypeHeadingIds);
|
||||
}
|
||||
parser.use(rehypeRaw).use(rehypeStringify, { allowDangerousHtml: true });
|
||||
return {
|
||||
async render(content, renderOpts) {
|
||||
const vfile = new VFile({ value: content, path: renderOpts?.fileURL });
|
||||
setVfileFrontmatter(vfile, renderOpts?.frontmatter ?? {});
|
||||
const result = await parser.process(vfile).catch((err) => {
|
||||
err = prefixError(err, `Failed to parse Markdown file "${vfile.path}"`);
|
||||
console.error(err);
|
||||
throw err;
|
||||
});
|
||||
const astroData = safelyGetAstroData(result.data);
|
||||
if (astroData instanceof InvalidAstroDataError) {
|
||||
throw astroData;
|
||||
}
|
||||
return {
|
||||
code: String(result.value),
|
||||
metadata: {
|
||||
headings: result.data.__astroHeadings ?? [],
|
||||
imagePaths: result.data.imagePaths ?? /* @__PURE__ */ new Set(),
|
||||
frontmatter: astroData.frontmatter ?? {}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
function prefixError(err, prefix) {
|
||||
if (err?.message) {
|
||||
try {
|
||||
err.message = `${prefix}:
|
||||
${err.message}`;
|
||||
return err;
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
const wrappedError = new Error(`${prefix}${err ? `: ${err}` : ""}`);
|
||||
try {
|
||||
wrappedError.stack = err.stack;
|
||||
wrappedError.cause = err;
|
||||
} catch {
|
||||
}
|
||||
return wrappedError;
|
||||
}
|
||||
export {
|
||||
InvalidAstroDataError2 as InvalidAstroDataError,
|
||||
createMarkdownProcessor,
|
||||
createShikiHighlighter,
|
||||
markdownConfigDefaults,
|
||||
rehypeHeadingIds2 as rehypeHeadingIds,
|
||||
rehypePrism2 as rehypePrism,
|
||||
rehypeShiki2 as rehypeShiki,
|
||||
remarkCollectImages2 as remarkCollectImages,
|
||||
setVfileFrontmatter2 as setVfileFrontmatter
|
||||
};
|
1
node_modules/@astrojs/markdown-remark/dist/internal.d.ts
generated
vendored
Normal file
1
node_modules/@astrojs/markdown-remark/dist/internal.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export { InvalidAstroDataError, safelyGetAstroData } from './frontmatter-injection.js';
|
5
node_modules/@astrojs/markdown-remark/dist/internal.js
generated
vendored
Normal file
5
node_modules/@astrojs/markdown-remark/dist/internal.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import { InvalidAstroDataError, safelyGetAstroData } from "./frontmatter-injection.js";
|
||||
export {
|
||||
InvalidAstroDataError,
|
||||
safelyGetAstroData
|
||||
};
|
2
node_modules/@astrojs/markdown-remark/dist/load-plugins.d.ts
generated
vendored
Normal file
2
node_modules/@astrojs/markdown-remark/dist/load-plugins.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type * as unified from 'unified';
|
||||
export declare function loadPlugins(items: (string | [string, any] | unified.Plugin<any[], any> | [unified.Plugin<any[], any>, any])[]): Promise<[unified.Plugin, any?]>[];
|
22
node_modules/@astrojs/markdown-remark/dist/load-plugins.js
generated
vendored
Normal file
22
node_modules/@astrojs/markdown-remark/dist/load-plugins.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import { importPlugin as _importPlugin } from "#import-plugin";
|
||||
async function importPlugin(p) {
|
||||
if (typeof p === "string") {
|
||||
return await _importPlugin(p);
|
||||
} else {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
function loadPlugins(items) {
|
||||
return items.map((p) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (Array.isArray(p)) {
|
||||
const [plugin, opts] = p;
|
||||
return importPlugin(plugin).then((m) => resolve([m, opts])).catch((e) => reject(e));
|
||||
}
|
||||
return importPlugin(p).then((m) => resolve([m])).catch((e) => reject(e));
|
||||
});
|
||||
});
|
||||
}
|
||||
export {
|
||||
loadPlugins
|
||||
};
|
2
node_modules/@astrojs/markdown-remark/dist/rehype-collect-headings.d.ts
generated
vendored
Normal file
2
node_modules/@astrojs/markdown-remark/dist/rehype-collect-headings.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { RehypePlugin } from './types.js';
|
||||
export declare function rehypeHeadingIds(): ReturnType<RehypePlugin>;
|
90
node_modules/@astrojs/markdown-remark/dist/rehype-collect-headings.js
generated
vendored
Normal file
90
node_modules/@astrojs/markdown-remark/dist/rehype-collect-headings.js
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
import Slugger from "github-slugger";
|
||||
import { visit } from "unist-util-visit";
|
||||
import { InvalidAstroDataError, safelyGetAstroData } from "./frontmatter-injection.js";
|
||||
const rawNodeTypes = /* @__PURE__ */ new Set(["text", "raw", "mdxTextExpression"]);
|
||||
const codeTagNames = /* @__PURE__ */ new Set(["code", "pre"]);
|
||||
function rehypeHeadingIds() {
|
||||
return function(tree, file) {
|
||||
const headings = [];
|
||||
const slugger = new Slugger();
|
||||
const isMDX = isMDXFile(file);
|
||||
const astroData = safelyGetAstroData(file.data);
|
||||
visit(tree, (node) => {
|
||||
if (node.type !== "element") return;
|
||||
const { tagName } = node;
|
||||
if (tagName[0] !== "h") return;
|
||||
const [, level] = /h([0-6])/.exec(tagName) ?? [];
|
||||
if (!level) return;
|
||||
const depth = Number.parseInt(level);
|
||||
let text = "";
|
||||
visit(node, (child, __, parent) => {
|
||||
if (child.type === "element" || parent == null) {
|
||||
return;
|
||||
}
|
||||
if (child.type === "raw") {
|
||||
if (/^\n?<.*>\n?$/.test(child.value)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (rawNodeTypes.has(child.type)) {
|
||||
if (isMDX || codeTagNames.has(parent.tagName)) {
|
||||
let value = child.value;
|
||||
if (isMdxTextExpression(child) && !(astroData instanceof InvalidAstroDataError)) {
|
||||
const frontmatterPath = getMdxFrontmatterVariablePath(child);
|
||||
if (Array.isArray(frontmatterPath) && frontmatterPath.length > 0) {
|
||||
const frontmatterValue = getMdxFrontmatterVariableValue(astroData, frontmatterPath);
|
||||
if (typeof frontmatterValue === "string") {
|
||||
value = frontmatterValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
text += value;
|
||||
} else {
|
||||
text += child.value.replace(/\{/g, "${");
|
||||
}
|
||||
}
|
||||
});
|
||||
node.properties = node.properties || {};
|
||||
if (typeof node.properties.id !== "string") {
|
||||
let slug = slugger.slug(text);
|
||||
if (slug.endsWith("-")) slug = slug.slice(0, -1);
|
||||
node.properties.id = slug;
|
||||
}
|
||||
headings.push({ depth, slug: node.properties.id, text });
|
||||
});
|
||||
file.data.__astroHeadings = headings;
|
||||
};
|
||||
}
|
||||
function isMDXFile(file) {
|
||||
return Boolean(file.history[0]?.endsWith(".mdx"));
|
||||
}
|
||||
function getMdxFrontmatterVariablePath(node) {
|
||||
if (!node.data?.estree || node.data.estree.body.length !== 1) return new Error();
|
||||
const statement = node.data.estree.body[0];
|
||||
if (statement?.type !== "ExpressionStatement" || statement.expression.type !== "MemberExpression")
|
||||
return new Error();
|
||||
let expression = statement.expression;
|
||||
const expressionPath = [];
|
||||
while (expression.type === "MemberExpression" && expression.property.type === (expression.computed ? "Literal" : "Identifier")) {
|
||||
expressionPath.push(
|
||||
expression.property.type === "Literal" ? String(expression.property.value) : expression.property.name
|
||||
);
|
||||
expression = expression.object;
|
||||
}
|
||||
if (expression.type !== "Identifier" || expression.name !== "frontmatter") return new Error();
|
||||
return expressionPath.reverse();
|
||||
}
|
||||
function getMdxFrontmatterVariableValue(astroData, path) {
|
||||
let value = astroData.frontmatter;
|
||||
for (const key of path) {
|
||||
if (!value[key]) return void 0;
|
||||
value = value[key];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function isMdxTextExpression(node) {
|
||||
return node.type === "mdxTextExpression";
|
||||
}
|
||||
export {
|
||||
rehypeHeadingIds
|
||||
};
|
2
node_modules/@astrojs/markdown-remark/dist/rehype-images.d.ts
generated
vendored
Normal file
2
node_modules/@astrojs/markdown-remark/dist/rehype-images.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { MarkdownVFile } from './types.js';
|
||||
export declare function rehypeImages(): () => (tree: any, file: MarkdownVFile) => void;
|
25
node_modules/@astrojs/markdown-remark/dist/rehype-images.js
generated
vendored
Normal file
25
node_modules/@astrojs/markdown-remark/dist/rehype-images.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
import { visit } from "unist-util-visit";
|
||||
function rehypeImages() {
|
||||
return () => function(tree, file) {
|
||||
const imageOccurrenceMap = /* @__PURE__ */ new Map();
|
||||
visit(tree, (node) => {
|
||||
if (node.type !== "element") return;
|
||||
if (node.tagName !== "img") return;
|
||||
if (node.properties?.src) {
|
||||
node.properties.src = decodeURI(node.properties.src);
|
||||
if (file.data.imagePaths?.has(node.properties.src)) {
|
||||
const { ...props } = node.properties;
|
||||
const index = imageOccurrenceMap.get(node.properties.src) || 0;
|
||||
imageOccurrenceMap.set(node.properties.src, index + 1);
|
||||
node.properties["__ASTRO_IMAGE_"] = JSON.stringify({ ...props, index });
|
||||
Object.keys(props).forEach((prop) => {
|
||||
delete node.properties[prop];
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
export {
|
||||
rehypeImages
|
||||
};
|
3
node_modules/@astrojs/markdown-remark/dist/rehype-prism.d.ts
generated
vendored
Normal file
3
node_modules/@astrojs/markdown-remark/dist/rehype-prism.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { Root } from 'hast';
|
||||
import type { Plugin } from 'unified';
|
||||
export declare const rehypePrism: Plugin<[], Root>;
|
15
node_modules/@astrojs/markdown-remark/dist/rehype-prism.js
generated
vendored
Normal file
15
node_modules/@astrojs/markdown-remark/dist/rehype-prism.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import { runHighlighterWithAstro } from "@astrojs/prism/dist/highlighter";
|
||||
import { highlightCodeBlocks } from "./highlight.js";
|
||||
const rehypePrism = () => {
|
||||
return async (tree) => {
|
||||
await highlightCodeBlocks(tree, (code, language) => {
|
||||
let { html, classLanguage } = runHighlighterWithAstro(language, code);
|
||||
return Promise.resolve(
|
||||
`<pre class="${classLanguage}" data-language="${language}"><code is:raw class="${classLanguage}">${html}</code></pre>`
|
||||
);
|
||||
});
|
||||
};
|
||||
};
|
||||
export {
|
||||
rehypePrism
|
||||
};
|
4
node_modules/@astrojs/markdown-remark/dist/rehype-shiki.d.ts
generated
vendored
Normal file
4
node_modules/@astrojs/markdown-remark/dist/rehype-shiki.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import type { Root } from 'hast';
|
||||
import type { Plugin } from 'unified';
|
||||
import type { ShikiConfig } from './types.js';
|
||||
export declare const rehypeShiki: Plugin<[ShikiConfig?], Root>;
|
13
node_modules/@astrojs/markdown-remark/dist/rehype-shiki.js
generated
vendored
Normal file
13
node_modules/@astrojs/markdown-remark/dist/rehype-shiki.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import { highlightCodeBlocks } from "./highlight.js";
|
||||
import { createShikiHighlighter } from "./shiki.js";
|
||||
const rehypeShiki = (config) => {
|
||||
let highlighterAsync;
|
||||
return async (tree) => {
|
||||
highlighterAsync ??= createShikiHighlighter(config);
|
||||
const highlighter = await highlighterAsync;
|
||||
await highlightCodeBlocks(tree, highlighter.highlight);
|
||||
};
|
||||
};
|
||||
export {
|
||||
rehypeShiki
|
||||
};
|
2
node_modules/@astrojs/markdown-remark/dist/remark-collect-images.d.ts
generated
vendored
Normal file
2
node_modules/@astrojs/markdown-remark/dist/remark-collect-images.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { MarkdownVFile } from './types.js';
|
||||
export declare function remarkCollectImages(): (tree: any, vfile: MarkdownVFile) => void;
|
36
node_modules/@astrojs/markdown-remark/dist/remark-collect-images.js
generated
vendored
Normal file
36
node_modules/@astrojs/markdown-remark/dist/remark-collect-images.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
import { definitions } from "mdast-util-definitions";
|
||||
import { visit } from "unist-util-visit";
|
||||
function remarkCollectImages() {
|
||||
return function(tree, vfile) {
|
||||
if (typeof vfile?.path !== "string") return;
|
||||
const definition = definitions(tree);
|
||||
const imagePaths = /* @__PURE__ */ new Set();
|
||||
visit(tree, ["image", "imageReference"], (node) => {
|
||||
if (node.type === "image") {
|
||||
if (shouldOptimizeImage(node.url)) imagePaths.add(decodeURI(node.url));
|
||||
}
|
||||
if (node.type === "imageReference") {
|
||||
const imageDefinition = definition(node.identifier);
|
||||
if (imageDefinition) {
|
||||
if (shouldOptimizeImage(imageDefinition.url))
|
||||
imagePaths.add(decodeURI(imageDefinition.url));
|
||||
}
|
||||
}
|
||||
});
|
||||
vfile.data.imagePaths = imagePaths;
|
||||
};
|
||||
}
|
||||
function shouldOptimizeImage(src) {
|
||||
return !isValidUrl(src) && !src.startsWith("/");
|
||||
}
|
||||
function isValidUrl(str) {
|
||||
try {
|
||||
new URL(str);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export {
|
||||
remarkCollectImages
|
||||
};
|
12
node_modules/@astrojs/markdown-remark/dist/shiki.d.ts
generated
vendored
Normal file
12
node_modules/@astrojs/markdown-remark/dist/shiki.d.ts
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { ShikiConfig } from './types.js';
|
||||
export interface ShikiHighlighter {
|
||||
highlight(code: string, lang?: string, options?: {
|
||||
inline?: boolean;
|
||||
attributes?: Record<string, string>;
|
||||
/**
|
||||
* Raw `meta` information to be used by Shiki transformers
|
||||
*/
|
||||
meta?: string;
|
||||
}): Promise<string>;
|
||||
}
|
||||
export declare function createShikiHighlighter({ langs, theme, themes, defaultColor, wrap, transformers, langAlias, }?: ShikiConfig): Promise<ShikiHighlighter>;
|
130
node_modules/@astrojs/markdown-remark/dist/shiki.js
generated
vendored
Normal file
130
node_modules/@astrojs/markdown-remark/dist/shiki.js
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
import {
|
||||
createCssVariablesTheme,
|
||||
getHighlighter,
|
||||
isSpecialLang
|
||||
} from "shiki";
|
||||
import { visit } from "unist-util-visit";
|
||||
const ASTRO_COLOR_REPLACEMENTS = {
|
||||
"--astro-code-foreground": "--astro-code-color-text",
|
||||
"--astro-code-background": "--astro-code-color-background"
|
||||
};
|
||||
const COLOR_REPLACEMENT_REGEX = new RegExp(
|
||||
`${Object.keys(ASTRO_COLOR_REPLACEMENTS).join("|")}`,
|
||||
"g"
|
||||
);
|
||||
let _cssVariablesTheme;
|
||||
const cssVariablesTheme = () => _cssVariablesTheme ?? (_cssVariablesTheme = createCssVariablesTheme({ variablePrefix: "--astro-code-" }));
|
||||
async function createShikiHighlighter({
|
||||
langs = [],
|
||||
theme = "github-dark",
|
||||
themes = {},
|
||||
defaultColor,
|
||||
wrap = false,
|
||||
transformers = [],
|
||||
langAlias = {}
|
||||
} = {}) {
|
||||
theme = theme === "css-variables" ? cssVariablesTheme() : theme;
|
||||
const highlighter = await getHighlighter({
|
||||
langs: ["plaintext", ...langs],
|
||||
langAlias,
|
||||
themes: Object.values(themes).length ? Object.values(themes) : [theme]
|
||||
});
|
||||
return {
|
||||
async highlight(code, lang = "plaintext", options) {
|
||||
const resolvedLang = langAlias[lang] ?? lang;
|
||||
const loadedLanguages = highlighter.getLoadedLanguages();
|
||||
if (!isSpecialLang(lang) && !loadedLanguages.includes(resolvedLang)) {
|
||||
try {
|
||||
await highlighter.loadLanguage(resolvedLang);
|
||||
} catch (_err) {
|
||||
const langStr = lang === resolvedLang ? `"${lang}"` : `"${lang}" (aliased to "${resolvedLang}")`;
|
||||
console.warn(
|
||||
`[Shiki] The language ${langStr} doesn't exist, falling back to "plaintext".`
|
||||
);
|
||||
lang = "plaintext";
|
||||
}
|
||||
}
|
||||
const themeOptions = Object.values(themes).length ? { themes } : { theme };
|
||||
const inline = options?.inline ?? false;
|
||||
return highlighter.codeToHtml(code, {
|
||||
...themeOptions,
|
||||
defaultColor,
|
||||
lang,
|
||||
// NOTE: while we can spread `options.attributes` here so that Shiki can auto-serialize this as rendered
|
||||
// attributes on the top-level tag, it's not clear whether it is fine to pass all attributes as meta, as
|
||||
// they're technically not meta, nor parsed from Shiki's `parseMetaString` API.
|
||||
meta: options?.meta ? { __raw: options?.meta } : void 0,
|
||||
transformers: [
|
||||
{
|
||||
pre(node) {
|
||||
if (inline) {
|
||||
node.tagName = "code";
|
||||
}
|
||||
const {
|
||||
class: attributesClass,
|
||||
style: attributesStyle,
|
||||
...rest
|
||||
} = options?.attributes ?? {};
|
||||
Object.assign(node.properties, rest);
|
||||
const classValue = (normalizePropAsString(node.properties.class) ?? "") + (attributesClass ? ` ${attributesClass}` : "");
|
||||
const styleValue = (normalizePropAsString(node.properties.style) ?? "") + (attributesStyle ? `; ${attributesStyle}` : "");
|
||||
node.properties.class = classValue.replace(/shiki/g, "astro-code");
|
||||
node.properties.dataLanguage = lang;
|
||||
if (wrap === false) {
|
||||
node.properties.style = styleValue + "; overflow-x: auto;";
|
||||
} else if (wrap === true) {
|
||||
node.properties.style = styleValue + "; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;";
|
||||
}
|
||||
},
|
||||
line(node) {
|
||||
if (resolvedLang === "diff") {
|
||||
const innerSpanNode = node.children[0];
|
||||
const innerSpanTextNode = innerSpanNode?.type === "element" && innerSpanNode.children?.[0];
|
||||
if (innerSpanTextNode && innerSpanTextNode.type === "text") {
|
||||
const start = innerSpanTextNode.value[0];
|
||||
if (start === "+" || start === "-") {
|
||||
innerSpanTextNode.value = innerSpanTextNode.value.slice(1);
|
||||
innerSpanNode.children.unshift({
|
||||
type: "element",
|
||||
tagName: "span",
|
||||
properties: { style: "user-select: none;" },
|
||||
children: [{ type: "text", value: start }]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
code(node) {
|
||||
if (inline) {
|
||||
return node.children[0];
|
||||
}
|
||||
},
|
||||
root(node) {
|
||||
if (Object.values(themes).length) {
|
||||
return;
|
||||
}
|
||||
const themeName = typeof theme === "string" ? theme : theme.name;
|
||||
if (themeName === "css-variables") {
|
||||
visit(node, "element", (child) => {
|
||||
if (child.properties?.style) {
|
||||
child.properties.style = replaceCssVariables(child.properties.style);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
...transformers
|
||||
]
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
function normalizePropAsString(value) {
|
||||
return Array.isArray(value) ? value.join(" ") : value;
|
||||
}
|
||||
function replaceCssVariables(str) {
|
||||
return str.replace(COLOR_REPLACEMENT_REGEX, (match) => ASTRO_COLOR_REPLACEMENTS[match] || match);
|
||||
}
|
||||
export {
|
||||
createShikiHighlighter
|
||||
};
|
60
node_modules/@astrojs/markdown-remark/dist/types.d.ts
generated
vendored
Normal file
60
node_modules/@astrojs/markdown-remark/dist/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
import type * as hast from 'hast';
|
||||
import type * as mdast from 'mdast';
|
||||
import type { Options as RemarkRehypeOptions } from 'remark-rehype';
|
||||
import type { BuiltinTheme, HighlighterCoreOptions, LanguageRegistration, ShikiTransformer, ThemeRegistration, ThemeRegistrationRaw } from 'shiki';
|
||||
import type * as unified from 'unified';
|
||||
import type { DataMap, VFile } from 'vfile';
|
||||
export type { Node } from 'unist';
|
||||
export type MarkdownAstroData = {
|
||||
frontmatter: Record<string, any>;
|
||||
};
|
||||
export type RemarkPlugin<PluginParameters extends any[] = any[]> = unified.Plugin<PluginParameters, mdast.Root>;
|
||||
export type RemarkPlugins = (string | [string, any] | RemarkPlugin | [RemarkPlugin, any])[];
|
||||
export type RehypePlugin<PluginParameters extends any[] = any[]> = unified.Plugin<PluginParameters, hast.Root>;
|
||||
export type RehypePlugins = (string | [string, any] | RehypePlugin | [RehypePlugin, any])[];
|
||||
export type RemarkRehype = RemarkRehypeOptions;
|
||||
export type ThemePresets = BuiltinTheme | 'css-variables';
|
||||
export interface ShikiConfig {
|
||||
langs?: LanguageRegistration[];
|
||||
langAlias?: HighlighterCoreOptions['langAlias'];
|
||||
theme?: ThemePresets | ThemeRegistration | ThemeRegistrationRaw;
|
||||
themes?: Record<string, ThemePresets | ThemeRegistration | ThemeRegistrationRaw>;
|
||||
defaultColor?: 'light' | 'dark' | string | false;
|
||||
wrap?: boolean | null;
|
||||
transformers?: ShikiTransformer[];
|
||||
}
|
||||
export interface AstroMarkdownOptions {
|
||||
syntaxHighlight?: 'shiki' | 'prism' | false;
|
||||
shikiConfig?: ShikiConfig;
|
||||
remarkPlugins?: RemarkPlugins;
|
||||
rehypePlugins?: RehypePlugins;
|
||||
remarkRehype?: RemarkRehype;
|
||||
gfm?: boolean;
|
||||
smartypants?: boolean;
|
||||
}
|
||||
export interface MarkdownProcessor {
|
||||
render: (content: string, opts?: MarkdownProcessorRenderOptions) => Promise<MarkdownProcessorRenderResult>;
|
||||
}
|
||||
export interface MarkdownProcessorRenderOptions {
|
||||
/** Used for frontmatter injection plugins */
|
||||
frontmatter?: Record<string, any>;
|
||||
}
|
||||
export interface MarkdownProcessorRenderResult {
|
||||
code: string;
|
||||
metadata: {
|
||||
headings: MarkdownHeading[];
|
||||
imagePaths: Set<string>;
|
||||
frontmatter: Record<string, any>;
|
||||
};
|
||||
}
|
||||
export interface MarkdownHeading {
|
||||
depth: number;
|
||||
slug: string;
|
||||
text: string;
|
||||
}
|
||||
export interface MarkdownVFile extends VFile {
|
||||
data: Record<string, unknown> & Partial<DataMap> & {
|
||||
__astroHeadings?: MarkdownHeading[];
|
||||
imagePaths?: Set<string>;
|
||||
};
|
||||
}
|
0
node_modules/@astrojs/markdown-remark/dist/types.js
generated
vendored
Normal file
0
node_modules/@astrojs/markdown-remark/dist/types.js
generated
vendored
Normal file
Reference in New Issue
Block a user