From 4d09aabed4d8e0df12aa3088cab772447dc3deeb Mon Sep 17 00:00:00 2001 From: Jan Wille Date: Fri, 28 Feb 2025 15:28:25 +0100 Subject: [PATCH] make `mathjs` a singleton and allow for import via api This allows for modification of `mathjs` by the user, mostly to allow for the use of `math.import` to define custom functions --- packages/core/src/api/API.ts | 9 +++++++++ packages/core/src/api/InternalAPI.ts | 4 ++++ packages/core/src/fields/viewFields/fields/MathVF.ts | 3 +-- packages/core/src/utils/MathJS.ts | 9 +++++++++ 4 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 packages/core/src/utils/MathJS.ts diff --git a/packages/core/src/api/API.ts b/packages/core/src/api/API.ts index 83e944a5..be04df11 100644 --- a/packages/core/src/api/API.ts +++ b/packages/core/src/api/API.ts @@ -1,3 +1,4 @@ +import type { ImportObject as MathJSImportObject, ImportOptions as MathJSImportOptions } from 'mathjs'; import { SyntaxHighlightingAPI } from 'packages/core/src/api/SyntaxHighlightingAPI'; import type { ButtonGroupOptions, @@ -827,4 +828,12 @@ export abstract class API { lineEnd: lineEnd, }); } + + /** + * Import new definitions into the internal mathJS instance. + * For details on how to use, see https://mathjs.org/docs/reference/functions/import.html + */ + public mathJSimport(object: MathJSImportObject | MathJSImportObject[], options?: MathJSImportOptions): void { + this.plugin.internal.math.import(object, options); + } } diff --git a/packages/core/src/api/InternalAPI.ts b/packages/core/src/api/InternalAPI.ts index 18ea245e..a3ff7388 100644 --- a/packages/core/src/api/InternalAPI.ts +++ b/packages/core/src/api/InternalAPI.ts @@ -1,3 +1,4 @@ +import type { MathJsInstance } from 'mathjs'; import type { Moment } from 'moment'; import type { LifecycleHook } from 'packages/core/src/api/API'; import type { FileAPI } from 'packages/core/src/api/FileAPI'; @@ -28,6 +29,7 @@ import type { ContextMenuItemDefinition, IContextMenu } from 'packages/core/src/ import type { IFuzzySearch } from 'packages/core/src/utils/IFuzzySearch'; import type { IJsRenderer } from 'packages/core/src/utils/IJsRenderer'; import type { MBLiteral } from 'packages/core/src/utils/Literal'; +import { createMathJS } from 'packages/core/src/utils/MathJS'; import { mount, unmount } from 'svelte'; import type { z } from 'zod'; @@ -75,10 +77,12 @@ export const IMAGE_FILE_EXTENSIONS_WITH_DOTS = IMAGE_FILE_EXTENSIONS.map(ext => export abstract class InternalAPI { readonly plugin: Plugin; readonly file: FileAPI; + readonly math: MathJsInstance; constructor(plugin: Plugin, fileAPI: FileAPI) { this.plugin = plugin; this.file = fileAPI; + this.math = createMathJS(); } // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/core/src/fields/viewFields/fields/MathVF.ts b/packages/core/src/fields/viewFields/fields/MathVF.ts index 23fd9163..034734b2 100644 --- a/packages/core/src/fields/viewFields/fields/MathVF.ts +++ b/packages/core/src/fields/viewFields/fields/MathVF.ts @@ -1,5 +1,4 @@ import type { EvalFunction } from 'mathjs'; -import { compile as MathJsCompile } from 'mathjs'; import { AbstractViewField } from 'packages/core/src/fields/viewFields/AbstractViewField'; import type { ViewFieldMountable } from 'packages/core/src/fields/viewFields/ViewFieldMountable'; import type { ViewFieldVariable } from 'packages/core/src/fields/viewFields/ViewFieldVariable'; @@ -50,7 +49,7 @@ export class MathVF extends AbstractViewField { } } - this.expression = MathJsCompile(this.expressionStr); + this.expression = this.plugin.internal.math.compile(this.expressionStr); } private buildMathJSContext(): Record { diff --git a/packages/core/src/utils/MathJS.ts b/packages/core/src/utils/MathJS.ts new file mode 100644 index 00000000..8d497c1b --- /dev/null +++ b/packages/core/src/utils/MathJS.ts @@ -0,0 +1,9 @@ +import type { MathJsInstance, ConfigOptions } from 'mathjs'; +import { create as MathJSCreate, all } from 'mathjs'; + +export function createMathJS(): MathJsInstance { + // TODO: we should probably limit the functionality of MathJS + // we don't need full support for matrices, big numbers and all the other high level stuff + const options: ConfigOptions = {}; + return MathJSCreate(all, options); +}