first commit
This commit is contained in:
73
menu.ts
Normal file
73
menu.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { Plugin, MarkdownPostProcessorContext, TFile, Vault } from 'obsidian';
|
||||
|
||||
// Node.js shell module for opening files/folders
|
||||
const { shell } = require('electron');
|
||||
|
||||
export default class MenuPlugin extends Plugin {
|
||||
async onload() {
|
||||
this.registerMarkdownCodeBlockProcessor('menu', this.menuProcessor.bind(this));
|
||||
}
|
||||
|
||||
async menuProcessor(source: string, el: HTMLElement, ctx: MarkdownPostProcessorContext) {
|
||||
// Parse optional class from first line
|
||||
let lines = source.split('\n').map(l => l.trim()).filter(Boolean);
|
||||
let menuClass = 'menu-container';
|
||||
if (lines[0]?.startsWith('class:')) {
|
||||
menuClass += ' ' + lines[0].replace('class:', '').trim();
|
||||
lines = lines.slice(1);
|
||||
}
|
||||
const container = el.createDiv({ cls: menuClass });
|
||||
|
||||
for (const line of lines) {
|
||||
let match;
|
||||
// Internal Obsidian link: [[file|alias]]
|
||||
if ((match = line.match(/^\[\[(.+?)(\|(.+?))?]]$/))) {
|
||||
const fileName = match[1];
|
||||
const alias = match[3] || match[1];
|
||||
const a = container.createEl('a', { text: alias, cls: 'internal-link' });
|
||||
a.setAttr('data-href', fileName);
|
||||
a.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
this.app.workspace.openLinkText(fileName, ctx.sourcePath);
|
||||
});
|
||||
continue;
|
||||
}
|
||||
// Markdown link: [text](url)
|
||||
if ((match = line.match(/^\[(.+?)]\((.+?)\)$/))) {
|
||||
const text = match[1];
|
||||
const url = match[2];
|
||||
// Local file/folder (file:/// or absolute path)
|
||||
if (url.startsWith('file:///') || url.match(/^([a-zA-Z]:\\|\\\\)/)) {
|
||||
const a = container.createEl('a', { text });
|
||||
a.style.cursor = 'pointer';
|
||||
a.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
// Remove file:/// if present
|
||||
let path = url.replace('file:///', '');
|
||||
// Decode URI
|
||||
path = decodeURIComponent(path);
|
||||
shell.openPath(path);
|
||||
});
|
||||
} else if (url.startsWith('http')) {
|
||||
// Web link
|
||||
const a = container.createEl('a', { text });
|
||||
a.href = url;
|
||||
a.target = '_blank';
|
||||
a.rel = 'noopener noreferrer';
|
||||
a.style.cursor = 'pointer';
|
||||
} else {
|
||||
// Try to open as vault file
|
||||
const a = container.createEl('a', { text });
|
||||
a.style.cursor = 'pointer';
|
||||
a.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
this.app.workspace.openLinkText(url, ctx.sourcePath);
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Plain text fallback
|
||||
container.createEl('span', { text: line });
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user