Skip to content

RainCat1998/obsidian-custom-attachment-location

Repository files navigation

Custom Attachment Location

This is a plugin for Obsidian that allows to customize attachment location with tokens (${noteFileName}, ${date:format}, etc) like typora.

Features

  • Modify location for attachment folder.
  • Modify file name for Pasted Files.
  • Collect attachments - take all attachments from the notes and puts them into the corresponding configured folders.

Settings

Location for new attachments

  • Same to "Files & Links -> Default location for new attachments".
  • Put "./" at the beginning of the path if you want to use relative path.
  • See available tokens.
  • example: assets/${noteFileName}, ./assets/${noteFileName}, ./assets/${noteFileName}/${date:YYYY}

Generated attachment file name

  • See available tokens.
  • example: ${originalAttachmentFileName}-${date:YYYYMMDDHHmmssSSS}, ${noteFileName}-img-${date:YYYYMMDD}
  • Obsidian default: Pasted image ${date:YYYYMMDDHHmmss}.

Markdown URL format

Format for the URL that will be inserted into Markdown.

Warning

This setting is needed for very specific use cases. For majority of users, it should stay blank.

  • If set, all links to attachments will be created as markdown links, even if Obsidian settings are configured to use [[Wikilinks]].
  • If set to ${generatedAttachmentFilePath}, it is almost the same as leaving it blank, considering the previous bullet point. Leave this setting blank instead.
  • If set to ${noteFilePath}, the most likely it is not what you need, as it will insert link to the note itself, instead of the attachment files. Some users reported they have this incorrect value set automatically during the invalid update. Leave this setting blank instead.

Should rename attachment folder

Automatically update attachment folder name if Location for New Attachments contains ${noteFileName}.

Should rename attachment files

Automatically update attachment files in target md file if Generated attachment file name contains ${noteFileName}.

Special characters replacement

Automatically replace special characters in attachment folder and file name with the specified string.

Should rename attachments to lowercase

Automatically set all characters in folder name and pasted image name to be lowercase.

Should convert pasted images to JPEG

Paste images from clipboard converting them to JPEG.

JPEG Quality

The smaller the quality, the greater the compression ratio.

Convert images on drag&drop

If enabled and Convert pasted images to JPEG setting is enabled, images drag&dropped into the editor will be converted to JPEG.

Rename only images

If enabled, only image files will be renamed.

If disabled, all attachment files will be renamed.

Rename pasted files with known names

If enabled, pasted copied files with known names will be renamed.

If disabled, only clipboard image objects (e.g., screenshots) will be renamed.

Rename attachments on drag&drop

If enabled, attachments dragged and dropped into the editor will be renamed according to the Generated attachment file name setting.

Should rename collected attachments

If enabled, attachments processed via Collect attachments commands will be renamed according to the Generated attachment file name setting.

Duplicate name separator

When you are pasting/dragging a file with the same name as an existing file, this separator will be added to the file name.

E.g., when you are dragging file existingFile.pdf, it will be renamed to existingFile 1.pdf, existingFile 2.pdf, etc, getting the first name available.

Default value is (space).

Should keep empty attachment folders

If enabled, empty attachment folders will be preserved, useful for source control purposes.

Should delete orphan attachments

If enabled, when the note is deleted, its orphan attachments are deleted as well.

Tokens

The following tokens can be used in the Location for New Attachments, Generated attachment file name and Markdown URL format settings.

Token strings: ${token} or ${token:format}. token is case-insensitive. format is case-sensitive. When ${token} is used, format is empty string.

${attachmentFileSize}

Size of the attachment file.

Format:

  • Bn (default): size in bytes rounded to n decimal points. n is a number (0 if omitted).
  • KBn: size in kilobytes rounded to n decimal points. n is a number (0 if omitted).
  • MBn: size in megabytes rounded to n decimal points. n is a number (0 if omitted).

${date}

Current date/time.

Format: Moment.js formatting.

${frontmatter}

Frontmatter value of the current note.

Format: frontmatter key. Nested keys are supported, e.g., key1.key2.3.key4.

${generatedAttachmentFileName}

The generated file name of the attachment (available only inside Markdown URL format setting).

Format:

  • (default): Unchanged file name. Example: foo/bar/baz qux quux.pdf -> baz qux quux.
  • leftn: Left n characters of the file name. Example left2: foo/bar/baz qux quux.pdf -> ba.
  • lower: Lowercase file name. Example: foo/bar/Baz QUX quux.pdf -> baz qux quux.
  • rightn: Right n characters of the file name. Example right2: foo/bar/baz qux quux.pdf -> ux.
  • slug: Slugified file name. Example: foo/bar/baz qux quux.pdf -> baz-qux-quux.
  • upper: Uppercase file name. Example: foo/bar/Baz QUX quux.pdf -> BAZ QUX QUUX.

${generatedAttachmentFilePath}

The generated file path of the attachment (available only inside Markdown URL format setting).

Example: foo/bar/baz.pdf -> foo/bar/baz.pdf.

${heading}

The heading above the cursor in the note editor where the attachment is inserted.

Format:

  • (default) any: Heading of the nearest any level #...# Heading.
  • 1: Heading of the nearest # Heading.
  • 2: Heading of the nearest ## Heading.
  • 3: Heading of the nearest ### Heading.
  • 4: Heading of the nearest #### Heading.
  • 5: Heading of the nearest ##### Heading.
  • 6: Heading of the nearest ###### Heading.

${noteFileCreationDate}

Note file creation date/time.

Format: Moment.js formatting.

${noteFileModificationDate}

Note file modification date/time.

Format: Moment.js formatting.

${noteFileName}

Current note file name.

Format:

  • (default): Unchanged file name. Example: foo/bar/baz qux quux.md -> baz qux quux.
  • leftn: Left n characters of the file name. Example left2: foo/bar/baz qux quux.md -> ba.
  • lower: Lowercase file name. Example: foo/bar/Baz QUX quux.md -> baz qux quux.
  • rightn: Right n characters of the file name. Example right2: foo/bar/baz qux quux.md -> ux.
  • slug: Slugified file name. Example: foo/bar/baz qux quux.md -> baz-qux-quux.
  • upper: Uppercase file name. Example: foo/bar/Baz QUX quux.md -> BAZ QUX QUUX.

${noteFilePath}

Current note full path.

Example: foo/bar/baz.md -> foo/bar/baz.md.

${noteFolderName}

Current note's folder name.

Format:

  • (default): Unchanged folder name. Example: foo/bar baz qux/quux.md -> bar baz qux.

  • leftn: Left n characters of the folder name. Example left2: foo/bar baz qux/quux.md -> ba.

  • lower: Lowercase folder name. Example: foo/Bar BAZ qux/quux.md -> bar baz qux.

  • rightn: Right n characters of the folder name. Example right2: foo/bar baz qux/quux.md -> ux.

  • slug: Slugified folder name. Example: foo/bar baz qux/quux.md -> bar-baz-qux.

  • upper: Uppercase folder name. Example: foo/Bar BAZ qux/quux.md -> BAR BAZ QUX.

  • indexFromEndn: 0-based index from the end of the folder tree. Example indexFromEnd1: foo/bar/baz/qux/quux.md -> baz.

  • indexFromStartn: 0-based index from the start of the folder tree. Example indexFromStart1: foo/bar/baz/qux/quux.md -> bar.

You can combine both kind of format formats, having indexFrom... first:

  • indexFromEndn,leftm. Example: indexFromEnd1,left2: foo/bar/baz/qux/quux.md -> ba (first two characters of baz).

${noteFolderPath}

Current note's folder full path.

Example: foo/bar/baz.md -> foo/bar.

${originalAttachmentFileExtension}

Extension of the original attachment file.

Example: foo.bar.pdf -> pdf.

${originalAttachmentFileName}

File name of the original attachment file.

Format:

  • (default): File name as is. Example: foo bar.baz.pdf -> foo bar.baz.
  • leftn: Left n characters of the file name. Example left2: foo/bar baz qux/quux.pdf -> ba.
  • lower: Lowercase folder name. Example: foo Bar.BAZ.pdf -> foo bar.baz.
  • rightn: Right n characters of the folder name. Example left2: foo/bar baz qux/quux.pdf -> ux.
  • slug: Slugified file name. Example: foo bar.baz.pdf -> foo-bar-baz.
  • upper: Uppercase folder name. Example: foo Bar.BAZ.pdf -> FOO BAR.BAZ.

${prompt}

The value asked from the user prompt.

Also in the prompt modal, you can preview the file, if it is supported by Obsidian (image, video, pdf).

Format:

  • (default): Unchanged value entered by user. Example: foo bar -> foo bar.
  • leftn: Left n characters of the value entered by user. Example left2: foo bar -> fo.
  • lower: Lowercased value entered by user. Example: foo Bar -> foo bar.
  • rightn: Right n characters of the value entered by user. Example right2: foo bar -> ar.
  • slug: Slugified value entered by user. Example: foo bar.baz -> foo-bar-baz.
  • upper: Uppercased value entered by user Example: foo Bar -> FOO BAR.

${random}

Random value.

Format:

  • Dn: n random digits. n is a number (1 if omitted).
  • Ln: n random letters. n is a number (1 if omitted).
  • DLn: n random digits or letters. n is a number (1 if omitted).
  • uuid: Random UUID.

Custom tokens

You can define custom tokens in the Custom tokens setting.

The custom tokens are defined as functions, both sync and async are supported.

Example:

registerCustomToken('foo', (ctx) => {
  return ctx.noteFileName + ctx.app.appId + ctx.format + ctx.obsidian.apiVersion;
});

registerCustomToken('bar', async (ctx) => {
  await sleep(100);
  return ctx.noteFileName + ctx.app.appId + ctx.format + ctx.obsidian.apiVersion;
});

registerCustomToken('baz', async (ctx) => {
  return ctx.noteFileName + await ctx.fillTemplate('corge ${grault} garply ${waldo:fred} plugh');
});

Then you can use the defined ${foo}, ${bar:xyzzy} tokens in the Location for New Attachments, Generated attachment file name and Markdown URL format settings.

See spec of the ctx argument.

Changelog

All notable changes to this project will be documented in the CHANGELOG.

Installation

The plugin is available in the official Community Plugins repository.

Beta versions

To install the latest beta release of this plugin (regardless if it is available in the official Community Plugins repository or not), follow these steps:

  1. Ensure you have the BRAT plugin installed and enabled.
  2. Click Install via BRAT.
  3. An Obsidian pop-up window should appear. In the window, click the Add plugin button once and wait a few seconds for the plugin to install.

Debugging

By default, debug messages for this plugin are hidden.

To show them, run the following command:

window.DEBUG.enable('obsidian-custom-attachment-location');

For more details, refer to the documentation.

Support

Buy Me A Coffee

License

© RainCat1998

Maintainer: Michael Naumov

About

Customize attachment location with variables($filename, $data, etc) like typora.

Resources

License

Stars

Watchers

Forks

Sponsor this project

Packages

No packages published