Paladin
December 28, 2024, 3:25am
1
Hello,
I have transferred my notes from Joplin to Obsidian. However, my note titles contain characters like #, ?, and : that Obsidian does not accept. Therefore, the titles are incomplete. But the full titles of my notes are available in the ‘Title’ field. So, I have to manually adjust the titles using an application called ‘Smart Rename’. This means I am copying the file name from the ‘Title’ field without unwanted characters and pasting it into the note name automatically. Considering that I have a large number of notes, is it possible to automate this process for all notes?
I don’t have any experience in coding. I would appreciate it if programmer friends could help with the script. @mnaoumov
Although I’ve been manually editing the titles of my notes for a few months, this topic will be useful and important for users like me who have transitioned from note-taking apps like Joplin to Obsidian.
DON’T FORGET TO BACKUP YOUR VAULT BEFORE RUNNING ANY CODE
Take the following js
code and insert it in Obsidian anywhere that can run js
code, e.g. Ctrl + Shift + I
, dataviewjs
etc
The code does the following
Loops over all md
files in your vault
Checks if the corresponding file has title
in frontmatter
Replaces all unsafe characters to underscore (_
)
Ensures the result file name and path don’t exceed certain length limits:
259 characters in total on Windows
255 bytes in name, non-English characters can take more than 1 byte
Trims trailing spaces (
) and periods (.
) as they are not valid on Windows
Renames the file into the safe title
Outputs the progress and all errors, if any
Feel free to ask for more features if needed
async function renameAllNotesToTheirTitles() {
// https://superuser.com/questions/1620259/the-maximum-length-of-the-path-of-a-file-259-or-258-characters
const MAX_FILE_PATH_LENGTH = 259;
// https://serverfault.com/questions/9546/filename-length-limits-on-linux
const MAX_NAME_BYTES_LENGTH = 255;
const INVALID_CHARACTERS_REG_EXP = /[#\^\[\]|*\\\/<>:?]/g;
const REPLACEMENT_CHARACTER = '_';
const basePath = app.vault.adapter.basePath;
let i = 0;
const notes = app.vault.getMarkdownFiles().sort((a, b) => a.path.localeCompare(b.path));
for (const note of notes) {
i++;
console.log(`Processing ${i} / ${notes.length} - ${note.path}`);
try {
let title = app.metadataCache.getFileCache(note)?.frontmatter?.['title'];
if (!title) {
console.warn(`No title found for ${note.path}`);
title = note.basename;
}
title = String(title);
const safeTitle = title.replace(INVALID_CHARACTERS_REG_EXP, REPLACEMENT_CHARACTER);
const dir = note.parent?.getParentPrefix() ?? '';
const fullDir = `${basePath}/${dir}`;
const fullPath = `${fullDir}${safeTitle}.md`;
let trimmedSafeTitle = safeTitle;
const trimLength = Math.max(fullPath.length - MAX_FILE_PATH_LENGTH, bytesLength(title) - MAX_NAME_BYTES_LENGTH + '.md'.length);
if (trimLength >= safeTitle.length) {
console.error(`Cannot set safe title for ${fullPath} as the path is too long`);
} else {
trimmedSafeTitle = safeTitle.slice(0, safeTitle.length - trimLength);
}
trimmedSafeTitle = trimmedSafeTitle.replace(/[ .]+$/, REPLACEMENT_CHARACTER);
const newPath = `${dir}${trimmedSafeTitle}.md`;
if (note.path === newPath) {
console.log('No need to rename');
continue;
}
console.log(`Renaming ${note.path} to ${newPath}`);
await app.fileManager.renameFile(note, newPath);
} catch (e) {
console.error(`Error processing ${note.path}`, e);
}
}
}
function bytesLength(str) {
return new Blob([str]).size;
}
await renameAllNotesToTheirTitles();
system
Closed
March 28, 2025, 4:15am
3
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.