remark-obsidian-links
Version:
a remark plugin that converts obsidian internal links into common links
349 lines (341 loc) • 11.5 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
default: () => remarkConvertObsidianInternalLinks
});
module.exports = __toCommonJS(index_exports);
// node_modules/.pnpm/unist-util-is@6.0.0/node_modules/unist-util-is/lib/index.js
var convert = (
// Note: overloads in JSDoc can’t yet use different `@template`s.
/**
* @type {(
* (<Condition extends string>(test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & {type: Condition}) &
* (<Condition extends Props>(test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Condition) &
* (<Condition extends TestFunction>(test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Predicate<Condition, Node>) &
* ((test?: null | undefined) => (node?: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node) &
* ((test?: Test) => Check)
* )}
*/
/**
* @param {Test} [test]
* @returns {Check}
*/
function(test) {
if (test === null || test === void 0) {
return ok;
}
if (typeof test === "function") {
return castFactory(test);
}
if (typeof test === "object") {
return Array.isArray(test) ? anyFactory(test) : propsFactory(test);
}
if (typeof test === "string") {
return typeFactory(test);
}
throw new Error("Expected function, string, or object as test");
}
);
function anyFactory(tests) {
const checks = [];
let index = -1;
while (++index < tests.length) {
checks[index] = convert(tests[index]);
}
return castFactory(any);
function any(...parameters) {
let index2 = -1;
while (++index2 < checks.length) {
if (checks[index2].apply(this, parameters)) return true;
}
return false;
}
}
function propsFactory(check) {
const checkAsRecord = (
/** @type {Record<string, unknown>} */
check
);
return castFactory(all);
function all(node) {
const nodeAsRecord = (
/** @type {Record<string, unknown>} */
/** @type {unknown} */
node
);
let key;
for (key in check) {
if (nodeAsRecord[key] !== checkAsRecord[key]) return false;
}
return true;
}
}
function typeFactory(check) {
return castFactory(type);
function type(node) {
return node && node.type === check;
}
}
function castFactory(testFunction) {
return check;
function check(value, index, parent) {
return Boolean(
looksLikeANode(value) && testFunction.call(
this,
value,
typeof index === "number" ? index : void 0,
parent || void 0
)
);
}
}
function ok() {
return true;
}
function looksLikeANode(value) {
return value !== null && typeof value === "object" && "type" in value;
}
// node_modules/.pnpm/unist-util-visit-parents@6.0.1/node_modules/unist-util-visit-parents/lib/color.node.js
function color(d) {
return "\x1B[33m" + d + "\x1B[39m";
}
// node_modules/.pnpm/unist-util-visit-parents@6.0.1/node_modules/unist-util-visit-parents/lib/index.js
var empty = [];
var CONTINUE = true;
var EXIT = false;
var SKIP = "skip";
function visitParents(tree, test, visitor, reverse) {
let check;
if (typeof test === "function" && typeof visitor !== "function") {
reverse = visitor;
visitor = test;
} else {
check = test;
}
const is2 = convert(check);
const step = reverse ? -1 : 1;
factory(tree, void 0, [])();
function factory(node, index, parents) {
const value = (
/** @type {Record<string, unknown>} */
node && typeof node === "object" ? node : {}
);
if (typeof value.type === "string") {
const name = (
// `hast`
typeof value.tagName === "string" ? value.tagName : (
// `xast`
typeof value.name === "string" ? value.name : void 0
)
);
Object.defineProperty(visit2, "name", {
value: "node (" + color(node.type + (name ? "<" + name + ">" : "")) + ")"
});
}
return visit2;
function visit2() {
let result = empty;
let subresult;
let offset;
let grandparents;
if (!test || is2(node, index, parents[parents.length - 1] || void 0)) {
result = toResult(visitor(node, parents));
if (result[0] === EXIT) {
return result;
}
}
if ("children" in node && node.children) {
const nodeAsParent = (
/** @type {UnistParent} */
node
);
if (nodeAsParent.children && result[0] !== SKIP) {
offset = (reverse ? nodeAsParent.children.length : -1) + step;
grandparents = parents.concat(nodeAsParent);
while (offset > -1 && offset < nodeAsParent.children.length) {
const child = nodeAsParent.children[offset];
subresult = factory(child, offset, grandparents)();
if (subresult[0] === EXIT) {
return subresult;
}
offset = typeof subresult[1] === "number" ? subresult[1] : offset + step;
}
}
}
return result;
}
}
}
function toResult(value) {
if (Array.isArray(value)) {
return value;
}
if (typeof value === "number") {
return [CONTINUE, value];
}
return value === null || value === void 0 ? empty : [value];
}
// node_modules/.pnpm/unist-util-visit@5.0.0/node_modules/unist-util-visit/lib/index.js
function visit(tree, testOrVisitor, visitorOrReverse, maybeReverse) {
let reverse;
let test;
let visitor;
if (typeof testOrVisitor === "function" && typeof visitorOrReverse !== "function") {
test = void 0;
visitor = testOrVisitor;
reverse = visitorOrReverse;
} else {
test = testOrVisitor;
visitor = visitorOrReverse;
reverse = maybeReverse;
}
visitParents(tree, test, overload, reverse);
function overload(node, parents) {
const parent = parents[parents.length - 1];
const index = parent ? parent.children.indexOf(node) : void 0;
return visitor(node, index, parent);
}
}
// src/utils.ts
var defaultSlugify = (str) => {
return str.toLowerCase().replace(/[^\w]+/g, "-").replace(/(^-|-$)+/g, "");
};
var slugfiyFileNameBase = (url, slugify) => {
const imgExts = ["jpg", "jpeg", "png", "gif", "svg", "webp", "bmp"];
const urlArr = url.split("/");
let fileName = urlArr.pop();
let ext;
if (imgExts.some((ext2) => url.endsWith(ext2))) {
const fileNameArr = fileName.split(".");
ext = fileNameArr.pop();
fileName = fileNameArr.join(".");
}
url = `${slugify(fileName)}${ext ? `.${ext}` : ""}`;
urlArr.push(url);
return urlArr.join("/");
};
// src/index.ts
function remarkConvertObsidianInternalLinks(options) {
var _a, _b, _c, _d, _e;
const [linkPattern, linkSubst] = (_a = options == null ? void 0 : options.linkPrefix) != null ? _a : [];
const [imagePattern, imageSubst] = (_b = options == null ? void 0 : options.imagePrefix) != null ? _b : [];
const linkClass = (_c = options == null ? void 0 : options.linkClass) != null ? _c : "link-page";
const idClass = (_d = options == null ? void 0 : options.idClass) != null ? _d : "link-id";
const slugify = (_e = options == null ? void 0 : options.slugify) != null ? _e : defaultSlugify;
return (tree) => {
visit(tree, "paragraph", (p) => {
if (!p.children) return;
const substChildren = [];
let skipIndex = 0;
let wasTarget = false;
p.children.forEach((node, i) => {
var _a2;
if (i < skipIndex) return;
if (node.type === "text") {
let forImage = false;
let textBeforeLinkVal = node.value;
if (wasTarget) {
textBeforeLinkVal = textBeforeLinkVal.slice(1);
wasTarget = false;
}
const nextEl1 = p.children[i + 1];
const nextEl2 = p.children[i + 2];
if ((textBeforeLinkVal.endsWith("[") || textBeforeLinkVal.endsWith("![")) && (nextEl1 == null ? void 0 : nextEl1.type) === "linkReference" && (nextEl2 == null ? void 0 : nextEl2.type) === "text" && nextEl2.value.startsWith("]")) {
wasTarget = true;
if (textBeforeLinkVal.endsWith("![")) {
forImage = true;
textBeforeLinkVal = textBeforeLinkVal.slice(0, -2);
} else {
textBeforeLinkVal = textBeforeLinkVal.slice(0, -1);
}
let url = (_a2 = nextEl1.label) != null ? _a2 : "";
let urlText, id, isIdLink = false;
if (url.includes("|")) {
[url, urlText] = url.split("|");
}
if (url.includes("#")) {
[url, id] = url.split("#");
}
if (url) {
url = slugfiyFileNameBase(url, slugify);
}
if (id) {
if (!url) {
isIdLink = true;
}
url = url + "#" + slugify(id);
}
if (!forImage && typeof linkPattern === "string" && typeof linkSubst === "string") {
url = url.replace(linkPattern, linkSubst);
} else if (forImage && typeof imagePattern === "string" && typeof imageSubst === "string") {
url = url.replace(imagePattern, imageSubst);
}
if (!urlText) {
if (isIdLink) {
urlText = id;
} else {
urlText = url;
}
}
substChildren.push({
type: "text",
value: textBeforeLinkVal
});
if (forImage) {
substChildren.push({
type: "image",
url,
alt: urlText
});
} else {
substChildren.push({
type: "link",
url,
data: {
hProperties: {
class: isIdLink ? idClass : linkClass
}
},
children: [
{
type: "text",
value: urlText
}
]
});
}
skipIndex = i + 2;
} else {
wasTarget = false;
substChildren.push({
type: "text",
value: textBeforeLinkVal
});
}
} else {
wasTarget = false;
substChildren.push(node);
}
});
p.children = substChildren;
});
};
}