Add resolveRefs transform
Provide a transformation function that maps absolute references to resources into relative references based on the location of a page. This makes it possible to use the same links across multiple pages in the hierarchy that works when loaded as files from the filesystem.
This commit is contained in:
parent
7aa937a7e9
commit
17f8693eae
4 changed files with 105 additions and 2 deletions
52
utils/resolve-refs.ts
Normal file
52
utils/resolve-refs.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
import * as posix from "node:path/posix";
|
||||
import { Node, Element } from "antihtml";
|
||||
|
||||
function shallowCopyElement(element: Element) {
|
||||
const copy = new Element(element.name);
|
||||
copy.attributes = new Map(element.attributes);
|
||||
copy.childNodes = element.childNodes;
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
Resolves absolute href attributes in a and link elements the Node tree into relative references from the given directory.
|
||||
|
||||
@param node Node tree to transform
|
||||
@param dir Absolute path to directory to resolve references from.
|
||||
@returns new node tree with href attributes transformed, or the original node if no transformations took place.
|
||||
*/
|
||||
export function resolveRefs(node: Node, dir: string) {
|
||||
if (!(node instanceof Element)) {
|
||||
return node;
|
||||
}
|
||||
let resolvedNode = node;
|
||||
const name = node.name;
|
||||
if (
|
||||
(name === "link" || name === "a")
|
||||
&& node.attributes.has("href")
|
||||
) {
|
||||
const original = node.attributes.get("href")!
|
||||
/* node:coverage ignore next 3 */
|
||||
if (!original.startsWith("/")) {
|
||||
console.log(`Warning: found relative href to ${original}`);
|
||||
} else {
|
||||
const ref = posix.relative(dir, original);
|
||||
resolvedNode = shallowCopyElement(node);
|
||||
resolvedNode.attributes.set("href", ref);
|
||||
}
|
||||
}
|
||||
const resolvedChildren: Node[] = [];
|
||||
let modifiedChildren = false;
|
||||
for (const child of resolvedNode.childNodes) {
|
||||
const resolvedChild = resolveRefs(child, dir);
|
||||
if (child !== resolvedChild) {
|
||||
modifiedChildren = true;
|
||||
}
|
||||
resolvedChildren.push(resolvedChild);
|
||||
}
|
||||
if (modifiedChildren) {
|
||||
resolvedNode = shallowCopyElement(node);
|
||||
resolvedNode.childNodes = resolvedChildren;
|
||||
}
|
||||
return resolvedNode;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue