Skip to content

Instantly share code, notes, and snippets.

@zanza00
Last active November 28, 2024 22:49
Show Gist options
  • Save zanza00/f875bdcd1aa3ee7cd1ec061c6adb485c to your computer and use it in GitHub Desktop.
Save zanza00/f875bdcd1aa3ee7cd1ec061c6adb485c to your computer and use it in GitHub Desktop.
check all files of an obsidian vault

Obsidian Date Adder

A simple Deno CLI tool to manage the date field in Obsidian vault markdown files' frontmatter.

JSR Version

Features

  • Scans markdown files in an Obsidian vault recursively
  • Identifies files missing the date field in their frontmatter
  • Automatically adds the date field using file creation date when run with write permissions
  • Preserves existing frontmatter structure and other fields

Prerequisites

  • Deno version 2.x or higher

Usage

Run the script directly:

deno run --allow-read --allow-write jsr:@zanza00/obsidian-date-adder /path/to/vault

If you want to only view files without modifying them, omit the --allow-write flag:

deno run --allow-read jsr:@zanza00/obsidian-date-adder /path/to/vault

Example output:

File: /path/to/vault/notes/example-note.md
Created: 2024-01-15T10:30
Current Frontmatter:
id: abc123
tags:
  - note
  - example
File updated with new date field
---

Date Format

The date is added in the format: YYYY-MM-DDTHH:mm

For example: 2024-01-15T10:30

Notes

  • The script will only modify files that don't already have a date field
  • The script uses the file's creation date for the date field
  • Only .md files are processed
  • Files without frontmatter are ignored
  • Existing frontmatter fields are preserved
  • Run with --allow-write to automatically update files, omit it to only view files

Links

License

MIT

import { parse } from "jsr:@std/yaml@1";
import { walk } from "jsr:@std/fs@1/walk";
interface Frontmatter {
date?: string;
[key: string]: unknown;
}
const folderPath = Deno.args[0];
if (!folderPath) {
console.error("Please provide a folder path");
console.error("Usage: deno run --allow-read --allow-write obsidian-date-adder.ts <folder_path>");
Deno.exit(1);
}
try {
const stats = await Deno.stat(folderPath);
if (!stats.isDirectory) {
console.error("The provided path is not a directory");
Deno.exit(1);
}
} catch {
console.error(`Folder ${folderPath} does not exist`);
Deno.exit(1);
}
const canWrite = (await Deno.permissions.query({ name: "write", path: folderPath })).state === "granted";
for await (const entry of walk(folderPath, {
includeDirs: false,
match: [/\.md$/],
skip: [/\.git/],
})) {
try {
const content = await Deno.readTextFile(entry.path);
if (!content.startsWith("---")) {
continue;
}
const endOfFrontmatter = content.indexOf("---", 3);
if (endOfFrontmatter === -1) {
continue;
}
const frontmatterContent = content.slice(3, endOfFrontmatter).trim();
const frontmatter = parse(frontmatterContent) as Frontmatter;
if (!frontmatter.date) {
const fileInfo = await Deno.stat(entry.path);
const creationTime = fileInfo.birthtime || new Date();
const formattedDate = creationTime.toISOString().slice(0, 16);
console.log(`File: ${entry.path}`);
console.log(`Created: ${formattedDate}`);
console.log("Current Frontmatter:");
console.log(frontmatterContent);
if (canWrite) {
const newFrontmatter = {
...frontmatter,
date: formattedDate,
};
const newContent = `---\n${Object.entries(newFrontmatter)
.map(([key, value]) => `${key}: ${value}`)
.join("\n")}
---${content.slice(endOfFrontmatter + 3)}`;
try {
await Deno.writeTextFile(entry.path, newContent);
console.log("File updated with new date field");
} catch (error: unknown) {
if (error instanceof Error) {
console.error(`Error updating file ${entry.path}: ${error.message}`);
} else {
console.error(`Unknown error updating file ${entry.path}`);
}
}
}
console.log("---");
}
} catch (error: unknown) {
if (error instanceof Error) {
console.error(`Error processing file ${entry.path}: ${error.message}`);
} else {
console.error(`Unknown error processing file ${entry.path}`);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment