2023-05-21 08:57:23 +00:00
|
|
|
import { Editor, MarkdownView, Plugin, Notice } from "obsidian";
|
|
|
|
|
|
|
|
|
|
import { PseudocodeSettingTab } from "src/setting_tab";
|
|
|
|
|
import { PseudocodeSuggestor } from "src/auto_complete";
|
2023-03-14 14:13:41 +00:00
|
|
|
import {
|
2023-05-21 08:57:23 +00:00
|
|
|
PseudocodeSettings,
|
|
|
|
|
DEFAULT_SETTINGS,
|
|
|
|
|
PseudocodeBlockInit,
|
|
|
|
|
BLOCK_NAME,
|
|
|
|
|
} from "src/setting";
|
2023-05-21 10:50:15 +00:00
|
|
|
import {
|
|
|
|
|
translateUnsupportedMacrosPerf,
|
|
|
|
|
checkTranslatedMacros,
|
|
|
|
|
} from "src/latex_translator";
|
2023-05-22 08:03:45 +00:00
|
|
|
import { createExportButton } from "src/export_button";
|
2023-06-07 16:12:36 +00:00
|
|
|
import { extractInlineMacros } from "src/inline_macro";
|
2024-06-05 08:13:40 +00:00
|
|
|
import { setObserver, detachObserver, setPseudocodeTheme } from "src/theme";
|
2023-03-13 11:40:20 +00:00
|
|
|
|
|
|
|
|
import * as pseudocode from "pseudocode";
|
2023-03-13 07:05:19 +00:00
|
|
|
|
2023-03-13 11:40:20 +00:00
|
|
|
export default class PseudocodePlugin extends Plugin {
|
|
|
|
|
settings: PseudocodeSettings;
|
2023-06-02 01:34:38 +00:00
|
|
|
preamble: string = "";
|
2023-03-13 11:40:20 +00:00
|
|
|
|
2023-03-14 14:13:41 +00:00
|
|
|
async pseudocodeHandler(
|
|
|
|
|
source: string,
|
|
|
|
|
el: HTMLElement,
|
|
|
|
|
ctx: any
|
|
|
|
|
): Promise<any> {
|
2023-04-29 05:15:40 +00:00
|
|
|
const blockDiv = el.createDiv({ cls: "pseudocode-block" });
|
|
|
|
|
const blockWidth = this.settings.blockSize;
|
2025-11-10 04:01:39 +00:00
|
|
|
blockDiv.style.width = `${blockWidth}em`;
|
2025-11-10 03:59:29 +00:00
|
|
|
blockDiv.addEventListener("click", (event) => {
|
2025-11-10 05:58:25 +00:00
|
|
|
const target = (event.target as HTMLElement | null);
|
|
|
|
|
if(target && target.tagName !== 'BUTTON')
|
2025-11-10 05:56:00 +00:00
|
|
|
(target
|
2025-11-10 05:58:25 +00:00
|
|
|
.closest('.pseudocode-block')
|
|
|
|
|
?.parentElement?.parentElement
|
|
|
|
|
?.querySelector('.edit-block-button') as HTMLElement | null)
|
|
|
|
|
?.click();
|
2025-11-10 03:59:29 +00:00
|
|
|
});
|
2023-04-29 05:15:40 +00:00
|
|
|
|
2023-06-07 16:12:36 +00:00
|
|
|
// Extract inline macros
|
|
|
|
|
const [inlineMacros, nonMacroLines] = extractInlineMacros(source);
|
|
|
|
|
const allPreamble = this.preamble + inlineMacros;
|
|
|
|
|
|
2023-05-19 13:19:03 +00:00
|
|
|
// find all $ enclosements in source, and add the preamble.
|
|
|
|
|
// TODO: Might be able to optimize.
|
|
|
|
|
const mathRegex = /\$(.*?)\$/g;
|
2023-06-07 16:12:36 +00:00
|
|
|
const withPreamble = nonMacroLines.replace(mathRegex, (_, group1) => {
|
|
|
|
|
return `$${allPreamble}${group1}$`;
|
2023-05-19 13:19:03 +00:00
|
|
|
});
|
|
|
|
|
|
2023-05-29 15:23:43 +00:00
|
|
|
const preEl = blockDiv.createEl("pre", {
|
|
|
|
|
cls: "code",
|
|
|
|
|
text: withPreamble,
|
|
|
|
|
});
|
2023-03-13 11:40:20 +00:00
|
|
|
|
2023-03-24 11:52:02 +00:00
|
|
|
try {
|
2023-04-29 05:24:02 +00:00
|
|
|
pseudocode.renderElement(preEl, this.settings.jsSettings);
|
2023-06-08 02:36:50 +00:00
|
|
|
createExportButton(this, blockDiv, inlineMacros, nonMacroLines);
|
2023-03-24 11:52:02 +00:00
|
|
|
} catch (error) {
|
|
|
|
|
console.log(error);
|
2023-05-21 08:57:23 +00:00
|
|
|
const errorSpan = blockDiv.createEl("span", {
|
|
|
|
|
text: "\u274C " + error.message,
|
|
|
|
|
});
|
2023-04-16 04:15:32 +00:00
|
|
|
errorSpan.classList.add("error-message");
|
2023-04-29 05:15:40 +00:00
|
|
|
blockDiv.empty();
|
|
|
|
|
blockDiv.appendChild(errorSpan);
|
2023-03-24 11:52:02 +00:00
|
|
|
}
|
2024-06-05 08:13:40 +00:00
|
|
|
|
|
|
|
|
// Set the pseudocode theme
|
|
|
|
|
if (this.settings.followSystemTheme) {
|
|
|
|
|
setPseudocodeTheme(blockDiv);
|
|
|
|
|
}
|
2023-03-13 11:40:20 +00:00
|
|
|
}
|
2023-03-13 07:05:19 +00:00
|
|
|
|
|
|
|
|
async onload() {
|
|
|
|
|
await this.loadSettings();
|
2023-05-31 04:00:32 +00:00
|
|
|
|
2024-06-05 01:22:37 +00:00
|
|
|
setObserver();
|
|
|
|
|
|
2023-05-31 04:00:32 +00:00
|
|
|
if (this.settings.preambleEnabled) {
|
|
|
|
|
console.log("Preamble is enabled.");
|
|
|
|
|
await this.loadPreamble();
|
|
|
|
|
}
|
2023-03-13 07:05:19 +00:00
|
|
|
|
2023-03-14 14:13:41 +00:00
|
|
|
this.registerMarkdownCodeBlockProcessor(
|
2023-03-17 03:03:13 +00:00
|
|
|
BLOCK_NAME,
|
2023-03-14 14:13:41 +00:00
|
|
|
this.pseudocodeHandler.bind(this)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Register suggest
|
|
|
|
|
this.registerEditorSuggest(new PseudocodeSuggestor(this));
|
2023-03-13 07:05:19 +00:00
|
|
|
|
|
|
|
|
// This adds a settings tab so the user can configure various aspects of the plugin
|
2023-03-13 11:40:20 +00:00
|
|
|
this.addSettingTab(new PseudocodeSettingTab(this.app, this));
|
2023-03-13 07:05:19 +00:00
|
|
|
|
2023-03-22 16:11:44 +00:00
|
|
|
// Auto-gen pseudocode block command.
|
|
|
|
|
this.addCommand({
|
|
|
|
|
id: "pseudocode-in-obs",
|
|
|
|
|
name: "Insert a new pseudocode block",
|
|
|
|
|
editorCallback: (editor: Editor, view: MarkdownView) => {
|
|
|
|
|
editor.replaceSelection(PseudocodeBlockInit);
|
|
|
|
|
},
|
|
|
|
|
});
|
2023-03-13 07:05:19 +00:00
|
|
|
}
|
|
|
|
|
|
2024-06-05 01:22:37 +00:00
|
|
|
onunload() {
|
|
|
|
|
detachObserver();
|
|
|
|
|
}
|
2023-03-13 07:05:19 +00:00
|
|
|
|
2023-05-19 13:19:03 +00:00
|
|
|
async loadPreamble() {
|
2023-05-21 08:57:23 +00:00
|
|
|
try {
|
|
|
|
|
this.preamble = await this.app.vault.adapter.read(
|
|
|
|
|
this.settings.preamblePath
|
|
|
|
|
);
|
|
|
|
|
} catch (error) {
|
2023-05-19 13:19:03 +00:00
|
|
|
console.log(error);
|
|
|
|
|
// Extract the search path from the error message.
|
|
|
|
|
const searchPath = error.message.match(/'(.*?)'/g)[0];
|
2023-05-21 08:57:23 +00:00
|
|
|
new Notice(
|
|
|
|
|
"Pseudocode Plugin: Preamble file not found at " +
|
|
|
|
|
searchPath +
|
|
|
|
|
"."
|
|
|
|
|
);
|
2023-05-19 13:19:03 +00:00
|
|
|
this.preamble = "";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
2023-05-21 10:50:15 +00:00
|
|
|
this.preamble = translateUnsupportedMacrosPerf(this.preamble);
|
|
|
|
|
this.preamble = checkTranslatedMacros(this.preamble);
|
|
|
|
|
console.log("Loaded preamble:\n" + this.preamble);
|
|
|
|
|
console.log(
|
|
|
|
|
"Preamble file loaded. You can check the detail in console."
|
|
|
|
|
);
|
2023-05-20 09:21:56 +00:00
|
|
|
if (this.settings.preambleLoadedNotice) {
|
|
|
|
|
new Notice("Pseudocode Plugin: Preamble file loaded.");
|
|
|
|
|
}
|
2023-05-21 08:57:23 +00:00
|
|
|
} catch (error) {
|
2023-05-19 13:19:03 +00:00
|
|
|
console.log(error);
|
2023-05-21 08:57:23 +00:00
|
|
|
new Notice(
|
|
|
|
|
"Pseudocode Plugin: Preamble file contains invalid LaTeX. " +
|
|
|
|
|
"Please refer to console for details."
|
|
|
|
|
);
|
2023-05-19 13:19:03 +00:00
|
|
|
this.preamble = "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-13 07:05:19 +00:00
|
|
|
async loadSettings() {
|
2023-03-14 14:13:41 +00:00
|
|
|
this.settings = Object.assign(
|
|
|
|
|
{},
|
|
|
|
|
DEFAULT_SETTINGS,
|
|
|
|
|
await this.loadData()
|
|
|
|
|
);
|
2023-03-13 07:05:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async saveSettings() {
|
|
|
|
|
await this.saveData(this.settings);
|
|
|
|
|
}
|
|
|
|
|
}
|