feat: add formatDate and getIconCode utility exports

This commit is contained in:
saberzero1 2026-04-03 15:04:35 +02:00
parent ef25479647
commit 8b6e32ba07
No known key found for this signature in database
22 changed files with 426 additions and 71 deletions

3
dist/date.d.ts vendored Normal file
View file

@ -0,0 +1,3 @@
declare function formatDate(d: Date, locale?: string): string;
export { formatDate };

12
dist/date.js vendored Normal file
View file

@ -0,0 +1,12 @@
// src/date.ts
function formatDate(d, locale = "en-US") {
return d.toLocaleDateString(locale, {
year: "numeric",
month: "short",
day: "2-digit",
});
}
export { formatDate };
//# sourceMappingURL=date.js.map
//# sourceMappingURL=date.js.map

1
dist/date.js.map vendored Normal file
View file

@ -0,0 +1 @@
{"version":3,"sources":["../src/date.ts"],"names":[],"mappings":";AAAO,SAAS,UAAA,CAAW,CAAA,EAAS,MAAA,GAAiB,OAAA,EAAiB;AACpE,EAAA,OAAO,CAAA,CAAE,mBAAmB,MAAA,EAAQ;AAAA,IAClC,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO,OAAA;AAAA,IACP,GAAA,EAAK;AAAA,GACN,CAAA;AACH","file":"date.js","sourcesContent":["export function formatDate(d: Date, locale: string = \"en-US\"): string {\n return d.toLocaleDateString(locale, {\n year: \"numeric\",\n month: \"short\",\n day: \"2-digit\",\n });\n}\n"]}

5
dist/dom.d.ts vendored
View file

@ -1,5 +1,8 @@
declare function removeAllChildren(el: HTMLElement): void;
declare function registerEscapeHandler(outsideContainer: HTMLElement | null, onEscape: () => void): () => void;
declare function registerEscapeHandler(
outsideContainer: HTMLElement | null,
onEscape: () => void,
): () => void;
declare function normalizeRelativeURLs(html: Document, baseUrl: string): void;
export { normalizeRelativeURLs, registerEscapeHandler, removeAllChildren };

15
dist/dom.js vendored
View file

@ -5,8 +5,7 @@ function removeAllChildren(el) {
}
}
function registerEscapeHandler(outsideContainer, onEscape) {
if (!outsideContainer) return () => {
};
if (!outsideContainer) return () => {};
const onClick = (e) => {
if (!outsideContainer.classList.contains("active")) {
return;
@ -39,7 +38,15 @@ function normalizeRelativeURLs(html, baseUrl) {
const attr = el.hasAttribute("href") ? "href" : "src";
const val = el.getAttribute(attr);
if (!val) continue;
if (val.startsWith("http://") || val.startsWith("https://") || val.startsWith("mailto:") || val.startsWith("tel:") || val.startsWith("#") || val.startsWith("/") || val.startsWith("data:")) {
if (
val.startsWith("http://") ||
val.startsWith("https://") ||
val.startsWith("mailto:") ||
val.startsWith("tel:") ||
val.startsWith("#") ||
val.startsWith("/") ||
val.startsWith("data:")
) {
continue;
}
try {
@ -53,4 +60,4 @@ function normalizeRelativeURLs(html, baseUrl) {
export { normalizeRelativeURLs, registerEscapeHandler, removeAllChildren };
//# sourceMappingURL=dom.js.map
//# sourceMappingURL=dom.js.map
//# sourceMappingURL=dom.js.map

3
dist/emoji.d.ts vendored Normal file
View file

@ -0,0 +1,3 @@
declare function getIconCode(char: string): string;
export { getIconCode };

28
dist/emoji.js vendored Normal file
View file

@ -0,0 +1,28 @@
// src/emoji.ts
var U200D = String.fromCharCode(8205);
var UFE0Fg = /\uFE0F/g;
function getIconCode(char) {
return toCodePoint(char.indexOf(U200D) < 0 ? char.replace(UFE0Fg, "") : char);
}
function toCodePoint(unicodeSurrogates) {
const r = [];
let c = 0,
p = 0,
i = 0;
while (i < unicodeSurrogates.length) {
c = unicodeSurrogates.charCodeAt(i++);
if (p) {
r.push((65536 + ((p - 55296) << 10) + (c - 56320)).toString(16));
p = 0;
} else if (55296 <= c && c <= 56319) {
p = c;
} else {
r.push(c.toString(16));
}
}
return r.join("-");
}
export { getIconCode };
//# sourceMappingURL=emoji.js.map
//# sourceMappingURL=emoji.js.map

1
dist/emoji.js.map vendored Normal file
View file

@ -0,0 +1 @@
{"version":3,"sources":["../src/emoji.ts"],"names":[],"mappings":";AAAA,IAAM,KAAA,GAAQ,MAAA,CAAO,YAAA,CAAa,IAAI,CAAA;AACtC,IAAM,MAAA,GAAS,SAAA;AAER,SAAS,YAAY,IAAA,EAAsB;AAChD,EAAA,OAAO,WAAA,CAAY,IAAA,CAAK,OAAA,CAAQ,KAAK,CAAA,GAAI,CAAA,GAAI,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,GAAI,IAAI,CAAA;AAC9E;AAEA,SAAS,YAAY,iBAAA,EAAmC;AACtD,EAAA,MAAM,IAAc,EAAC;AACrB,EAAA,IAAI,CAAA,GAAI,CAAA,EACN,CAAA,GAAI,CAAA,EACJ,CAAA,GAAI,CAAA;AAEN,EAAA,OAAO,CAAA,GAAI,kBAAkB,MAAA,EAAQ;AACnC,IAAA,CAAA,GAAI,iBAAA,CAAkB,WAAW,CAAA,EAAG,CAAA;AACpC,IAAA,IAAI,CAAA,EAAG;AACL,MAAA,CAAA,CAAE,IAAA,CAAA,CAAM,SAAU,CAAA,GAAI,KAAA,IAAU,OAAO,CAAA,GAAI,KAAA,CAAA,EAAQ,QAAA,CAAS,EAAE,CAAC,CAAA;AAC/D,MAAA,CAAA,GAAI,CAAA;AAAA,IACN,CAAA,MAAA,IAAW,KAAA,IAAS,CAAA,IAAK,CAAA,IAAK,KAAA,EAAO;AACnC,MAAA,CAAA,GAAI,CAAA;AAAA,IACN,CAAA,MAAO;AACL,MAAA,CAAA,CAAE,IAAA,CAAK,CAAA,CAAE,QAAA,CAAS,EAAE,CAAC,CAAA;AAAA,IACvB;AAAA,EACF;AACA,EAAA,OAAO,CAAA,CAAE,KAAK,GAAG,CAAA;AACnB","file":"emoji.js","sourcesContent":["const U200D = String.fromCharCode(8205);\nconst UFE0Fg = /\\uFE0F/g;\n\nexport function getIconCode(char: string): string {\n return toCodePoint(char.indexOf(U200D) < 0 ? char.replace(UFE0Fg, \"\") : char);\n}\n\nfunction toCodePoint(unicodeSurrogates: string): string {\n const r: string[] = [];\n let c = 0,\n p = 0,\n i = 0;\n\n while (i < unicodeSurrogates.length) {\n c = unicodeSurrogates.charCodeAt(i++);\n if (p) {\n r.push((65536 + ((p - 55296) << 10) + (c - 56320)).toString(16));\n p = 0;\n } else if (55296 <= c && c <= 56319) {\n p = c;\n } else {\n r.push(c.toString(16));\n }\n }\n return r.join(\"-\");\n}\n"]}

16
dist/escape.js vendored
View file

@ -1,11 +1,21 @@
// src/escape.ts
function escapeHTML(unsafe) {
return unsafe.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#039;");
return unsafe
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;")
.replaceAll("'", "&#039;");
}
function unescapeHTML(html) {
return html.replaceAll("&amp;", "&").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&quot;", '"').replaceAll("&#039;", "'");
return html
.replaceAll("&amp;", "&")
.replaceAll("&lt;", "<")
.replaceAll("&gt;", ">")
.replaceAll("&quot;", '"')
.replaceAll("&#039;", "'");
}
export { escapeHTML, unescapeHTML };
//# sourceMappingURL=escape.js.map
//# sourceMappingURL=escape.js.map
//# sourceMappingURL=escape.js.map

48
dist/index.d.ts vendored
View file

@ -1,8 +1,40 @@
export { RelativeURL, SimpleSlug, TransformOptions, endsWith, getAllSegmentPrefixes, getBasePath, getFileExtension, getFullSlug, getFullSlugFromUrl, isAbsoluteURL, isFilePath, isFolderPath, isFullSlug, isRelativeURL, isSimpleSlug, joinSegments, pathToRoot, resolveBasePath, resolvePath, resolveRelative, simplifySlug, slugTag, slugifyFilePath, slugifyPath, splitAnchor, stripSlashes, transformInternalLink, transformLink, trimSuffix } from './path.js';
export { normalizeRelativeURLs, registerEscapeHandler, removeAllChildren } from './dom.js';
export { capitalize, classNames } from './lang.js';
export { escapeHTML, unescapeHTML } from './escape.js';
export { htmlToJsx } from './jsx.js';
export { FilePath, FullSlug } from '@quartz-community/types';
import 'hast-util-to-jsx-runtime';
import 'hast';
export {
RelativeURL,
SimpleSlug,
TransformOptions,
endsWith,
getAllSegmentPrefixes,
getBasePath,
getFileExtension,
getFullSlug,
getFullSlugFromUrl,
isAbsoluteURL,
isFilePath,
isFolderPath,
isFullSlug,
isRelativeURL,
isSimpleSlug,
joinSegments,
pathToRoot,
resolveBasePath,
resolvePath,
resolveRelative,
simplifySlug,
slugTag,
slugifyFilePath,
slugifyPath,
splitAnchor,
stripSlashes,
transformInternalLink,
transformLink,
trimSuffix,
} from "./path.js";
export { normalizeRelativeURLs, registerEscapeHandler, removeAllChildren } from "./dom.js";
export { capitalize, classNames } from "./lang.js";
export { escapeHTML, unescapeHTML } from "./escape.js";
export { htmlToJsx } from "./jsx.js";
export { formatDate } from "./date.js";
export { getIconCode } from "./emoji.js";
export { FilePath, FullSlug } from "@quartz-community/types";
import "hast-util-to-jsx-runtime";
import "hast";

168
dist/index.js vendored
View file

@ -1,7 +1,7 @@
import { slug } from 'github-slugger';
import { toJsxRuntime } from 'hast-util-to-jsx-runtime';
import { jsxs, jsx, Fragment } from 'preact/jsx-runtime';
import { h } from 'preact';
import { slug } from "github-slugger";
import { toJsxRuntime } from "hast-util-to-jsx-runtime";
import { jsxs, jsx, Fragment } from "preact/jsx-runtime";
import { h } from "preact";
// src/path.ts
function isFilePath(s) {
@ -14,7 +14,7 @@ function isFullSlug(s) {
return validStart && validEnding && !_containsForbiddenCharacters(s);
}
function isSimpleSlug(s) {
const validStart = !(s.startsWith(".") || s.length > 1 && s.startsWith("/"));
const validStart = !(s.startsWith(".") || (s.length > 1 && s.startsWith("/")));
const validEnding = !endsWith(s, "index");
return validStart && !_containsForbiddenCharacters(s) && validEnding && !_hasFileExtension(s);
}
@ -60,7 +60,10 @@ function joinSegments(...args) {
if (args.length === 0) {
return "";
}
let joined = args.filter((segment) => segment !== "" && segment !== "/").map((segment) => stripSlashes(segment)).join("/");
let joined = args
.filter((segment) => segment !== "" && segment !== "/")
.map((segment) => stripSlashes(segment))
.join("/");
const first = args[0];
const last = args[args.length - 1];
if (first?.startsWith("/")) {
@ -106,7 +109,12 @@ function getFileExtension(s) {
return s.match(/\.[A-Za-z0-9]+$/)?.[0];
}
function isFolderPath(fplike) {
return fplike.endsWith("/") || endsWith(fplike, "index") || endsWith(fplike, "index.md") || endsWith(fplike, "index.html");
return (
fplike.endsWith("/") ||
endsWith(fplike, "index") ||
endsWith(fplike, "index.md") ||
endsWith(fplike, "index.html")
);
}
function getAllSegmentPrefixes(path) {
const segments = path.split("/");
@ -117,7 +125,12 @@ function getAllSegmentPrefixes(path) {
return results;
}
function pathToRoot(slug) {
let rootPath = slug.split("/").filter((x) => x !== "").slice(0, -1).map((_) => "..").join("/");
let rootPath = slug
.split("/")
.filter((x) => x !== "")
.slice(0, -1)
.map((_) => "..")
.join("/");
if (rootPath.length === 0) {
rootPath = ".";
}
@ -136,7 +149,10 @@ function splitAnchor(link) {
return [fp, slugged];
}
function slugTag(tag) {
return tag.split("/").map((tagSegment) => _sluggify(tagSegment)).join("/");
return tag
.split("/")
.map((tagSegment) => _sluggify(tagSegment))
.join("/");
}
function transformInternalLink(link) {
const [fplike, anchor] = splitAnchor(decodeURI(link));
@ -155,7 +171,8 @@ function transformLink(src, target, opts) {
if (opts.strategy === "relative") {
return targetSlug;
} else {
const effectiveSrc = !endsWith(src, "index") && opts.allSlugs.includes(`${src}/index`) ? `${src}/index` : src;
const effectiveSrc =
!endsWith(src, "index") && opts.allSlugs.includes(`${src}/index`) ? `${src}/index` : src;
const folderTail = isFolderPath(targetSlug) ? "/" : "";
const canonicalSlug = stripSlashes(targetSlug.slice(".".length));
const [targetCanonical, targetAnchor] = splitAnchor(canonicalSlug);
@ -186,9 +203,18 @@ function transformLink(src, target, opts) {
}
}
function slugifyPath(s) {
return s.split("/").map(
(segment) => segment.replace(/\s/g, "-").replace(/&/g, "-and-").replace(/%/g, "-percent").replace(/\?/g, "").replace(/#/g, "")
).join("/").replace(/\/$/, "");
return s
.split("/")
.map((segment) =>
segment
.replace(/\s/g, "-")
.replace(/&/g, "-and-")
.replace(/%/g, "-percent")
.replace(/\?/g, "")
.replace(/#/g, ""),
)
.join("/")
.replace(/\/$/, "");
}
function _sluggify(s) {
return slugifyPath(s);
@ -219,8 +245,7 @@ function removeAllChildren(el) {
}
}
function registerEscapeHandler(outsideContainer, onEscape) {
if (!outsideContainer) return () => {
};
if (!outsideContainer) return () => {};
const onClick = (e) => {
if (!outsideContainer.classList.contains("active")) {
return;
@ -253,7 +278,15 @@ function normalizeRelativeURLs(html, baseUrl) {
const attr = el.hasAttribute("href") ? "href" : "src";
const val = el.getAttribute(attr);
if (!val) continue;
if (val.startsWith("http://") || val.startsWith("https://") || val.startsWith("mailto:") || val.startsWith("tel:") || val.startsWith("#") || val.startsWith("/") || val.startsWith("data:")) {
if (
val.startsWith("http://") ||
val.startsWith("https://") ||
val.startsWith("mailto:") ||
val.startsWith("tel:") ||
val.startsWith("#") ||
val.startsWith("/") ||
val.startsWith("data:")
) {
continue;
}
try {
@ -275,10 +308,20 @@ function classNames(...classes) {
// src/escape.ts
function escapeHTML(unsafe) {
return unsafe.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#039;");
return unsafe
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;")
.replaceAll("'", "&#039;");
}
function unescapeHTML(html) {
return html.replaceAll("&amp;", "&").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&quot;", '"').replaceAll("&#039;", "'");
return html
.replaceAll("&amp;", "&")
.replaceAll("&lt;", "<")
.replaceAll("&gt;", ">")
.replaceAll("&quot;", '"')
.replaceAll("&#039;", "'");
}
function childrenToString(children) {
if (typeof children === "string") return children;
@ -286,9 +329,15 @@ function childrenToString(children) {
return String(children ?? "");
}
var builtinComponents = {
table: (props) => /* @__PURE__ */ jsx("div", { class: "table-container", children: /* @__PURE__ */ jsx("table", { ...props }) }),
style: ({ children, ...rest }) => h("style", { ...rest, dangerouslySetInnerHTML: { __html: childrenToString(children) } }),
script: ({ children, ...rest }) => h("script", { ...rest, dangerouslySetInnerHTML: { __html: childrenToString(children) } })
table: (props) =>
/* @__PURE__ */ jsx("div", {
class: "table-container",
children: /* @__PURE__ */ jsx("table", { ...props }),
}),
style: ({ children, ...rest }) =>
h("style", { ...rest, dangerouslySetInnerHTML: { __html: childrenToString(children) } }),
script: ({ children, ...rest }) =>
h("script", { ...rest, dangerouslySetInnerHTML: { __html: childrenToString(children) } }),
};
function htmlToJsx(tree, components) {
return toJsxRuntime(tree, {
@ -296,10 +345,81 @@ function htmlToJsx(tree, components) {
jsx,
jsxs,
elementAttributeNameCase: "html",
components: { ...builtinComponents, ...components }
components: { ...builtinComponents, ...components },
});
}
export { capitalize, classNames, endsWith, escapeHTML, getAllSegmentPrefixes, getBasePath, getFileExtension, getFullSlug, getFullSlugFromUrl, htmlToJsx, isAbsoluteURL, isFilePath, isFolderPath, isFullSlug, isRelativeURL, isSimpleSlug, joinSegments, normalizeRelativeURLs, pathToRoot, registerEscapeHandler, removeAllChildren, resolveBasePath, resolvePath, resolveRelative, simplifySlug, slugTag, slugifyFilePath, slugifyPath, splitAnchor, stripSlashes, transformInternalLink, transformLink, trimSuffix, unescapeHTML };
// src/date.ts
function formatDate(d, locale = "en-US") {
return d.toLocaleDateString(locale, {
year: "numeric",
month: "short",
day: "2-digit",
});
}
// src/emoji.ts
var U200D = String.fromCharCode(8205);
var UFE0Fg = /\uFE0F/g;
function getIconCode(char) {
return toCodePoint(char.indexOf(U200D) < 0 ? char.replace(UFE0Fg, "") : char);
}
function toCodePoint(unicodeSurrogates) {
const r = [];
let c = 0,
p = 0,
i = 0;
while (i < unicodeSurrogates.length) {
c = unicodeSurrogates.charCodeAt(i++);
if (p) {
r.push((65536 + ((p - 55296) << 10) + (c - 56320)).toString(16));
p = 0;
} else if (55296 <= c && c <= 56319) {
p = c;
} else {
r.push(c.toString(16));
}
}
return r.join("-");
}
export {
capitalize,
classNames,
endsWith,
escapeHTML,
formatDate,
getAllSegmentPrefixes,
getBasePath,
getFileExtension,
getFullSlug,
getFullSlugFromUrl,
getIconCode,
htmlToJsx,
isAbsoluteURL,
isFilePath,
isFolderPath,
isFullSlug,
isRelativeURL,
isSimpleSlug,
joinSegments,
normalizeRelativeURLs,
pathToRoot,
registerEscapeHandler,
removeAllChildren,
resolveBasePath,
resolvePath,
resolveRelative,
simplifySlug,
slugTag,
slugifyFilePath,
slugifyPath,
splitAnchor,
stripSlashes,
transformInternalLink,
transformLink,
trimSuffix,
unescapeHTML,
};
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

4
dist/jsx.d.ts vendored
View file

@ -1,5 +1,5 @@
import { Components } from 'hast-util-to-jsx-runtime';
import { Node } from 'hast';
import { Components } from "hast-util-to-jsx-runtime";
import { Node } from "hast";
/**
* Convert a HAST tree to Preact JSX, with sensible defaults for Quartz plugins.

22
dist/jsx.js vendored
View file

@ -1,6 +1,6 @@
import { toJsxRuntime } from 'hast-util-to-jsx-runtime';
import { jsxs, jsx, Fragment } from 'preact/jsx-runtime';
import { h } from 'preact';
import { toJsxRuntime } from "hast-util-to-jsx-runtime";
import { jsxs, jsx, Fragment } from "preact/jsx-runtime";
import { h } from "preact";
// src/jsx.tsx
function childrenToString(children) {
@ -9,9 +9,15 @@ function childrenToString(children) {
return String(children ?? "");
}
var builtinComponents = {
table: (props) => /* @__PURE__ */ jsx("div", { class: "table-container", children: /* @__PURE__ */ jsx("table", { ...props }) }),
style: ({ children, ...rest }) => h("style", { ...rest, dangerouslySetInnerHTML: { __html: childrenToString(children) } }),
script: ({ children, ...rest }) => h("script", { ...rest, dangerouslySetInnerHTML: { __html: childrenToString(children) } })
table: (props) =>
/* @__PURE__ */ jsx("div", {
class: "table-container",
children: /* @__PURE__ */ jsx("table", { ...props }),
}),
style: ({ children, ...rest }) =>
h("style", { ...rest, dangerouslySetInnerHTML: { __html: childrenToString(children) } }),
script: ({ children, ...rest }) =>
h("script", { ...rest, dangerouslySetInnerHTML: { __html: childrenToString(children) } }),
};
function htmlToJsx(tree, components) {
return toJsxRuntime(tree, {
@ -19,10 +25,10 @@ function htmlToJsx(tree, components) {
jsx,
jsxs,
elementAttributeNameCase: "html",
components: { ...builtinComponents, ...components }
components: { ...builtinComponents, ...components },
});
}
export { htmlToJsx };
//# sourceMappingURL=jsx.js.map
//# sourceMappingURL=jsx.js.map
//# sourceMappingURL=jsx.js.map

2
dist/lang.js vendored
View file

@ -8,4 +8,4 @@ function classNames(...classes) {
export { capitalize, classNames };
//# sourceMappingURL=lang.js.map
//# sourceMappingURL=lang.js.map
//# sourceMappingURL=lang.js.map

44
dist/path.d.ts vendored
View file

@ -1,17 +1,17 @@
import { FullSlug, FilePath } from '@quartz-community/types';
export { FilePath, FullSlug } from '@quartz-community/types';
import { FullSlug, FilePath } from "@quartz-community/types";
export { FilePath, FullSlug } from "@quartz-community/types";
/** No '/index' ending, no file extension, can have trailing slash for folders. */
type SimpleSlug = string & {
_brand: "SimpleSlug";
_brand: "SimpleSlug";
};
/** Starts with './' or '../', used for navigation. */
type RelativeURL = string & {
_brand: "RelativeURL";
_brand: "RelativeURL";
};
interface TransformOptions {
strategy: "absolute" | "relative" | "shortest";
allSlugs: FullSlug[];
strategy: "absolute" | "relative" | "shortest";
allSlugs: FullSlug[];
}
declare function isFilePath(s: string): s is FilePath;
declare function isFullSlug(s: string): s is FullSlug;
@ -49,4 +49,34 @@ declare function transformLink(src: FullSlug, target: string, opts: TransformOpt
*/
declare function slugifyPath(s: string): string;
export { type RelativeURL, type SimpleSlug, type TransformOptions, endsWith, getAllSegmentPrefixes, getBasePath, getFileExtension, getFullSlug, getFullSlugFromUrl, isAbsoluteURL, isFilePath, isFolderPath, isFullSlug, isRelativeURL, isSimpleSlug, joinSegments, pathToRoot, resolveBasePath, resolvePath, resolveRelative, simplifySlug, slugTag, slugifyFilePath, slugifyPath, splitAnchor, stripSlashes, transformInternalLink, transformLink, trimSuffix };
export {
type RelativeURL,
type SimpleSlug,
type TransformOptions,
endsWith,
getAllSegmentPrefixes,
getBasePath,
getFileExtension,
getFullSlug,
getFullSlugFromUrl,
isAbsoluteURL,
isFilePath,
isFolderPath,
isFullSlug,
isRelativeURL,
isSimpleSlug,
joinSegments,
pathToRoot,
resolveBasePath,
resolvePath,
resolveRelative,
simplifySlug,
slugTag,
slugifyFilePath,
slugifyPath,
splitAnchor,
stripSlashes,
transformInternalLink,
transformLink,
trimSuffix,
};

77
dist/path.js vendored
View file

@ -1,4 +1,4 @@
import { slug } from 'github-slugger';
import { slug } from "github-slugger";
// src/path.ts
function isFilePath(s) {
@ -11,7 +11,7 @@ function isFullSlug(s) {
return validStart && validEnding && !_containsForbiddenCharacters(s);
}
function isSimpleSlug(s) {
const validStart = !(s.startsWith(".") || s.length > 1 && s.startsWith("/"));
const validStart = !(s.startsWith(".") || (s.length > 1 && s.startsWith("/")));
const validEnding = !endsWith(s, "index");
return validStart && !_containsForbiddenCharacters(s) && validEnding && !_hasFileExtension(s);
}
@ -57,7 +57,10 @@ function joinSegments(...args) {
if (args.length === 0) {
return "";
}
let joined = args.filter((segment) => segment !== "" && segment !== "/").map((segment) => stripSlashes(segment)).join("/");
let joined = args
.filter((segment) => segment !== "" && segment !== "/")
.map((segment) => stripSlashes(segment))
.join("/");
const first = args[0];
const last = args[args.length - 1];
if (first?.startsWith("/")) {
@ -103,7 +106,12 @@ function getFileExtension(s) {
return s.match(/\.[A-Za-z0-9]+$/)?.[0];
}
function isFolderPath(fplike) {
return fplike.endsWith("/") || endsWith(fplike, "index") || endsWith(fplike, "index.md") || endsWith(fplike, "index.html");
return (
fplike.endsWith("/") ||
endsWith(fplike, "index") ||
endsWith(fplike, "index.md") ||
endsWith(fplike, "index.html")
);
}
function getAllSegmentPrefixes(path) {
const segments = path.split("/");
@ -114,7 +122,12 @@ function getAllSegmentPrefixes(path) {
return results;
}
function pathToRoot(slug) {
let rootPath = slug.split("/").filter((x) => x !== "").slice(0, -1).map((_) => "..").join("/");
let rootPath = slug
.split("/")
.filter((x) => x !== "")
.slice(0, -1)
.map((_) => "..")
.join("/");
if (rootPath.length === 0) {
rootPath = ".";
}
@ -133,7 +146,10 @@ function splitAnchor(link) {
return [fp, slugged];
}
function slugTag(tag) {
return tag.split("/").map((tagSegment) => _sluggify(tagSegment)).join("/");
return tag
.split("/")
.map((tagSegment) => _sluggify(tagSegment))
.join("/");
}
function transformInternalLink(link) {
const [fplike, anchor] = splitAnchor(decodeURI(link));
@ -152,7 +168,8 @@ function transformLink(src, target, opts) {
if (opts.strategy === "relative") {
return targetSlug;
} else {
const effectiveSrc = !endsWith(src, "index") && opts.allSlugs.includes(`${src}/index`) ? `${src}/index` : src;
const effectiveSrc =
!endsWith(src, "index") && opts.allSlugs.includes(`${src}/index`) ? `${src}/index` : src;
const folderTail = isFolderPath(targetSlug) ? "/" : "";
const canonicalSlug = stripSlashes(targetSlug.slice(".".length));
const [targetCanonical, targetAnchor] = splitAnchor(canonicalSlug);
@ -183,9 +200,18 @@ function transformLink(src, target, opts) {
}
}
function slugifyPath(s) {
return s.split("/").map(
(segment) => segment.replace(/\s/g, "-").replace(/&/g, "-and-").replace(/%/g, "-percent").replace(/\?/g, "").replace(/#/g, "")
).join("/").replace(/\/$/, "");
return s
.split("/")
.map((segment) =>
segment
.replace(/\s/g, "-")
.replace(/&/g, "-and-")
.replace(/%/g, "-percent")
.replace(/\?/g, "")
.replace(/#/g, ""),
)
.join("/")
.replace(/\/$/, "");
}
function _sluggify(s) {
return slugifyPath(s);
@ -209,6 +235,33 @@ function _addRelativeToStart(s) {
return s;
}
export { endsWith, getAllSegmentPrefixes, getBasePath, getFileExtension, getFullSlug, getFullSlugFromUrl, isAbsoluteURL, isFilePath, isFolderPath, isFullSlug, isRelativeURL, isSimpleSlug, joinSegments, pathToRoot, resolveBasePath, resolvePath, resolveRelative, simplifySlug, slugTag, slugifyFilePath, slugifyPath, splitAnchor, stripSlashes, transformInternalLink, transformLink, trimSuffix };
export {
endsWith,
getAllSegmentPrefixes,
getBasePath,
getFileExtension,
getFullSlug,
getFullSlugFromUrl,
isAbsoluteURL,
isFilePath,
isFolderPath,
isFullSlug,
isRelativeURL,
isSimpleSlug,
joinSegments,
pathToRoot,
resolveBasePath,
resolvePath,
resolveRelative,
simplifySlug,
slugTag,
slugifyFilePath,
slugifyPath,
splitAnchor,
stripSlashes,
transformInternalLink,
transformLink,
trimSuffix,
};
//# sourceMappingURL=path.js.map
//# sourceMappingURL=path.js.map
//# sourceMappingURL=path.js.map

View file

@ -48,6 +48,14 @@
"types": "./dist/jsx.d.ts",
"import": "./dist/jsx.js"
},
"./date": {
"types": "./dist/date.d.ts",
"import": "./dist/date.js"
},
"./emoji": {
"types": "./dist/emoji.d.ts",
"import": "./dist/emoji.js"
},
"./package.json": "./package.json"
},
"main": "./dist/index.js",

7
src/date.ts Normal file
View file

@ -0,0 +1,7 @@
export function formatDate(d: Date, locale: string = "en-US"): string {
return d.toLocaleDateString(locale, {
year: "numeric",
month: "short",
day: "2-digit",
});
}

26
src/emoji.ts Normal file
View file

@ -0,0 +1,26 @@
const U200D = String.fromCharCode(8205);
const UFE0Fg = /\uFE0F/g;
export function getIconCode(char: string): string {
return toCodePoint(char.indexOf(U200D) < 0 ? char.replace(UFE0Fg, "") : char);
}
function toCodePoint(unicodeSurrogates: string): string {
const r: string[] = [];
let c = 0,
p = 0,
i = 0;
while (i < unicodeSurrogates.length) {
c = unicodeSurrogates.charCodeAt(i++);
if (p) {
r.push((65536 + ((p - 55296) << 10) + (c - 56320)).toString(16));
p = 0;
} else if (55296 <= c && c <= 56319) {
p = c;
} else {
r.push(c.toString(16));
}
}
return r.join("-");
}

View file

@ -36,3 +36,6 @@ export { classNames, capitalize } from "./lang.js";
export { escapeHTML, unescapeHTML } from "./escape.js";
export { htmlToJsx } from "./jsx.js";
export { formatDate } from "./date.js";
export { getIconCode } from "./emoji.js";

View file

@ -7,6 +7,8 @@ export default defineConfig({
dom: "src/dom.ts",
lang: "src/lang.ts",
escape: "src/escape.ts",
date: "src/date.ts",
emoji: "src/emoji.ts",
jsx: "src/jsx.tsx",
},
format: ["esm"],