@teachinglab/omd 0.7.20 → 0.7.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/omdExpression.js +61 -0
package/package.json
CHANGED
package/src/omdExpression.js
CHANGED
|
@@ -8,6 +8,7 @@ import { omdNumber } from "./omdNumber.js";
|
|
|
8
8
|
import { omdVariable } from "./omdVariable.js";
|
|
9
9
|
import { omdMetaExpression } from "./omdMetaExpression.js"
|
|
10
10
|
import { parseExpressionString } from "./omdUtils.js";
|
|
11
|
+
import { getNodeForAST } from "../omd/core/omdUtilities.js";
|
|
11
12
|
|
|
12
13
|
export class omdExpression extends omdMetaExpression
|
|
13
14
|
{
|
|
@@ -21,6 +22,7 @@ export class omdExpression extends omdMetaExpression
|
|
|
21
22
|
this.operatorSet = [];
|
|
22
23
|
|
|
23
24
|
this.inset = 5;
|
|
25
|
+
this.expressionNode = null;
|
|
24
26
|
|
|
25
27
|
this.expressionStack = new jsvgLayoutGroup();
|
|
26
28
|
this.expressionStack.setPosition( this.inset, 0 );
|
|
@@ -28,15 +30,56 @@ export class omdExpression extends omdMetaExpression
|
|
|
28
30
|
this.addChild( this.expressionStack );
|
|
29
31
|
}
|
|
30
32
|
|
|
33
|
+
_renderWithExpressionNode(expressionString, fontSize) {
|
|
34
|
+
if (typeof math === 'undefined' || typeof math.parse !== 'function') {
|
|
35
|
+
throw new Error('math.js is required to parse expression strings');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const ast = math.parse(expressionString);
|
|
39
|
+
const NodeType = getNodeForAST(ast);
|
|
40
|
+
const exprNode = new NodeType(ast);
|
|
41
|
+
|
|
42
|
+
if (typeof fontSize === 'number' && exprNode.setFontSize) {
|
|
43
|
+
exprNode.setFontSize(fontSize);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (exprNode.hideBackgroundByDefault) exprNode.hideBackgroundByDefault();
|
|
47
|
+
if (exprNode.computeDimensions) exprNode.computeDimensions();
|
|
48
|
+
if (exprNode.updateLayout) exprNode.updateLayout();
|
|
49
|
+
|
|
50
|
+
if (typeof this.expressionStack.removeAllChildren === 'function') {
|
|
51
|
+
this.expressionStack.removeAllChildren();
|
|
52
|
+
} else {
|
|
53
|
+
this.expressionStack.childList = [];
|
|
54
|
+
}
|
|
55
|
+
this.expressionStack.addChild(exprNode);
|
|
56
|
+
this.expressionStack.setSpacer(0);
|
|
57
|
+
|
|
58
|
+
this.expressionNode = exprNode;
|
|
59
|
+
this.updateLayout();
|
|
60
|
+
}
|
|
61
|
+
|
|
31
62
|
loadFromJSON( data )
|
|
32
63
|
{
|
|
33
64
|
// Accept either structured object or a plain expression string
|
|
34
65
|
if ( typeof data === 'string' ) {
|
|
66
|
+
try {
|
|
67
|
+
this._renderWithExpressionNode(data, data.fontSize);
|
|
68
|
+
return;
|
|
69
|
+
} catch (e) {
|
|
70
|
+
console.warn('⚠️ omdExpression math.js render failed, falling back to legacy parsing:', e?.message || e);
|
|
71
|
+
}
|
|
35
72
|
const parsed = parseExpressionString(data);
|
|
36
73
|
if ( parsed ) data = parsed;
|
|
37
74
|
}
|
|
38
75
|
// Handle object with 'expression' string property
|
|
39
76
|
else if ( typeof data === 'object' && data.expression && typeof data.expression === 'string' ) {
|
|
77
|
+
try {
|
|
78
|
+
this._renderWithExpressionNode(data.expression, data.fontSize);
|
|
79
|
+
return;
|
|
80
|
+
} catch (e) {
|
|
81
|
+
console.warn('⚠️ omdExpression math.js render failed, falling back to legacy parsing:', e?.message || e);
|
|
82
|
+
}
|
|
40
83
|
const parsed = parseExpressionString(data.expression);
|
|
41
84
|
if ( parsed ) {
|
|
42
85
|
// Merge parsed data into data object
|
|
@@ -117,6 +160,24 @@ export class omdExpression extends omdMetaExpression
|
|
|
117
160
|
|
|
118
161
|
updateLayout()
|
|
119
162
|
{
|
|
163
|
+
if (this.expressionNode) {
|
|
164
|
+
const node = this.expressionNode;
|
|
165
|
+
if (node.computeDimensions) node.computeDimensions();
|
|
166
|
+
if (node.updateLayout) node.updateLayout();
|
|
167
|
+
|
|
168
|
+
this.expressionStack.doHorizontalLayout();
|
|
169
|
+
this.expressionStack.setPosition(this.inset, this.inset);
|
|
170
|
+
|
|
171
|
+
const W = node.width || this.expressionStack.width;
|
|
172
|
+
const H = node.height || this.expressionStack.height;
|
|
173
|
+
|
|
174
|
+
this.backRect.setWidthAndHeight( W + this.inset*2, H + this.inset*2 );
|
|
175
|
+
this.setWidthAndHeight( this.backRect.width, this.backRect.height );
|
|
176
|
+
this.width = this.backRect.width;
|
|
177
|
+
this.height = this.backRect.height;
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
120
181
|
this.expressionStack.doHorizontalLayout();
|
|
121
182
|
|
|
122
183
|
var W = this.expressionStack.width;
|