Created
August 19, 2025 08:33
-
-
Save lepinkainen/828f495eee3ba3fce3b7726a179c861b to your computer and use it in GitHub Desktop.
Create a colour based on note name
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = async (params) => { | |
const { app } = params; | |
const file = app.workspace.getActiveFile(); | |
if (!file) return; | |
// Only run for Markdown files | |
if (!file.name.endsWith(".md")) return; | |
// Read full note text | |
let content = await app.vault.read(file); | |
// Hash → deterministic muted hex color for backgrounds | |
function stringToColor(str) { | |
let hash = 0; | |
for (let i = 0; i < str.length; i++) { | |
hash = str.charCodeAt(i) + ((hash << 5) - hash); | |
} | |
// Generate muted colors by constraining RGB values to a narrower, lighter range | |
let color = "#"; | |
for (let i = 0; i < 3; i++) { | |
// Get base value from hash | |
const rawValue = (hash >> (i * 8)) & 0xff; | |
// Map to muted range: 160-220 (instead of 0-255) for softer colors | |
const mutedValue = 160 + (rawValue % 61); | |
color += ("00" + mutedValue.toString(16)).slice(-2); | |
} | |
return '"' + color + '"'; | |
} | |
// Check if a cover value is an image link/URL | |
function isImageLink(coverValue) { | |
if (!coverValue) return false; | |
// Remove quotes and whitespace | |
const cleanValue = coverValue.replace(/['"]/g, "").trim(); | |
// Check for common image extensions | |
const imageExtensions = /\.(jpg|jpeg|png|gif|bmp|svg|webp)$/i; | |
if (imageExtensions.test(cleanValue)) return true; | |
// Check for URLs (http/https) | |
if (/^https?:\/\//.test(cleanValue)) return true; | |
// Check for Obsidian internal links [[filename]] | |
if (/^\[\[.*\]\]$/.test(cleanValue)) return true; | |
// Check for markdown image syntax  | |
if (/^!\[.*\]\(.*\)$/.test(cleanValue)) return true; | |
return false; | |
} | |
const title = file.basename.trim(); | |
const newColor = stringToColor(title); | |
// Ensure frontmatter exists | |
if (!/^---/.test(content)) { | |
content = `---\ncover: ${newColor}\n---\n\n${content}`; | |
} else if (/^cover: .*/m.test(content)) { | |
// Check if existing cover is an image link before replacing | |
const existingCoverMatch = content.match(/^cover: (.*)$/m); | |
if (existingCoverMatch && !isImageLink(existingCoverMatch[1])) { | |
// Only replace if it's not an image link | |
content = content.replace(/^cover: .*/m, `cover: ${newColor}`); | |
} | |
// If it is an image link, don't replace it | |
} else { | |
// Insert cover into frontmatter block | |
content = content.replace( | |
/^---([\s\S]*?)---/, | |
(match, inner) => `---${inner}\ncover: ${newColor}\n---` | |
); | |
} | |
await app.vault.modify(file, content); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment