feat: add Astro reference site and organize book contents
Reference site / build (push) Canceled after 0s
Reference site / build (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
export const contentsRoot = fileURLToPath(new URL('../../contents/', import.meta.url));
|
||||
|
||||
export function normalizeBase(value = '/') {
|
||||
if (!/^\/(?:[A-Za-z0-9_-]+\/)*[A-Za-z0-9_-]*\/?$/.test(value)) {
|
||||
throw new Error('SITE_BASE must be / or an absolute path of URL-safe segments');
|
||||
}
|
||||
return value === '/' ? '/' : `/${value.split('/').filter(Boolean).join('/')}/`;
|
||||
}
|
||||
|
||||
/** Rewrite Markdown document links, not code, fragments, or external URLs. */
|
||||
export function documentHref(href, sourceFile, base = '/') {
|
||||
if (/^(?:[a-z][a-z\d+.-]*:|\/\/|#)/i.test(href)) return href;
|
||||
const match = href.match(/^([^?#]+\.md)([?#].*)?$/i);
|
||||
if (!match) return href;
|
||||
const filename = path.resolve(path.dirname(sourceFile), decodeURIComponent(match[1]));
|
||||
const relative = path.relative(contentsRoot, filename);
|
||||
if (relative.startsWith('..') || path.isAbsolute(relative)) {
|
||||
throw new Error(`Markdown link outside contents/: ${href} in ${sourceFile}`);
|
||||
}
|
||||
const slug = relative.replace(/\.md$/i, '').split(path.sep).map(encodeURIComponent).join('/');
|
||||
return `${normalizeBase(base)}book/${slug}/${match[2] ?? ''}`;
|
||||
}
|
||||
|
||||
export default function documentLinks({ base = '/' } = {}) {
|
||||
return (tree, file) => {
|
||||
function walk(node) {
|
||||
if ((node.type === 'link' || node.type === 'definition') && typeof node.url === 'string') {
|
||||
node.url = documentHref(node.url, file.path, base);
|
||||
}
|
||||
for (const child of node.children ?? []) walk(child);
|
||||
}
|
||||
walk(tree);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import { existsSync } from 'node:fs';
|
||||
import { loadEnvFile } from 'node:process';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
// CLI environment wins; use the same optional .env file for Astro and link checks.
|
||||
const file = fileURLToPath(new URL('../.env', import.meta.url));
|
||||
if (existsSync(file)) loadEnvFile(file);
|
||||
Reference in New Issue
Block a user