Also an opportunity to refactor the transclusion code, which had become very messy
112 lines
2.7 KiB
TypeScript
112 lines
2.7 KiB
TypeScript
import {
|
|
mdLinkRegex,
|
|
wikiLinkRegex,
|
|
} from "../../client/markdown_parser/constants.ts";
|
|
import {
|
|
getNameFromPath,
|
|
parseToRef,
|
|
} from "@silverbulletmd/silverbullet/lib/ref";
|
|
|
|
export type LinkType = "wikilink" | "markdownlink";
|
|
/**
|
|
* Represents a transclusion
|
|
*/
|
|
export type Transclusion = {
|
|
url: string;
|
|
alias: string;
|
|
dimension?: ContentDimensions;
|
|
linktype: LinkType;
|
|
};
|
|
/**
|
|
* Describes the dimensions of a transclusion, if provided through the alias.
|
|
* Can be parsed from the alias using {@link parseDimensionFromAlias}
|
|
*/
|
|
export type ContentDimensions = {
|
|
width?: number;
|
|
height?: number;
|
|
};
|
|
|
|
/**
|
|
* Parse an alias, possibly containing dimensions into an object
|
|
* @example "alias", "alias|100", "alias|100x200", "100", "100x200"
|
|
*/
|
|
export function parseDimensionFromAlias(text: string): {
|
|
alias: string;
|
|
dimension?: ContentDimensions;
|
|
} {
|
|
let alias: string;
|
|
let dim: ContentDimensions | undefined;
|
|
if (text.includes("|")) {
|
|
const [aliasPart, dimPart] = text.split("|");
|
|
alias = aliasPart;
|
|
const [width, height] = dimPart.split("x");
|
|
dim = {};
|
|
if (width) {
|
|
dim.width = parseInt(width, 10);
|
|
}
|
|
if (height) {
|
|
dim.height = parseInt(height, 10);
|
|
}
|
|
} else if (/^[x\d]/.test(text)) {
|
|
const [width, height] = text.split("x");
|
|
dim = {};
|
|
if (width) {
|
|
dim.width = parseInt(width, 10);
|
|
}
|
|
if (height) {
|
|
dim.height = parseInt(height, 10);
|
|
}
|
|
alias = "";
|
|
} else {
|
|
alias = text;
|
|
}
|
|
|
|
return { alias, dimension: dim };
|
|
}
|
|
|
|
/**
|
|
* Parses a transclusion of the type `![[]]` or `![]()`
|
|
* @param text
|
|
*/
|
|
export function parseTransclusion(text: string): Transclusion | null {
|
|
let url, alias;
|
|
let linktype: LinkType = "markdownlink";
|
|
// TODO: Take in the tree and use tree nodes to get url and alias (Applies to all regex uses)
|
|
mdLinkRegex.lastIndex = 0;
|
|
wikiLinkRegex.lastIndex = 0;
|
|
let match: RegExpMatchArray | null = null;
|
|
if ((match = mdLinkRegex.exec(text)) && match.groups) {
|
|
({ url, title: alias } = match.groups);
|
|
|
|
linktype = "markdownlink";
|
|
} else if ((match = wikiLinkRegex.exec(text)) && match.groups) {
|
|
({ stringRef: url, alias } = match.groups);
|
|
linktype = "wikilink";
|
|
} else {
|
|
// We found no match
|
|
return null;
|
|
}
|
|
|
|
let dimension: ContentDimensions | undefined;
|
|
if (alias) {
|
|
({ alias, dimension: dimension } = parseDimensionFromAlias(alias));
|
|
} else {
|
|
alias = "";
|
|
}
|
|
|
|
return {
|
|
url,
|
|
alias,
|
|
dimension,
|
|
linktype,
|
|
};
|
|
}
|
|
|
|
export function nameFromTransclusion(t: Transclusion): string {
|
|
const ref = parseToRef(t.url);
|
|
if (!ref) {
|
|
throw new Error(`Cannot extract name from transclusion: ${t.url}`);
|
|
}
|
|
return getNameFromPath(ref.path);
|
|
}
|