From ac959196bf2d78a45ab8700f71b0307270fd9a6d Mon Sep 17 00:00:00 2001 From: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> Date: Sat, 22 Nov 2025 03:41:18 +0530 Subject: [PATCH 1/4] links and jpgs working Signed-off-by: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> --- src/app/docs/[...slug]/page.tsx | 51 ++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/src/app/docs/[...slug]/page.tsx b/src/app/docs/[...slug]/page.tsx index 53ee320..253a44b 100644 --- a/src/app/docs/[...slug]/page.tsx +++ b/src/app/docs/[...slug]/page.tsx @@ -18,15 +18,29 @@ type PageProps = Readonly<{ searchParams: Promise<{ version?: string }> }> +function resolvePath(baseFile: string, relativePath: string) { + if (relativePath.startsWith('/')) return relativePath.slice(1); + const stack = baseFile.split('/'); + stack.pop(); // Remove current filename + const parts = relativePath.split('/'); + for (const part of parts) { + if (part === '.') continue; + if (part === '..') { + if (stack.length > 0) stack.pop(); + } else { + stack.push(part); + } + } + return stack.join('/'); +} + export default async function Page(props: PageProps) { const params = await props.params const searchParams = await props.searchParams - // Get version from URL or use default const version = (searchParams.version as VersionKey) || getDefaultVersion() const branch = getBranchForVersion(version) - // Build page map for this branch const { routeMap, filePaths } = await buildPageMapForBranch(branch) const route = params.slug ? params.slug.join('/') : '' @@ -42,10 +56,39 @@ export default async function Page(props: PageProps) { `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${docsPath}${filePath}`, { headers: makeGitHubHeaders(), cache: 'no-store' } ) + if (!response.ok) notFound() - const data = await response.text() - const processedData = convertHtmlScriptsToJsxComments(data) + const rawText = await response.text() + + const filePathToRoute = new Map(); + Object.entries(routeMap).forEach(([r, fp]) => filePathToRoute.set(fp, r)); + + const rewrittenText = rawText.replace(/(!?\[.*?\])\((.*?)\)/g, (match, label, link) => { + if (/^(http|https|mailto:|#)/.test(link)) return match; + + const isImage = label.startsWith('!'); + const [linkUrl, linkHash] = link.split('#'); + + const resolvedPath = resolvePath(filePath, linkUrl); + + if (isImage) { + const rawUrl = `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${docsPath}${resolvedPath}`; + return `${label}(${rawUrl})`; + } else { + let targetRoute = filePathToRoute.get(resolvedPath); + if (!targetRoute) targetRoute = filePathToRoute.get(resolvedPath + '.md'); + if (!targetRoute) targetRoute = filePathToRoute.get(resolvedPath + '.mdx'); + + if (targetRoute) { + return `${label}(/docs/${targetRoute}${linkHash ? '#' + linkHash : ''})`; + } + + return `${label}(https://raw.githubusercontent.com/${user}/${repo}/${branch}/${docsPath}${resolvedPath})`; + } + }); + + const processedData = convertHtmlScriptsToJsxComments(rewrittenText) .replace(//gi, '
') .replace(/align=center/g, 'align="center"') .replace(/frameborder="0"/g, 'frameBorder="0"') From ee0f70cc3c7ab94032795041541955a5e65c5a7f Mon Sep 17 00:00:00 2001 From: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> Date: Sat, 22 Nov 2025 03:44:48 +0530 Subject: [PATCH 2/4] gifs working Signed-off-by: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> --- src/app/docs/[...slug]/page.tsx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/app/docs/[...slug]/page.tsx b/src/app/docs/[...slug]/page.tsx index 253a44b..45e2ada 100644 --- a/src/app/docs/[...slug]/page.tsx +++ b/src/app/docs/[...slug]/page.tsx @@ -64,7 +64,8 @@ export default async function Page(props: PageProps) { const filePathToRoute = new Map(); Object.entries(routeMap).forEach(([r, fp]) => filePathToRoute.set(fp, r)); - const rewrittenText = rawText.replace(/(!?\[.*?\])\((.*?)\)/g, (match, label, link) => { + // 1. Rewrite Markdown links/images: [alt](url) or ![alt](url) + let rewrittenText = rawText.replace(/(!?\[.*?\])\((.*?)\)/g, (match, label, link) => { if (/^(http|https|mailto:|#)/.test(link)) return match; const isImage = label.startsWith('!'); @@ -88,6 +89,16 @@ export default async function Page(props: PageProps) { } }); + // 2. Rewrite HTML tags: + rewrittenText = rewrittenText.replace(/]*?)src=["']([^"']+)["']([^>]*?)>/gi, (match, pre, src, post) => { + if (/^(http|https|mailto:|#|data:)/.test(src)) return match; + + const resolvedPath = resolvePath(filePath, src); + const rawUrl = `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${docsPath}${resolvedPath}`; + + return ``; + }); + const processedData = convertHtmlScriptsToJsxComments(rewrittenText) .replace(//gi, '
') .replace(/align=center/g, 'align="center"') From 782430157f7d92128c85f7082c777d8881a90909 Mon Sep 17 00:00:00 2001 From: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> Date: Sat, 22 Nov 2025 03:56:40 +0530 Subject: [PATCH 3/4] all rel links working Signed-off-by: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> --- src/app/docs/[...slug]/page.tsx | 40 ++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/app/docs/[...slug]/page.tsx b/src/app/docs/[...slug]/page.tsx index 45e2ada..99ffad1 100644 --- a/src/app/docs/[...slug]/page.tsx +++ b/src/app/docs/[...slug]/page.tsx @@ -61,11 +61,46 @@ export default async function Page(props: PageProps) { const rawText = await response.text() + let contentWithIncludes = rawText; + const includeRegex = /{%\s*include\s+["']([^"']+)["']\s*%}/g; + const includeMatches = Array.from(rawText.matchAll(includeRegex)); + + if (includeMatches.length > 0) { + const uniqueIncludes = [...new Set(includeMatches.map(m => m[1]))]; + + const includeContents = await Promise.all(uniqueIncludes.map(async (relativePath) => { + const resolvedPath = resolvePath(filePath, relativePath); + const url = `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${docsPath}${resolvedPath}`; + + try { + const res = await fetch(url, { headers: makeGitHubHeaders(), cache: 'no-store' }); + if (res.ok) { + return { path: relativePath, text: await res.text() }; + } + + const rootUrl = `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${resolvedPath}`; + const rootRes = await fetch(rootUrl, { headers: makeGitHubHeaders(), cache: 'no-store' }); + if (rootRes.ok) { + return { path: relativePath, text: await rootRes.text() }; + } + + return { path: relativePath, text: `> **Error**: Could not include \`${relativePath}\` (File not found)` }; + } catch (e) { + return { path: relativePath, text: `> **Error**: Failed to fetch \`${relativePath}\`` }; + } + })); + + includeContents.forEach(({ path, text }) => { + const escapedPath = path.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const pattern = new RegExp(`{%\\s*include\\s+["']${escapedPath}["']\\s*%}`, 'g'); + contentWithIncludes = contentWithIncludes.replace(pattern, () => text); + }); + } + const filePathToRoute = new Map(); Object.entries(routeMap).forEach(([r, fp]) => filePathToRoute.set(fp, r)); - // 1. Rewrite Markdown links/images: [alt](url) or ![alt](url) - let rewrittenText = rawText.replace(/(!?\[.*?\])\((.*?)\)/g, (match, label, link) => { + let rewrittenText = contentWithIncludes.replace(/(!?\[.*?\])\((.*?)\)/g, (match, label, link) => { if (/^(http|https|mailto:|#)/.test(link)) return match; const isImage = label.startsWith('!'); @@ -89,7 +124,6 @@ export default async function Page(props: PageProps) { } }); - // 2. Rewrite HTML tags: rewrittenText = rewrittenText.replace(/]*?)src=["']([^"']+)["']([^>]*?)>/gi, (match, pre, src, post) => { if (/^(http|https|mailto:|#|data:)/.test(src)) return match; From a862e3932a3bb383113baaa6fb312fcb6e9bcafa Mon Sep 17 00:00:00 2001 From: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> Date: Sat, 22 Nov 2025 04:11:48 +0530 Subject: [PATCH 4/4] lint Signed-off-by: Vedansh Saini <77830698+vedansh-5@users.noreply.github.com> --- src/app/docs/[...slug]/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/docs/[...slug]/page.tsx b/src/app/docs/[...slug]/page.tsx index 99ffad1..63f943f 100644 --- a/src/app/docs/[...slug]/page.tsx +++ b/src/app/docs/[...slug]/page.tsx @@ -85,7 +85,7 @@ export default async function Page(props: PageProps) { } return { path: relativePath, text: `> **Error**: Could not include \`${relativePath}\` (File not found)` }; - } catch (e) { + } catch { return { path: relativePath, text: `> **Error**: Failed to fetch \`${relativePath}\`` }; } }));