@teachinglab/omd 0.2.10 → 0.3.1
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/docs/api/configuration-options.md +198 -198
- package/docs/api/eventManager.md +82 -82
- package/docs/api/focusFrameManager.md +144 -144
- package/docs/api/index.md +105 -105
- package/docs/api/main.md +62 -62
- package/docs/api/omdBinaryExpressionNode.md +86 -86
- package/docs/api/omdCanvas.md +83 -83
- package/docs/api/omdConfigManager.md +112 -112
- package/docs/api/omdConstantNode.md +52 -52
- package/docs/api/omdDisplay.md +87 -87
- package/docs/api/omdEquationNode.md +174 -174
- package/docs/api/omdEquationSequenceNode.md +258 -258
- package/docs/api/omdEquationStack.md +156 -156
- package/docs/api/omdFunctionNode.md +82 -82
- package/docs/api/omdGroupNode.md +78 -78
- package/docs/api/omdHelpers.md +87 -87
- package/docs/api/omdLeafNode.md +85 -85
- package/docs/api/omdNode.md +201 -201
- package/docs/api/omdOperationDisplayNode.md +117 -117
- package/docs/api/omdOperatorNode.md +91 -91
- package/docs/api/omdParenthesisNode.md +133 -133
- package/docs/api/omdPopup.md +191 -191
- package/docs/api/omdPowerNode.md +131 -131
- package/docs/api/omdRationalNode.md +144 -144
- package/docs/api/omdSimplification.md +78 -78
- package/docs/api/omdSqrtNode.md +144 -144
- package/docs/api/omdStepVisualizer.md +146 -146
- package/docs/api/omdStepVisualizerHighlighting.md +65 -65
- package/docs/api/omdStepVisualizerInteractiveSteps.md +108 -108
- package/docs/api/omdStepVisualizerLayout.md +70 -70
- package/docs/api/omdStepVisualizerTextBoxes.md +76 -76
- package/docs/api/omdTranscriptionService.md +95 -95
- package/docs/api/omdTreeDiff.md +169 -169
- package/docs/api/omdUnaryExpressionNode.md +137 -137
- package/docs/api/omdUtilities.md +82 -82
- package/docs/api/omdVariableNode.md +123 -123
- package/omd/nodes/omdConstantNode.js +141 -141
- package/omd/nodes/omdGroupNode.js +67 -67
- package/omd/nodes/omdLeafNode.js +76 -76
- package/omd/nodes/omdOperatorNode.js +108 -108
- package/omd/nodes/omdParenthesisNode.js +292 -292
- package/omd/nodes/omdPowerNode.js +235 -235
- package/omd/nodes/omdRationalNode.js +295 -295
- package/omd/nodes/omdVariableNode.js +122 -122
- package/omd/simplification/omdSimplification.js +140 -140
- package/omd/step-visualizer/omdStepVisualizer.js +947 -947
- package/omd/step-visualizer/omdStepVisualizerLayout.js +892 -892
- package/omd/utils/omdStepVisualizerInteractiveSteps.js +5 -3
- package/package.json +1 -1
- package/src/index.js +11 -0
- package/src/omdBalanceHanger.js +2 -1
- package/src/omdEquation.js +1 -1
- package/src/omdNumber.js +1 -1
- package/src/omdNumberLine.js +13 -7
- package/src/omdRatioChart.js +11 -0
- package/src/omdShapes.js +1 -1
- package/src/omdTapeDiagram.js +1 -1
- package/src/omdTerm.js +1 -1
package/omd/nodes/omdLeafNode.js
CHANGED
|
@@ -1,77 +1,77 @@
|
|
|
1
|
-
import { omdNode } from "./omdNode.js";
|
|
2
|
-
import { getTextBounds } from "../core/omdUtilities.js";
|
|
3
|
-
import { jsvgTextLine } from '@teachinglab/jsvg';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Represents a leaf in the AST tree, such as an operator, constant, variable, or grouping symbol.
|
|
7
|
-
* @extends omdNode
|
|
8
|
-
*/
|
|
9
|
-
export class omdLeafNode extends omdNode {
|
|
10
|
-
/**
|
|
11
|
-
* Creates a leaf node from the AST data.
|
|
12
|
-
* @param {Object} astNodeData - The AST node containing leaf information.
|
|
13
|
-
*/
|
|
14
|
-
constructor(nodeData) {
|
|
15
|
-
super(nodeData);
|
|
16
|
-
this.type = "omdLeafNode";
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Creates and positions the text element for the constant
|
|
21
|
-
* @param {string|number} text - The text content to display.
|
|
22
|
-
*/
|
|
23
|
-
createTextElement(text) {
|
|
24
|
-
let textElement = new jsvgTextLine();
|
|
25
|
-
textElement.setText(text);
|
|
26
|
-
|
|
27
|
-
textElement.setTextAnchor('middle');
|
|
28
|
-
textElement.svgObject.setAttribute('dominant-baseline', 'middle');
|
|
29
|
-
|
|
30
|
-
this.addChild(textElement);
|
|
31
|
-
|
|
32
|
-
return textElement;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
clone() {
|
|
36
|
-
const clone = new this.constructor(this.astNodeData);
|
|
37
|
-
|
|
38
|
-
// The crucial step: link the clone to its origin
|
|
39
|
-
clone.provenance.push(this.id);
|
|
40
|
-
|
|
41
|
-
return clone;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
updateTextElement(text) {
|
|
45
|
-
this.textElement.setText(text);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Calculates the dimensions of the node
|
|
50
|
-
* @override
|
|
51
|
-
*/
|
|
52
|
-
computeDimensions() {
|
|
53
|
-
// Gerard: Checks for parent fontSize property and updates size accordingly
|
|
54
|
-
let fontSize = this.getFontSize();
|
|
55
|
-
this.textElement.setFontSize(fontSize);
|
|
56
|
-
|
|
57
|
-
// Gerard: Gets text bounds based on fontSize using temporary span element
|
|
58
|
-
let bounds = getTextBounds(this.textElement.getText(), fontSize);
|
|
59
|
-
this.setWidthAndHeight(bounds.width, bounds.height);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Updates the position of the node
|
|
64
|
-
* @override
|
|
65
|
-
*/
|
|
66
|
-
updateLayout() {
|
|
67
|
-
this.updateTextPosition();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Updates the position of the text
|
|
72
|
-
* @private
|
|
73
|
-
*/
|
|
74
|
-
updateTextPosition() {
|
|
75
|
-
this.textElement.setPosition(this.width / 2, this.height / 2);
|
|
76
|
-
}
|
|
1
|
+
import { omdNode } from "./omdNode.js";
|
|
2
|
+
import { getTextBounds } from "../core/omdUtilities.js";
|
|
3
|
+
import { jsvgTextLine } from '@teachinglab/jsvg';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Represents a leaf in the AST tree, such as an operator, constant, variable, or grouping symbol.
|
|
7
|
+
* @extends omdNode
|
|
8
|
+
*/
|
|
9
|
+
export class omdLeafNode extends omdNode {
|
|
10
|
+
/**
|
|
11
|
+
* Creates a leaf node from the AST data.
|
|
12
|
+
* @param {Object} astNodeData - The AST node containing leaf information.
|
|
13
|
+
*/
|
|
14
|
+
constructor(nodeData) {
|
|
15
|
+
super(nodeData);
|
|
16
|
+
this.type = "omdLeafNode";
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates and positions the text element for the constant
|
|
21
|
+
* @param {string|number} text - The text content to display.
|
|
22
|
+
*/
|
|
23
|
+
createTextElement(text) {
|
|
24
|
+
let textElement = new jsvgTextLine();
|
|
25
|
+
textElement.setText(text);
|
|
26
|
+
|
|
27
|
+
textElement.setTextAnchor('middle');
|
|
28
|
+
textElement.svgObject.setAttribute('dominant-baseline', 'middle');
|
|
29
|
+
|
|
30
|
+
this.addChild(textElement);
|
|
31
|
+
|
|
32
|
+
return textElement;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
clone() {
|
|
36
|
+
const clone = new this.constructor(this.astNodeData);
|
|
37
|
+
|
|
38
|
+
// The crucial step: link the clone to its origin
|
|
39
|
+
clone.provenance.push(this.id);
|
|
40
|
+
|
|
41
|
+
return clone;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
updateTextElement(text) {
|
|
45
|
+
this.textElement.setText(text);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Calculates the dimensions of the node
|
|
50
|
+
* @override
|
|
51
|
+
*/
|
|
52
|
+
computeDimensions() {
|
|
53
|
+
// Gerard: Checks for parent fontSize property and updates size accordingly
|
|
54
|
+
let fontSize = this.getFontSize();
|
|
55
|
+
this.textElement.setFontSize(fontSize);
|
|
56
|
+
|
|
57
|
+
// Gerard: Gets text bounds based on fontSize using temporary span element
|
|
58
|
+
let bounds = getTextBounds(this.textElement.getText(), fontSize);
|
|
59
|
+
this.setWidthAndHeight(bounds.width, bounds.height);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Updates the position of the node
|
|
64
|
+
* @override
|
|
65
|
+
*/
|
|
66
|
+
updateLayout() {
|
|
67
|
+
this.updateTextPosition();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Updates the position of the text
|
|
72
|
+
* @private
|
|
73
|
+
*/
|
|
74
|
+
updateTextPosition() {
|
|
75
|
+
this.textElement.setPosition(this.width / 2, this.height / 2);
|
|
76
|
+
}
|
|
77
77
|
}
|
|
@@ -1,109 +1,109 @@
|
|
|
1
|
-
import { omdLeafNode } from "./omdLeafNode.js";
|
|
2
|
-
import { omdColor } from "../../src/omdColor.js";
|
|
3
|
-
import { getMultiplicationSymbol } from "../config/omdConfigManager.js";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Leaf node that represents an operator symbol.
|
|
7
|
-
* @extends omdLeafNode
|
|
8
|
-
*/
|
|
9
|
-
export class omdOperatorNode extends omdLeafNode {
|
|
10
|
-
/**
|
|
11
|
-
* Creates a leaf node from the AST data.
|
|
12
|
-
* @param {Object} astNodeData - The AST node containing leaf information.
|
|
13
|
-
*/
|
|
14
|
-
constructor(nodeData) {
|
|
15
|
-
super(nodeData);
|
|
16
|
-
this.type = "omdOperatorNode";
|
|
17
|
-
|
|
18
|
-
this.opName = this.parseOpName(nodeData);
|
|
19
|
-
|
|
20
|
-
// Use configured multiplication symbol for display while keeping internal opName as '*'
|
|
21
|
-
const displaySymbol = this.opName === '*' ? getMultiplicationSymbol() : this.opName;
|
|
22
|
-
this.textElement = super.createTextElement(displaySymbol);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
parseOpName(nodeData) {
|
|
26
|
-
if (typeof nodeData === "string")
|
|
27
|
-
return nodeData;
|
|
28
|
-
|
|
29
|
-
// Use a map for user-friendly display of operators
|
|
30
|
-
const operatorMap = {
|
|
31
|
-
'multiply': getMultiplicationSymbol(),
|
|
32
|
-
'divide': '÷',
|
|
33
|
-
'add': '+',
|
|
34
|
-
'subtract': '−',
|
|
35
|
-
'pow': '^',
|
|
36
|
-
'unaryMinus': '-',
|
|
37
|
-
'unaryPlus': '+'
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const op = nodeData.op || nodeData.fn;
|
|
41
|
-
return operatorMap[op] || op;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
parseType() {
|
|
45
|
-
return "operator";
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Calculates the dimensions of the node.
|
|
50
|
-
* Adds padding around the node.
|
|
51
|
-
* @override
|
|
52
|
-
*/
|
|
53
|
-
computeDimensions() {
|
|
54
|
-
super.computeDimensions();
|
|
55
|
-
|
|
56
|
-
const ratio = this.getFontSize() / this.getRootFontSize();
|
|
57
|
-
const padding = 4 * ratio;
|
|
58
|
-
let paddedWidth = this.width + padding;
|
|
59
|
-
let paddedHeight = this.height + padding;
|
|
60
|
-
this.setWidthAndHeight(paddedWidth, paddedHeight);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Updates the layout of the node.
|
|
65
|
-
* @override
|
|
66
|
-
*/
|
|
67
|
-
updateLayout() {
|
|
68
|
-
super.updateLayout();
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Converts the omdOperatorNode to a math.js AST node.
|
|
73
|
-
* @returns {Object} A math.js-compatible AST node.
|
|
74
|
-
*/
|
|
75
|
-
toMathJSNode() {
|
|
76
|
-
// This node is purely visual; its properties are used by its parent.
|
|
77
|
-
// It reconstructs a minimal AST for cloning purposes.
|
|
78
|
-
const astNode = {
|
|
79
|
-
type: 'OperatorNode',
|
|
80
|
-
op: this.opName,
|
|
81
|
-
fn: this.opName, // Simplification, may need adjustment for complex ops
|
|
82
|
-
args: []
|
|
83
|
-
};
|
|
84
|
-
astNode.clone = function() {
|
|
85
|
-
const clone = { ...this };
|
|
86
|
-
clone.argumentNodeList.argument = clone.argument;
|
|
87
|
-
return clone;
|
|
88
|
-
};
|
|
89
|
-
return astNode;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
toString() {
|
|
93
|
-
return this.opName;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
highlight(color) {
|
|
97
|
-
super.highlight(color);
|
|
98
|
-
if (this.opLabel) {
|
|
99
|
-
this.opLabel.setFillColor(omdColor.white);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
clearProvenanceHighlights() {
|
|
104
|
-
super.clearProvenanceHighlights();
|
|
105
|
-
if (this.opLabel) {
|
|
106
|
-
this.opLabel.setFillColor(omdColor.text);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
1
|
+
import { omdLeafNode } from "./omdLeafNode.js";
|
|
2
|
+
import { omdColor } from "../../src/omdColor.js";
|
|
3
|
+
import { getMultiplicationSymbol } from "../config/omdConfigManager.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Leaf node that represents an operator symbol.
|
|
7
|
+
* @extends omdLeafNode
|
|
8
|
+
*/
|
|
9
|
+
export class omdOperatorNode extends omdLeafNode {
|
|
10
|
+
/**
|
|
11
|
+
* Creates a leaf node from the AST data.
|
|
12
|
+
* @param {Object} astNodeData - The AST node containing leaf information.
|
|
13
|
+
*/
|
|
14
|
+
constructor(nodeData) {
|
|
15
|
+
super(nodeData);
|
|
16
|
+
this.type = "omdOperatorNode";
|
|
17
|
+
|
|
18
|
+
this.opName = this.parseOpName(nodeData);
|
|
19
|
+
|
|
20
|
+
// Use configured multiplication symbol for display while keeping internal opName as '*'
|
|
21
|
+
const displaySymbol = this.opName === '*' ? getMultiplicationSymbol() : this.opName;
|
|
22
|
+
this.textElement = super.createTextElement(displaySymbol);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
parseOpName(nodeData) {
|
|
26
|
+
if (typeof nodeData === "string")
|
|
27
|
+
return nodeData;
|
|
28
|
+
|
|
29
|
+
// Use a map for user-friendly display of operators
|
|
30
|
+
const operatorMap = {
|
|
31
|
+
'multiply': getMultiplicationSymbol(),
|
|
32
|
+
'divide': '÷',
|
|
33
|
+
'add': '+',
|
|
34
|
+
'subtract': '−',
|
|
35
|
+
'pow': '^',
|
|
36
|
+
'unaryMinus': '-',
|
|
37
|
+
'unaryPlus': '+'
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const op = nodeData.op || nodeData.fn;
|
|
41
|
+
return operatorMap[op] || op;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
parseType() {
|
|
45
|
+
return "operator";
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Calculates the dimensions of the node.
|
|
50
|
+
* Adds padding around the node.
|
|
51
|
+
* @override
|
|
52
|
+
*/
|
|
53
|
+
computeDimensions() {
|
|
54
|
+
super.computeDimensions();
|
|
55
|
+
|
|
56
|
+
const ratio = this.getFontSize() / this.getRootFontSize();
|
|
57
|
+
const padding = 4 * ratio;
|
|
58
|
+
let paddedWidth = this.width + padding;
|
|
59
|
+
let paddedHeight = this.height + padding;
|
|
60
|
+
this.setWidthAndHeight(paddedWidth, paddedHeight);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Updates the layout of the node.
|
|
65
|
+
* @override
|
|
66
|
+
*/
|
|
67
|
+
updateLayout() {
|
|
68
|
+
super.updateLayout();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Converts the omdOperatorNode to a math.js AST node.
|
|
73
|
+
* @returns {Object} A math.js-compatible AST node.
|
|
74
|
+
*/
|
|
75
|
+
toMathJSNode() {
|
|
76
|
+
// This node is purely visual; its properties are used by its parent.
|
|
77
|
+
// It reconstructs a minimal AST for cloning purposes.
|
|
78
|
+
const astNode = {
|
|
79
|
+
type: 'OperatorNode',
|
|
80
|
+
op: this.opName,
|
|
81
|
+
fn: this.opName, // Simplification, may need adjustment for complex ops
|
|
82
|
+
args: []
|
|
83
|
+
};
|
|
84
|
+
astNode.clone = function() {
|
|
85
|
+
const clone = { ...this };
|
|
86
|
+
clone.argumentNodeList.argument = clone.argument;
|
|
87
|
+
return clone;
|
|
88
|
+
};
|
|
89
|
+
return astNode;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
toString() {
|
|
93
|
+
return this.opName;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
highlight(color) {
|
|
97
|
+
super.highlight(color);
|
|
98
|
+
if (this.opLabel) {
|
|
99
|
+
this.opLabel.setFillColor(omdColor.white);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
clearProvenanceHighlights() {
|
|
104
|
+
super.clearProvenanceHighlights();
|
|
105
|
+
if (this.opLabel) {
|
|
106
|
+
this.opLabel.setFillColor(omdColor.text);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
109
|
}
|