OOKNET                             [ /  search the index  ]  
──────────────────────────────────────────────────────────────────────────────────────
══════════════════════════════════════════════════════════════════════════════════════
OOKNET   [ /  search  ]  
────────────────────────────────────────────────
════════════════════════════════════════════════
 
 
master @ 122 LINES
 
[ HISTORY ]  [ UP ]
 

// Wikilink resolution. The map is built by scanning content frontmatter
// directly (remark plugins run outside astro:content), keyed by every
// name an author might reach for: file id and title.
import { readdirSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { readManifests, registerOf, registerLabel } from "./registers";

export type WikiMap = Map<string, string>;

const FM_RE = /^---\n([\s\S]*?)\n---/;

function fmField(fm: string, key: string): string | null {
  const m = fm.match(new RegExp(`^${key}:\\s*["']?(.+?)["']?\\s*$`, "m"));
  return m ? m[1] : null;
}

function mdFiles(dir: string, prefix = ""): string[] {
  let out: string[] = [];
  for (const entry of readdirSync(dir, { withFileTypes: true })) {
    const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
    if (entry.isDirectory()) out = out.concat(mdFiles(join(dir, entry.name), rel))
;
    else if (entry.name.endsWith(".md")) out.push(rel);
  }
  return out;
}

function scan(map: WikiMap, dir: string, urlFor: (id: string) => string) {
  let files: string[];
  try {
    files = mdFiles(dir);
  } catch {
    return; // collection dir may not exist yet
  }
  for (const file of files) {
    const id = file.replace(/\.md$/, "");
    const url = urlFor(id);
    const fm = readFileSync(join(dir, file), "utf8").match(FM_RE)?.[1] ?? "";
    if (fmField(fm, "draft") === "true") continue;
    map.set(id.toLowerCase(), url);
    const title = fmField(fm, "title");
    if (title) map.set(title.toLowerCase(), url);
  }
}

export function buildWikiMap(contentDir = "src/content"): WikiMap {
  const map: WikiMap = new Map();
  scan(map, join(contentDir, "kb"), (id) => `/kb/${id}/`);
  return map;
}

export function resolveWikilink(target: string, map: WikiMap): string | null {
  return map.get(target.trim().toLowerCase()) ?? null;
}

// ── Backlinks ────────────────────────────────────────────────────────
// The same graph, inverted: for each page, which pages link to it.

export interface Backlink {
  url: string;
  label: string;
}

const WIKI_RE = /\[\[([^\]|]+)(?:\|[^\]]+)?\]\]/g;

/** Wikilink targets in a markdown body. Code is stripped first so
 *  literal `[[syntax]]` in docs doesn't count as a reference - mirrors
 *  the remark plugin, which never sees code as text nodes. */
export function extractWikiTargets(body: string): string[] {
  const stripped = body
    .replace(/^(?:```|~~~)[\s\S]*?^(?:```|~~~)/gm, "")
    .replace(/`[^`\n]+`/g, "");
  return [...stripped.matchAll(WIKI_RE)].map((m) => m[1].trim());
}

function scanSources(
  out: Map<string, Backlink[]>,
  map: WikiMap,
  dir: string,
  urlFor: (id: string) => string,
  labelFor: (id: string, fm: string) => string,
) {
  let files: string[];
  try {
    files = mdFiles(dir);
  } catch {
    return;
  }
  for (const file of files) {
    const id = file.replace(/\.md$/, "");
    const raw = readFileSync(join(dir, file), "utf8");
    const fmMatch = raw.match(FM_RE);
    const fm = fmMatch?.[1] ?? "";
    if (fmField(fm, "draft") === "true") continue;
    const srcUrl = urlFor(id);
    const targets = new Set<string>();
    for (const t of extractWikiTargets(raw.slice(fmMatch?.[0].length ?? 0))) {
      const url = resolveWikilink(t, map);
      if (url && url !== srcUrl) targets.add(url);
    }
    for (const target of targets) {
      if (!out.has(target)) out.set(target, []);
      out.get(target)!.push({ url: srcUrl, label: labelFor(id, fm) });
    }
  }
}

/** Target url ? pages whose body links to it. Dead links and
 *  self-references are dropped; sources carry their register label. */
export function buildBacklinks(contentDir = "src/content"): Map<string, Backlink[]
> {
  const map = buildWikiMap(contentDir);
  const manifests = readManifests(join(contentDir, "kb"));
  const out = new Map<string, Backlink[]>();
  scanSources(out, map, join(contentDir, "kb"), (id) => `/kb/${id}/`, (id, fm) => 
{
    const title = fmField(fm, "title") ?? id;
    return `${registerLabel(registerOf(id, manifests).register)} - ${title.toUpper
Case()}`;
  });
  for (const list of out.values()) {
    list.sort((a, b) => a.label.localeCompare(b.label, "en", { numeric: true }));
  }
  return out;
}

// Wikilink resolution. The map is built by 
scanning content frontmatter
// directly (remark plugins run outside astr
o:content), keyed by every
// name an author might reach for: file id a
nd title.
import { readdirSync, readFileSync } from "n
ode:fs";
import { join } from "node:path";
import { readManifests, registerOf, register
Label } from "./registers";

export type WikiMap = Map<string, string>;

const FM_RE = /^---\n([\s\S]*?)\n---/;

function fmField(fm: string, key: string): s
tring | null {
  const m = fm.match(new RegExp(`^${key}:\\s
*["']?(.+?)["']?\\s*$`, "m"));
  return m ? m[1] : null;
}

function mdFiles(dir: string, prefix = ""): 
string[] {
  let out: string[] = [];
  for (const entry of readdirSync(dir, { wit
hFileTypes: true })) {
    const rel = prefix ? `${prefix}/${entry.
name}` : entry.name;
    if (entry.isDirectory()) out = out.conca
t(mdFiles(join(dir, entry.name), rel));
    else if (entry.name.endsWith(".md")) out
.push(rel);
  }
  return out;
}

function scan(map: WikiMap, dir: string, url
For: (id: string) => string) {
  let files: string[];
  try {
    files = mdFiles(dir);
  } catch {
    return; // collection dir may not exist 
yet
  }
  for (const file of files) {
    const id = file.replace(/\.md$/, "");
    const url = urlFor(id);
    const fm = readFileSync(join(dir, file),
 "utf8").match(FM_RE)?.[1] ?? "";
    if (fmField(fm, "draft") === "true") con
tinue;
    map.set(id.toLowerCase(), url);
    const title = fmField(fm, "title");
    if (title) map.set(title.toLowerCase(), 
url);
  }
}

export function buildWikiMap(contentDir = "s
rc/content"): WikiMap {
  const map: WikiMap = new Map();
  scan(map, join(contentDir, "kb"), (id) => 
`/kb/${id}/`);
  return map;
}

export function resolveWikilink(target: stri
ng, map: WikiMap): string | null {
  return map.get(target.trim().toLowerCase()
) ?? null;
}

// ── Backlinks ────────────────────────────
────────────────────────────
// The same graph, inverted: for each page, 
which pages link to it.

export interface Backlink {
  url: string;
  label: string;
}

const WIKI_RE = /\[\[([^\]|]+)(?:\|[^\]]+)?\
]\]/g;

/** Wikilink targets in a markdown body. Cod
e is stripped first so
 *  literal `[[syntax]]` in docs doesn't cou
nt as a reference - mirrors
 *  the remark plugin, which never sees code
 as text nodes. */
export function extractWikiTargets(body: str
ing): string[] {
  const stripped = body
    .replace(/^(?:```|~~~)[\s\S]*?^(?:```|~~
~)/gm, "")
    .replace(/`[^`\n]+`/g, "");
  return [...stripped.matchAll(WIKI_RE)].map
((m) => m[1].trim());
}

function scanSources(
  out: Map<string, Backlink[]>,
  map: WikiMap,
  dir: string,
  urlFor: (id: string) => string,
  labelFor: (id: string, fm: string) => stri
ng,
) {
  let files: string[];
  try {
    files = mdFiles(dir);
  } catch {
    return;
  }
  for (const file of files) {
    const id = file.replace(/\.md$/, "");
    const raw = readFileSync(join(dir, file)
, "utf8");
    const fmMatch = raw.match(FM_RE);
    const fm = fmMatch?.[1] ?? "";
    if (fmField(fm, "draft") === "true") con
tinue;
    const srcUrl = urlFor(id);
    const targets = new Set<string>();
    for (const t of extractWikiTargets(raw.s
lice(fmMatch?.[0].length ?? 0))) {
      const url = resolveWikilink(t, map);
      if (url && url !== srcUrl) targets.add
(url);
    }
    for (const target of targets) {
      if (!out.has(target)) out.set(target, 
[]);
      out.get(target)!.push({ url: srcUrl, l
abel: labelFor(id, fm) });
    }
  }
}

/** Target url ? pages whose body links to i
t. Dead links and
 *  self-references are dropped; sources car
ry their register label. */
export function buildBacklinks(contentDir = 
"src/content"): Map<string, Backlink[]> {
  const map = buildWikiMap(contentDir);
  const manifests = readManifests(join(conte
ntDir, "kb"));
  const out = new Map<string, Backlink[]>();
  scanSources(out, map, join(contentDir, "kb
"), (id) => `/kb/${id}/`, (id, fm) => {
    const title = fmField(fm, "title") ?? id
;
    return `${registerLabel(registerOf(id, m
anifests).register)} - ${title.toUpperCase()
}`;
  });
  for (const list of out.values()) {
    list.sort((a, b) => a.label.localeCompar
e(b.label, "en", { numeric: true }));
  }
  return out;
}
 
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET