mirror of
https://github.com/callumalpass/tasknotes.git
synced 2026-07-22 12:50:26 +00:00
docs: fix custom-site internal link routing
This commit is contained in:
parent
735706ead4
commit
3e40202a09
2 changed files with 63 additions and 3 deletions
|
|
@ -62,6 +62,24 @@ function parseMarkdown(raw) {
|
|||
return { fm, html };
|
||||
}
|
||||
|
||||
function splitHref(href) {
|
||||
const queryIndex = href.indexOf('?');
|
||||
const hashIndex = href.indexOf('#');
|
||||
let end = href.length;
|
||||
if (queryIndex !== -1 && queryIndex < end) end = queryIndex;
|
||||
if (hashIndex !== -1 && hashIndex < end) end = hashIndex;
|
||||
return { pathPart: href.slice(0, end), suffix: href.slice(end) };
|
||||
}
|
||||
|
||||
function mdLinkPathToUrl(linkPath, mdPath) {
|
||||
const pageDir = '/' + path.posix.dirname(mdPath).replace(/^\.(?:\/|$)/, '');
|
||||
const resolved = linkPath.startsWith('/')
|
||||
? path.posix.normalize(linkPath)
|
||||
: path.posix.normalize(path.posix.join(pageDir || '/', linkPath));
|
||||
const relativeMdPath = resolved.replace(/^\/+/, '');
|
||||
return mdPathToUrl(relativeMdPath);
|
||||
}
|
||||
|
||||
// Rewrite relative image src/href paths to absolute URL paths.
|
||||
// Markdown files reference assets relative to their own location, but the
|
||||
// built HTML is served from a URL path that doesn't match the source path
|
||||
|
|
@ -76,6 +94,24 @@ function resolveAssetPaths(html, mdPath) {
|
|||
});
|
||||
}
|
||||
|
||||
// Rewrite local markdown links to route URLs so links stay valid regardless
|
||||
// of the current page path (e.g. `foo.md` -> `/foo/`).
|
||||
function resolveMarkdownLinks(html, mdPath) {
|
||||
return html.replace(/(<a\b[^>]*\shref=")([^"]+)(")/g, (_, pre, href, post) => {
|
||||
if (!href) return _;
|
||||
if (href.startsWith('#')) return _;
|
||||
if (href.startsWith('//')) return _;
|
||||
if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(href)) return _;
|
||||
|
||||
const { pathPart, suffix } = splitHref(href);
|
||||
if (!pathPart) return _;
|
||||
if (!/\.md$/i.test(pathPart)) return _;
|
||||
|
||||
const rewritten = mdLinkPathToUrl(pathPart, mdPath);
|
||||
return pre + rewritten + suffix + post;
|
||||
});
|
||||
}
|
||||
|
||||
function extractTitle(html, fm) {
|
||||
if (fm.title) return fm.title;
|
||||
const m = html.match(/<h1[^>]*>([\s\S]*?)<\/h1>/);
|
||||
|
|
@ -158,6 +194,26 @@ async function ensureDir(p) {
|
|||
await fs.mkdir(p, { recursive: true });
|
||||
}
|
||||
|
||||
async function listMarkdownFiles(rootDir) {
|
||||
const files = [];
|
||||
|
||||
async function walk(dir) {
|
||||
const entries = await fs.readdir(dir, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
const fullPath = path.join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
await walk(fullPath);
|
||||
continue;
|
||||
}
|
||||
if (!entry.isFile() || !entry.name.endsWith('.md')) continue;
|
||||
files.push(path.relative(rootDir, fullPath).split(path.sep).join('/'));
|
||||
}
|
||||
}
|
||||
|
||||
await walk(rootDir);
|
||||
return files;
|
||||
}
|
||||
|
||||
async function readSource(mdPath) {
|
||||
// Local override takes precedence over the source docs file
|
||||
const override = path.join(SRC, 'overrides', mdPath);
|
||||
|
|
@ -204,8 +260,10 @@ async function main() {
|
|||
await fs.copyFile(cname, path.join(DIST, 'CNAME'));
|
||||
}
|
||||
|
||||
// Build every page listed in the nav
|
||||
const pages = flattenNav(nav);
|
||||
// Build every markdown doc so cross-links outside the nav still resolve
|
||||
const navPages = flattenNav(nav);
|
||||
const allDocPages = await listMarkdownFiles(DOCS);
|
||||
const pages = [...new Set([...navPages, ...allDocPages])];
|
||||
let built = 0, skipped = 0;
|
||||
|
||||
for (const mdPath of pages) {
|
||||
|
|
@ -213,7 +271,7 @@ async function main() {
|
|||
if (!raw) { skipped++; continue; }
|
||||
|
||||
const { fm, html: rawHtml } = parseMarkdown(raw);
|
||||
const html = resolveAssetPaths(rawHtml, mdPath);
|
||||
const html = resolveMarkdownLinks(resolveAssetPaths(rawHtml, mdPath), mdPath);
|
||||
const url = mdPathToUrl(mdPath);
|
||||
const title = extractTitle(html, fm);
|
||||
const body = stripH1(html);
|
||||
|
|
|
|||
|
|
@ -35,3 +35,5 @@ Example:
|
|||
- Thanks to @martin-forge for reporting
|
||||
- Consolidated documentation cleanup for accuracy and clarity across API, webhook, NLP, privacy, settings, and view docs (corrected outdated endpoint/behavior details, normalized current settings paths, and tightened non-release prose)
|
||||
- Fixed a broken docs cross-reference from Property Types Reference to Task Properties settings
|
||||
- Fixed docs site link generation so internal Markdown links resolve to route URLs instead of broken `.md` paths (for example `/views/default-base-templates/`)
|
||||
- Fixed docs release-note links by building all Markdown docs pages, including pages not listed directly in sidebar nav
|
||||
|
|
|
|||
Loading…
Reference in a new issue