diff --git a/data.json b/data.json index 51d11c2..3840fe3 100644 --- a/data.json +++ b/data.json @@ -1,6 +1,24 @@ { "rExecutablePath": "/usr/local/bin/R", - "rstudioPandocPath": "/opt/homebrew/bin/", + "rstudioPandocPath": "/opt/homebrew/bin/pandoc", "quartoExecutablePath": "/usr/local/bin/quarto", - "enableFloatingMenu": true + "enableFloatingMenu": true, + "rPaths": [ + "/usr/local/bin/R", + "/usr/local/bin/R", + "/usr/local/bin/R", + "/usr/local/bin/R" + ], + "pandocPaths": [ + "/opt/homebrew/bin/pandoc", + "/opt/homebrew/bin/pandoc", + "/opt/homebrew/bin/pandoc", + "/opt/homebrew/bin/pandoc" + ], + "quartoPaths": [ + "/usr/local/bin/quarto", + "/usr/local/bin/quarto", + "/usr/local/bin/quarto", + "/usr/local/bin/quarto" + ] } \ No newline at end of file diff --git a/main.ts b/main.ts index a96922c..5ed7f6b 100644 --- a/main.ts +++ b/main.ts @@ -11,6 +11,7 @@ import { PluginSettingTab, Setting, FileSystemAdapter, + DropdownComponent } from 'obsidian'; import { spawn, ChildProcessWithoutNullStreams } from 'child_process'; @@ -20,8 +21,8 @@ import { promisify } from 'util'; import * as os from 'os'; import { createHash } from 'crypto'; import { pathToFileURL } from 'url'; - - +import { execSync } from 'child_process'; +const which = require('which'); // Promisify fs functions @@ -32,24 +33,20 @@ const VIEW_TYPE_R_ENVIRONMENT = 'r-environment-view'; const VIEW_TYPE_R_HELP = 'r-help-view'; - - -// Define the settings interface +// Extend the settings interface interface CombinedPluginSettings { rExecutablePath: string; rstudioPandocPath: string; quartoExecutablePath: string; - enableFloatingMenu: boolean; // **Add this line** - // Add any additional settings from FloatingMenuPlugin if needed + enableFloatingMenu: boolean; } // Define default settings const DEFAULT_SETTINGS: CombinedPluginSettings = { - rExecutablePath: '/usr/local/bin/R', - rstudioPandocPath: '/opt/homebrew/bin/', - quartoExecutablePath: '/usr/local/bin/quarto', - enableFloatingMenu: true, // **Add this line with a default value** - // Initialize additional settings if needed + rExecutablePath: '', + rstudioPandocPath: '', + quartoExecutablePath: '', + enableFloatingMenu: true, }; // FloatingMenuPlugin functionality @@ -510,32 +507,22 @@ class MyPluginSettingTab extends PluginSettingTab { containerEl.empty(); + console.log('Displaying settings'); + containerEl.createEl('h2', { text: 'R Integration Settings' }); // Function to process path for Windows compatibility with type annotation -function formatPathForWindows(path: string): string { - if (navigator.platform.includes('Win')) { - // First, replace all single backslashes with double backslashes - // Then, replace all forward slashes with double backslashes - return path.replace(/\\/g, '\\\\').replace(/\//g, '\\\\'); - } - return path; -} - // Setting for R Executable Path new Setting(containerEl) .setName('Path to R Executable') - .setDesc('Specify the full path to your R executable.') - .addText((text) => + .setDesc('Specify the path to your R executable.') + .addText(text => text - .setPlaceholder('/usr/local/bin/R') - .setValue(formatPathForWindows(this.plugin.settings.rExecutablePath)) + .setPlaceholder('Enter path to R executable') + .setValue(this.plugin.settings.rExecutablePath) .onChange(async (value) => { - const formattedValue = formatPathForWindows(value.trim()); - console.log('R Executable Path changed to: ' + formattedValue); - - this.plugin.settings.rExecutablePath = formattedValue; + this.plugin.settings.rExecutablePath = value.trim(); await this.plugin.saveSettings(); new Notice('R executable path updated successfully.'); }) @@ -544,37 +531,35 @@ new Setting(containerEl) // Setting for RStudio Pandoc Path new Setting(containerEl) .setName('Path to RStudio Pandoc') - .setDesc('Specify the full path to your RStudio Pandoc installation.') - .addText((text) => + .setDesc('Specify the path to your RStudio Pandoc installation.') + .addText(text => text - .setPlaceholder('/opt/homebrew/bin/') - .setValue(formatPathForWindows(this.plugin.settings.rstudioPandocPath)) + .setPlaceholder('Enter path to RStudio Pandoc') + .setValue(this.plugin.settings.rstudioPandocPath) .onChange(async (value) => { - const formattedValue = formatPathForWindows(value.trim()); - console.log('RStudio Pandoc Path changed to: ' + formattedValue); - - this.plugin.settings.rstudioPandocPath = formattedValue; + this.plugin.settings.rstudioPandocPath = value.trim(); await this.plugin.saveSettings(); new Notice('RStudio Pandoc path updated successfully.'); }) ); - // Setting for Quarto Executable Path - new Setting(containerEl) +// Setting for Quarto Executable Path +new Setting(containerEl) .setName('Quarto Executable Path') - .setDesc('Specify the full path to your Quarto executable. Example: /usr/local/bin/quarto') - .addText((text) => + .setDesc('Specify the path to your Quarto executable.') + .addText(text => text - .setPlaceholder('/usr/local/bin/quarto') + .setPlaceholder('Enter path to Quarto executable') .setValue(this.plugin.settings.quartoExecutablePath) .onChange(async (value) => { - console.log('Quarto Executable Path changed to: ' + value); this.plugin.settings.quartoExecutablePath = value.trim(); await this.plugin.saveSettings(); new Notice('Quarto executable path updated successfully.'); }) ); + + // Toggle for menu new Setting(containerEl) .setName('Enable Floating Menu') @@ -595,8 +580,8 @@ new Setting(containerEl) } }) ); -} -} + +}} export default class CombinedPlugin extends Plugin { // Settings @@ -615,11 +600,119 @@ export default class CombinedPlugin extends Plugin { // Define markers and constants (from RCodeEvaluatorPlugin) // ... (Include any necessary constants) + + + +// Retrieve the PATH from the user’s shell to include common directories +getUserShellPath(): string { + try { + const userPath = execSync('echo $PATH', { shell: '/bin/bash' }).toString().trim(); + return userPath; + } catch (error) { + console.error("Could not retrieve PATH from user's shell:", error); + return process.env.PATH || ''; + } +} +setupPathEnvironment() { + process.env.PATH = this.getUserShellPath(); + + if (process.platform === 'darwin') { + process.env.PATH += ':/usr/local/bin:/opt/homebrew/bin'; + } else if (process.platform === 'linux') { + process.env.PATH += ':/usr/local/bin'; + } else if (process.platform === 'win32') { + // Use ProgramFiles and ProgramFiles(x86) environment variables for portability + const programFiles = process.env.ProgramFiles || 'C:\\Program Files'; + const programFilesX86 = process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)'; + + let rPaths: string[] = []; + + // Function to find R paths in a given base directory + function findRPaths(baseDir: string) { + try { + const rDir = path.join(baseDir, 'R'); + if (fs.existsSync(rDir)) { + let versions = fs.readdirSync(rDir); + + // Filter directories that match the pattern 'R-x.x.x' + versions = versions.filter(version => /^R-\d+\.\d+\.\d+$/.test(version)); + + // Sort the versions in descending order + versions.sort((a, b) => { + const versionA = a.match(/R-(\d+\.\d+\.\d+)/)?.[1]; + const versionB = b.match(/R-(\d+\.\d+\.\d+)/)?.[1]; + if (versionA && versionB) { + return compareVersions(versionB, versionA); // Descending order + } else { + return 0; + } + }); + + versions.forEach(version => { + const binPath = path.join(rDir, version, 'bin'); + if (fs.existsSync(binPath)) { + rPaths.push(binPath); + } + }); + } + } catch (error) { + console.error(`Error accessing ${baseDir}:`, error); + } + } + + // Compare version strings 'x.x.x' + function compareVersions(v1: string, v2: string): number { + const v1Parts = v1.split('.').map(Number); + const v2Parts = v2.split('.').map(Number); + for (let i = 0; i < v1Parts.length; i++) { + if (v1Parts[i] > v2Parts[i]) return 1; + if (v1Parts[i] < v2Parts[i]) return -1; + } + return 0; + } + + // Find R paths in both ProgramFiles and ProgramFiles(x86) + findRPaths(programFiles); + findRPaths(programFilesX86); + + // Append found R paths to PATH + rPaths.forEach(rPath => { + process.env.PATH = `${rPath};${process.env.PATH}`; + }); + + console.log('Updated PATH environment variable:', process.env.PATH); + } +} + + + +// Find executable paths using `which` +async getExecutablePaths(executable: string): Promise { + const isWindows = process.platform === 'win32'; + const executableName = isWindows ? `${executable}.exe` : executable; // Add .exe for Windows + + try { + const paths = await which(executable, { all: true }); + return Array.isArray(paths) ? paths : [paths]; + } catch (error) { + console.error(`Error finding ${executable}:`, error); + return []; + } +} + + async onload() { console.log('Loading Combined Floating Menu and R Code Evaluator Plugin'); // Load settings await this.loadSettings(); + + + // Set up PATH environment + this.setupPathEnvironment(); + + + // Initialize Floating Menu this.floatingMenu = new FloatingMenu(this); @@ -1365,9 +1458,13 @@ removeOutputCallout(editor: Editor, uniqueId: string) { // Start R process startRProcess(notePath: string): ChildProcessWithoutNullStreams { - const rExecutable = this.settings.rExecutablePath || '/usr/local/bin/R'; // Use user-specified path or default + const rExecutable = this.settings.rExecutablePath.trim() || '/usr/local/bin/R'; // Use user-specified path or default + if (!rExecutable) { + new Notice('R executable path is not set. Please update the path in settings.'); + throw new Error('R executable path is not set.'); + } console.log(`Starting R process for note: ${notePath} using executable: ${rExecutable}`); - + // User feedback if R path fails: if (!fs.existsSync(rExecutable)) { diff --git a/manifest.json b/manifest.json index 6a41b38..60ae858 100644 --- a/manifest.json +++ b/manifest.json @@ -1 +1 @@ -{"id":"ridian","name":"Ridian","version":"0.0.3","minAppVersion":"0.15.0","description":"Execute R code blocks and display outputs and plots & render documents with Quarto.","author":"Michel Nivard","authorUrl":"","isDesktopOnly":true} \ No newline at end of file +{"id":"ridian","name":"Ridian","version":"0.0.4","minAppVersion":"0.15.0","description":"Execute R code blocks and display outputs and plots & render documents with Quarto within Obsidian.","author":"Michel Nivard","authorUrl":"https://github.com/MichelNivard/Ridian","isDesktopOnly":true} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 11e969c..e91e18b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,21 @@ { "name": "Ridian", - "version": "0.0.3", + "version": "0.0.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "Ridian", - "version": "0.0.3", + "version": "0.0.4", "license": "GNU GPL v3.0", "dependencies": { "@types/prismjs": "^1.26.5", - "prismjs": "^1.29.0" + "glob": "^9.3.5", + "prismjs": "^1.29.0", + "which": "^5.0.0" }, "devDependencies": { + "@types/glob": "^8.1.0", "@types/node": "^16.11.6", "@typescript-eslint/eslint-plugin": "5.29.0", "@typescript-eslint/parser": "5.29.0", @@ -660,6 +663,17 @@ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, + "node_modules/@types/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "^5.1.2", + "@types/node": "*" + } + }, "node_modules/@types/http-cache-semantics": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", @@ -685,6 +699,13 @@ "@types/node": "*" } }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "16.18.115", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.115.tgz", @@ -1013,9 +1034,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "peer": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/boolean": { "version": "3.2.0", @@ -1195,6 +1214,31 @@ "node": ">= 8" } }, + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/debug": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", @@ -1866,8 +1910,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "peer": true + "license": "ISC" }, "node_modules/function-bind": { "version": "1.1.2", @@ -1927,22 +1970,18 @@ } }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "peer": true, + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -1961,6 +2000,30 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/global-agent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", @@ -2253,6 +2316,7 @@ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "peer": true, "dependencies": { "once": "^1.3.0", @@ -2264,6 +2328,7 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, + "license": "ISC", "peer": true }, "node_modules/is-extglob": { @@ -2307,11 +2372,13 @@ } }, "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "peer": true + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "license": "ISC", + "engines": { + "node": ">=16" + } }, "node_modules/js-yaml": { "version": "4.1.0", @@ -2425,6 +2492,12 @@ "node": ">=8" } }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, "node_modules/matcher": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", @@ -2486,6 +2559,15 @@ "node": "*" } }, + "node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "license": "ISC", + "engines": { + "node": ">=8" + } + }, "node_modules/moment": { "version": "2.29.4", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", @@ -2664,6 +2746,7 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "peer": true, "engines": { "node": ">=0.10.0" @@ -2679,6 +2762,31 @@ "node": ">=8" } }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -2873,6 +2981,29 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/roarr": { "version": "2.15.4", "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", @@ -3193,19 +3324,18 @@ "peer": true }, "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "peer": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "license": "ISC", "dependencies": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" }, "bin": { - "node-which": "bin/node-which" + "node-which": "bin/which.js" }, "engines": { - "node": ">= 8" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/word-wrap": { diff --git a/package.json b/package.json index 883613d..7606b38 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Ridian", - "version": "0.0.3", + "version": "0.0.4", "description": "Execute R code blocks and display outputs and plots within Obsidian.", "main": "main.js", "scripts": { @@ -12,6 +12,7 @@ "author": "", "license": "GNU GPL v3.0", "devDependencies": { + "@types/glob": "^8.1.0", "@types/node": "^16.11.6", "@typescript-eslint/eslint-plugin": "5.29.0", "@typescript-eslint/parser": "5.29.0", @@ -24,6 +25,8 @@ }, "dependencies": { "@types/prismjs": "^1.26.5", - "prismjs": "^1.29.0" + "glob": "^9.3.5", + "prismjs": "^1.29.0", + "which": "^5.0.0" } } diff --git a/styles.css b/styles.css index d40e2d8..894c7f3 100644 --- a/styles.css +++ b/styles.css @@ -220,40 +220,72 @@ img[alt*="right"] { 100% { background-position: 0 0; } } - - -/* R Syntax Highlighting */ -.cm-keyword { - color: #007acc; /* Blue */ +/* Light Mode */ +.theme-light .cm-keyword { + color: #0000ff; /* Bright Blue */ font-weight: bold; } -.cm-atom { - color: #e69138; /* Orange */ +.theme-light .cm-atom { + color: #aa5500; /* Brownish-Orange */ } -.cm-string { - color: #a31515; /* Red */ +.theme-light .cm-string { + color: #008000; /* Dark Green */ } -.cm-comment { - color: #008000; /* Green */ +.theme-light .cm-comment { + color: #999999; /* Grey */ font-style: italic; } -.cm-number { - color: #098658; /* Teal */ +.theme-light .cm-number { + color: #ff00ff; /* Magenta */ } -.cm-operator { +.theme-light .cm-operator { color: #000000; /* Black */ } -.cm-punctuation { +.theme-light .cm-punctuation { color: #000000; /* Black */ } -.cm-variable { - color: #001080; /* Navy */ +.theme-light .cm-variable { + color: #0000ff; /* Blue */ +} + +/* Dark Mode */ +.theme-dark .cm-keyword { + color: #7aa2f7; /* Soft Blue */ + font-weight: bold; +} + +.theme-dark .cm-atom { + color: #dca561; /* Muted Orange */ } +.theme-dark .cm-string { + color: #98c379; /* Green */ +} + +.theme-dark .cm-comment { + color: #5c6370; /* Gray */ + font-style: italic; +} + +.theme-dark .cm-number { + color: #d55fde; /* Soft Magenta */ +} + +.theme-dark .cm-operator { + color: #c8ccd4; /* Light Gray */ +} + +.theme-dark .cm-punctuation { + color: #abb2bf; /* Gray */ +} + +.theme-dark .cm-variable { + color: #61afef; /* Lighter Blue */ +} diff --git a/versions.json b/versions.json index cef525c..532dcaa 100644 --- a/versions.json +++ b/versions.json @@ -1,3 +1,3 @@ { - "0.0.3": "0.15.0" + "0.0.4": "0.15.0" }