obsidian-dev-utils
Version:
This is the collection of useful functions that you can use for your Obsidian plugin development
717 lines (716 loc) • 19.9 kB
text/typescript
/**
* @packageDocumentation
*
* This module provides utilities for handling and updating links within Obsidian vaults. It includes
* functions to split paths, update links in files, and generate markdown links with various options.
*/
import type { App, CachedMetadata, Plugin, Reference, TFile } from 'obsidian';
import type { Promisable } from 'type-fest';
import type { MaybeReturn } from '../Type.mjs';
import type { PathOrFile } from './FileSystem.mjs';
import type { ProcessOptions } from './Vault.mjs';
/**
* A style of the link path.
*/
export declare enum LinkPathStyle {
/**
* Use the absolute path in the vault.
*
* @example `[[path/from/the/vault/root/target]]`
*/
AbsolutePathInVault = "AbsolutePathInVault",
/**
* Use the default link path style defined in Obsidian settings.
*/
ObsidianSettingsDefault = "ObsidianSettingsDefault",
/**
* Use the relative path to the source.
*
* @example `[[../../relative/path/to/target]]`
*/
RelativePathToTheSource = "RelativePathToTheSource",
/**
* Use the shortest path when possible.
*
* @example `[[shortest-path-to-target]]`
*/
ShortestPathWhenPossible = "ShortestPathWhenPossible"
}
/**
* A style of the link.
*/
export declare enum LinkStyle {
/**
* Force the link to be in markdown format.
*
* @example `[alias](path/to/target.md)`
*/
Markdown = "Markdown",
/**
* Use the default link style defined in Obsidian settings.
*/
ObsidianSettingsDefault = "ObsidianSettingsDefault",
/**
* Preserve the existing link style.
*/
PreserveExisting = "PreserveExisting",
/**
* Force the link to be in wikilink format.
*
* @example `[[path/to/target]]`
* @example `[[path/to/target|alias]]`
*/
Wikilink = "Wikilink"
}
/**
* Options for {@link convertLink}.
*/
export interface ConvertLinkOptions {
/**
* An Obsidian app instance.
*/
app: App;
/**
* A reference for the link.
*/
link: Reference;
/**
* A style of the link.
*/
linkStyle?: LinkStyle;
/**
* A source file containing the link.
*/
newSourcePathOrFile: PathOrFile;
/**
* An old path of the link.
*/
oldSourcePathOrFile?: PathOrFile;
/**
* Whether to update file name alias. Defaults to `true`.
*/
shouldUpdateFileNameAlias?: boolean;
}
/**
* Options for {@link generateMarkdownLink}.
*/
export interface GenerateMarkdownLinkOptions {
/**
* An alias for the link.
*
* @example `[[alias|link]]`
* @example `[alias](link.md)`
*/
alias?: string;
/**
* An Obsidian app instance.
*/
app: App;
/**
* Indicates if the link should be embedded. If not provided, it will be inferred based on the file type.
*
* If `true`: `![[target]]`.
*
* If `false`: `[[target]]`.
*/
isEmbed?: boolean;
/**
* Whether to allow an empty alias for embeds. Defaults to `true`.
*
* Applicable only if the result link style is {@link LinkStyle.Markdown}.
*
* If `true`: ``.
*
* If `false`: ``.
*/
isEmptyEmbedAliasAllowed?: boolean;
/**
* Whether to allow non-existing files. Defaults to `false`.
*
* If `false` and {@link targetPathOrFile} is a non-existing file, an error will be thrown.
*/
isNonExistingFileAllowed?: boolean;
/**
* Whether to allow a single subpath. Defaults to `true`.
*
* Applicable only if {@link targetPathOrFile} and {@link sourcePathOrFile} are the same file.
*
* If `true`: `[[#subpath]]`.
*
* If `false`: `[[source#subpath]]`
*/
isSingleSubpathAllowed?: boolean;
/**
* A style of the link path.
*/
linkPathStyle?: LinkPathStyle;
/**
* A style of the link.
*/
linkStyle?: LinkStyle;
/**
* An original link text.
*
* If provided, it will be used to infer the values of
*
* - {@link isEmbed}
* - {@link linkStyle}
* - {@link shouldUseAngleBrackets}
* - {@link shouldUseLeadingDotForRelativePaths}
* - {@link shouldUseLeadingSlashForAbsolutePaths}
*
* These inferred values will be overridden by corresponding settings if specified.
*/
originalLink?: string;
/**
* Whether to escape the alias. Defaults to `false`.
*
* Applicable only if the result link style is {@link LinkStyle.Markdown}.
*
* If `true`: `[\*\*alias\*\*](link.md)`.
*
* If `false`: `[**alias**](link.md)`.
*/
shouldEscapeAlias?: boolean;
/**
* Whether to include the attachment extension in the embed alias. Defaults to `false`.
*
* Applicable only if {@link isEmptyEmbedAliasAllowed} is `false`.
*
* If `true`: `[foo.png](foo.png)`.
*
* If `false`: `[foo](foo.png)`.
*/
shouldIncludeAttachmentExtensionToEmbedAlias?: boolean;
/**
* Indicates if the link should use angle brackets. Defaults to `false`.
*
* Applicable only if {@link linkStyle} is {@link LinkStyle.Markdown}.
*
* If `true`: `[alias](<path with spaces.md>)`.
*
* If `false`: `[alias](path%20with%20spaces.md)`.
*/
shouldUseAngleBrackets?: boolean;
/**
* Indicates if the link should use a leading dot. Defaults to `false`.
*
* Applicable only if {@link linkPathStyle} is {@link LinkPathStyle.RelativePathToSource}.
*
* If `true`: `[[./relative/path/to/target]]`
*
* If `false`: `[[relative/path/to/target]]`
*/
shouldUseLeadingDotForRelativePaths?: boolean;
/**
* Indicates if the link should use a leading slash. Defaults to `false`.
*
* Applicable only if {@link linkPathStyle} is {@link LinkPathStyle.AbsolutePathInVault}.
*
* If `true`: `[[/absolute/path/to/target]]`
*
* If `false`: `[[absolute/path/to/target]]`
*/
shouldUseLeadingSlashForAbsolutePaths?: boolean;
/**
* A source path of the link.
*/
sourcePathOrFile: PathOrFile;
/**
* A subpath of the link.
*
* Should be empty or start with `#`.
*
* @example `[[link-with-empty-subpath]]`
* @example `[[link-with-subpath#subpath]]`
* @example `[[link-with-subpath#subpath#nested-subpath]]`
*/
subpath?: string;
/**
* A target path or file.
*/
targetPathOrFile: PathOrFile;
}
/**
* Options for {@link generateRawMarkdownLink}.
*/
export interface GenerateRawMarkdownLinkOptions {
/**
* An alias of the link. Defaults to `undefined`.
*/
alias?: string | undefined;
/**
* Whether the link should be an embed link. Defaults to `false`.
*/
isEmbed?: boolean;
/**
* Whether the link should be a wikilink.
*/
isWikilink: boolean;
/**
* Whether to escape the alias. Applicable only if {@link isWikilink} is `false`. Defaults to `false`.
*/
shouldEscapeAlias?: boolean;
/**
* Whether to use angle brackets. Applicable only if {@link isWikilink} is `false`. Defaults to `false`.
*/
shouldUseAngleBrackets?: boolean;
/**
* A title of the link.
*/
title?: string;
/**
* An URL of the link.
*/
url: string;
}
/**
* A result of parsing a link.
*/
export interface ParseLinkResult {
/**
* An alias of the link.
*
* @example
* ```
* [\*alias\*](link.md) -> \*alias\*
* ```
*/
alias?: string;
/**
* An encoded URL of the link.
*
* @example
* ```
* [alias](<link with space.md>) -> link%20with%20space.md
* ```
*/
encodedUrl?: string;
/**
* An end offset of the link in the original text.
*/
endOffset: number;
/**
* Indicates if the link has angle brackets.
*
* @example
* ```
* [alias](<link.md>) -> true
* [alias](link.md) -> false
* ```
*/
hasAngleBrackets?: boolean;
/**
* Indicates if the link is an embed link.
*
* @example
* ```
* ![[alias]] -> true
* [[alias]] -> false
* ```
*/
isEmbed: boolean;
/**
* Indicates if the link is external.
*
* @example
* ```
* [alias](https://example.com) -> true
* [alias](file.md) -> false
* ```
*/
isExternal: boolean;
/**
* Indicates if the link is a wikilink.
*
* @example
* ```
* [[alias]] -> true
* [alias](link.md) -> false
* ```
*/
isWikilink: boolean;
/**
* A raw link text.
*
* @example
* ```
* [alias](link.md) -> [alias](link.md)
* ```
*/
raw: string;
/**
* A start offset of the link in the original text.
*/
startOffset: number;
/**
* A title of the link.
*
* @example
* ```
* [alias](link.md "title") -> title
* ```
*/
title?: string;
/**
* An unescaped alias of the link.
*
* @example
* ```
* [\*alias\*](link.md) -> *alias*
* ```
*/
unescapedAlias?: string;
/**
* An URL of the link.
*
* @example
* ```
* [alias](link%20with%20space.md) -> link with space.md
* ```
*/
url: string;
}
/**
* Options for {@link shouldResetAlias}.
*/
export interface ShouldResetAliasOptions {
/**
* An Obsidian app instance.
*/
app: App;
/**
* A display text of the link.
*/
displayText: string | undefined;
/**
* Indicates if the link is a wikilink.
*/
isWikilink?: boolean;
/**
* A source path of the link.
*/
newSourcePathOrFile: PathOrFile;
/**
* An old source file containing the link.
*/
oldSourcePathOrFile?: PathOrFile;
/**
* An old target path of the link.
*/
oldTargetPath: PathOrFile;
/**
* A target path or file.
*/
targetPathOrFile: PathOrFile;
}
/**
* Splits a link into its link path and subpath.
*/
export interface SplitSubpathResult {
/**
* A link path.
*/
linkPath: string;
/**
* A subpath.
*/
subpath: string;
}
/**
* Options for {@link updateLink}.
*/
export interface UpdateLinkOptions {
/**
* An Obsidian app instance.
*/
app: App;
/**
* A reference for the link.
*/
link: Reference;
/**
* Whether to force markdown links.
*/
linkStyle?: LinkStyle;
/**
* A source file containing the link.
*/
newSourcePathOrFile: PathOrFile;
/**
* A file associated with the link.
*/
newTargetPathOrFile: PathOrFile;
/**
* An old source file containing the link.
*/
oldSourcePathOrFile?: PathOrFile;
/**
* An old path of the file.
*/
oldTargetPathOrFile?: PathOrFile;
/**
* Whether to update file name alias. Defaults to `true`.
*/
shouldUpdateFileNameAlias?: boolean;
}
/**
* Options for {@link updateLinksInFile}.
*/
export interface UpdateLinksInFileOptions extends ProcessOptions {
/**
* An Obsidian app instance.
*/
app: App;
/**
* A style of the link.
*/
linkStyle?: LinkStyle;
/**
* A file to update the links in.
*/
newSourcePathOrFile: PathOrFile;
/**
* An old path of the file.
*/
oldSourcePathOrFile?: PathOrFile;
/**
* Whether to update only embedded links.
*/
shouldUpdateEmbedOnlyLinks?: boolean;
/**
* Whether to update file name alias. Defaults to `true`.
*/
shouldUpdateFileNameAlias?: boolean;
}
/**
* Options for {@link updateLinksInContent}.
*/
interface UpdateLinksInContentOptions {
/**
* An Obsidian app instance.
*/
app: App;
/**
* A content to update the links in.
*/
content: string;
/**
* A style of the link.
*/
linkStyle?: LinkStyle;
/**
* A new source path or file.
*/
newSourcePathOrFile: PathOrFile;
/**
* An old source path or file.
*/
oldSourcePathOrFile?: PathOrFile;
/**
* Whether to update only embedded links.
*/
shouldUpdateEmbedOnlyLinks?: boolean;
/**
* Whether to update file name alias.
*/
shouldUpdateFileNameAlias?: boolean;
}
/**
* Converts a link to a new path.
*
* @param options - The options for converting the link.
* @returns The converted link.
*/
export declare function convertLink(options: ConvertLinkOptions): string;
/**
* Edits the backlinks for a file or path.
*
* @param app - The Obsidian application instance.
* @param pathOrFile - The path or file to edit the backlinks for.
* @param linkConverter - The function that converts each link.
* @param processOptions - Optional options for retrying the operation.
* @returns A {@link Promise} that resolves when the backlinks have been edited.
*/
export declare function editBacklinks(app: App, pathOrFile: PathOrFile, linkConverter: (link: Reference) => Promisable<MaybeReturn<string>>, processOptions?: ProcessOptions): Promise<void>;
/**
* Edits the backlinks for a file or path.
*
* @param app - The Obsidian application instance.
* @param pathOrFile - The path or file to edit the backlinks for.
* @param linkConverter - The function that converts each link.
* @param processOptions - Optional options for retrying the operation.
* @returns A {@link Promise} that resolves when the backlinks have been edited.
*/
export declare function editLinks(app: App, pathOrFile: PathOrFile, linkConverter: (link: Reference) => Promisable<MaybeReturn<string>>, processOptions?: ProcessOptions): Promise<void>;
/**
* Edits the links in a content string.
*
* @param app - The Obsidian application instance.
* @param content - The content to edit the links in.
* @param linkConverter - The function that converts each link.
* @param abortSignal - The abort signal to control the execution of the function.
* @returns The promise that resolves to the updated content.
*/
export declare function editLinksInContent(app: App, content: string, linkConverter: (link: Reference) => Promisable<MaybeReturn<string>>, abortSignal?: AbortSignal): Promise<string>;
/**
* Encodes a URL.
*
* @param url - The URL to encode.
* @returns The encoded URL.
*/
export declare function encodeUrl(url: string): string;
/**
* Escapes the alias of a markdown link.
*
* @param alias - An alias of a markdown link.
* @returns An escaped alias.
*
* @example
* ```ts
* escapeAlias('**alias**') // '\\*\\*alias\\*\\*'
* ```
*/
export declare function escapeAlias(alias: string): string;
/**
* Extracts the file associated with a link.
*
* @param app - The Obsidian application instance.
* @param link - The reference cache for the link.
* @param sourcePathOrFile - The source path or file.
* @param shouldAllowNonExistingFile - Whether to allow non-existing files. Defaults to `false`.
* @returns The file associated with the link, or null if not found.
*/
export declare function extractLinkFile(app: App, link: Reference, sourcePathOrFile: PathOrFile, shouldAllowNonExistingFile?: boolean): null | TFile;
/**
* Fixes the frontmatter markdown links in the provided metadata cache.
*
* @param cache - The metadata cache to fix the frontmatter markdown links in.
* @returns Whether the frontmatter markdown links were fixed.
*/
export declare function fixFrontmatterMarkdownLinks(cache: CachedMetadata): boolean;
/**
* Generates a markdown link based on the provided parameters.
*
* @param options - The options for generating the markdown link.
* @returns The generated markdown link.
*/
export declare function generateMarkdownLink(options: GenerateMarkdownLinkOptions): string;
/**
* Generates a raw markdown link based on the provided options.
*
* @param options - The options for generating a raw markdown link.
* @returns A raw markdown link.
*/
export declare function generateRawMarkdownLink(options: GenerateRawMarkdownLinkOptions): string;
/**
* Parses a link into its components.
*
* @param str - The link to parse.
* @returns The parsed link.
*/
export declare function parseLink(str: string): null | ParseLinkResult;
/**
* Parses all links in a string.
*
* @param str - The string to parse the links in.
* @returns The parsed links.
*/
export declare function parseLinks(str: string): ParseLinkResult[];
/**
* Registers a function that returns default options for generating a markdown link.
*
* @param plugin - The plugin instance.
* @param fn - The function that returns the default options.
*/
export declare function registerGenerateMarkdownLinkDefaultOptionsFn(plugin: Plugin, fn: () => Partial<GenerateMarkdownLinkOptions>): void;
/**
* Determines if the alias of a link should be reset.
*
* @param options - The options for determining if the alias should be reset.
* @returns Whether the alias should be reset.
*/
export declare function shouldResetAlias(options: ShouldResetAliasOptions): boolean;
/**
* Splits a link into its link path and subpath.
*
* @param link - The link to split.
* @returns An object containing the link path and subpath.
*/
export declare function splitSubpath(link: string): SplitSubpathResult;
/**
* Tests whether a link uses angle brackets, possibly embed:
* `[title](<link>)`, ``.
*
* @param link - Link to test
* @returns Whether the link uses angle brackets
*/
export declare function testAngleBrackets(link: string): boolean;
/**
* Tests whether a link is an embed link:
* `![[link]]`, ``.
*
* @param link - Link to test
* @returns Whether the link is an embed link
*/
export declare function testEmbed(link: string): boolean;
/**
* Tests whether a link has a leading dot, possibly embed:
* `[[./link]]`, `[title](./link)`, `[title](<./link>)`,
* `![[./link]]`, ``, ``.
*
* @param link - Link to test
* @returns Whether the link has a leading dot
*/
export declare function testLeadingDot(link: string): boolean;
/**
* Tests whether a link has a leading slash, possibly embed:
* `[[/link]]`, `[title](/link)`, `[title](</link>)`,
* `![[/link]]`, ``, ``.
*
* @param link - Link to test
* @returns Whether the link has a leading slash
*/
export declare function testLeadingSlash(link: string): boolean;
/**
* Tests whether a link is a wikilink, possibly embed:
* `[[link]]`, `![[link]]`.
*
* @param link - Link to test
* @returns Whether the link is a wikilink
*/
export declare function testWikilink(link: string): boolean;
/**
* Unescapes the alias of a markdown link.
*
* @param escapedAlias - An escaped alias.
* @returns An unescaped alias.
*
* @example
* ```ts
* unescapeAlias('\\*\\*alias\\*\\*') // '**alias**'
* ```
*/
export declare function unescapeAlias(escapedAlias: string): string;
/**
* Updates a link based on the provided parameters.
*
* @param options - The options for updating the link.
* @returns The updated link.
*/
export declare function updateLink(options: UpdateLinkOptions): string;
/**
* Updates the links in a content string based on the provided parameters.
*
* @param options - The options for updating the links.
* @returns A {@link Promise} that resolves to the content with updated links.
*/
export declare function updateLinksInContent(options: UpdateLinksInContentOptions): Promise<string>;
/**
* Updates the links in a file based on the provided parameters.
*
* @param options - The options for updating the links.
* @returns A {@link Promise} that resolves when the links are updated.
*/
export declare function updateLinksInFile(options: UpdateLinksInFileOptions): Promise<void>;
export {};