UNPKG

htex

Version:

Academic writing for the 21st century

84 lines (64 loc) 2.27 kB
import path from "path"; export function isRootRelative (url) { return url.startsWith("/"); } export function isAbsolute (url) { return /^[a-z]+:/.test(url); } export function relative (url) { if (!url) { return ""; } if (url?.url) { // page object url = url.url; } let pagePath = url.replace(/[^/]+$/, ""); let ret = path.relative(pagePath, "/"); return ret || "."; } export function absolutize (...urls) { let host = this?.ctx.main.domain ?? "https://phd.verou.me"; let ret = host; for (let url of urls.reverse()) { ret = new URL(url, ret); } return ret; } export function rebase_url (url, from_base, to_base = this?.page.url) { // Use a dummy base URL to ensure the bases are absolute let dummyBase = 'https://dummy/'; // Resolve old_base and new_base to absolute URLs let absoluteOldBase = new URL(from_base, dummyBase); let absoluteNewBase = new URL(to_base, dummyBase); // Convert the url relative to the old base to an absolute URL let absoluteUrl = new URL(url, absoluteOldBase); // Determine the relative path from the new base let relativeUrl = path.relative(absoluteNewBase.pathname, absoluteUrl.pathname); let local = absoluteUrl.search + absoluteUrl.hash; if (local && !relativeUrl.endsWith("/")) { relativeUrl = relativeUrl + "/"; } return relativeUrl + local; } export function relativize (url) { return rebase_url(url, "/", this.page.url); } export const URL_ATTRIBUTES_TO_ELEMENT = { src: ["img", "video", "audio", "iframe", "object", "embed", "script", "source"], href: ["a", "link", "base"], data: ["object"], poster: ["video"], }; export const URL_ELEMENTS = Object.values(URL_ATTRIBUTES_TO_ELEMENT).flat(); export const URL_ATTRIBUTES = Object.keys(URL_ATTRIBUTES_TO_ELEMENT); export const URL_ELEMENTS_PATTERN = RegExp(`(?<=<(${ URL_ELEMENTS.join("|") })\\s+(?:[^>]*?\\s+)?(${ URL_ATTRIBUTES.join("|") })=")([^"]+)(?=")`, "gisu"); /** Go over embedded resources and make them relative to base_url */ export function relativize_urls (html, content_url) { return html.replace(URL_ELEMENTS_PATTERN, (url, tag, attribute) => { if (!URL_ATTRIBUTES_TO_ELEMENT[attribute]?.includes(tag) || isAbsolute(url)) { return url; } return rebase_url(url, content_url, this.page.url); }); }