kmap-term-tree 0.9.20 → 0.9.22

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 (37) hide show
  1. package/demo/index.html +124 -10
  2. package/dist/src/KmapTermTree.d.ts +30 -47
  3. package/dist/src/KmapTermTree.js +536 -221
  4. package/dist/src/KmapTermTree.js.map +1 -1
  5. package/dist/src/asciimath-parser.d.ts +17 -0
  6. package/dist/src/asciimath-parser.js +472 -0
  7. package/dist/src/asciimath-parser.js.map +1 -0
  8. package/dist/src/index.d.ts +2 -0
  9. package/dist/src/index.js +2 -0
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/katex-css.d.ts +2 -0
  12. package/dist/src/katex-css.js +7 -0
  13. package/dist/src/katex-css.js.map +1 -0
  14. package/dist/src/model.d.ts +30 -0
  15. package/dist/src/model.js +26 -0
  16. package/dist/src/model.js.map +1 -0
  17. package/dist/src/parser.js.map +1 -1
  18. package/dist/src/tokenizer.d.ts +2 -2
  19. package/dist/src/tokenizer.js.map +1 -1
  20. package/dist/stories/index.stories.d.ts +20 -0
  21. package/dist/stories/index.stories.js +26 -2
  22. package/dist/stories/index.stories.js.map +1 -1
  23. package/dist/test/asciimath-parser.test.d.ts +1 -0
  24. package/dist/test/asciimath-parser.test.js +45 -0
  25. package/dist/test/asciimath-parser.test.js.map +1 -0
  26. package/dist/test/kmap-term-tree.test.js +30 -7
  27. package/dist/test/kmap-term-tree.test.js.map +1 -1
  28. package/dist/tsconfig.tsbuildinfo +1 -1
  29. package/package.json +19 -53
  30. package/src/KmapTermTree.ts +557 -235
  31. package/src/asciimath-parser.ts +554 -0
  32. package/src/index.ts +2 -0
  33. package/src/katex-css.ts +7 -0
  34. package/src/model.ts +57 -0
  35. package/stories/index.stories.ts +35 -2
  36. package/test/asciimath-parser.test.ts +50 -0
  37. package/test/kmap-term-tree.test.ts +44 -7
@@ -1 +1 @@
1
- {"version":3,"file":"KmapTermTree.js","sourceRoot":"","sources":["../../src/KmapTermTree.ts"],"names":[],"mappings":"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","sourcesContent":["import {css, html, LitElement, PropertyValues, svg} from 'lit';\nimport {property, state, query} from 'lit/decorators.js';\nimport {ifDefined} from 'lit/directives/if-defined.js';\nimport {Parser, TermNode} from \"./parser.js\";\nimport {Token} from \"./tokenizer.js\";\n\ninterface Connection {\n from: number,\n to: number,\n}\ninterface Position {\n x: number,\n y: number,\n width: number,\n height: number,\n}\ninterface Edge {\n from: Position,\n to: Position,\n}\nexport class KmapTermTree extends LitElement {\n declare shadowRoot: ShadowRoot;\n\n // language=CSS\n static styles = css`\n :host {\n display: block;\n color: var(--kmap-term-tree-text-color, #000);\n position: relative;\n }\n .tokens, .nodes, kmap-term-tree-edges {\n position: absolute;\n }\n .tokens, .nodes {\n white-space: nowrap;\n }\n .notokens {\n white-space: nowrap;\n height: 0px;\n }\n .notokens div {\n display: inline-block;\n }\n kmap-term-tree-edges {\n width: 100%;\n height: 100%;\n }\n .token {\n display: inline-block;\n }\n .token, .node {\n display: inline-block;\n position: relative;\n background-color: var(--kmap-term-tree-background-color, white);\n }\n .node {\n display: inline-block;\n position: relative;\n border: 1px solid var(--kmap-term-tree-border-color, #005b9f);\n padding: 0px 4px;\n border-radius: 1em;\n margin: -1px -5px;\n }\n .node[depth=\"0\"], .node:not([depth]) {\n visibility: hidden;\n }\n .node[depth=\"1\"] {\n top: calc(var(--kmap-term-tree-vertical-distance, 1.5em) * 1.5);\n }\n .node[depth=\"2\"] {\n top: calc(var(--kmap-term-tree-vertical-distance, 1.5em) * 3);\n }\n .node[depth=\"3\"] {\n top: calc(var(--kmap-term-tree-vertical-distance, 1.5em) * 4.5);\n }\n .node[depth=\"4\"] {\n top: calc(var(--kmap-term-tree-vertical-distance, 1.5em) * 6);\n }\n .node[depth=\"5\"] {\n top: calc(var(--kmap-term-tree-vertical-distance, 1.5em) * 7.5);\n }\n .node[depth=\"6\"] {\n top: calc(var(--kmap-term-tree-vertical-distance, 1.5em) * 9);\n }\n `;\n\n private parser: Parser = new Parser();\n\n @property({ type: String }) term?: string;\n @property({type: Number}) tension: number = 0;\n\n @state() tokens?: Token[];\n @state() nodes?: TermNode[];\n @state() termNode?: TermNode;\n @state() depths?: {[key: string]: number};\n @state() maxDepths?: number;\n\n @state() connections?: Connection[];\n\n @query(\"kmap-term-tree-edges\") edgesElement?: KmapTermTreeEdge;\n @query(\"#tokens\") tokensElement?: HTMLDivElement;\n\n // @ts-ignore\n updateSlotted({target}) {\n // @ts-ignore\n this.term = target.assignedNodes().map((n) => n.textContent).join('');\n }\n\n protected update(_changedProperties: PropertyValues) {\n if (_changedProperties.has(\"term\")) {\n if (this.term !== undefined) {\n this.tokens = Token.tokenize(this.term);\n this.termNode = this.parser.parse(this.tokens);\n\n let map: {[key: string]: number} = {};\n this.maxDepths = this.calcDepths(this.termNode, map);\n\n let connections: Connection[] = [];\n this.termNode.breadthFirst((n) => {\n if (n.leftChildNode !== undefined)\n connections.push({from: n.token.id, to: n.leftChildNode.token.id})\n if (n.rightChildNode !== undefined)\n connections.push({from: n.token.id, to: n.rightChildNode.token.id})\n });\n this.depths = map;\n this.connections = connections;\n }\n }\n super.update(_changedProperties);\n }\n\n private calcDepths(node: TermNode, map: { [p: string]: number }): number {\n let depth = 0;\n if (node.leftChildNode)\n depth = Math.max(depth, this.calcDepths(node.leftChildNode, map) + 1);\n if (node.rightChildNode)\n depth = Math.max(depth, this.calcDepths(node.rightChildNode, map) + 1);\n map[node.token.id] = depth;\n return depth;\n }\n\n render() {\n return html`\n ${this.connections ? html`\n <kmap-term-tree-edges .tension=\"${this.tension}\"></kmap-term-tree-edges>\n ` : ''}\n ${!this.tokens ? '' : html`\n <div class=\"tokens\" id=\"tokens\">\n ${this.tokens.map((t) => html`\n <div class=\"token\" id=\"${t.id}\">${KmapTermTree._prettify(t.value)}</div>\n `)}\n </div>\n <div class=\"notokens\">\n ${this.tokens.map((t) => html`\n <div>${KmapTermTree._prettify(t.value)}</div>\n `)}\n </div>\n ` }\n ${this.tokens && this.depths ? html`\n <div class=\"nodes\">\n ${this.tokens.map((t) => html`\n <div class=\"node\" id=\"n${t.id}\" depth=\"${ifDefined(this.depths ? this.depths[t.id]: undefined)}\">${KmapTermTree._prettify(t.value)}</div>\n `)}\n </div>\n ` : ''}\n <div hidden>\n <slot @slotchange=${this.updateSlotted}></slot>\n </div>\n `;\n }\n\n protected async updated(_changedProperties: PropertyValues) {\n if (_changedProperties.has(\"connections\")) {\n await this.updateComplete;\n\n if (this.tokensElement && this.maxDepths ) {\n let tokensHeight = this.tokensElement.offsetHeight;\n //console.log(this.maxDepths)\n //console.log(tokensHeight + \"px\")\n this.style.setProperty(\"--kmap-term-tree-max-depth\", \"\" + this.maxDepths);\n this.style.setProperty(\"--kmap-term-tree-vertical-distance\", tokensHeight + \"px\");\n this.style.height = \"calc(3px + var(--kmap-term-tree-vertical-distance) * (var(--kmap-term-tree-max-depth)*1.5 + 1))\";\n //console.log(this.style.height);\n }\n\n let edges: Edge[] = [];\n if (this.edgesElement && this.connections) {\n for (const connection of this.connections) {\n let edge = this._connect(connection);\n if (edge)\n edges.push(edge);\n }\n this.edgesElement.edges = edges;\n }\n }\n }\n\n _connect(connection: Connection): Edge | undefined {\n let from = this.shadowRoot.getElementById(\"n\" + connection.from);\n let to = this.shadowRoot.getElementById(\"n\" + connection.to);\n if (!from || !to)\n return;\n let frompos = this._findAbsolutePosition(from);\n let topos = this._findAbsolutePosition(to);\n\n return { from: frompos, to: topos };\n }\n\n _findAbsolutePosition(element: HTMLElement): Position {\n var x: number = 0;\n var y: number = 0;\n var el: HTMLElement | null = element;\n for (; el !== this; el = el.offsetParent as HTMLElement) {\n x += el.offsetLeft;\n y += el.offsetTop;\n }\n return {\n x: x,\n y: y,\n width: element.offsetWidth,\n height: element.offsetHeight,\n };\n }\n\n private static _prettify(value: string) {\n switch (value) {\n case '*':\n return \"·\"\n case '-':\n return \"−\"; // math minus\n default:\n return value;\n }\n }\n}\n\nexport class KmapTermTreeEdge extends LitElement {\n static styles = css`\n :host {\n display: block;\n stroke: var(--kmap-term-tree-edge-color, #fbc02d);\n position: relative;\n }\n `;\n\n @property({type: Number}) tension: number = .5;\n @property({type: Array}) edges: Edge[] = [];\n\n render() {\n const parent = this.offsetParent as HTMLElement;\n //language=SVG\n return this.edges === undefined ? '' : svg`\n <svg style=\"position:absolute;left:0px;top:0px\" width=\"${parent.clientWidth}\" height=\"${parent.clientHeight}\">\n ${this.edges.map(edge => svg`\n <path d=\"${this._path(edge)}\" fill=\"none\" stroke-width=\"2\" stroke-opacity=\".9\"/>\n `)}\n </svg>\n `;\n }\n\n _path(edge: Edge) {\n let fromx = edge.from.x + edge.from.width / 2;\n let fromy = edge.from.y + edge.from.height / 2;\n let tox = edge.to.x + edge.to.width / 2;\n let toy = edge.to.y + edge.to.height / 2;\n\n var delta = (toy-fromy) * this.tension;\n var hx1 = fromx;\n var hy1 = fromy + delta;\n var hx2 = tox;\n var hy2 = toy - delta;\n return \"M \" + fromx + \" \" + fromy +\n \" C \" + hx1 + \" \" + hy1\n + \" \" + hx2 + \" \" + hy2\n + \" \" + tox + \" \" + toy;\n }\n\n}\nwindow.customElements.define('kmap-term-tree-edges', KmapTermTreeEdge);\n"]}
1
+ {"version":3,"file":"KmapTermTree.js","sourceRoot":"","sources":["../../src/KmapTermTree.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, PropertyValues, svg } from 'lit';\nimport { property, state, query } from 'lit/decorators.js';\nimport katex from 'katex';\nimport { katexStyles } from './katex-css.js';\nimport { TermNode, TreeEdge } from './model.js';\nimport { parseAsciiMath, astToAnnotatedLatex } from './asciimath-parser.js';\n\nexport class KmapTermTree extends LitElement {\n static styles = [\n katexStyles,\n css`\n :host {\n display: block;\n position: relative;\n font-family: var(\n --kmap-term-tree-font-family,\n system-ui,\n -apple-system,\n sans-serif\n );\n color: var(--kmap-term-tree-text-color, #1f2937);\n user-select: none;\n width: 100%;\n }\n\n .container {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 100%;\n box-sizing: border-box;\n }\n\n .tree-canvas {\n position: relative;\n width: 100%;\n min-height: 80px;\n }\n\n .formula-wrapper {\n position: relative;\n z-index: 2;\n display: flex;\n justify-content: center;\n align-items: center;\n padding-top: 4px;\n font-size: var(--kmap-term-tree-formula-font-size, 1.35rem);\n }\n\n .highlight-overlay {\n position: absolute;\n z-index: 1;\n pointer-events: none;\n background-color: var(\n --kmap-term-tree-highlight-color,\n rgba(251, 191, 36, 0.28)\n );\n border: 2px solid\n var(--kmap-term-tree-highlight-outline, rgba(245, 158, 11, 0.75));\n border-radius: 6px;\n box-sizing: border-box;\n transition: left 0.12s ease-out, top 0.12s ease-out,\n width 0.12s ease-out, height 0.12s ease-out;\n }\n\n .edges-svg {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: 1;\n overflow: visible;\n }\n\n .edge-path {\n fill: none;\n stroke: var(--kmap-term-tree-edge-color, #f59e0b);\n stroke-width: 2.2;\n stroke-linecap: round;\n opacity: 0.85;\n transition: stroke 0.2s ease, stroke-width 0.2s ease, opacity 0.2s ease;\n }\n\n .edge-path.highlighted {\n stroke: var(--kmap-term-tree-highlight-edge-color, #d97706);\n stroke-width: 3.2;\n opacity: 1;\n }\n\n .tree-node {\n position: absolute;\n z-index: 2;\n transform: translate(-50%, -50%);\n display: inline-flex;\n flex-direction: column;\n align-items: center;\n cursor: pointer;\n transition: transform 0.15s ease, box-shadow 0.15s ease;\n }\n\n .tree-node:hover,\n .tree-node.active {\n transform: translate(-50%, -50%) scale(1.15);\n }\n\n .node-badge {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: var(--kmap-term-tree-background-color, #ffffff);\n border: 2px solid var(--kmap-term-tree-border-color, #0284c7);\n color: var(--kmap-term-tree-node-text-color, #0284c7);\n font-weight: 700;\n font-size: 1rem;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);\n box-sizing: border-box;\n transition: all 0.2s ease;\n }\n\n .tree-node:hover .node-badge,\n .tree-node.active .node-badge {\n background: var(--kmap-term-tree-active-node-bg, #0284c7);\n color: #ffffff;\n border-color: var(--kmap-term-tree-active-node-border, #0284c7);\n box-shadow: 0 4px 8px rgba(2, 132, 199, 0.35);\n }\n\n .node-label {\n margin-top: 2px;\n font-size: 0.7rem;\n font-weight: 500;\n color: #64748b;\n white-space: nowrap;\n background: rgba(255, 255, 255, 0.95);\n padding: 1px 4px;\n border-radius: 4px;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n }\n\n /* KaTeX Highlight */\n .highlight-term {\n background-color: var(\n --kmap-term-tree-highlight-color,\n rgba(251, 191, 36, 0.35)\n ) !important;\n border-radius: 4px;\n outline: 2px solid\n var(--kmap-term-tree-highlight-outline, rgba(245, 158, 11, 0.7));\n transition: background-color 0.2s ease, outline 0.2s ease;\n }\n\n .info-bar {\n margin-top: 12px;\n padding: 6px 14px;\n background: #f8fafc;\n border: 1px solid #e2e8f0;\n border-radius: 8px;\n font-size: 0.88rem;\n display: flex;\n align-items: center;\n gap: 8px;\n color: #334155;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);\n }\n\n .info-badge {\n font-weight: 700;\n color: #0284c7;\n background: #e0f2fe;\n padding: 2px 8px;\n border-radius: 4px;\n }\n\n .error-msg {\n color: #dc2626;\n padding: 8px;\n font-size: 0.9rem;\n }\n `,\n ];\n\n @property({ type: String }) term?: string;\n @property({ type: Number }) tension: number = 0.5;\n @property({ type: Boolean }) showLabels: boolean = false;\n @property({ type: Boolean }) showDetails: boolean = true;\n\n @state() private ast?: TermNode;\n @state() private error?: string;\n @state() private flatNodes: TermNode[] = [];\n @state() private edges: TreeEdge[] = [];\n @state() private activeNodeId?: string;\n @state() private activeSubtreeIds: Set<string> = new Set();\n @state() private treeHeight: number = 100;\n @state() private highlightRect?: {\n left: number;\n top: number;\n width: number;\n height: number;\n };\n\n @query('#formula') private formulaElement?: HTMLElement;\n @query('.tree-canvas') private treeCanvasElement?: HTMLElement;\n\n private resizeObserver?: ResizeObserver;\n\n connectedCallback() {\n super.connectedCallback();\n this.resizeObserver = new ResizeObserver(() => {\n this.recalculateLayout();\n });\n }\n\n disconnectedCallback() {\n this.resizeObserver?.disconnect();\n super.disconnectedCallback();\n }\n\n // Support slotted content: <kmap-term-tree>2a+3b</kmap-term-tree>\n updateSlotted(event: Event) {\n const slot = event.target as HTMLSlotElement;\n const text = slot\n .assignedNodes()\n .map(n => n.textContent)\n .join('')\n .trim();\n if (text && text !== this.term) {\n this.term = text;\n }\n }\n\n protected willUpdate(changedProperties: PropertyValues) {\n if (changedProperties.has('term') && this.term !== undefined) {\n this.parseInput(this.term);\n }\n }\n\n private parseInput(termStr: string) {\n try {\n this.error = undefined;\n const cleanTerm = termStr.trim();\n if (!cleanTerm) {\n this.ast = undefined;\n this.flatNodes = [];\n this.edges = [];\n return;\n }\n\n this.ast = parseAsciiMath(cleanTerm);\n this.activeNodeId = this.ast.id;\n this.activeSubtreeIds = this.collectSubtreeIds(this.ast);\n } catch (e: any) {\n this.error = e.message || 'Fehler beim Parsen des Terms';\n this.ast = undefined;\n this.flatNodes = [];\n this.edges = [];\n }\n }\n\n protected async updated(changedProperties: PropertyValues) {\n if (changedProperties.has('term') || changedProperties.has('ast')) {\n this.renderKaTeX();\n await this.updateComplete;\n this.recalculateLayout();\n if (this.treeCanvasElement && this.resizeObserver) {\n this.resizeObserver.observe(this.treeCanvasElement);\n }\n }\n }\n\n private renderKaTeX() {\n if (!this.formulaElement || !this.ast) return;\n\n try {\n const latex = astToAnnotatedLatex(this.ast);\n katex.render(latex, this.formulaElement, {\n trust: true,\n strict: false,\n throwOnError: false,\n });\n } catch (err: any) {\n this.error = err.message;\n }\n }\n\n private recalculateLayout() {\n if (\n !this.ast ||\n !this.formulaElement ||\n !this.treeCanvasElement ||\n !this.shadowRoot\n )\n return;\n\n const canvasRect = this.treeCanvasElement.getBoundingClientRect();\n if (canvasRect.width === 0) return;\n\n const flatNodes: TermNode[] = [];\n const nodeMap = new Map<string, TermNode>();\n\n // 1. Collect all nodes and measure leaf positions from KaTeX DOM elements\n const collectAndPositionLeaves = (node: TermNode) => {\n nodeMap.set(node.id, node);\n\n if (node.children.length === 0) {\n // Leaf node: measure rendered KaTeX span\n const el = this.shadowRoot!.getElementById(node.id);\n if (el) {\n const rect = el.getBoundingClientRect();\n node.x = rect.left - canvasRect.left + rect.width / 2;\n node.y = rect.bottom - canvasRect.top;\n node.width = rect.width;\n node.height = rect.height;\n } else {\n node.x = canvasRect.width / 2;\n node.y = 20;\n }\n } else {\n flatNodes.push(node);\n for (const child of node.children) {\n collectAndPositionLeaves(child);\n }\n }\n };\n\n collectAndPositionLeaves(this.ast);\n\n // 2. Position inner nodes bottom-up based on children coordinates\n const formulaRect = this.formulaElement.getBoundingClientRect();\n const formulaBottomRel = formulaRect.bottom - canvasRect.top;\n const initialGap = 34; // distance from formula bottom to level 1 operators\n const rowHeight = 40; // distance between tree levels\n\n const positionInnerNodes = (node: TermNode) => {\n for (const child of node.children) {\n if (child.children.length > 0) {\n positionInnerNodes(child);\n }\n }\n\n if (node.children.length > 0) {\n if (node.type === 'function' || node.isUnary) {\n // Center under the full function / unary expression: e.g. sin(arg) or -arg\n const el = this.shadowRoot!.getElementById(node.id);\n if (el) {\n const rect = el.getBoundingClientRect();\n node.x = rect.left - canvasRect.left + rect.width / 2;\n } else {\n node.x = node.children[0].x ?? 0;\n }\n } else {\n const first = node.children[0];\n const last = node.children[node.children.length - 1];\n node.x = ((first.x ?? 0) + (last.x ?? 0)) / 2;\n }\n node.y = formulaBottomRel + initialGap + (node.depth - 1) * rowHeight;\n }\n };\n\n positionInnerNodes(this.ast);\n\n // 3. Build edges between parent nodes and their children\n const edges: TreeEdge[] = [];\n for (const node of flatNodes) {\n if (node.x === undefined || node.y === undefined) continue;\n\n for (const child of node.children) {\n if (child.x === undefined || child.y === undefined) continue;\n\n edges.push({\n fromNodeId: child.id,\n toNodeId: node.id,\n fromX: child.x,\n fromY: child.y + (child.depth > 0 ? 14 : 2),\n toX: node.x,\n toY: node.y - 14,\n });\n }\n }\n\n const maxDepth = this.ast.depth;\n this.treeHeight = Math.max(\n 60,\n formulaBottomRel + initialGap + (maxDepth - 1) * rowHeight + 24\n );\n this.flatNodes = flatNodes;\n this.edges = edges;\n this.updateHighlightRect(this.activeNodeId);\n this.requestUpdate();\n }\n\n private collectSubtreeIds(node: TermNode): Set<string> {\n const ids = new Set<string>();\n const traverse = (n: TermNode) => {\n ids.add(n.id);\n for (const c of n.children) traverse(c);\n };\n traverse(node);\n return ids;\n }\n\n private onNodeHover(node: TermNode, enter: boolean) {\n if (!enter) {\n // Revert highlight to root node\n if (this.ast) {\n this.setActiveNode(this.ast);\n }\n return;\n }\n this.setActiveNode(node);\n }\n\n private setActiveNode(node: TermNode) {\n this.activeNodeId = node.id;\n this.activeSubtreeIds = this.collectSubtreeIds(node);\n this.updateHighlightRect(node.id);\n this.requestUpdate();\n }\n\n private findNode(\n root: TermNode | undefined,\n id: string\n ): TermNode | undefined {\n if (!root) return undefined;\n if (root.id === id) return root;\n for (const child of root.children) {\n const found = this.findNode(child, id);\n if (found) return found;\n }\n return undefined;\n }\n\n private getNodeVisualBounds(\n node: TermNode\n ): { top: number; bottom: number; left: number; right: number } | null {\n if (!this.shadowRoot) return null;\n\n let minTop = Infinity;\n let maxBottom = -Infinity;\n let minLeft = Infinity;\n let maxRight = -Infinity;\n\n const collectBounds = (n: TermNode) => {\n const el = this.shadowRoot!.getElementById(n.id);\n if (el) {\n const r = el.getBoundingClientRect();\n if (r.width > 0 && r.height > 0) {\n minTop = Math.min(minTop, r.top);\n maxBottom = Math.max(maxBottom, r.bottom);\n minLeft = Math.min(minLeft, r.left);\n maxRight = Math.max(maxRight, r.right);\n }\n }\n for (const child of n.children) {\n collectBounds(child);\n }\n };\n\n collectBounds(node);\n\n if (minTop === Infinity) return null;\n return { top: minTop, bottom: maxBottom, left: minLeft, right: maxRight };\n }\n\n private updateHighlightRect(nodeId?: string) {\n if (!nodeId || !this.shadowRoot || !this.treeCanvasElement || !this.ast) {\n this.highlightRect = undefined;\n return;\n }\n\n const node = this.findNode(this.ast, nodeId);\n if (!node) {\n this.highlightRect = undefined;\n return;\n }\n\n const bounds = this.getNodeVisualBounds(node);\n if (!bounds) {\n this.highlightRect = undefined;\n return;\n }\n\n const canvasRect = this.treeCanvasElement.getBoundingClientRect();\n const paddingX = 4;\n const paddingY = 4;\n\n this.highlightRect = {\n left: bounds.left - canvasRect.left - paddingX,\n top: bounds.top - canvasRect.top - paddingY,\n width: bounds.right - bounds.left + paddingX * 2,\n height: bounds.bottom - bounds.top + paddingY * 2,\n };\n }\n\n private renderPath(edge: TreeEdge): string {\n const delta = (edge.toY - edge.fromY) * this.tension;\n const hx1 = edge.fromX;\n const hy1 = edge.fromY + delta;\n const hx2 = edge.toX;\n const hy2 = edge.toY - delta;\n\n return `M ${edge.fromX} ${edge.fromY} C ${hx1} ${hy1} ${hx2} ${hy2} ${edge.toX} ${edge.toY}`;\n }\n\n render() {\n const activeNode =\n this.flatNodes.find(n => n.id === this.activeNodeId) || this.ast;\n const isRoot = activeNode?.id === this.ast?.id;\n\n return html`\n <div class=\"container\">\n <!-- Canvas area with formula, edges, and operator nodes sharing the same coordinate space -->\n <div class=\"tree-canvas\" style=\"height: ${this.treeHeight}px\">\n ${this.highlightRect\n ? html`\n <div\n class=\"highlight-overlay\"\n style=\"left: ${this.highlightRect.left}px; top: ${this\n .highlightRect.top}px; width: ${this.highlightRect\n .width}px; height: ${this.highlightRect.height}px;\"\n ></div>\n `\n : ''}\n\n <div class=\"formula-wrapper\">\n <div id=\"formula\"></div>\n </div>\n\n ${this.error\n ? html`<div class=\"error-msg\">${this.error}</div>`\n : html`\n <svg class=\"edges-svg\">\n ${this.edges.map(\n edge => svg`\n <path\n class=\"edge-path ${\n this.activeSubtreeIds.has(edge.fromNodeId) &&\n this.activeSubtreeIds.has(edge.toNodeId)\n ? 'highlighted'\n : ''\n }\"\n d=\"${this.renderPath(edge)}\"\n />\n `\n )}\n </svg>\n\n ${this.flatNodes.map(\n node => html`\n <div\n class=\"tree-node ${this.activeNodeId === node.id\n ? 'active'\n : ''}\"\n style=\"left: ${node.x}px; top: ${node.y}px;\"\n @mouseenter=${() => this.onNodeHover(node, true)}\n @mouseleave=${() => this.onNodeHover(node, false)}\n @click=${() => this.setActiveNode(node)}\n >\n <div class=\"node-badge\" title=\"${node.label}\">\n ${node.symbol}\n </div>\n ${this.showLabels\n ? html`<span class=\"node-label\">${node.label}</span>`\n : ''}\n </div>\n `\n )}\n `}\n </div>\n\n <!-- Didactic info box -->\n ${this.showDetails && activeNode\n ? html`\n <div class=\"info-bar\">\n <span>${isRoot ? 'Hauptrechenart:' : 'Teilterm:'}</span>\n <span class=\"info-badge\">${activeNode.label}</span>\n <span style=\"color: #64748b\">\n ${activeNode.children.length === 2\n ? `(verknüpft 2 Teilterme mit ${activeNode.symbol})`\n : activeNode.isUnary\n ? `(wirkt auf ${\n activeNode.children[0].label || 'Ausdruck'\n })`\n : ''}\n </span>\n </div>\n `\n : ''}\n\n <div hidden>\n <slot @slotchange=${this.updateSlotted}></slot>\n </div>\n </div>\n `;\n }\n}\n"]}
@@ -0,0 +1,17 @@
1
+ import { TermNode } from './model.js';
2
+ export declare function resetNodeIdCounter(): void;
3
+ /**
4
+ * Calculates depths bottom-up:
5
+ * Leaves have depth 0.
6
+ * A parent node has depth = max(children.depth) + 1.
7
+ * Returns the maximum depth of the tree.
8
+ */
9
+ export declare function calculateDepths(node: TermNode): number;
10
+ /**
11
+ * Parses an AsciiMath string into a TermNode AST with Math-JSON support.
12
+ */
13
+ export declare function parseAsciiMath(input: string): TermNode;
14
+ /**
15
+ * Generates LaTeX from the AST with embedded `\htmlId{...}` for KaTeX.
16
+ */
17
+ export declare function astToAnnotatedLatex(node: TermNode): string;
@@ -0,0 +1,472 @@
1
+ import { GERMAN_LABELS, OPERATOR_SYMBOLS } from './model.js';
2
+ const KNOWN_FUNCTIONS = new Set([
3
+ 'sin',
4
+ 'cos',
5
+ 'tan',
6
+ 'cot',
7
+ 'sec',
8
+ 'csc',
9
+ 'arcsin',
10
+ 'arccos',
11
+ 'arctan',
12
+ 'sinh',
13
+ 'cosh',
14
+ 'tanh',
15
+ 'exp',
16
+ 'ln',
17
+ 'log',
18
+ 'sqrt',
19
+ 'abs',
20
+ ]);
21
+ const FUNCTION_MAP = {
22
+ sin: 'Sin',
23
+ cos: 'Cos',
24
+ tan: 'Tan',
25
+ cot: 'Cot',
26
+ arcsin: 'Arcsin',
27
+ arccos: 'Arccos',
28
+ arctan: 'Arctan',
29
+ sinh: 'Sinh',
30
+ cosh: 'Cosh',
31
+ tanh: 'Tanh',
32
+ ln: 'Ln',
33
+ log: 'Log',
34
+ sqrt: 'Sqrt',
35
+ abs: 'Abs',
36
+ exp: 'Exp',
37
+ };
38
+ const GREEK_LETTERS = new Set([
39
+ 'alpha',
40
+ 'beta',
41
+ 'gamma',
42
+ 'delta',
43
+ 'epsilon',
44
+ 'zeta',
45
+ 'eta',
46
+ 'theta',
47
+ 'iota',
48
+ 'kappa',
49
+ 'lambda',
50
+ 'mu',
51
+ 'nu',
52
+ 'xi',
53
+ 'pi',
54
+ 'rho',
55
+ 'sigma',
56
+ 'tau',
57
+ 'upsilon',
58
+ 'phi',
59
+ 'chi',
60
+ 'psi',
61
+ 'omega',
62
+ ]);
63
+ class Tokenizer {
64
+ constructor(input) {
65
+ this.pos = 0;
66
+ this.input = input.trim();
67
+ }
68
+ tokenize() {
69
+ const rawTokens = [];
70
+ while (this.pos < this.input.length) {
71
+ const ch = this.input[this.pos];
72
+ if (/\s/.test(ch)) {
73
+ this.pos++;
74
+ continue;
75
+ }
76
+ // Numbers: integer or floating point
77
+ if (/\d/.test(ch)) {
78
+ let num = '';
79
+ while (this.pos < this.input.length &&
80
+ /[\d.]/.test(this.input[this.pos])) {
81
+ num += this.input[this.pos++];
82
+ }
83
+ rawTokens.push({ type: 'NUMBER', value: num });
84
+ continue;
85
+ }
86
+ // Words: functions, greek letters, or sequences of variable characters
87
+ if (/[a-zA-Z]/.test(ch)) {
88
+ let word = '';
89
+ while (this.pos < this.input.length &&
90
+ /[a-zA-Z]/.test(this.input[this.pos])) {
91
+ word += this.input[this.pos++];
92
+ }
93
+ const lower = word.toLowerCase();
94
+ if (KNOWN_FUNCTIONS.has(lower)) {
95
+ rawTokens.push({ type: 'FUNCTION', value: lower });
96
+ }
97
+ else if (GREEK_LETTERS.has(lower)) {
98
+ rawTokens.push({ type: 'VARIABLE', value: lower });
99
+ }
100
+ else {
101
+ // In school mathematics, "2ab" or "xy" means 2 * a * b or x * y
102
+ for (const char of word) {
103
+ rawTokens.push({ type: 'VARIABLE', value: char });
104
+ }
105
+ }
106
+ continue;
107
+ }
108
+ // 'xx' or '·' or '*' as multiplication
109
+ if (ch === 'x' && this.input[this.pos + 1] === 'x') {
110
+ rawTokens.push({ type: 'OPERATOR', value: '*' });
111
+ this.pos += 2;
112
+ continue;
113
+ }
114
+ if (ch === '·' || ch === '*') {
115
+ rawTokens.push({ type: 'OPERATOR', value: '*' });
116
+ this.pos++;
117
+ continue;
118
+ }
119
+ // Division: '/' or ':'
120
+ if (ch === '/' || ch === ':') {
121
+ rawTokens.push({ type: 'OPERATOR', value: ch });
122
+ this.pos++;
123
+ continue;
124
+ }
125
+ // Other operators
126
+ if (ch === '+' || ch === '-' || ch === '^') {
127
+ rawTokens.push({ type: 'OPERATOR', value: ch });
128
+ this.pos++;
129
+ continue;
130
+ }
131
+ // Parentheses & brackets
132
+ if (ch === '(' || ch === '[') {
133
+ rawTokens.push({ type: 'LPAREN', value: ch });
134
+ this.pos++;
135
+ continue;
136
+ }
137
+ if (ch === ')' || ch === ']') {
138
+ rawTokens.push({ type: 'RPAREN', value: ch });
139
+ this.pos++;
140
+ continue;
141
+ }
142
+ if (ch === ',') {
143
+ rawTokens.push({ type: 'COMMA', value: ch });
144
+ this.pos++;
145
+ continue;
146
+ }
147
+ // Fallback: skip unrecognized characters
148
+ this.pos++;
149
+ }
150
+ // Insert implicit multiplication between operands where appropriate
151
+ const tokens = [];
152
+ for (let i = 0; i < rawTokens.length; i++) {
153
+ const cur = rawTokens[i];
154
+ tokens.push(cur);
155
+ if (i < rawTokens.length - 1) {
156
+ const next = rawTokens[i + 1];
157
+ const curEndsOperand = cur.type === 'NUMBER' ||
158
+ cur.type === 'VARIABLE' ||
159
+ cur.type === 'RPAREN';
160
+ const nextStartsOperand = next.type === 'NUMBER' ||
161
+ next.type === 'VARIABLE' ||
162
+ next.type === 'FUNCTION' ||
163
+ next.type === 'LPAREN';
164
+ if (curEndsOperand && nextStartsOperand) {
165
+ tokens.push({ type: 'OPERATOR', value: '*', implicit: true });
166
+ }
167
+ }
168
+ }
169
+ tokens.push({ type: 'EOF', value: '' });
170
+ return tokens;
171
+ }
172
+ }
173
+ let nodeIdCounter = 1;
174
+ export function resetNodeIdCounter() {
175
+ nodeIdCounter = 1;
176
+ }
177
+ class PrattParser {
178
+ constructor(tokens) {
179
+ this.pos = 0;
180
+ this.tokens = tokens;
181
+ }
182
+ current() {
183
+ return this.tokens[this.pos];
184
+ }
185
+ consume(expectedType) {
186
+ const token = this.current();
187
+ if (expectedType && token.type !== expectedType) {
188
+ throw new Error(`Erwartet ${expectedType}, aber erhalten: ${token.type} (${token.value})`);
189
+ }
190
+ this.pos++;
191
+ return token;
192
+ }
193
+ parse(precedence = 0) {
194
+ let left = this.parsePrefix();
195
+ while (true) {
196
+ const token = this.current();
197
+ if (token.type !== 'OPERATOR')
198
+ break;
199
+ const opPrec = this.getInfixPrecedence(token.value);
200
+ if (opPrec <= precedence)
201
+ break;
202
+ this.pos++;
203
+ left = this.parseInfix(left, token, opPrec);
204
+ }
205
+ return left;
206
+ }
207
+ parsePrefix() {
208
+ const token = this.current();
209
+ if (token.type === 'NUMBER') {
210
+ this.pos++;
211
+ const val = parseFloat(token.value);
212
+ return {
213
+ id: `n${nodeIdCounter++}`,
214
+ type: 'literal',
215
+ value: val,
216
+ raw: token.value,
217
+ symbol: token.value,
218
+ label: `Zahl ${token.value}`,
219
+ mathJson: val,
220
+ children: [],
221
+ depth: 0,
222
+ };
223
+ }
224
+ if (token.type === 'VARIABLE') {
225
+ this.pos++;
226
+ return {
227
+ id: `n${nodeIdCounter++}`,
228
+ type: 'variable',
229
+ raw: token.value,
230
+ symbol: token.value,
231
+ label: `Variable ${token.value}`,
232
+ mathJson: token.value,
233
+ children: [],
234
+ depth: 0,
235
+ };
236
+ }
237
+ if (token.type === 'FUNCTION') {
238
+ this.pos++;
239
+ const fnName = FUNCTION_MAP[token.value] || token.value;
240
+ let arg;
241
+ if (this.current().type === 'LPAREN') {
242
+ this.consume('LPAREN');
243
+ arg = this.parse(0);
244
+ this.consume('RPAREN');
245
+ }
246
+ else {
247
+ arg = this.parse(35); // higher than *, /, ^
248
+ }
249
+ const symbol = token.value === 'sqrt' ? '√' : token.value;
250
+ return {
251
+ id: `n${nodeIdCounter++}`,
252
+ type: 'function',
253
+ op: fnName,
254
+ symbol,
255
+ label: GERMAN_LABELS[fnName] || fnName,
256
+ mathJson: [fnName, arg.mathJson],
257
+ children: [arg],
258
+ depth: 0,
259
+ };
260
+ }
261
+ // Unary plus or minus
262
+ if (token.type === 'OPERATOR' &&
263
+ (token.value === '-' || token.value === '+')) {
264
+ this.pos++;
265
+ const op = token.value;
266
+ const operand = this.parse(30); // Prefix unary precedence
267
+ if (op === '-') {
268
+ return {
269
+ id: `n${nodeIdCounter++}`,
270
+ type: 'operator',
271
+ isUnary: true,
272
+ op: 'Negate',
273
+ symbol: '−',
274
+ label: GERMAN_LABELS['Negate'],
275
+ mathJson: ['Negate', operand.mathJson],
276
+ children: [operand],
277
+ depth: 0,
278
+ };
279
+ }
280
+ else {
281
+ return operand;
282
+ }
283
+ }
284
+ // Parentheses
285
+ if (token.type === 'LPAREN') {
286
+ this.pos++;
287
+ const expr = this.parse(0);
288
+ this.consume('RPAREN');
289
+ expr.isParenthesized = true;
290
+ return expr;
291
+ }
292
+ throw new Error(`Unerwartetes Zeichen: ${token.value || token.type}`);
293
+ }
294
+ getInfixPrecedence(op) {
295
+ switch (op) {
296
+ case '+':
297
+ case '-':
298
+ return 10;
299
+ case '*':
300
+ case '/':
301
+ case ':':
302
+ return 20;
303
+ case '^':
304
+ return 40;
305
+ default:
306
+ return 0;
307
+ }
308
+ }
309
+ parseInfix(left, token, precedence) {
310
+ const op = token.value;
311
+ const isRightAssoc = op === '^';
312
+ const nextPrec = isRightAssoc ? precedence - 1 : precedence;
313
+ const right = this.parse(nextPrec);
314
+ let opName = 'Add';
315
+ if (op === '-')
316
+ opName = 'Subtract';
317
+ else if (op === '*')
318
+ opName = 'Multiply';
319
+ else if (op === '/' || op === ':')
320
+ opName = 'Divide';
321
+ else if (op === '^')
322
+ opName = 'Power';
323
+ const symbol = OPERATOR_SYMBOLS[opName] || op;
324
+ const label = GERMAN_LABELS[opName] || opName;
325
+ return {
326
+ id: `n${nodeIdCounter++}`,
327
+ type: 'operator',
328
+ op: opName,
329
+ symbol,
330
+ label,
331
+ implicit: token.implicit,
332
+ mathJson: [opName, left.mathJson, right.mathJson],
333
+ children: [left, right],
334
+ depth: 0,
335
+ };
336
+ }
337
+ }
338
+ /**
339
+ * Calculates depths bottom-up:
340
+ * Leaves have depth 0.
341
+ * A parent node has depth = max(children.depth) + 1.
342
+ * Returns the maximum depth of the tree.
343
+ */
344
+ export function calculateDepths(node) {
345
+ if (node.children.length === 0) {
346
+ node.depth = 0;
347
+ return 0;
348
+ }
349
+ let maxChild = 0;
350
+ for (const child of node.children) {
351
+ maxChild = Math.max(maxChild, calculateDepths(child));
352
+ }
353
+ node.depth = maxChild + 1;
354
+ return node.depth;
355
+ }
356
+ /**
357
+ * Parses an AsciiMath string into a TermNode AST with Math-JSON support.
358
+ */
359
+ export function parseAsciiMath(input) {
360
+ resetNodeIdCounter();
361
+ const tokenizer = new Tokenizer(input);
362
+ const tokens = tokenizer.tokenize();
363
+ const parser = new PrattParser(tokens);
364
+ const root = parser.parse(0);
365
+ calculateDepths(root);
366
+ return root;
367
+ }
368
+ function getOperatorPrecedence(node) {
369
+ if (node.type !== 'operator')
370
+ return 999;
371
+ if (node.isUnary)
372
+ return 30;
373
+ switch (node.op) {
374
+ case 'Add':
375
+ case 'Subtract':
376
+ return 10;
377
+ case 'Multiply':
378
+ case 'Divide':
379
+ return 20;
380
+ case 'Power':
381
+ return 40;
382
+ default:
383
+ return 0;
384
+ }
385
+ }
386
+ function needsParens(parent, child, isLeft) {
387
+ if (child.isParenthesized)
388
+ return true;
389
+ if (child.type !== 'operator')
390
+ return false;
391
+ const pPrec = getOperatorPrecedence(parent);
392
+ const cPrec = getOperatorPrecedence(child);
393
+ if (cPrec < pPrec)
394
+ return true;
395
+ if (cPrec === pPrec) {
396
+ // Subtraction and division are left-associative, right operand needs parentheses
397
+ if (!isLeft && (parent.op === 'Subtract' || parent.op === 'Divide'))
398
+ return true;
399
+ }
400
+ return false;
401
+ }
402
+ /**
403
+ * Generates LaTeX from the AST with embedded `\htmlId{...}` for KaTeX.
404
+ */
405
+ export function astToAnnotatedLatex(node) {
406
+ if (node.type === 'literal') {
407
+ return `\\htmlId{${node.id}}{${node.raw}}`;
408
+ }
409
+ if (node.type === 'variable') {
410
+ // Greek letters support (e.g. \pi, \alpha)
411
+ const varName = GREEK_LETTERS.has(node.symbol)
412
+ ? `\\${node.symbol}`
413
+ : node.symbol;
414
+ return `\\htmlId{${node.id}}{${varName}}`;
415
+ }
416
+ if (node.type === 'function') {
417
+ const childLatex = astToAnnotatedLatex(node.children[0]);
418
+ let fnSymbol;
419
+ if (node.op === 'Sqrt' || node.symbol === '√' || node.symbol === 'sqrt') {
420
+ fnSymbol = `\\sqrt{${childLatex}}`;
421
+ }
422
+ else if (node.symbol === 'abs') {
423
+ fnSymbol = `\\left|${childLatex}\\right|`;
424
+ }
425
+ else {
426
+ fnSymbol = `\\operatorname{${node.symbol}}\\left(${childLatex}\\right)`;
427
+ }
428
+ return `\\htmlId{${node.id}}{${fnSymbol}}`;
429
+ }
430
+ if (node.type === 'operator') {
431
+ if (node.isUnary) {
432
+ const childLatex = astToAnnotatedLatex(node.children[0]);
433
+ return `\\htmlId{${node.id}}{-${childLatex}}`;
434
+ }
435
+ const left = node.children[0];
436
+ const right = node.children[1];
437
+ let leftLatex = astToAnnotatedLatex(left);
438
+ let rightLatex = astToAnnotatedLatex(right);
439
+ if (needsParens(node, left, true)) {
440
+ leftLatex = `\\left(${leftLatex}\\right)`;
441
+ }
442
+ if (needsParens(node, right, false)) {
443
+ rightLatex = `\\left(${rightLatex}\\right)`;
444
+ }
445
+ if (node.op === 'Add') {
446
+ return `\\htmlId{${node.id}}{${leftLatex} \\htmlId{op_${node.id}}{+} ${rightLatex}}`;
447
+ }
448
+ if (node.op === 'Subtract') {
449
+ return `\\htmlId{${node.id}}{${leftLatex} \\htmlId{op_${node.id}}{-} ${rightLatex}}`;
450
+ }
451
+ if (node.op === 'Multiply') {
452
+ // Implicit multiplication styling (e.g. 2a, 4ac, (2+a)(3-b))
453
+ const isImplicit = node.implicit ||
454
+ (left.type === 'literal' &&
455
+ (right.type === 'variable' || right.type === 'function')) ||
456
+ (left.type === 'variable' && right.type === 'variable') ||
457
+ right.isParenthesized;
458
+ const opSymbol = isImplicit
459
+ ? ''
460
+ : ' \\htmlId{op_' + node.id + '}{\\cdot} ';
461
+ return `\\htmlId{${node.id}}{${leftLatex}${opSymbol}${rightLatex}}`;
462
+ }
463
+ if (node.op === 'Divide') {
464
+ return `\\htmlId{${node.id}}{\\frac{${leftLatex}}{${rightLatex}}}`;
465
+ }
466
+ if (node.op === 'Power') {
467
+ return `\\htmlId{${node.id}}{${leftLatex}^{${rightLatex}}}`;
468
+ }
469
+ }
470
+ return '';
471
+ }
472
+ //# sourceMappingURL=asciimath-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asciimath-parser.js","sourceRoot":"","sources":["../../src/asciimath-parser.ts"],"names":[],"mappings":"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","sourcesContent":["import { TermNode, GERMAN_LABELS, OPERATOR_SYMBOLS } from './model.js';\n\nconst KNOWN_FUNCTIONS = new Set([\n 'sin',\n 'cos',\n 'tan',\n 'cot',\n 'sec',\n 'csc',\n 'arcsin',\n 'arccos',\n 'arctan',\n 'sinh',\n 'cosh',\n 'tanh',\n 'exp',\n 'ln',\n 'log',\n 'sqrt',\n 'abs',\n]);\n\nconst FUNCTION_MAP: Record<string, string> = {\n sin: 'Sin',\n cos: 'Cos',\n tan: 'Tan',\n cot: 'Cot',\n arcsin: 'Arcsin',\n arccos: 'Arccos',\n arctan: 'Arctan',\n sinh: 'Sinh',\n cosh: 'Cosh',\n tanh: 'Tanh',\n ln: 'Ln',\n log: 'Log',\n sqrt: 'Sqrt',\n abs: 'Abs',\n exp: 'Exp',\n};\n\nconst GREEK_LETTERS = new Set([\n 'alpha',\n 'beta',\n 'gamma',\n 'delta',\n 'epsilon',\n 'zeta',\n 'eta',\n 'theta',\n 'iota',\n 'kappa',\n 'lambda',\n 'mu',\n 'nu',\n 'xi',\n 'pi',\n 'rho',\n 'sigma',\n 'tau',\n 'upsilon',\n 'phi',\n 'chi',\n 'psi',\n 'omega',\n]);\n\ntype TokenType =\n | 'NUMBER'\n | 'VARIABLE'\n | 'FUNCTION'\n | 'OPERATOR'\n | 'LPAREN'\n | 'RPAREN'\n | 'COMMA'\n | 'EOF';\n\ninterface Token {\n type: TokenType;\n value: string;\n implicit?: boolean;\n}\n\nclass Tokenizer {\n private input: string;\n private pos = 0;\n\n constructor(input: string) {\n this.input = input.trim();\n }\n\n tokenize(): Token[] {\n const rawTokens: Token[] = [];\n\n while (this.pos < this.input.length) {\n const ch = this.input[this.pos];\n\n if (/\\s/.test(ch)) {\n this.pos++;\n continue;\n }\n\n // Numbers: integer or floating point\n if (/\\d/.test(ch)) {\n let num = '';\n while (\n this.pos < this.input.length &&\n /[\\d.]/.test(this.input[this.pos])\n ) {\n num += this.input[this.pos++];\n }\n rawTokens.push({ type: 'NUMBER', value: num });\n continue;\n }\n\n // Words: functions, greek letters, or sequences of variable characters\n if (/[a-zA-Z]/.test(ch)) {\n let word = '';\n while (\n this.pos < this.input.length &&\n /[a-zA-Z]/.test(this.input[this.pos])\n ) {\n word += this.input[this.pos++];\n }\n const lower = word.toLowerCase();\n\n if (KNOWN_FUNCTIONS.has(lower)) {\n rawTokens.push({ type: 'FUNCTION', value: lower });\n } else if (GREEK_LETTERS.has(lower)) {\n rawTokens.push({ type: 'VARIABLE', value: lower });\n } else {\n // In school mathematics, \"2ab\" or \"xy\" means 2 * a * b or x * y\n for (const char of word) {\n rawTokens.push({ type: 'VARIABLE', value: char });\n }\n }\n continue;\n }\n\n // 'xx' or '·' or '*' as multiplication\n if (ch === 'x' && this.input[this.pos + 1] === 'x') {\n rawTokens.push({ type: 'OPERATOR', value: '*' });\n this.pos += 2;\n continue;\n }\n if (ch === '·' || ch === '*') {\n rawTokens.push({ type: 'OPERATOR', value: '*' });\n this.pos++;\n continue;\n }\n\n // Division: '/' or ':'\n if (ch === '/' || ch === ':') {\n rawTokens.push({ type: 'OPERATOR', value: ch });\n this.pos++;\n continue;\n }\n\n // Other operators\n if (ch === '+' || ch === '-' || ch === '^') {\n rawTokens.push({ type: 'OPERATOR', value: ch });\n this.pos++;\n continue;\n }\n\n // Parentheses & brackets\n if (ch === '(' || ch === '[') {\n rawTokens.push({ type: 'LPAREN', value: ch });\n this.pos++;\n continue;\n }\n if (ch === ')' || ch === ']') {\n rawTokens.push({ type: 'RPAREN', value: ch });\n this.pos++;\n continue;\n }\n\n if (ch === ',') {\n rawTokens.push({ type: 'COMMA', value: ch });\n this.pos++;\n continue;\n }\n\n // Fallback: skip unrecognized characters\n this.pos++;\n }\n\n // Insert implicit multiplication between operands where appropriate\n const tokens: Token[] = [];\n for (let i = 0; i < rawTokens.length; i++) {\n const cur = rawTokens[i];\n tokens.push(cur);\n\n if (i < rawTokens.length - 1) {\n const next = rawTokens[i + 1];\n const curEndsOperand =\n cur.type === 'NUMBER' ||\n cur.type === 'VARIABLE' ||\n cur.type === 'RPAREN';\n const nextStartsOperand =\n next.type === 'NUMBER' ||\n next.type === 'VARIABLE' ||\n next.type === 'FUNCTION' ||\n next.type === 'LPAREN';\n\n if (curEndsOperand && nextStartsOperand) {\n tokens.push({ type: 'OPERATOR', value: '*', implicit: true });\n }\n }\n }\n\n tokens.push({ type: 'EOF', value: '' });\n return tokens;\n }\n}\n\nlet nodeIdCounter = 1;\n\nexport function resetNodeIdCounter() {\n nodeIdCounter = 1;\n}\n\nclass PrattParser {\n private tokens: Token[];\n private pos = 0;\n\n constructor(tokens: Token[]) {\n this.tokens = tokens;\n }\n\n private current(): Token {\n return this.tokens[this.pos];\n }\n\n private consume(expectedType?: TokenType): Token {\n const token = this.current();\n if (expectedType && token.type !== expectedType) {\n throw new Error(\n `Erwartet ${expectedType}, aber erhalten: ${token.type} (${token.value})`\n );\n }\n this.pos++;\n return token;\n }\n\n parse(precedence = 0): TermNode {\n let left = this.parsePrefix();\n\n while (true) {\n const token = this.current();\n if (token.type !== 'OPERATOR') break;\n\n const opPrec = this.getInfixPrecedence(token.value);\n if (opPrec <= precedence) break;\n\n this.pos++;\n left = this.parseInfix(left, token, opPrec);\n }\n\n return left;\n }\n\n private parsePrefix(): TermNode {\n const token = this.current();\n\n if (token.type === 'NUMBER') {\n this.pos++;\n const val = parseFloat(token.value);\n return {\n id: `n${nodeIdCounter++}`,\n type: 'literal',\n value: val,\n raw: token.value,\n symbol: token.value,\n label: `Zahl ${token.value}`,\n mathJson: val,\n children: [],\n depth: 0,\n };\n }\n\n if (token.type === 'VARIABLE') {\n this.pos++;\n return {\n id: `n${nodeIdCounter++}`,\n type: 'variable',\n raw: token.value,\n symbol: token.value,\n label: `Variable ${token.value}`,\n mathJson: token.value,\n children: [],\n depth: 0,\n };\n }\n\n if (token.type === 'FUNCTION') {\n this.pos++;\n const fnName = FUNCTION_MAP[token.value] || token.value;\n let arg: TermNode;\n\n if (this.current().type === 'LPAREN') {\n this.consume('LPAREN');\n arg = this.parse(0);\n this.consume('RPAREN');\n } else {\n arg = this.parse(35); // higher than *, /, ^\n }\n\n const symbol = token.value === 'sqrt' ? '√' : token.value;\n\n return {\n id: `n${nodeIdCounter++}`,\n type: 'function',\n op: fnName,\n symbol,\n label: GERMAN_LABELS[fnName] || fnName,\n mathJson: [fnName, arg.mathJson],\n children: [arg],\n depth: 0,\n };\n }\n\n // Unary plus or minus\n if (\n token.type === 'OPERATOR' &&\n (token.value === '-' || token.value === '+')\n ) {\n this.pos++;\n const op = token.value;\n const operand = this.parse(30); // Prefix unary precedence\n\n if (op === '-') {\n return {\n id: `n${nodeIdCounter++}`,\n type: 'operator',\n isUnary: true,\n op: 'Negate',\n symbol: '−',\n label: GERMAN_LABELS['Negate'],\n mathJson: ['Negate', operand.mathJson],\n children: [operand],\n depth: 0,\n };\n } else {\n return operand;\n }\n }\n\n // Parentheses\n if (token.type === 'LPAREN') {\n this.pos++;\n const expr = this.parse(0);\n this.consume('RPAREN');\n expr.isParenthesized = true;\n return expr;\n }\n\n throw new Error(`Unerwartetes Zeichen: ${token.value || token.type}`);\n }\n\n private getInfixPrecedence(op: string): number {\n switch (op) {\n case '+':\n case '-':\n return 10;\n case '*':\n case '/':\n case ':':\n return 20;\n case '^':\n return 40;\n default:\n return 0;\n }\n }\n\n private parseInfix(\n left: TermNode,\n token: Token,\n precedence: number\n ): TermNode {\n const op = token.value;\n const isRightAssoc = op === '^';\n const nextPrec = isRightAssoc ? precedence - 1 : precedence;\n const right = this.parse(nextPrec);\n\n let opName = 'Add';\n if (op === '-') opName = 'Subtract';\n else if (op === '*') opName = 'Multiply';\n else if (op === '/' || op === ':') opName = 'Divide';\n else if (op === '^') opName = 'Power';\n\n const symbol = OPERATOR_SYMBOLS[opName] || op;\n const label = GERMAN_LABELS[opName] || opName;\n\n return {\n id: `n${nodeIdCounter++}`,\n type: 'operator',\n op: opName,\n symbol,\n label,\n implicit: token.implicit,\n mathJson: [opName, left.mathJson, right.mathJson],\n children: [left, right],\n depth: 0,\n };\n }\n}\n\n/**\n * Calculates depths bottom-up:\n * Leaves have depth 0.\n * A parent node has depth = max(children.depth) + 1.\n * Returns the maximum depth of the tree.\n */\nexport function calculateDepths(node: TermNode): number {\n if (node.children.length === 0) {\n node.depth = 0;\n return 0;\n }\n let maxChild = 0;\n for (const child of node.children) {\n maxChild = Math.max(maxChild, calculateDepths(child));\n }\n node.depth = maxChild + 1;\n return node.depth;\n}\n\n/**\n * Parses an AsciiMath string into a TermNode AST with Math-JSON support.\n */\nexport function parseAsciiMath(input: string): TermNode {\n resetNodeIdCounter();\n const tokenizer = new Tokenizer(input);\n const tokens = tokenizer.tokenize();\n const parser = new PrattParser(tokens);\n const root = parser.parse(0);\n calculateDepths(root);\n return root;\n}\n\nfunction getOperatorPrecedence(node: TermNode): number {\n if (node.type !== 'operator') return 999;\n if (node.isUnary) return 30;\n switch (node.op) {\n case 'Add':\n case 'Subtract':\n return 10;\n case 'Multiply':\n case 'Divide':\n return 20;\n case 'Power':\n return 40;\n default:\n return 0;\n }\n}\n\nfunction needsParens(\n parent: TermNode,\n child: TermNode,\n isLeft: boolean\n): boolean {\n if (child.isParenthesized) return true;\n if (child.type !== 'operator') return false;\n\n const pPrec = getOperatorPrecedence(parent);\n const cPrec = getOperatorPrecedence(child);\n\n if (cPrec < pPrec) return true;\n if (cPrec === pPrec) {\n // Subtraction and division are left-associative, right operand needs parentheses\n if (!isLeft && (parent.op === 'Subtract' || parent.op === 'Divide'))\n return true;\n }\n return false;\n}\n\n/**\n * Generates LaTeX from the AST with embedded `\\htmlId{...}` for KaTeX.\n */\nexport function astToAnnotatedLatex(node: TermNode): string {\n if (node.type === 'literal') {\n return `\\\\htmlId{${node.id}}{${node.raw}}`;\n }\n\n if (node.type === 'variable') {\n // Greek letters support (e.g. \\pi, \\alpha)\n const varName = GREEK_LETTERS.has(node.symbol)\n ? `\\\\${node.symbol}`\n : node.symbol;\n return `\\\\htmlId{${node.id}}{${varName}}`;\n }\n\n if (node.type === 'function') {\n const childLatex = astToAnnotatedLatex(node.children[0]);\n let fnSymbol: string;\n if (node.op === 'Sqrt' || node.symbol === '√' || node.symbol === 'sqrt') {\n fnSymbol = `\\\\sqrt{${childLatex}}`;\n } else if (node.symbol === 'abs') {\n fnSymbol = `\\\\left|${childLatex}\\\\right|`;\n } else {\n fnSymbol = `\\\\operatorname{${node.symbol}}\\\\left(${childLatex}\\\\right)`;\n }\n return `\\\\htmlId{${node.id}}{${fnSymbol}}`;\n }\n\n if (node.type === 'operator') {\n if (node.isUnary) {\n const childLatex = astToAnnotatedLatex(node.children[0]);\n return `\\\\htmlId{${node.id}}{-${childLatex}}`;\n }\n\n const left = node.children[0];\n const right = node.children[1];\n\n let leftLatex = astToAnnotatedLatex(left);\n let rightLatex = astToAnnotatedLatex(right);\n\n if (needsParens(node, left, true)) {\n leftLatex = `\\\\left(${leftLatex}\\\\right)`;\n }\n if (needsParens(node, right, false)) {\n rightLatex = `\\\\left(${rightLatex}\\\\right)`;\n }\n\n if (node.op === 'Add') {\n return `\\\\htmlId{${node.id}}{${leftLatex} \\\\htmlId{op_${node.id}}{+} ${rightLatex}}`;\n }\n if (node.op === 'Subtract') {\n return `\\\\htmlId{${node.id}}{${leftLatex} \\\\htmlId{op_${node.id}}{-} ${rightLatex}}`;\n }\n if (node.op === 'Multiply') {\n // Implicit multiplication styling (e.g. 2a, 4ac, (2+a)(3-b))\n const isImplicit =\n node.implicit ||\n (left.type === 'literal' &&\n (right.type === 'variable' || right.type === 'function')) ||\n (left.type === 'variable' && right.type === 'variable') ||\n right.isParenthesized;\n const opSymbol = isImplicit\n ? ''\n : ' \\\\htmlId{op_' + node.id + '}{\\\\cdot} ';\n return `\\\\htmlId{${node.id}}{${leftLatex}${opSymbol}${rightLatex}}`;\n }\n if (node.op === 'Divide') {\n return `\\\\htmlId{${node.id}}{\\\\frac{${leftLatex}}{${rightLatex}}}`;\n }\n if (node.op === 'Power') {\n return `\\\\htmlId{${node.id}}{${leftLatex}^{${rightLatex}}}`;\n }\n }\n\n return '';\n}\n"]}