@neosjs/vitepress-theme
Version:
NeosJS VitePress theme
90 lines (89 loc) • 3.49 kB
JavaScript
import { inBrowser } from "vitepress";
export const EXTERNAL_URL_RE = /^[a-z]+:/i;
export const APPEARANCE_KEY = "neos-theme-appearance";
export const HASH_RE = /#.*$/;
export const EXT_RE = /(index)?\.(md|html)$/;
export { inBrowser };
export const notFoundPageData = {
relativePath: "",
filePath: "",
title: "404",
description: "Not Found",
headers: [],
frontmatter: { sidebar: false, layout: "page" },
lastUpdated: 0,
isNotFound: true
};
export function isActive(currentPath, matchPath, asRegex = false) {
if (matchPath === void 0) return false;
currentPath = normalize(`/${currentPath}`);
if (asRegex) return new RegExp(matchPath).test(currentPath);
if (normalize(matchPath) !== currentPath) return false;
const hashMatch = matchPath.match(HASH_RE);
if (hashMatch) return (inBrowser ? location.hash : "") === hashMatch[0];
return true;
}
export function normalize(path) {
return decodeURI(path).replace(HASH_RE, "").replace(EXT_RE, "");
}
export function isExternal(path) {
return EXTERNAL_URL_RE.test(path);
}
export function resolveSiteDataByRoute(siteData, relativePath) {
const localeIndex = Object.keys(siteData.locales).find(
(key) => key !== "root" && !isExternal(key) && isActive(relativePath, `/${key}/`, true)
) || "root";
return Object.assign({}, siteData, {
localeIndex,
lang: siteData.locales[localeIndex]?.lang ?? siteData.lang,
dir: siteData.locales[localeIndex]?.dir ?? siteData.dir,
title: siteData.locales[localeIndex]?.title ?? siteData.title,
titleTemplate: siteData.locales[localeIndex]?.titleTemplate ?? siteData.titleTemplate,
description: siteData.locales[localeIndex]?.description ?? siteData.description,
head: mergeHead(siteData.head, siteData.locales[localeIndex]?.head ?? []),
themeConfig: {
...siteData.themeConfig,
...siteData.locales[localeIndex]?.themeConfig
}
});
}
export function createTitle(siteData, pageData) {
const title = pageData.title || siteData.title;
const template = pageData.titleTemplate ?? siteData.titleTemplate;
if (typeof template === "string" && template.includes(":title")) {
return template.replace(/:title/g, title);
}
const templateString = createTitleTemplate(siteData.title, template);
return `${title}${templateString}`;
}
function createTitleTemplate(siteTitle, template) {
if (template === false) return "";
if (template === true || template === void 0) return ` | ${siteTitle}`;
if (siteTitle === template) return "";
return ` | ${template}`;
}
function hasTag(head, tag) {
const [tagType, tagAttrs] = tag;
if (tagType !== "meta") return false;
const keyAttr = Object.entries(tagAttrs)[0];
if (keyAttr == null) return false;
return head.some(
([type, attrs]) => type === tagType && attrs[keyAttr[0]] === keyAttr[1]
);
}
export function mergeHead(prev, curr) {
return [...prev.filter((tagAttrs) => !hasTag(curr, tagAttrs)), ...curr];
}
const INVALID_CHAR_REGEX = /[\u0000-\u001F"#$&*+,:;<=>?[\]^`{|}\u007F]/g;
const DRIVE_LETTER_REGEX = /^[a-z]:/i;
export function sanitizeFileName(name) {
const match = DRIVE_LETTER_REGEX.exec(name);
const driveLetter = match ? match[0] : "";
return driveLetter + name.slice(driveLetter.length).replace(INVALID_CHAR_REGEX, "_").replace(/(^|\/)_+(?=[^/]*$)/, "$1");
}
export function slash(p) {
return p.replace(/\\/g, "/");
}
export function escapeRegExp(str) {
return str.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
}