UNPKG

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
/** * @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`: `![](foo.png)`. * * If `false`: `![foo](foo.png)`. */ 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>)`, `![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]]`, `![title](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]]`, `![title](./link)`, `![title](<./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]]`, `![title](/link)`, `![title](</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 {};