diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..b94d9dc --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "semi": true, + "singleQuote": true, + "trailingComma": "es5", + "tabWidth": 2, + "printWidth": 80 +} diff --git a/README.md b/README.md index c0e04e6..e420e1a 100644 --- a/README.md +++ b/README.md @@ -4,27 +4,27 @@ This is a custom plugin for rendering flowcharts in Obsidian using **flowchart.j ## Features -- Renders flowcharts using `flowchart.js` syntax within Obsidian notes. -- Supports customization of flowchart styles, such as line width, font size, colors, and element styling, directly from the plugin settings. -- Adjustable settings for each part of the flowchart, including start and end symbols, decision conditions, operations, and more. -- Provides an easy way to create interactive and visually appealing diagrams in your notes. +- Renders flowcharts using `flowchart.js` syntax within Obsidian notes. +- Supports customization of flowchart styles, such as line width, font size, colors, and element styling, directly from the plugin settings. +- Adjustable settings for each part of the flowchart, including start and end symbols, decision conditions, operations, and more. +- Provides an easy way to create interactive and visually appealing diagrams in your notes. ## How to Use 1. Open a note in Obsidian and add a `flowchart` code block, like this: - ````markdown - ```flowchart - st=>start: Start - op=>operation: My Operation - cond=>condition: Yes or No? - e=>end: End + ````markdown + ```flowchart + st=>start: Start + op=>operation: My Operation + cond=>condition: Yes or No? + e=>end: End - st->op->cond - cond(yes)->e - cond(no)->op - ``` - ```` + st->op->cond + cond(yes)->e + cond(no)->op + ``` + ```` 2. The plugin will render the flowchart according to the configuration specified in the plugin settings. @@ -32,13 +32,13 @@ This is a custom plugin for rendering flowcharts in Obsidian using **flowchart.j The plugin includes various settings that allow you to customize the appearance of the flowchart: -- **Line Width**: Controls the width of lines in the flowchart. -- **Font Size**: Sets the font size for text within the flowchart. -- **Font Color**: Changes the color of the font. -- **Line Color**: Sets the color of the lines connecting elements. -- **Element Color**: Adjusts the color of the shapes around text. -- **Fill Color**: Sets the background fill color for elements. -- **Yes/No Text**: Customizes the labels for decision paths. +- **Line Width**: Controls the width of lines in the flowchart. +- **Font Size**: Sets the font size for text within the flowchart. +- **Font Color**: Changes the color of the font. +- **Line Color**: Sets the color of the lines connecting elements. +- **Element Color**: Adjusts the color of the shapes around text. +- **Fill Color**: Sets the background fill color for elements. +- **Yes/No Text**: Customizes the labels for decision paths. You can access these settings under **Settings** > **Community Plugins** > **Flowchart Plugin**. @@ -48,17 +48,17 @@ You can access these settings under **Settings** > **Community Plugins** > **Flo If you're new to Obsidian plugin development: -- Clone this repository or use it as a template. -- Ensure NodeJS is installed (minimum v16). -- Run `npm install` to install dependencies. -- Use `npm run dev` to compile the plugin and start in watch mode. +- Clone this repository or use it as a template. +- Ensure NodeJS is installed (minimum v16). +- Run `npm install` to install dependencies. +- Use `npm run dev` to compile the plugin and start in watch mode. ### Building the Plugin To build the plugin: -- Run `npm run build` to compile the TypeScript code. -- Files will be output to the `dist` folder for use in Obsidian. +- Run `npm run build` to compile the TypeScript code. +- Files will be output to the `dist` folder for use in Obsidian. ## Manually Installing the Plugin @@ -78,9 +78,9 @@ If you'd like to install the plugin manually: If you encounter issues with rendering or plugin behavior: -- Ensure you are using a compatible version of Obsidian. -- Check the developer console (`Cmd + Option + I` on macOS or `Ctrl + Shift + I` on Windows/Linux) for error messages. -- Adjust settings to verify if certain configuration options are causing issues. +- Ensure you are using a compatible version of Obsidian. +- Check the developer console (`Cmd + Option + I` on macOS or `Ctrl + Shift + I` on Windows/Linux) for error messages. +- Adjust settings to verify if certain configuration options are causing issues. ## Contributing diff --git a/esbuild.config.mjs b/esbuild.config.mjs index aaa4475..a104666 100644 --- a/esbuild.config.mjs +++ b/esbuild.config.mjs @@ -1,6 +1,6 @@ -import esbuild from "esbuild"; -import process from "process"; -import builtins from "builtin-modules"; +import esbuild from 'esbuild'; +import process from 'process'; +import builtins from 'builtin-modules'; const banner = `/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD @@ -8,36 +8,36 @@ if you want to view the source, please visit the github repository of this plugi */ `; -const prod = process.argv[2] === "production"; +const prod = process.argv[2] === 'production'; const context = await esbuild.context({ banner: { js: banner, }, - entryPoints: ["main.ts"], + entryPoints: ['main.ts'], bundle: true, external: [ - "obsidian", - "electron", - "@codemirror/autocomplete", - "@codemirror/collab", - "@codemirror/commands", - "@codemirror/language", - "@codemirror/lint", - "@codemirror/search", - "@codemirror/state", - "@codemirror/view", - "@lezer/common", - "@lezer/highlight", - "@lezer/lr", + 'obsidian', + 'electron', + '@codemirror/autocomplete', + '@codemirror/collab', + '@codemirror/commands', + '@codemirror/language', + '@codemirror/lint', + '@codemirror/search', + '@codemirror/state', + '@codemirror/view', + '@lezer/common', + '@lezer/highlight', + '@lezer/lr', ...builtins, ], - format: "cjs", - target: "es2018", - logLevel: "info", - sourcemap: prod ? false : "inline", + format: 'cjs', + target: 'es2018', + logLevel: 'info', + sourcemap: prod ? false : 'inline', treeShaking: true, - outfile: "main.js", + outfile: 'main.js', minify: prod, }); diff --git a/eslint.config.js b/eslint.config.js index a558287..d48ab43 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,25 +1,25 @@ -const typescriptEslintParser = require("@typescript-eslint/parser"); -const typescriptEslintPlugin = require("@typescript-eslint/eslint-plugin"); +const typescriptEslintParser = require('@typescript-eslint/parser'); +const typescriptEslintPlugin = require('@typescript-eslint/eslint-plugin'); module.exports = [ { - ignores: ["node_modules", "main.js"], // Ignoring the default generated files and directories + ignores: ['node_modules', 'main.js'], // Ignoring the default generated files and directories }, { - files: ["**/*.ts"], // Apply the configuration to TypeScript files + files: ['**/*.ts'], // Apply the configuration to TypeScript files languageOptions: { parser: typescriptEslintParser, - ecmaVersion: "latest", // Always using the latest ECMAScript version - sourceType: "module", // Modern JavaScript uses module import/export syntax + ecmaVersion: 'latest', // Always using the latest ECMAScript version + sourceType: 'module', // Modern JavaScript uses module import/export syntax }, plugins: { - "@typescript-eslint": typescriptEslintPlugin, // Using TypeScript-specific plugin + '@typescript-eslint': typescriptEslintPlugin, // Using TypeScript-specific plugin }, rules: { - "@typescript-eslint/no-unused-vars": ["error", { args: "none" }], // Replacing 'no-unused-vars' with TS-specific version - "@typescript-eslint/ban-ts-comment": "off", // Allowing use of ts comments if needed - "@typescript-eslint/no-empty-function": "off", // Allowing empty functions for flexibility - "no-prototype-builtins": "off", // Allowing direct calls to object's prototype functions + '@typescript-eslint/no-unused-vars': ['error', { args: 'none' }], // Replacing 'no-unused-vars' with TS-specific version + '@typescript-eslint/ban-ts-comment': 'off', // Allowing use of ts comments if needed + '@typescript-eslint/no-empty-function': 'off', // Allowing empty functions for flexibility + 'no-prototype-builtins': 'off', // Allowing direct calls to object's prototype functions }, }, ]; diff --git a/main.ts b/main.ts index 2754e36..362c369 100644 --- a/main.ts +++ b/main.ts @@ -1,5 +1,5 @@ -import { App, Plugin, PluginSettingTab, Setting } from "obsidian"; -import * as flowchart from "flowchart.js"; +import { App, Plugin, PluginSettingTab, Setting } from 'obsidian'; +import * as flowchart from 'flowchart.js'; interface FlowchartPluginSettings { config: Record; @@ -9,28 +9,28 @@ const DEFAULT_SETTINGS: FlowchartPluginSettings = { config: { x: 0, y: 0, - "line-width": 2, - "line-length": 50, - "text-margin": 10, - "font-size": 14, - "font-color": "black", - "line-color": "black", - "element-color": "black", - fill: "white", - "yes-text": "yes", - "no-text": "no", - "arrow-end": "block", + 'line-width': 2, + 'line-length': 50, + 'text-margin': 10, + 'font-size': 14, + 'font-color': 'black', + 'line-color': 'black', + 'element-color': 'black', + fill: 'white', + 'yes-text': 'yes', + 'no-text': 'no', + 'arrow-end': 'block', scale: 1, symbols: { start: { - "font-color": "black", - "element-color": "black", - fill: "white", + 'font-color': 'black', + 'element-color': 'black', + fill: 'white', }, end: { - "font-color": "black", - "element-color": "black", - fill: "white", + 'font-color': 'black', + 'element-color': 'black', + fill: 'white', }, }, }, @@ -42,15 +42,12 @@ export default class FlowchartPlugin extends Plugin { async onload() { await this.loadSettings(); - console.log("Flowchart plugin loaded"); + console.log('Flowchart plugin loaded'); // Register the markdown post processor for 'flowchart' code blocks - this.registerMarkdownCodeBlockProcessor( - "flowchart", - (source, el, ctx) => { - this.renderFlowchart(source, el); - }, - ); + this.registerMarkdownCodeBlockProcessor('flowchart', (source, el, ctx) => { + this.renderFlowchart(source, el); + }); this.addSettingTab(new FlowchartSettingTab(this.app, this)); } @@ -60,17 +57,17 @@ export default class FlowchartPlugin extends Plugin { requestAnimationFrame(() => { try { const diagram = flowchart.parse(source); - const container = el.createEl("div", { - cls: "obsidian-flowchart-container", + const container = el.createEl('div', { + cls: 'obsidian-flowchart-container', }); diagram.drawSVG(container, this.settings.config); // Apply a fix for deprecated xlink attributes this.fixXlinkAttributes(container); } catch (error) { - console.error("Error rendering flowchart: ", error); - el.createEl("div", { - text: "Error rendering flowchart. Check your markup.", + console.error('Error rendering flowchart: ', error); + el.createEl('div', { + text: 'Error rendering flowchart. Check your markup.', }); } }); @@ -78,26 +75,22 @@ export default class FlowchartPlugin extends Plugin { fixXlinkAttributes(el: HTMLElement) { // Find elements with deprecated xlink attributes and replace them - const elements = el.querySelectorAll("[*|href]"); + const elements = el.querySelectorAll('[*|href]'); elements.forEach((element) => { - const xlinkHref = element.getAttribute("xlink:href"); + const xlinkHref = element.getAttribute('xlink:href'); if (xlinkHref) { - element.setAttribute("href", xlinkHref); - element.removeAttribute("xlink:href"); + element.setAttribute('href', xlinkHref); + element.removeAttribute('xlink:href'); } }); } onunload() { - console.log("Flowchart plugin unloaded"); + console.log('Flowchart plugin unloaded'); } async loadSettings() { - this.settings = Object.assign( - {}, - DEFAULT_SETTINGS, - await this.loadData(), - ); + this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); } async saveSettings() { @@ -118,127 +111,114 @@ class FlowchartSettingTab extends PluginSettingTab { containerEl.empty(); - containerEl.createEl("h2", { text: "Flowchart Plugin Settings" }); + containerEl.createEl('h2', { text: 'Flowchart Plugin Settings' }); new Setting(containerEl) - .setName("Line Width") - .setDesc("Set the line width for the flowchart.") + .setName('Line Width') + .setDesc('Set the line width for the flowchart.') .addText((text) => text - .setValue( - this.plugin.settings.config["line-width"].toString(), - ) + .setValue(this.plugin.settings.config['line-width'].toString()) .onChange(async (value) => { - this.plugin.settings.config["line-width"] = - parseInt(value) || 2; + this.plugin.settings.config['line-width'] = parseInt(value) || 2; await this.plugin.saveSettings(); - }), + }) ); new Setting(containerEl) - .setName("Line Length") - .setDesc("Set the line length for the flowchart.") + .setName('Line Length') + .setDesc('Set the line length for the flowchart.') .addText((text) => text - .setValue( - this.plugin.settings.config["line-length"].toString(), - ) + .setValue(this.plugin.settings.config['line-length'].toString()) .onChange(async (value) => { - this.plugin.settings.config["line-length"] = - parseInt(value) || 2; + this.plugin.settings.config['line-length'] = parseInt(value) || 2; await this.plugin.saveSettings(); - }), + }) ); new Setting(containerEl) - .setName("Yes Text") - .setDesc("Text for Yes responses in the flowchart.") + .setName('Yes Text') + .setDesc('Text for Yes responses in the flowchart.') .addText((text) => text - .setValue(this.plugin.settings.config["yes-text"]) + .setValue(this.plugin.settings.config['yes-text']) .onChange(async (value) => { - this.plugin.settings.config["yes-text"] = - value || "yes"; + this.plugin.settings.config['yes-text'] = value || 'yes'; await this.plugin.saveSettings(); - }), + }) ); new Setting(containerEl) - .setName("No Text") - .setDesc("Text for No responses in the flowchart.") + .setName('No Text') + .setDesc('Text for No responses in the flowchart.') .addText((text) => text - .setValue(this.plugin.settings.config["no-text"]) + .setValue(this.plugin.settings.config['no-text']) .onChange(async (value) => { - this.plugin.settings.config["no-text"] = value || "no"; + this.plugin.settings.config['no-text'] = value || 'no'; await this.plugin.saveSettings(); - }), + }) ); new Setting(containerEl) - .setName("Font Size") - .setDesc("Set the font size for the flowchart.") + .setName('Font Size') + .setDesc('Set the font size for the flowchart.') .addText((text) => text - .setValue( - this.plugin.settings.config["font-size"].toString(), - ) + .setValue(this.plugin.settings.config['font-size'].toString()) .onChange(async (value) => { - this.plugin.settings.config["font-size"] = - parseInt(value) || 14; + this.plugin.settings.config['font-size'] = parseInt(value) || 14; await this.plugin.saveSettings(); - }), + }) ); new Setting(containerEl) - .setName("Font Color") - .setDesc("Set the font color for the flowchart.") + .setName('Font Color') + .setDesc('Set the font color for the flowchart.') .addColorPicker((picker) => picker - .setValue(this.plugin.settings.config["font-color"]) + .setValue(this.plugin.settings.config['font-color']) .onChange(async (value) => { - this.plugin.settings.config["font-color"] = - value || "black"; + this.plugin.settings.config['font-color'] = value || 'black'; await this.plugin.saveSettings(); - }), + }) ); new Setting(containerEl) - .setName("Line Color") - .setDesc("Set the line color for the flowchart.") + .setName('Line Color') + .setDesc('Set the line color for the flowchart.') .addColorPicker((picker) => picker - .setValue(this.plugin.settings.config["line-color"]) + .setValue(this.plugin.settings.config['line-color']) .onChange(async (value) => { - this.plugin.settings.config["line-color"] = - value || "black"; + this.plugin.settings.config['line-color'] = value || 'black'; await this.plugin.saveSettings(); - }), + }) ); new Setting(containerEl) - .setName("Element Color") - .setDesc("Set the element color for the flowchart.") + .setName('Element Color') + .setDesc('Set the element color for the flowchart.') .addColorPicker((picker) => picker - .setValue(this.plugin.settings.config["element-color"]) + .setValue(this.plugin.settings.config['element-color']) .onChange(async (value) => { - this.plugin.settings.config["element-color"] = - value || "black"; + this.plugin.settings.config['element-color'] = value || 'black'; await this.plugin.saveSettings(); - }), + }) ); new Setting(containerEl) - .setName("Fill Color") - .setDesc("Set the background fill color for the flowchart.") + .setName('Fill Color') + .setDesc('Set the background fill color for the flowchart.') .addColorPicker((picker) => picker - .setValue(this.plugin.settings.config["fill"]) + .setValue(this.plugin.settings.config['fill']) .onChange(async (value) => { - this.plugin.settings.config["fill"] = value || "white"; + this.plugin.settings.config['fill'] = value || 'white'; await this.plugin.saveSettings(); - }), + }) ); } } diff --git a/package.json b/package.json index 5d00019..4ff1d6d 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "dev": "node esbuild.config.mjs", "build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production", "version": "node version-bump.mjs && git add manifest.json versions.json", - "format": "prettier --write ." + "format": "prettier --write .", + "lint": "eslint '**/*.ts'" }, "keywords": [], "author": "land0r", diff --git a/version-bump.mjs b/version-bump.mjs index d409fa0..3f6c905 100644 --- a/version-bump.mjs +++ b/version-bump.mjs @@ -1,14 +1,14 @@ -import { readFileSync, writeFileSync } from "fs"; +import { readFileSync, writeFileSync } from 'fs'; const targetVersion = process.env.npm_package_version; // read minAppVersion from manifest.json and bump version to target version -let manifest = JSON.parse(readFileSync("manifest.json", "utf8")); +let manifest = JSON.parse(readFileSync('manifest.json', 'utf8')); const { minAppVersion } = manifest; manifest.version = targetVersion; -writeFileSync("manifest.json", JSON.stringify(manifest, null, "\t")); +writeFileSync('manifest.json', JSON.stringify(manifest, null, '\t')); // update versions.json with target version and minAppVersion from manifest.json -let versions = JSON.parse(readFileSync("versions.json", "utf8")); +let versions = JSON.parse(readFileSync('versions.json', 'utf8')); versions[targetVersion] = minAppVersion; -writeFileSync("versions.json", JSON.stringify(versions, null, "\t")); +writeFileSync('versions.json', JSON.stringify(versions, null, '\t'));