mirror of
https://github.com/quartz-community/utils.git
synced 2026-07-22 02:50:27 +00:00
feat: add formatDate and getIconCode utility exports
This commit is contained in:
parent
ef25479647
commit
8b6e32ba07
22 changed files with 426 additions and 71 deletions
3
dist/date.d.ts
vendored
Normal file
3
dist/date.d.ts
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
declare function formatDate(d: Date, locale?: string): string;
|
||||
|
||||
export { formatDate };
|
||||
12
dist/date.js
vendored
Normal file
12
dist/date.js
vendored
Normal 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
1
dist/date.js.map
vendored
Normal 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
5
dist/dom.d.ts
vendored
|
|
@ -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
15
dist/dom.js
vendored
|
|
@ -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
3
dist/emoji.d.ts
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
declare function getIconCode(char: string): string;
|
||||
|
||||
export { getIconCode };
|
||||
28
dist/emoji.js
vendored
Normal file
28
dist/emoji.js
vendored
Normal 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
1
dist/emoji.js.map
vendored
Normal 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
16
dist/escape.js
vendored
|
|
@ -1,11 +1,21 @@
|
|||
// src/escape.ts
|
||||
function escapeHTML(unsafe) {
|
||||
return unsafe.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
||||
return unsafe
|
||||
.replaceAll("&", "&")
|
||||
.replaceAll("<", "<")
|
||||
.replaceAll(">", ">")
|
||||
.replaceAll('"', """)
|
||||
.replaceAll("'", "'");
|
||||
}
|
||||
function unescapeHTML(html) {
|
||||
return html.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll(""", '"').replaceAll("'", "'");
|
||||
return html
|
||||
.replaceAll("&", "&")
|
||||
.replaceAll("<", "<")
|
||||
.replaceAll(">", ">")
|
||||
.replaceAll(""", '"')
|
||||
.replaceAll("'", "'");
|
||||
}
|
||||
|
||||
export { escapeHTML, unescapeHTML };
|
||||
//# sourceMappingURL=escape.js.map
|
||||
//# sourceMappingURL=escape.js.map
|
||||
//# sourceMappingURL=escape.js.map
|
||||
|
|
|
|||
48
dist/index.d.ts
vendored
48
dist/index.d.ts
vendored
|
|
@ -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
168
dist/index.js
vendored
|
|
@ -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("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
||||
return unsafe
|
||||
.replaceAll("&", "&")
|
||||
.replaceAll("<", "<")
|
||||
.replaceAll(">", ">")
|
||||
.replaceAll('"', """)
|
||||
.replaceAll("'", "'");
|
||||
}
|
||||
function unescapeHTML(html) {
|
||||
return html.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll(""", '"').replaceAll("'", "'");
|
||||
return html
|
||||
.replaceAll("&", "&")
|
||||
.replaceAll("<", "<")
|
||||
.replaceAll(">", ">")
|
||||
.replaceAll(""", '"')
|
||||
.replaceAll("'", "'");
|
||||
}
|
||||
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
2
dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/jsx.d.ts
vendored
4
dist/jsx.d.ts
vendored
|
|
@ -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
22
dist/jsx.js
vendored
|
|
@ -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
2
dist/lang.js
vendored
|
|
@ -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
44
dist/path.d.ts
vendored
|
|
@ -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
77
dist/path.js
vendored
|
|
@ -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
|
||||
|
|
@ -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
7
src/date.ts
Normal 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
26
src/emoji.ts
Normal 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("-");
|
||||
}
|
||||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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"],
|
||||
|
|
|
|||
Loading…
Reference in a new issue