feat: added headers to links in local pages
This commit is contained in:
@@ -57,20 +57,32 @@ export function normalizeObsidianMarkdown(content) {
|
||||
|
||||
// 2. Convert wikilinks with label: [[target-slug|Custom Label]] -> [Custom Label](/posts/target-slug/)
|
||||
normalized = normalized.replace(/\[\[([^|\]]+)\|([^\]]+)\]\]/g, (match, target, label) => {
|
||||
const slug = slugify(target);
|
||||
return `[${label.trim()}](/posts/${slug}/)`;
|
||||
return `[${label.trim()}](${wikilinkUrl(target)})`;
|
||||
});
|
||||
|
||||
// 3. Convert simple wikilinks: [[target-slug]] -> [target-slug](/posts/target-slug/)
|
||||
normalized = normalized.replace(/\[\[([^\]]+)\]\]/g, (match, target) => {
|
||||
const trimmed = target.trim();
|
||||
const slug = slugify(trimmed);
|
||||
return `[${trimmed}](/posts/${slug}/)`;
|
||||
return `[${trimmed}](${wikilinkUrl(trimmed)})`;
|
||||
});
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
function wikilinkUrl(target) {
|
||||
const trimmed = target.trim();
|
||||
const fragmentIndex = trimmed.indexOf("#");
|
||||
|
||||
if (fragmentIndex === -1) {
|
||||
return `/posts/${slugify(trimmed)}/`;
|
||||
}
|
||||
|
||||
const noteSlug = slugify(trimmed.slice(0, fragmentIndex));
|
||||
const headerSlug = slugify(trimmed.slice(fragmentIndex + 1));
|
||||
const fragment = headerSlug ? `#${headerSlug}` : "";
|
||||
return `/posts/${noteSlug}/${fragment}`;
|
||||
}
|
||||
|
||||
function slugify(text) {
|
||||
return text
|
||||
.toLowerCase()
|
||||
|
||||
@@ -3,10 +3,27 @@ import assert from "node:assert/strict";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import http from "node:http";
|
||||
import { createServer, triggerEleventyBuild } from "../server.js";
|
||||
import { createServer, normalizeObsidianMarkdown, triggerEleventyBuild } from "../server.js";
|
||||
|
||||
const TEST_SECRET = "super-secret-test-token";
|
||||
|
||||
test("Obsidian normalization: preserves linked note header fragments", () => {
|
||||
const normalized = normalizeObsidianMarkdown(
|
||||
"See [[a note#header one]] and [[another note#Second Header|the other section]]."
|
||||
);
|
||||
|
||||
assert.match(
|
||||
normalized,
|
||||
/\[a note#header one\]\(\/posts\/a-note\/#header-one\)/,
|
||||
"A wikilink header must become a URL fragment on the linked note"
|
||||
);
|
||||
assert.match(
|
||||
normalized,
|
||||
/\[the other section\]\(\/posts\/another-note\/#second-header\)/,
|
||||
"Aliased wikilinks must retain their linked-note header fragment"
|
||||
);
|
||||
});
|
||||
|
||||
test("Ingestion API: rejects requests without proper Bearer token", async () => {
|
||||
const tmpDir = fs.mkdtempSync(path.join(process.cwd(), "test-tmp-site-"));
|
||||
const tmpPosts = fs.mkdtempSync(path.join(process.cwd(), "test-tmp-posts-"));
|
||||
|
||||
Reference in New Issue
Block a user