Skip to content

Commit ce20b76

Browse files
committed
fix #130
1 parent bf30b7e commit ce20b76

7 files changed

Lines changed: 206 additions & 50 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
### Bug Fixes
44

5+
- **([#130](https://github.com/cortex-js/compute-engine/issues/130)) Prefix/Postfix
6+
Operator LaTeX Serialization**: Fixed incorrect LaTeX output for prefix operators
7+
(like `Negate`) and postfix operators (like `Factorial`) when applied to
8+
expressions with lower precedence. Previously, `Negate(Add(a, b))` incorrectly
9+
serialized as `-a+b` instead of `-(a+b)`, causing round-trip failures where
10+
parsing the output produced a mathematically different expression. Similarly,
11+
`Factorial(Add(a, b))` now correctly serializes as `(a+b)!` instead of `a+b!`.
12+
The fix ensures operands are wrapped in parentheses when their precedence is
13+
lower than the operator's precedence.
14+
515
- **Rules Cache Isolation**: Fixed rules cache building failing with "Invalid
616
rule" errors when user expressions had previously polluted the global scope.
717
For example, parsing `x(y+z)` would add `x` as a symbol with function type to

src/compute-engine/latex-syntax/dictionary/definitions.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -486,13 +486,15 @@ function makeSerializeHandler(
486486
// We have a LaTeX version of the symbol
487487
//
488488
if (latex) {
489+
const prec = entry['precedence'] ?? 10000;
490+
489491
if (kind === 'postfix')
490492
return (serializer, expr) =>
491-
joinLatex([serializer.serialize(operand(expr, 1)), latex!]);
493+
joinLatex([serializer.wrap(operand(expr, 1), prec), latex!]);
492494

493495
if (kind === 'prefix')
494496
return (serializer, expr) =>
495-
joinLatex([latex!, serializer.serialize(operand(expr, 1))]);
497+
joinLatex([latex!, serializer.wrap(operand(expr, 1), prec)]);
496498

497499
if (kind === 'infix') {
498500
return (serializer, expr) => {
@@ -523,26 +525,28 @@ function makeSerializeHandler(
523525
// We do not have a LaTeX version of the symbol. Use a string symbol
524526
//
525527
const id = idTrigger ?? entry.name ?? 'unknown';
528+
const prec = entry['precedence'] ?? 10000;
529+
526530
if (kind === 'postfix')
527531
return (serializer, expr) =>
528532
joinLatex([
529-
serializer.serialize(operand(expr, 1)),
533+
serializer.wrap(operand(expr, 1), prec),
530534
serializer.serializeSymbol(id),
531535
]);
532536

533537
if (kind === 'prefix')
534538
return (serializer, expr) =>
535539
joinLatex([
536540
serializer.serializeSymbol(id),
537-
serializer.serialize(operand(expr, 1)),
541+
serializer.wrap(operand(expr, 1), prec),
538542
]);
539543

540544
if (kind === 'infix')
541545
return (serializer, expr) =>
542546
joinLatex([
543-
serializer.serialize(operand(expr, 1)),
547+
serializer.wrap(operand(expr, 1), prec + 1),
544548
serializer.serializeSymbol(id),
545-
serializer.serialize(operand(expr, 2)),
549+
serializer.wrap(operand(expr, 2), prec + 1),
546550
]);
547551

548552
// Function, symbol or expression. Depends on the actual shape of the

0 commit comments

Comments
 (0)