@teachinglab/omd 0.5.6 → 0.5.8

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.
Files changed (60) hide show
  1. package/canvas/ui/toolbar.js +6 -9
  2. package/index.js +3 -0
  3. package/npm-docs/DOCUMENTATION_SUMMARY.md +220 -0
  4. package/npm-docs/README.md +251 -0
  5. package/npm-docs/api/api-reference.md +85 -0
  6. package/npm-docs/api/configuration-options.md +198 -0
  7. package/npm-docs/api/eventManager.md +83 -0
  8. package/npm-docs/api/expression-nodes.md +561 -0
  9. package/npm-docs/api/focusFrameManager.md +145 -0
  10. package/npm-docs/api/index.md +106 -0
  11. package/npm-docs/api/main.md +63 -0
  12. package/npm-docs/api/omdBinaryExpressionNode.md +86 -0
  13. package/npm-docs/api/omdCanvas.md +84 -0
  14. package/npm-docs/api/omdConfigManager.md +113 -0
  15. package/npm-docs/api/omdConstantNode.md +53 -0
  16. package/npm-docs/api/omdDisplay.md +87 -0
  17. package/npm-docs/api/omdEquationNode.md +174 -0
  18. package/npm-docs/api/omdEquationSequenceNode.md +259 -0
  19. package/npm-docs/api/omdEquationStack.md +193 -0
  20. package/npm-docs/api/omdFunctionNode.md +83 -0
  21. package/npm-docs/api/omdGroupNode.md +79 -0
  22. package/npm-docs/api/omdHelpers.md +88 -0
  23. package/npm-docs/api/omdLeafNode.md +86 -0
  24. package/npm-docs/api/omdNode.md +202 -0
  25. package/npm-docs/api/omdOperationDisplayNode.md +118 -0
  26. package/npm-docs/api/omdOperatorNode.md +92 -0
  27. package/npm-docs/api/omdParenthesisNode.md +134 -0
  28. package/npm-docs/api/omdPopup.md +192 -0
  29. package/npm-docs/api/omdPowerNode.md +132 -0
  30. package/npm-docs/api/omdRationalNode.md +145 -0
  31. package/npm-docs/api/omdSequenceNode.md +128 -0
  32. package/npm-docs/api/omdSimplification.md +79 -0
  33. package/npm-docs/api/omdSqrtNode.md +144 -0
  34. package/npm-docs/api/omdStepVisualizer.md +147 -0
  35. package/npm-docs/api/omdStepVisualizerHighlighting.md +66 -0
  36. package/npm-docs/api/omdStepVisualizerInteractiveSteps.md +109 -0
  37. package/npm-docs/api/omdStepVisualizerLayout.md +71 -0
  38. package/npm-docs/api/omdStepVisualizerNodeUtils.md +140 -0
  39. package/npm-docs/api/omdStepVisualizerTextBoxes.md +77 -0
  40. package/npm-docs/api/omdToolbar.md +131 -0
  41. package/npm-docs/api/omdTranscriptionService.md +96 -0
  42. package/npm-docs/api/omdTreeDiff.md +170 -0
  43. package/npm-docs/api/omdUnaryExpressionNode.md +137 -0
  44. package/npm-docs/api/omdUtilities.md +83 -0
  45. package/npm-docs/api/omdVariableNode.md +123 -0
  46. package/npm-docs/api/selectTool.md +74 -0
  47. package/npm-docs/api/simplificationEngine.md +98 -0
  48. package/npm-docs/api/simplificationRules.md +77 -0
  49. package/npm-docs/api/simplificationUtils.md +64 -0
  50. package/npm-docs/api/transcribe.md +43 -0
  51. package/npm-docs/guides/equations.md +854 -0
  52. package/npm-docs/guides/factory-functions.md +354 -0
  53. package/npm-docs/guides/getting-started.md +318 -0
  54. package/npm-docs/guides/quick-examples.md +525 -0
  55. package/npm-docs/guides/visualizations.md +682 -0
  56. package/npm-docs/json-schemas.md +826 -0
  57. package/omd/utils/omdTranscriptionService.js +1 -1
  58. package/package.json +2 -1
  59. package/src/index.js +2 -0
  60. package/src/omdFactory.js +150 -0
@@ -0,0 +1,106 @@
1
+ # OMD Library Entry Point
2
+
3
+ This module (`omd/core/index.js`) serves as the main entry point for the OMD (Open Math Display) library. It re-exports all core classes, visualization components, and utility functions, making them easily accessible from a single import.
4
+
5
+ ## Overview
6
+
7
+ When you import from `@teachinglab/omd` (or directly from `omd/core/index.js`), you gain access to a comprehensive set of tools for building and manipulating mathematical expressions and their visual representations.
8
+
9
+ ## Named Exports
10
+
11
+ The primary way to use the library is through its named exports.
12
+
13
+ ### Core Node Classes
14
+
15
+ All classes extending `omdNode` are re-exported, allowing you to construct and work with various types of mathematical expressions:
16
+
17
+ - [`omdNode`](./omdNode.md)
18
+ - [`omdBinaryExpressionNode`](./omdBinaryExpressionNode.md)
19
+ - [`omdConstantNode`](./omdConstantNode.md)
20
+ - [`omdEquationNode`](./omdEquationNode.md)
21
+ - [`omdEquationSequenceNode`](./omdEquationSequenceNode.md)
22
+ - [`omdEquationStack`](./omdEquationStack.md)
23
+ - [`omdFunctionNode`](./omdFunctionNode.md)
24
+ - [`omdGroupNode`](./omdGroupNode.md)
25
+ - [`omdLeafNode`](./omdLeafNode.md)
26
+ - [`omdOperationDisplayNode`](./omdOperationDisplayNode.md)
27
+ - [`omdOperatorNode`](./omdOperatorNode.md)
28
+ - [`omdParenthesisNode`](./omdParenthesisNode.md)
29
+ - [`omdPowerNode`](./omdPowerNode.md)
30
+ - [`omdRationalNode`](./omdRationalNode.md)
31
+ - [`omdSqrtNode`](./omdSqrtNode.md)
32
+ - [`omdUnaryExpressionNode`](./omdUnaryExpressionNode.md)
33
+ - [`omdVariableNode`](./omdVariableNode.md)
34
+
35
+ ### Visualization Components
36
+
37
+ These classes provide high-level components for rendering and interacting with mathematical expressions:
38
+
39
+ - [`omdStepVisualizer`](./omdStepVisualizer.md)
40
+ - [`omdDisplay`](./omdDisplay.md)
41
+ - [`omdToolbar`](./omdToolbar.md)
42
+
43
+ ### Utilities
44
+
45
+ Essential utility functions and classes for parsing, simplification, and configuration management:
46
+
47
+ - `getNodeForAST`: A factory function to get the correct `omdNode` class for a given math.js AST.
48
+ - `simplifyStep`: Applies a single simplification step to an expression.
49
+ - `initializeConfig`: Initializes the OMD configuration.
50
+ - `setConfig`: Sets the OMD configuration.
51
+ - `getDefaultConfig`: Retrieves the default OMD configuration.
52
+ - `omdExpression`: A base class for expressions.
53
+ - `omdColor`: A utility class for working with colors.
54
+
55
+ ### `omdHelpers`
56
+
57
+ A collection of convenience functions for common operations:
58
+
59
+ #### `createNodeFromExpression(expression, mathjs)`
60
+ - Creates an `omdNode` instance from a string expression using a provided math.js instance.
61
+
62
+ #### `createEquation(equationString)`
63
+ - Creates an `omdEquationNode` from a string representation of an equation.
64
+
65
+ #### `createStepVisualizer(equationStrings)`
66
+ - Creates an `omdStepVisualizer` instance from an array of equation strings.
67
+
68
+ ## Re-Exports
69
+
70
+ The index also re-exports all named exports from the following modules:
71
+
72
+ - `../step-visualizer/omdStepVisualizer.js`
73
+ - `./omdUtilities.js`
74
+ - `../display/omdToolbar.js`
75
+
76
+ This means you can import their functions directly from the main entry point.
77
+
78
+ ## Default Export
79
+
80
+ The module also provides a default export, which is an object containing all the re-exported classes and functions, organized into logical groups (`nodes`, `helpers`, etc.). This allows for a more structured import if preferred.
81
+
82
+ ```javascript
83
+ import OMD from '@teachinglab/omd';
84
+
85
+ const equation = new OMD.nodes.omdEquationNode(...);
86
+ const display = new OMD.omdDisplay(...);
87
+ const helpers = OMD.helpers;
88
+ ```
89
+
90
+ ## Example Usage
91
+
92
+ ```javascript
93
+ import { omdDisplay, omdEquationNode, omdHelpers } from '@teachinglab/omd';
94
+
95
+ // Create an equation using a helper
96
+ const equation = omdHelpers.createEquation('2x + 5 = 15');
97
+
98
+ // Create a display and render the equation
99
+ const displayContainer = document.getElementById('math-container');
100
+ const display = new omdDisplay(displayContainer);
101
+
102
+ display.render(equation);
103
+
104
+ // You can also directly access node classes
105
+ const constant = new omdConstantNode({ value: 10 });
106
+ ```
@@ -0,0 +1,63 @@
1
+ # main.js - OMD AI Visual Generator
2
+
3
+ This `main.js` file powers the OMD AI Visual Generator, an interactive web page that uses AI to create mathematical visualizations from natural language prompts.
4
+
5
+ ## Core Functionality: The `OMDVisualGenerator` Class
6
+
7
+ The entire application is encapsulated within the `OMDVisualGenerator` class, which manages the UI, handles user input, and orchestrates the process of generating and rendering visuals.
8
+
9
+ ### Initialization
10
+
11
+ When the DOM is loaded, a new `OMDVisualGenerator` instance is created. The constructor calls:
12
+
13
+ - `initializeElements()`: Caches references to all necessary DOM elements (input fields, buttons, result panels).
14
+ - `attachEventListeners()`: Sets up all event listeners for user interactions.
15
+
16
+ ### Event Listeners
17
+
18
+ The application responds to the following user actions:
19
+
20
+ - **Generate Button Click / Enter Key**: Triggers the `generateVisual()` method.
21
+ - **Example Buttons**: Populate the input field with a predefined request and trigger `generateVisual()`.
22
+ - **Copy SVG Button**: Calls `copySvgToClipboard()` to save the generated visual.
23
+ - **Manual JSON Input**: A separate workflow allows users to bypass the AI and render a visual directly from their own OMD JSON.
24
+
25
+ ## Visual Generation Process
26
+
27
+ The core workflow is handled by the `generateVisual()` method:
28
+
29
+ 1. **Get Input**: Retrieves the user's natural language request from the input field.
30
+ 2. **Set Loading State**: Disables the UI to prevent multiple submissions while a request is in progress.
31
+ 3. **API Call**: Sends a `fetch` request to the Netlify serverless function at `/.netlify/functions/ai-omd-lookup`. The user's request is passed as a URL parameter.
32
+ 4. **Receive JSON**: The serverless function (not detailed in this file) communicates with an AI service and returns a JSON object that conforms to the OMD specification for a particular visual (e.g., a `balanceHanger` or `tapeDiagram`).
33
+ 5. **Display JSON**: The raw JSON response is pretty-printed and displayed in the UI for inspection.
34
+ 6. **Render Visual**: The `renderVisual(jsonData)` method is called.
35
+
36
+ ## Rendering the Visual (`renderVisual`)
37
+
38
+ This method is responsible for turning the AI-generated JSON into an SVG image:
39
+
40
+ 1. **Clear Previous Visual**: Removes any existing SVG from the display area.
41
+ 2. **Select OMD Class**: A `switch` statement reads the `omdType` property from the JSON to determine which OMD class to instantiate (e.g., `omdBalanceHanger`, `omdTable`).
42
+ 3. **Load Data**: The `loadFromJSON(jsonData)` method of the instantiated OMD object is called, configuring the object based on the AI-provided data.
43
+ 4. **Create SVG**: An SVG wrapper is created, and the OMD object's internal SVG group (`omdObject.svgObject`) is appended to it.
44
+ 5. **Display SVG**: The final SVG is added to the `visualResult` panel in the DOM.
45
+
46
+ ## Manual JSON Input
47
+
48
+ For testing and debugging, users can click the "Manual JSON Input" button to reveal a text area. They can paste their own OMD-compliant JSON and click "Render" to see it visualized, skipping the AI step entirely.
49
+
50
+ ## Utility Methods
51
+
52
+ - **`copySvgToClipboard()`**: An advanced feature that converts the generated SVG into a high-resolution PNG and uses the Clipboard API (`navigator.clipboard.write`) to copy it to the user's clipboard.
53
+ - **`setLoading(isLoading)`**: Toggles the disabled state of UI elements.
54
+ - **`showMessage(message, type)` / `showError(message)`**: Displays status messages (e.g., "Generating...", "Error") to the user.
55
+
56
+ ## Usage
57
+
58
+ This script is designed to be used with an `index.html` file that provides the necessary UI layout. It allows users to:
59
+
60
+ - Enter a description of a math concept (e.g., "a balance hanger with 2x + 3 on the left and 7 on the right").
61
+ - Click "Generate" to see it visualized by the AI.
62
+ - Inspect the underlying OMD JSON.
63
+ - Copy the resulting visual as a PNG image.
@@ -0,0 +1,86 @@
1
+ # omdBinaryExpressionNode
2
+
3
+ Represents a binary operation in a mathematical expression, such as addition (`a + b`), subtraction, multiplication, or division. This node is a cornerstone of the expression tree, containing a left operand, a right operand, and an operator.
4
+
5
+ ## Class Definition
6
+
7
+ ```javascript
8
+ export class omdBinaryExpressionNode extends omdNode
9
+ ```
10
+
11
+ ## Constructor
12
+
13
+ ### `new omdBinaryExpressionNode(ast)`
14
+
15
+ Creates a new `omdBinaryExpressionNode` instance.
16
+
17
+ - **`ast`** (`object`): The abstract syntax tree (AST) node from a parser like math.js. It must contain:
18
+ - `args`: An array with at least two operand nodes.
19
+ - `op`: The operator symbol (e.g., `+`, `*`).
20
+ - `fn`: The function name for the operation (e.g., `add`, `multiply`).
21
+ - `implicit` (`boolean`, optional): `true` if the multiplication is implicit (e.g., `2x`).
22
+
23
+ During construction, the node automatically handles a critical piece of mathematical convention: **implicit multiplication**. Based on the configuration in `omdConfigManager`, it will:
24
+
25
+ 1. **Reorder Operands**: If it encounters an expression like `x * 2`, it will automatically reorder it to the conventional `2 * x` by swapping the left and right child nodes.
26
+ 2. **Determine Implicit Form**: It checks if the combination of operands (e.g., a constant and a variable) should be represented implicitly. If so, it removes the visible operator (`*`) and marks the node as implicit.
27
+
28
+ ## Public Properties
29
+
30
+ - **`left`** ([`omdNode`](./omdNode.md)): The node representing the left-hand side of the operation.
31
+ - **`right`** ([`omdNode`](./omdNode.md)): The node representing the right-hand side of the operation.
32
+ - **`op`** ([`omdOperatorNode`](./omdOperatorNode.md) | `null`): The node for the operator. This is `null` for implicit multiplication.
33
+ - **`operation`** (`string`): The name of the mathematical function (e.g., `'add'`, `'multiply'`).
34
+ - **`isImplicit`** (`boolean`): `true` if the node represents implicit multiplication.
35
+
36
+ ## Public Methods
37
+
38
+ ### `clone()`
39
+
40
+ Creates a deep, recursive clone of the node, including its children (`left`, `right`, `op`). The new node's `provenance` property will link back to the ID of this original node.
41
+
42
+ - **Returns**: A new `omdBinaryExpressionNode` instance.
43
+
44
+ ### `evaluate(variables)`
45
+
46
+ Recursively evaluates the expression and returns the numerical result.
47
+
48
+ - **`variables`** (`object`, optional): A map of variable names to their numeric values (e.g., `{ x: 5 }`).
49
+ - **Returns**: `number` - The result of the calculation.
50
+ - **Throws**: An `Error` for unsupported operations or division by zero.
51
+
52
+ ### `needsParentheses()`
53
+
54
+ Determines if this expression needs to be wrapped in parentheses to maintain the correct order of operations when it is a child of another binary expression.
55
+
56
+ - **Returns**: `boolean` - `true` if parentheses are required.
57
+
58
+ ### `setHighlight(highlightOn, color)`
59
+
60
+ Applies or removes a highlight from the node and all of its children (left, right, and operator).
61
+
62
+ - **`highlightOn`** (`boolean`): `true` to highlight, `false` to remove.
63
+ - **`color`** (`string`, optional): The color of the highlight.
64
+
65
+ ### `clearProvenanceHighlights()`
66
+
67
+ Recursively clears all provenance-related highlights from this node and its children.
68
+
69
+ ### `toMathJSNode()`
70
+
71
+ Converts the node back into a math.js-compatible AST format.
72
+
73
+ - **Returns**: `object` - A math.js OperatorNode.
74
+
75
+ ### `toString()`
76
+
77
+ Converts the node into a human-readable string, automatically handling parentheses for precedence.
78
+
79
+ - **Returns**: `string` - The string representation of the expression.
80
+
81
+ ## Internal Methods
82
+
83
+ - **`_shouldUseImplicitMultiplication(left, right)`**: Checks the configuration to decide if implicit multiplication is appropriate for the given operand types.
84
+ - **`_shouldReorderMultiplication(left, right)`**: Determines if operands should be swapped to follow convention (e.g., `variable * constant` -> `constant * variable`).
85
+ - **`computeDimensions()`**: Calculates the bounding box of the expression.
86
+ - **`updateLayout()`**: Positions the left operand, operator, and right operand correctly, aligning them along their baseline.
@@ -0,0 +1,84 @@
1
+ # omdCanvas
2
+
3
+ The `omdCanvas` class is the core component for creating and managing an interactive 2D drawing surface. It provides the primary API for all canvas operations, including drawing and managing strokes, handling user input, and orchestrating various features like tools, a toolbar, and focus frames.
4
+
5
+ ## Class Definition
6
+
7
+ ```javascript
8
+ export class omdCanvas
9
+ ```
10
+
11
+ ## Constructor
12
+
13
+ ### `new omdCanvas(container, [options])`
14
+
15
+ Creates a new `omdCanvas` instance within a specified container element.
16
+
17
+ - **`container`** (`HTMLElement` | `string`): The HTML element or a CSS selector string for the container where the canvas will be rendered. Throws an error if the container is not found.
18
+ - **`options`** (`object`, optional): Configuration options for the canvas. These are passed to the `CanvasConfig` class. See the [Configuration Options](./configuration-options.md) for details.
19
+
20
+ ## Properties
21
+
22
+ - **`container`** (`HTMLElement`): The HTML container element for the canvas.
23
+ - **`config`** (`CanvasConfig`): The configuration object for the canvas.
24
+ - **`svg`** (`SVGElement`): The main `<svg>` element that serves as the drawing surface.
25
+ - **`backgroundLayer`** (`SVGGElement`): An SVG group (`<g>`) for background elements like the grid.
26
+ - **`drawingLayer`** (`SVGGElement`): The SVG group where all drawing strokes are rendered.
27
+ - **`uiLayer`** (`SVGGElement`): The SVG group for UI elements that overlay the drawing, such as selection boxes.
28
+ - **`focusFrameLayer`** (`SVGGElement`): The SVG group dedicated to holding `FocusFrame` elements.
29
+ - **`strokes`** (`Map<string, Stroke>`): A map of all stroke objects on the canvas, with their unique IDs as keys.
30
+ - **`selectedStrokes`** (`Set<string>`): A set of the IDs of all currently selected strokes.
31
+ - **`toolManager`** (`ToolManager`): The instance managing the active drawing tools (Pencil, Eraser, etc.).
32
+ - **`eventManager`** (`EventManager`): The instance managing all user input events.
33
+ - **`cursor`** (`Cursor`): The instance that manages the custom cursor's appearance and behavior.
34
+ - **`toolbar`** (`Toolbar`): The UI toolbar for tool selection (if enabled in config).
35
+ - **`focusFrameManager`** (`FocusFrameManager`): The instance managing focus frames (if enabled in config).
36
+
37
+ ## Public Methods
38
+
39
+ ### Stroke Management
40
+
41
+ - **`addStroke(stroke)`**: Adds a `Stroke` object to the canvas and renders it. Emits `strokeAdded`.
42
+ - **`removeStroke(strokeId)`**: Removes a stroke from the canvas by its ID. Emits `strokeRemoved`.
43
+ - **`clear()`**: Removes all strokes from the canvas. Emits `cleared`.
44
+
45
+ ### Selection
46
+
47
+ - **`selectStrokes(strokeIds)`**: Programmatically selects a set of strokes by their IDs. Emits `selectionChanged`.
48
+
49
+ ### Coordinate Conversion
50
+
51
+ - **`clientToSVG(clientX, clientY)`**: Converts screen coordinates (e.g., from a mouse event) to the canvas's local SVG coordinate system.
52
+ - **Returns**: `{ x, y }` object.
53
+
54
+ ### Exporting
55
+
56
+ - **`exportSVG()`**: Exports the canvas drawing as a clean SVG string. UI layers (`uiLayer`, `focusFrameLayer`) are excluded.
57
+ - **`async exportImage([format], [quality])`**: Exports the canvas as a bitmap image.
58
+ - **`format`** (`string`): `'png'`, `'jpeg'`, or `'webp'`. Default: `'png'`.
59
+ - **`quality`** (`number`): For JPEG/WebP, a value from 0 to 1. Default: `1`.
60
+ - **Returns**: `Promise<Blob>` that resolves with the image data.
61
+
62
+ ### Canvas Management
63
+
64
+ - **`resize(width, height)`**: Resizes the canvas. Emits `resized`.
65
+ - **`toggleGrid()`**: Toggles the visibility of the background grid.
66
+ - **`getInfo()`**: Returns an object with status information (dimensions, stroke count, active tool, etc.).
67
+ - **`destroy()`**: Completely removes the canvas and all associated managers, event listeners, and DOM elements. Emits `destroyed`.
68
+
69
+ ### Event Handling (Pub/Sub)
70
+
71
+ - **`on(event, callback)`**: Registers a listener for a custom canvas event.
72
+ - **`off(event, callback)`**: Removes a previously registered event listener.
73
+ - **`emit(event, [data])`**: Dispatches a custom event to all registered listeners.
74
+
75
+ ## Emitted Events
76
+
77
+ The `omdCanvas` is an event emitter. You can listen for these events using the `on()` method.
78
+
79
+ - `strokeAdded`, `strokeRemoved`, `cleared`: Fired for stroke operations.
80
+ - `selectionChanged`: Fired when the set of selected strokes changes.
81
+ - `resized`: Fired when the canvas dimensions change.
82
+ - `pointerDown`, `pointerMove`, `pointerUp`, etc.: Raw input events, normalized by the `EventManager`.
83
+ - `focusFrameCreated`, `focusFrameRemoved`, etc.: Events from the `FocusFrameManager`.
84
+ - `destroyed`: Fired when the `destroy()` method has completed.
@@ -0,0 +1,113 @@
1
+ # omdConfigManager
2
+
3
+ A module for managing the configuration of the OMD library. It handles loading settings from a JSON file, providing default values, and allowing runtime modifications.
4
+
5
+ ## Overview
6
+
7
+ The configuration is managed as a single JSON object. The system can be initialized with a path to a `omdConfig.json` file, or it will fall back to a default configuration. The manager supports both asynchronous and synchronous access to configuration values.
8
+
9
+ ### Default Configuration
10
+
11
+ If no `omdConfig.json` is found, the following default structure is used:
12
+
13
+ ```json
14
+ {
15
+ "multiplication": {
16
+ "symbol": "·",
17
+ "forceImplicit": false,
18
+ "implicitCombinations": {
19
+ "constantVariable": true,
20
+ "variableConstant": false,
21
+ "parenthesisAfterVariable": true,
22
+ "parenthesisAfterConstant": true,
23
+ "variableParenthesis": true,
24
+ "parenthesisParenthesis": true,
25
+ "parenthesisVariable": true,
26
+ "parenthesisConstant": true,
27
+ "variableVariable": true
28
+ }
29
+ },
30
+ "stepVisualizer": {
31
+ "dotSizes": {
32
+ "level0": 8,
33
+ "level1": 6,
34
+ "level2": 4
35
+ },
36
+ "fontWeights": {
37
+ "level0": 400,
38
+ "level1": 400,
39
+ "level2": 400
40
+ }
41
+ }
42
+ }
43
+ ```
44
+
45
+ ## Core Functions
46
+
47
+ ### `async initializeConfig(configSource)`
48
+
49
+ Loads the configuration from a file or object. It automatically detects the environment (browser or Node.js) to use the appropriate file loading mechanism (`fetch` or `fs`). This should be called once when your application starts.
50
+
51
+ - **`configSource`** (`string` | `object`, optional): A path to a JSON configuration file or a configuration object to use directly.
52
+ - **Returns**: `Promise<void>`
53
+
54
+ ### `async getConfig()`
55
+
56
+ Asynchronously gets the entire configuration object. If it hasn't been loaded yet, it will trigger the loading process with default settings.
57
+
58
+ - **Returns**: `Promise<object>` - A promise that resolves to the configuration object.
59
+
60
+ ### `getConfigSync()`
61
+
62
+ Synchronously gets the configuration object.
63
+
64
+ **Warning:** If called before `initializeConfig` has completed, this will return the default configuration, not the loaded one.
65
+
66
+ - **Returns**: `object` - The configuration object.
67
+
68
+ ### `setConfig(config)`
69
+
70
+ Sets the entire configuration directly, merging it with the default values.
71
+
72
+ - **`config`** (`object`): The configuration object to set.
73
+
74
+ ### `getConfigValue(path)`
75
+
76
+ Gets a specific configuration value using a dot-separated path (e.g., `'multiplication.symbol'`).
77
+
78
+ - **Returns**: The value at the specified path.
79
+
80
+ ### `setConfigValue(path, value)`
81
+
82
+ Sets a specific configuration value using a dot-separated path.
83
+
84
+ ## Utility Functions
85
+
86
+ - **`getMultiplicationSymbol()`**: Returns the configured symbol for multiplication.
87
+ - **`useImplicitMultiplication(combination)`**: Checks if implicit multiplication should be used, either globally or for a specific combination of operand types.
88
+ - **`getDotRadius(level)`**: Gets the dot radius for a given step level in the `omdStepVisualizer`.
89
+ - **`getFontWeight(level)`**: Gets the font weight for a given step level.
90
+ - **`getDefaultConfig()`**: Returns a copy of the default configuration object.
91
+ - **`isEnabled(category, setting)`**: Checks if a specific boolean setting is enabled.
92
+ - **`updateConfig(category, setting, value)`**: Updates a top-level configuration setting.
93
+ - **`resetConfig()`**: Throws an error. Direct file editing is required to reset the configuration.
94
+ - **`async reloadConfig()`**: Forces a reload of the configuration from the original file path.
95
+ - **`async getConfigAsync()`**: An alias for `getConfig()`.
96
+
97
+ ## Example
98
+
99
+ ```javascript
100
+ import { initializeConfig, getConfigValue, setConfigValue } from '@teachinglab/omd';
101
+
102
+ // Initialize at the start of your application
103
+ (async () => {
104
+ await initializeConfig();
105
+
106
+ // Get a specific value
107
+ const multSymbol = getConfigValue('multiplication.symbol'); // -> '·'
108
+
109
+ // Change a value at runtime
110
+ setConfigValue('multiplication.symbol', '*');
111
+ const newSymbol = getConfigValue('multiplication.symbol'); // -> '*'
112
+ })();
113
+ ```
@@ -0,0 +1,53 @@
1
+ # omdConstantNode
2
+
3
+ Represents a numeric constant in a mathematical expression. This node is a leaf node in the expression tree, meaning it does not have any children.
4
+
5
+ ## Class Definition
6
+
7
+ ```javascript
8
+ export class omdConstantNode extends omdLeafNode
9
+ ```
10
+
11
+ ## Constructor
12
+
13
+ ### `new omdConstantNode(ast)`
14
+
15
+ Creates a new `omdConstantNode` instance.
16
+
17
+ - **`ast`** (`object`): The abstract syntax tree (AST) node from a parser like math.js. It must contain:
18
+ - `value`: The numeric value of the constant.
19
+
20
+ ## Public Properties
21
+
22
+ - **`value`** (`number`): The numeric value of the constant.
23
+
24
+ ## Public Methods
25
+
26
+ ### `isConstant()`
27
+
28
+ Checks if the node represents a constant value.
29
+
30
+ - **Returns**: `boolean` - Always `true` for `omdConstantNode`.
31
+
32
+ ### `evaluate()`
33
+
34
+ Evaluates the constant node. Since it's a constant, it simply returns its value.
35
+
36
+ - **Returns**: `number` - The numeric value of the constant.
37
+
38
+ ### `toMathJSNode()`
39
+
40
+ Converts the node back into a math.js-compatible AST format.
41
+
42
+ - **Returns**: `object` - A math.js ConstantNode.
43
+
44
+ ### `toString()`
45
+
46
+ Converts the constant node into its string representation.
47
+
48
+ - **Returns**: `string` - The string representation of the constant.
49
+
50
+ ## Internal Methods
51
+
52
+ - **`computeDimensions()`**: Calculates the bounding box of the constant.
53
+ - **`updateLayout()`**: Positions the constant within its bounding box.
@@ -0,0 +1,87 @@
1
+ # omdDisplay
2
+
3
+ A high-level component for displaying mathematical expressions or a series of equation steps. It handles rendering, automatic centering, scaling, and layout management within a given HTML container.
4
+
5
+ ## Class Definition
6
+
7
+ ```javascript
8
+ export class omdDisplay
9
+ ```
10
+
11
+ ## Constructor
12
+
13
+ ### `new omdDisplay(container, [options])`
14
+
15
+ Creates a new `omdDisplay` instance.
16
+
17
+ - **`container`** (`HTMLElement`): The DOM element where the expression will be rendered.
18
+ - **`options`** (`object`, optional): Configuration options:
19
+ - `fontSize` (`number`): The base font size in pixels for the expression. Default: `32`.
20
+ - `centerContent` (`boolean`): If `true`, the content is automatically centered within the container. Default: `true`.
21
+ - `topMargin` (`number`): The top margin in pixels, used when centering content. Default: `40`.
22
+ - `bottomMargin` (`number`): The bottom margin in pixels. Default: `16`.
23
+ - `fitToContent` (`boolean`): If `true`, the SVG container will resize to tightly fit the content. Default: `false`.
24
+ - `autoScale` (`boolean`): If `true`, content will automatically scale down to fit the container. Default: `true`.
25
+ - `maxScale` (`number`): Maximum scale factor for `autoScale`. Default: `1` (no upscaling).
26
+ - `edgePadding` (`number`): Horizontal padding from edges when `autoScale` is enabled. Default: `16`.
27
+
28
+ ## Public Methods
29
+
30
+ ### `render(expression)`
31
+
32
+ Renders a mathematical expression or equation within the display. It intelligently handles different input types:
33
+
34
+ - If `expression` is a string containing semicolons (`;`), it's treated as a sequence of equations and rendered as an `omdStepVisualizer`.
35
+ - If `expression` is a string containing an equals sign (`=`), it's treated as a single equation and wrapped in an `omdStepVisualizer`.
36
+ - Otherwise, if `expression` is a string, it's parsed as a single mathematical expression.
37
+ - If `expression` is already an `omdNode` instance, it's rendered directly.
38
+
39
+ - **`expression`** (`string` | `omdNode`): The mathematical expression string or a pre-existing `omdNode` instance.
40
+ - **Returns**: `omdNode` - The root node of the rendered content (often an `omdStepVisualizer`).
41
+
42
+ ### `update(newNode)`
43
+
44
+ Replaces the currently displayed node with a new one, applying the current font size and centering if enabled. The new node is initialized before being added to the display.
45
+
46
+ - **`newNode`** (`omdNode`): The new node to display.
47
+
48
+ ### `getCurrentNode()`
49
+
50
+ Returns the node currently being displayed.
51
+
52
+ - **Returns**: `omdNode` | `null` - The current root node, or `null` if nothing is displayed.
53
+
54
+ ### `centerNode()`
55
+
56
+ Manually triggers the centering and scaling logic for the current node. This is particularly useful for `omdEquationSequenceNode` instances to align them by their equals signs, and for ensuring content fits within the container based on `autoScale` and `maxScale` options.
57
+
58
+ ### `fitToContent()`
59
+
60
+ Adjusts the SVG container's dimensions to tightly fit the rendered content, adding a small padding. This is useful for generating images or when the display needs to precisely match the content size.
61
+
62
+ ### `setFontSize(size)`
63
+
64
+ Updates the base font size for the currently displayed node and for any future content rendered. This will trigger a re-layout and re-centering.
65
+
66
+ - **`size`** (`number`): The new font size in pixels.
67
+
68
+ ### `setFont(fontFamily, fontWeight)`
69
+
70
+ Applies a specific font family and weight to all text elements within the rendered SVG. This setting is also stored for future content.
71
+
72
+ - **`fontFamily`** (`string`): CSS `font-family` string (e.g., `'"Shantell Sans", cursive'`).
73
+ - **`fontWeight`** (`string`, optional): CSS `font-weight` (e.g., `'400'`, `'bold'`). Default: `'400'`.
74
+
75
+ ### `clear()`
76
+
77
+ Removes the current expression from the display.
78
+
79
+ ### `destroy()`
80
+
81
+ Cleans up the component, removing all DOM elements and detaching the resize observer.
82
+
83
+ ## Internal Methods
84
+
85
+ - **`_setupSVG()`**: Initializes the main SVG element, sets its viewBox, and attaches a `ResizeObserver` to the container.
86
+ - **`_handleResize()`**: Callback for the `ResizeObserver` that updates the SVG viewBox and re-centers the content on container resize.
87
+ - **`_repositionOverlayToolbar()`**: Positions any overlay toolbars associated with the current node (e.g., for interactive step visualizers).