Initial commit - Claudesidian v0.2.0
Claude Code + Obsidian starter kit for AI-powered knowledge management. Features: - PARA method folder structure - Bootstrap initialization system - Pre-configured Claude Code commands and agents - Gemini Vision MCP server with video support - Helper scripts for vault management - Automated release management See README.md for setup instructions.
This commit is contained in:
Executable
+87
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Fixes attachment links after files have been renamed
|
||||
* Usage: node .scripts/fix-renamed-links.js <old-name> <new-name>
|
||||
*
|
||||
* This properly handles the case where files are renamed, not just moved
|
||||
*/
|
||||
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
if (args.length !== 2) {
|
||||
console.log('Usage: node .scripts/fix-renamed-links.js <old-filename> <new-filename>');
|
||||
console.log('Example: node .scripts/fix-renamed-links.js "CleanShot 2025-01-01.png" "Project Screenshot.png"');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const [oldName, newName] = args;
|
||||
const newPath = `05 Attachments/Organized/${newName}`;
|
||||
|
||||
console.log(`Fixing links: ${oldName} → ${newName}`);
|
||||
|
||||
// Function to walk directory
|
||||
function walkDir(dir, callback) {
|
||||
fs.readdirSync(dir).forEach(f => {
|
||||
const dirPath = path.join(dir, f);
|
||||
const isDirectory = fs.statSync(dirPath).isDirectory();
|
||||
if (isDirectory) {
|
||||
// Skip node_modules, .git
|
||||
if (!f.includes('node_modules') && !f.includes('.git')) {
|
||||
walkDir(dirPath, callback);
|
||||
}
|
||||
} else {
|
||||
callback(path.join(dir, f));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Process all markdown files
|
||||
let updatedCount = 0;
|
||||
const updatedFiles = [];
|
||||
|
||||
walkDir('.', (filepath) => {
|
||||
if (filepath.endsWith('.md')) {
|
||||
let content = fs.readFileSync(filepath, 'utf8');
|
||||
const originalContent = content;
|
||||
|
||||
// Escape special regex characters in filename
|
||||
const escapedOld = oldName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
|
||||
// Pattern 1: ![[oldname]] without path
|
||||
const pattern1 = new RegExp(`!\\[\\[${escapedOld}\\]\\]`, 'g');
|
||||
content = content.replace(pattern1, `![[${newPath}]]`);
|
||||
|
||||
// Pattern 2: ![[05 Attachments/oldname]]
|
||||
const pattern2 = new RegExp(`!\\[\\[05 Attachments/${escapedOld}\\]\\]`, 'g');
|
||||
content = content.replace(pattern2, `![[${newPath}]]`);
|
||||
|
||||
// Pattern 3: [[oldname]] without ! (for PDFs and other non-embedded)
|
||||
const pattern3 = new RegExp(`(?<!!)\\[\\[${escapedOld}\\]\\]`, 'g');
|
||||
content = content.replace(pattern3, `[[${newPath}]]`);
|
||||
|
||||
// Pattern 4: [[05 Attachments/oldname]] without !
|
||||
const pattern4 = new RegExp(`(?<!!)\\[\\[05 Attachments/${escapedOld}\\]\\]`, 'g');
|
||||
content = content.replace(pattern4, `[[${newPath}]]`);
|
||||
|
||||
// Write back if changed
|
||||
if (content !== originalContent) {
|
||||
fs.writeFileSync(filepath, content, 'utf8');
|
||||
updatedFiles.push(filepath);
|
||||
updatedCount++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Report results
|
||||
if (updatedCount > 0) {
|
||||
console.log(`\nUpdated ${updatedCount} files:`);
|
||||
updatedFiles.forEach(file => console.log(` - ${file}`));
|
||||
} else {
|
||||
console.log('\nNo files needed updating');
|
||||
}
|
||||
|
||||
console.log('\nDone!');
|
||||
Reference in New Issue
Block a user