Oscar Plaisant f91c506a9e update
2025-03-16 18:05:45 +01:00

257 lines
10 KiB
JavaScript

'use strict';
var obsidian = require('obsidian');
var child_process = require('child_process');
var path = require('path');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
const DEFAULT_SETTINGS = {
quartoPath: 'quarto',
enableQmdLinking: true,
quartoTypst: '',
emitCompilationLogs: true, // Default is to emit logs
};
class QmdAsMdPlugin extends obsidian.Plugin {
constructor() {
super(...arguments);
this.activePreviewProcesses = new Map();
}
async onload() {
console.log('Plugin is loading...');
try {
await this.loadSettings();
console.log('Settings loaded:', this.settings);
if (this.settings.enableQmdLinking) {
this.registerQmdExtension();
}
this.addSettingTab(new QmdSettingTab(this.app, this));
console.log('Settings tab added successfully');
this.addRibbonIcon('eye', 'Toggle Quarto Preview', async () => {
const activeView = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView);
if (activeView?.file && this.isQuartoFile(activeView.file)) {
console.log(`Toggling preview for: ${activeView.file.path}`);
await this.togglePreview(activeView.file);
}
else {
new obsidian.Notice('Current file is not a Quarto document');
}
});
console.log('Ribbon icon added');
this.addCommand({
id: 'toggle-quarto-preview',
name: 'Toggle Quarto Preview',
callback: async () => {
const activeView = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView);
if (activeView?.file && this.isQuartoFile(activeView.file)) {
console.log(`Command: Toggling preview for ${activeView.file.path}`);
await this.togglePreview(activeView.file);
}
else {
new obsidian.Notice('Current file is not a Quarto document');
}
},
hotkeys: [{ modifiers: ['Ctrl', 'Shift'], key: 'p' }],
});
console.log('Commands added');
}
catch (error) {
console.error('Error loading plugin:', error);
new obsidian.Notice('Failed to load QmdAsMdPlugin. Check the developer console for details.');
}
}
onunload() {
console.log('Plugin is unloading...');
this.stopAllPreviews();
}
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
}
async saveSettings() {
await this.saveData(this.settings);
}
isQuartoFile(file) {
return file.extension === 'qmd';
}
registerQmdExtension() {
console.log('Registering .qmd as markdown...');
this.registerExtensions(['qmd'], 'markdown');
console.log('.qmd registered as markdown');
}
async togglePreview(file) {
if (this.activePreviewProcesses.has(file.path)) {
await this.stopPreview(file);
}
else {
await this.startPreview(file);
}
}
async startPreview(file) {
if (this.activePreviewProcesses.has(file.path)) {
console.log(`Preview already running for: ${file.path}`);
return; // Preview already running
}
try {
const abstractFile = this.app.vault.getAbstractFileByPath(file.path);
if (!abstractFile || !(abstractFile instanceof obsidian.TFile)) {
new obsidian.Notice(`File ${file.path} not found`);
return;
}
const filePath = this.app.vault.adapter.getFullPath(abstractFile.path);
const workingDir = path__namespace.dirname(filePath);
console.log(`Resolved file path: ${filePath}`);
console.log(`Working directory: ${workingDir}`);
const envVars = {
...process.env,
};
if (this.settings.quartoTypst.trim()) {
envVars.QUARTO_TYPST = this.settings.quartoTypst.trim();
console.log(`QUARTO_TYPST set to: ${envVars.QUARTO_TYPST}`);
}
const quartoProcess = child_process.spawn(this.settings.quartoPath, ['preview', filePath], {
cwd: workingDir,
env: envVars,
});
let previewUrl = null;
quartoProcess.stdout?.on('data', (data) => {
const output = data.toString();
if (this.settings.emitCompilationLogs) {
console.log(`Quarto Preview Output: ${output}`);
}
if (output.includes('Browse at')) {
const match = output.match(/Browse at\s+(http:\/\/[^\s]+)/);
if (match && match[1]) {
previewUrl = match[1];
new obsidian.Notice(`Preview available at ${previewUrl}`);
const leaf = this.app.workspace.getLeaf('tab');
leaf.setViewState({
type: 'webviewer',
active: true,
state: {
url: previewUrl,
},
});
this.app.workspace.revealLeaf(leaf);
}
}
});
quartoProcess.stderr?.on('data', (data) => {
if (this.settings.emitCompilationLogs) {
console.error(`Quarto Preview Error: ${data}`);
}
});
quartoProcess.on('close', (code) => {
if (code !== null && code !== 0) {
new obsidian.Notice(`Quarto preview process exited with code ${code}`);
}
this.activePreviewProcesses.delete(file.path);
});
this.activePreviewProcesses.set(file.path, quartoProcess);
new obsidian.Notice('Quarto preview started');
}
catch (error) {
console.error('Failed to start Quarto preview:', error);
new obsidian.Notice('Failed to start Quarto preview');
}
}
async stopPreview(file) {
const quartoProcess = this.activePreviewProcesses.get(file.path);
if (quartoProcess) {
if (!quartoProcess.killed) {
quartoProcess.kill();
}
this.activePreviewProcesses.delete(file.path);
new obsidian.Notice('Quarto preview stopped');
}
}
stopAllPreviews() {
this.activePreviewProcesses.forEach((quartoProcess, filePath) => {
if (!quartoProcess.killed) {
quartoProcess.kill();
}
this.activePreviewProcesses.delete(filePath);
});
if (this.activePreviewProcesses.size > 0) {
new obsidian.Notice('All Quarto previews stopped');
}
}
}
class QmdSettingTab extends obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
console.log('Rendering settings tab...');
containerEl.createEl('h2', { text: 'Quarto Preview Settings' });
new obsidian.Setting(containerEl)
.setName('Quarto Path')
.setDesc('Path to Quarto executable (e.g., quarto, /usr/local/bin/quarto)')
.addText((text) => text
.setPlaceholder('quarto')
.setValue(this.plugin.settings.quartoPath)
.onChange(async (value) => {
console.log(`Quarto path changed to: ${value}`);
this.plugin.settings.quartoPath = value;
await this.plugin.saveSettings();
}));
new obsidian.Setting(containerEl)
.setName('Enable Editing Quarto Files')
.setDesc('By default, plugin allows editing .qmd files. Disable this feature if there is a conflict with .qmd editing enabled by another plugin')
.addToggle((toggle) => toggle
.setValue(this.plugin.settings.enableQmdLinking)
.onChange(async (value) => {
console.log(`Enable QMD Editing setting changed to: ${value}`);
this.plugin.settings.enableQmdLinking = value;
if (value) {
this.plugin.registerQmdExtension();
}
}));
new obsidian.Setting(containerEl)
.setName('QUARTO_TYPST Variable')
.setDesc('Define the QUARTO_TYPST environment variable (leave empty to unset)')
.addText((text) => text
.setPlaceholder('e.g., typst_path')
.setValue(this.plugin.settings.quartoTypst)
.onChange(async (value) => {
console.log(`QUARTO_TYPST set to: ${value}`);
this.plugin.settings.quartoTypst = value;
await this.plugin.saveSettings();
}));
new obsidian.Setting(containerEl)
.setName('Emit Compilation Logs')
.setDesc('Toggle whether to emit detailed compilation logs in the console')
.addToggle((toggle) => toggle
.setValue(this.plugin.settings.emitCompilationLogs)
.onChange(async (value) => {
console.log(`Emit Compilation Logs set to: ${value}`);
this.plugin.settings.emitCompilationLogs = value;
await this.plugin.saveSettings();
}));
console.log('Settings tab rendered successfully');
}
}
module.exports = QmdAsMdPlugin;
/* nosourcemap */