math-core 0.6.4__tar.gz → 0.7.0__tar.gz

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 (54) hide show
  1. {math_core-0.6.4 → math_core-0.7.0}/Cargo.lock +51 -45
  2. {math_core-0.6.4 → math_core-0.7.0}/Cargo.toml +1 -1
  3. {math_core-0.6.4 → math_core-0.7.0}/PKG-INFO +20 -19
  4. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/Cargo.toml +3 -3
  5. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/README.md +7 -0
  6. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/examples/browser_test.rs +3 -1
  7. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/examples/equations.rs +4 -2
  8. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/examples/minijinja.rs +2 -2
  9. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/character_class.rs +2 -2
  10. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/commands.rs +398 -39
  11. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/environments.rs +38 -18
  12. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/error.rs +56 -77
  13. math_core-0.7.0/crates/math-core/src/global_state.rs +10 -0
  14. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/lexer.rs +50 -18
  15. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/lib.rs +215 -88
  16. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/parser.rs +350 -316
  17. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/predefined.rs +93 -0
  18. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/specifications.rs +68 -30
  19. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/text_parser.rs +13 -5
  20. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/token.rs +162 -11
  21. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/token_queue.rs +17 -17
  22. math_core-0.7.0/crates/math-core/tests/configuration_test.rs +41 -0
  23. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/tests/conversion_test.rs +93 -10
  24. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/tests/custom_cmd_test.rs +8 -8
  25. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/tests/error_test.rs +10 -9
  26. math_core-0.7.0/crates/math-core/tests/substitution_test.rs +45 -0
  27. math_core-0.7.0/crates/math-core/tests/warnings_test.rs +36 -0
  28. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/tests/wiki_test.rs +15 -12
  29. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core-python/Cargo.toml +1 -1
  30. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core-python/README.md +19 -18
  31. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core-python/src/lib.rs +25 -10
  32. {math_core-0.6.4 → math_core-0.7.0}/crates/mathml-renderer/Cargo.toml +2 -0
  33. {math_core-0.6.4 → math_core-0.7.0}/crates/mathml-renderer/src/arena.rs +4 -7
  34. {math_core-0.6.4 → math_core-0.7.0}/crates/mathml-renderer/src/ast.rs +513 -303
  35. {math_core-0.6.4 → math_core-0.7.0}/crates/mathml-renderer/src/attribute.rs +26 -3
  36. math_core-0.7.0/crates/mathml-renderer/src/escaping.rs +47 -0
  37. math_core-0.7.0/crates/mathml-renderer/src/fmt.rs +17 -0
  38. {math_core-0.6.4 → math_core-0.7.0}/crates/mathml-renderer/src/length.rs +4 -0
  39. {math_core-0.6.4 → math_core-0.7.0}/crates/mathml-renderer/src/lib.rs +10 -4
  40. {math_core-0.6.4 → math_core-0.7.0}/crates/mathml-renderer/src/super_char.rs +42 -2
  41. {math_core-0.6.4 → math_core-0.7.0}/crates/mathml-renderer/src/symbol.rs +406 -106
  42. {math_core-0.6.4 → math_core-0.7.0}/crates/mathml-renderer/src/table.rs +89 -24
  43. {math_core-0.6.4 → math_core-0.7.0}/python/math_core/_math_core_rust.pyi +15 -15
  44. math_core-0.6.4/crates/mathml-renderer/src/fmt.rs +0 -10
  45. {math_core-0.6.4 → math_core-0.7.0}/LICENSE +0 -0
  46. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/atof.rs +0 -0
  47. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/color_defs.rs +0 -0
  48. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/html_utils.rs +0 -0
  49. {math_core-0.6.4 → math_core-0.7.0}/crates/math-core/src/split_on_ascii.rs +0 -0
  50. {math_core-0.6.4 → math_core-0.7.0}/crates/mathml-renderer/README.md +0 -0
  51. {math_core-0.6.4 → math_core-0.7.0}/crates/mathml-renderer/src/itoa.rs +0 -0
  52. {math_core-0.6.4 → math_core-0.7.0}/pyproject.toml +0 -0
  53. {math_core-0.6.4 → math_core-0.7.0}/python/math_core/__init__.py +0 -0
  54. {math_core-0.6.4 → math_core-0.7.0}/python/math_core/py.typed +0 -0
@@ -283,9 +283,9 @@ dependencies = [
283
283
 
284
284
  [[package]]
285
285
  name = "insta"
286
- version = "1.47.2"
286
+ version = "1.48.0"
287
287
  source = "registry+https://github.com/rust-lang/crates.io-index"
288
- checksum = "7b4a6248eb93a4401ed2f37dfe8ea592d3cf05b7cf4f8efa867b6895af7e094e"
288
+ checksum = "86f0f8fee8c926415c58d6ae43a08523a26faccb2323f5e6b644fe7dd4ef6b82"
289
289
  dependencies = [
290
290
  "console",
291
291
  "once_cell",
@@ -309,13 +309,12 @@ checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
309
309
 
310
310
  [[package]]
311
311
  name = "js-sys"
312
- version = "0.3.99"
312
+ version = "0.3.103"
313
313
  source = "registry+https://github.com/rust-lang/crates.io-index"
314
- checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11"
314
+ checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
315
315
  dependencies = [
316
316
  "cfg-if",
317
317
  "futures-util",
318
- "once_cell",
319
318
  "wasm-bindgen",
320
319
  ]
321
320
 
@@ -358,7 +357,7 @@ dependencies = [
358
357
 
359
358
  [[package]]
360
359
  name = "math-core"
361
- version = "0.6.4"
360
+ version = "0.7.0"
362
361
  dependencies = [
363
362
  "ariadne",
364
363
  "insta",
@@ -378,7 +377,7 @@ dependencies = [
378
377
 
379
378
  [[package]]
380
379
  name = "math-core-cli"
381
- version = "0.6.4"
380
+ version = "0.7.0"
382
381
  dependencies = [
383
382
  "ariadne",
384
383
  "clap",
@@ -391,7 +390,7 @@ dependencies = [
391
390
 
392
391
  [[package]]
393
392
  name = "math-core-python"
394
- version = "0.6.4"
393
+ version = "0.7.0"
395
394
  dependencies = [
396
395
  "ariadne",
397
396
  "math-core",
@@ -401,10 +400,12 @@ dependencies = [
401
400
 
402
401
  [[package]]
403
402
  name = "math-core-renderer-internal"
404
- version = "0.6.4"
403
+ version = "0.7.0"
405
404
  dependencies = [
406
405
  "bitflags",
407
406
  "dtoa",
407
+ "percent-encoding",
408
+ "rustc-hash",
408
409
  "serde",
409
410
  "stable-arena",
410
411
  "static_assertions",
@@ -414,7 +415,7 @@ dependencies = [
414
415
 
415
416
  [[package]]
416
417
  name = "math-core-wasm"
417
- version = "0.6.4"
418
+ version = "0.7.0"
418
419
  dependencies = [
419
420
  "ariadne",
420
421
  "js-sys",
@@ -427,9 +428,9 @@ dependencies = [
427
428
 
428
429
  [[package]]
429
430
  name = "memchr"
430
- version = "2.8.1"
431
+ version = "2.8.2"
431
432
  source = "registry+https://github.com/rust-lang/crates.io-index"
432
- checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8"
433
+ checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
433
434
 
434
435
  [[package]]
435
436
  name = "memo-map"
@@ -449,9 +450,9 @@ dependencies = [
449
450
 
450
451
  [[package]]
451
452
  name = "minijinja"
452
- version = "2.20.0"
453
+ version = "2.21.0"
453
454
  source = "registry+https://github.com/rust-lang/crates.io-index"
454
- checksum = "2929e494b2280e1e18959bb2e121da03347ae896896fdfaceaab43c88a02803f"
455
+ checksum = "cb3d648e68cea56d9858d535ee28f9538404e2dd8cb08ed0bd05dca379477f39"
455
456
  dependencies = [
456
457
  "memo-map",
457
458
  "serde",
@@ -494,6 +495,12 @@ version = "11.1.5"
494
495
  source = "registry+https://github.com/rust-lang/crates.io-index"
495
496
  checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e"
496
497
 
498
+ [[package]]
499
+ name = "percent-encoding"
500
+ version = "2.3.2"
501
+ source = "registry+https://github.com/rust-lang/crates.io-index"
502
+ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
503
+
497
504
  [[package]]
498
505
  name = "phf"
499
506
  version = "0.13.1"
@@ -566,9 +573,9 @@ dependencies = [
566
573
 
567
574
  [[package]]
568
575
  name = "pyo3"
569
- version = "0.28.3"
576
+ version = "0.29.0"
570
577
  source = "registry+https://github.com/rust-lang/crates.io-index"
571
- checksum = "91fd8e38a3b50ed1167fb981cd6fd60147e091784c427b8f7183a7ee32c31c12"
578
+ checksum = "cd274650b21d4bfc26a0a47587962c1edb425f69287324355cd040c3ea66071c"
572
579
  dependencies = [
573
580
  "libc",
574
581
  "once_cell",
@@ -580,18 +587,18 @@ dependencies = [
580
587
 
581
588
  [[package]]
582
589
  name = "pyo3-build-config"
583
- version = "0.28.3"
590
+ version = "0.29.0"
584
591
  source = "registry+https://github.com/rust-lang/crates.io-index"
585
- checksum = "e368e7ddfdeb98c9bca7f8383be1648fd84ab466bf2bc015e94008db6d35611e"
592
+ checksum = "c5e2a7d2f0d013342f295c048ad19237add5154a55b1c5a254c0ec93d4109078"
586
593
  dependencies = [
587
594
  "target-lexicon",
588
595
  ]
589
596
 
590
597
  [[package]]
591
598
  name = "pyo3-ffi"
592
- version = "0.28.3"
599
+ version = "0.29.0"
593
600
  source = "registry+https://github.com/rust-lang/crates.io-index"
594
- checksum = "7f29e10af80b1f7ccaf7f69eace800a03ecd13e883acfacc1e5d0988605f651e"
601
+ checksum = "ca85c467da1bbc8d866eea5deff9cf29ea5f7785054a17da36e65bda9c05845b"
595
602
  dependencies = [
596
603
  "libc",
597
604
  "pyo3-build-config",
@@ -599,9 +606,9 @@ dependencies = [
599
606
 
600
607
  [[package]]
601
608
  name = "pyo3-macros"
602
- version = "0.28.3"
609
+ version = "0.29.0"
603
610
  source = "registry+https://github.com/rust-lang/crates.io-index"
604
- checksum = "df6e520eff47c45997d2fc7dd8214b25dd1310918bbb2642156ef66a67f29813"
611
+ checksum = "9ac53762fd065daa3194dd09337a38bd793a188100fd1a9304c4ab312d901771"
605
612
  dependencies = [
606
613
  "proc-macro2",
607
614
  "pyo3-macros-backend",
@@ -611,13 +618,12 @@ dependencies = [
611
618
 
612
619
  [[package]]
613
620
  name = "pyo3-macros-backend"
614
- version = "0.28.3"
621
+ version = "0.29.0"
615
622
  source = "registry+https://github.com/rust-lang/crates.io-index"
616
- checksum = "c4cdc218d835738f81c2338f822078af45b4afdf8b2e33cbb5916f108b813acb"
623
+ checksum = "4ca3a1557399783172dc5bf39cfca835157732532cba56b71d2292161e53b362"
617
624
  dependencies = [
618
625
  "heck",
619
626
  "proc-macro2",
620
- "pyo3-build-config",
621
627
  "quote",
622
628
  "syn",
623
629
  ]
@@ -639,9 +645,9 @@ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
639
645
 
640
646
  [[package]]
641
647
  name = "regex"
642
- version = "1.12.3"
648
+ version = "1.12.4"
643
649
  source = "registry+https://github.com/rust-lang/crates.io-index"
644
- checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
650
+ checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba"
645
651
  dependencies = [
646
652
  "aho-corasick",
647
653
  "memchr",
@@ -662,9 +668,9 @@ dependencies = [
662
668
 
663
669
  [[package]]
664
670
  name = "regex-syntax"
665
- version = "0.8.5"
671
+ version = "0.8.11"
666
672
  source = "registry+https://github.com/rust-lang/crates.io-index"
667
- checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
673
+ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
668
674
 
669
675
  [[package]]
670
676
  name = "ron"
@@ -964,9 +970,9 @@ dependencies = [
964
970
 
965
971
  [[package]]
966
972
  name = "wasm-bindgen"
967
- version = "0.2.122"
973
+ version = "0.2.126"
968
974
  source = "registry+https://github.com/rust-lang/crates.io-index"
969
- checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409"
975
+ checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
970
976
  dependencies = [
971
977
  "cfg-if",
972
978
  "once_cell",
@@ -977,9 +983,9 @@ dependencies = [
977
983
 
978
984
  [[package]]
979
985
  name = "wasm-bindgen-futures"
980
- version = "0.4.72"
986
+ version = "0.4.76"
981
987
  source = "registry+https://github.com/rust-lang/crates.io-index"
982
- checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f"
988
+ checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d"
983
989
  dependencies = [
984
990
  "js-sys",
985
991
  "wasm-bindgen",
@@ -987,9 +993,9 @@ dependencies = [
987
993
 
988
994
  [[package]]
989
995
  name = "wasm-bindgen-macro"
990
- version = "0.2.122"
996
+ version = "0.2.126"
991
997
  source = "registry+https://github.com/rust-lang/crates.io-index"
992
- checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6"
998
+ checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
993
999
  dependencies = [
994
1000
  "quote",
995
1001
  "wasm-bindgen-macro-support",
@@ -997,9 +1003,9 @@ dependencies = [
997
1003
 
998
1004
  [[package]]
999
1005
  name = "wasm-bindgen-macro-support"
1000
- version = "0.2.122"
1006
+ version = "0.2.126"
1001
1007
  source = "registry+https://github.com/rust-lang/crates.io-index"
1002
- checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e"
1008
+ checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
1003
1009
  dependencies = [
1004
1010
  "bumpalo",
1005
1011
  "proc-macro2",
@@ -1010,18 +1016,18 @@ dependencies = [
1010
1016
 
1011
1017
  [[package]]
1012
1018
  name = "wasm-bindgen-shared"
1013
- version = "0.2.122"
1019
+ version = "0.2.126"
1014
1020
  source = "registry+https://github.com/rust-lang/crates.io-index"
1015
- checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437"
1021
+ checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
1016
1022
  dependencies = [
1017
1023
  "unicode-ident",
1018
1024
  ]
1019
1025
 
1020
1026
  [[package]]
1021
1027
  name = "wasm-bindgen-test"
1022
- version = "0.3.72"
1028
+ version = "0.3.76"
1023
1029
  source = "registry+https://github.com/rust-lang/crates.io-index"
1024
- checksum = "74fde991ccdc895cb7fbaa14b137d62af74d9011be67b71c694bfc40edd3119c"
1030
+ checksum = "2a0d555ca874445df8d314f94f5c948a4e74e5418f332c89f660a3d8310a96f4"
1025
1031
  dependencies = [
1026
1032
  "async-trait",
1027
1033
  "cast",
@@ -1041,9 +1047,9 @@ dependencies = [
1041
1047
 
1042
1048
  [[package]]
1043
1049
  name = "wasm-bindgen-test-macro"
1044
- version = "0.3.72"
1050
+ version = "0.3.76"
1045
1051
  source = "registry+https://github.com/rust-lang/crates.io-index"
1046
- checksum = "e925354648d2a4d1bf205412e36d520a800280622eef4719678d268e5d40e978"
1052
+ checksum = "94eb68555b95bcea5e8cf4abe280b529049479fa995bfc23734af96a6aedc120"
1047
1053
  dependencies = [
1048
1054
  "proc-macro2",
1049
1055
  "quote",
@@ -1052,9 +1058,9 @@ dependencies = [
1052
1058
 
1053
1059
  [[package]]
1054
1060
  name = "wasm-bindgen-test-shared"
1055
- version = "0.2.122"
1061
+ version = "0.2.126"
1056
1062
  source = "registry+https://github.com/rust-lang/crates.io-index"
1057
- checksum = "684365b586a9a6256c1cc3544eee8680de48d6041142f581776ec7b139622ae9"
1063
+ checksum = "c31d56021e873866c968588ed85ccdf56db5c426e44afdb4618c39895104b920"
1058
1064
 
1059
1065
  [[package]]
1060
1066
  name = "winapi-util"
@@ -7,7 +7,7 @@ resolver = "2"
7
7
  edition = "2024"
8
8
  rust-version = "1.91"
9
9
  license = "MIT"
10
- version = "0.6.4"
10
+ version = "0.7.0"
11
11
  repository = "https://github.com/tmke8/math-core"
12
12
 
13
13
  [workspace.dependencies]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: math-core
3
- Version: 0.6.4
3
+ Version: 0.7.0
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -46,12 +46,12 @@ from math_core import LatexToMathML
46
46
  converter = LatexToMathML()
47
47
 
48
48
  # Convert inline math
49
- mathml = converter.convert_with_local_counter("x^2 + y^2 = z^2", displaystyle=False)
49
+ mathml = converter.convert_with_local_state("x^2 + y^2 = z^2", displaystyle=False)
50
50
  print(mathml)
51
51
  # Output: <math><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><msup><mi>y</mi><mn>2</mn></msup><mo>=</mo><msup><mi>z</mi><mn>2</mn></msup></math>
52
52
 
53
53
  # Convert display math
54
- mathml = converter.convert_with_local_counter(r"\frac{1}{2}", displaystyle=True)
54
+ mathml = converter.convert_with_local_state(r"\frac{1}{2}", displaystyle=True)
55
55
  print(mathml)
56
56
  # Output: <math display="block"><mfrac><mn>1</mn><mn>2</mn></mfrac></math>
57
57
  ```
@@ -68,7 +68,7 @@ converter = LatexToMathML(pretty_print="always")
68
68
 
69
69
  # Convert LaTeX to MathML
70
70
  try:
71
- mathml = converter.convert_with_local_counter(r"\sqrt{x^2 + 1}", displaystyle=False)
71
+ mathml = converter.convert_with_local_state(r"\sqrt{x^2 + 1}", displaystyle=False)
72
72
  print(mathml)
73
73
  except LatexError as e:
74
74
  print(f"Conversion error: {e}")
@@ -87,10 +87,10 @@ macros = {
87
87
  }
88
88
 
89
89
  converter = LatexToMathML(macros=macros)
90
- mathml = converter.convert_with_local_counter(r"\d x", displaystyle=False)
90
+ mathml = converter.convert_with_local_state(r"\d x", displaystyle=False)
91
91
  ```
92
92
 
93
- ### Numbered Equations with Global Counter
93
+ ### Numbered Equations with Global State
94
94
 
95
95
  For documents with multiple numbered equations:
96
96
 
@@ -98,22 +98,22 @@ For documents with multiple numbered equations:
98
98
  converter = LatexToMathML()
99
99
 
100
100
  # First equation gets (1)
101
- eq1 = converter.convert_with_global_counter(
101
+ eq1 = converter.convert_with_global_state(
102
102
  r"\begin{align}E = mc^2\end{align}",
103
103
  displaystyle=True
104
104
  )
105
105
 
106
106
  # Second equation gets (2)
107
- eq2 = converter.convert_with_global_counter(
107
+ eq2 = converter.convert_with_global_state(
108
108
  r"\begin{align}F = ma\end{align}",
109
109
  displaystyle=True
110
110
  )
111
111
 
112
112
  # Reset counter when starting a new chapter/section
113
- converter.reset_global_counter()
113
+ converter.reset_global_state()
114
114
 
115
115
  # This equation gets (1) again
116
- eq3 = converter.convert_with_global_counter(
116
+ eq3 = converter.convert_with_global_state(
117
117
  r"\begin{align}p = mv\end{align}",
118
118
  displaystyle=True
119
119
  )
@@ -127,12 +127,12 @@ Use local counters when equation numbers should restart within each conversion:
127
127
  converter = LatexToMathML()
128
128
 
129
129
  # Each conversion has independent numbering
130
- doc1 = converter.convert_with_local_counter(
130
+ doc1 = converter.convert_with_local_state(
131
131
  r"\begin{align}a &= b\\c &= d\end{align}",
132
132
  displaystyle=True
133
133
  ) # Contains (1) and (2)
134
134
 
135
- doc2 = converter.convert_with_local_counter(
135
+ doc2 = converter.convert_with_local_state(
136
136
  r"\begin{align}x &= y\\z &= w\end{align}",
137
137
  displaystyle=True
138
138
  ) # Also contains (1) and (2)
@@ -152,11 +152,12 @@ The main converter class.
152
152
  - `ignore_unknown_commands` (`bool`, optional): A boolean indicating whether to ignore unknown LaTeX commands. If `True`, unknown commands be rendered as red text and the conversion will continue. Default: `False`.
153
153
  - `annotation` (`bool`, optional): A boolean indicating whether to include the original LaTeX as an annotation in the MathML output. Default: `False`.
154
154
  - `fancy_error` (`bool`, optional): A boolean indicating whether to render errors as rich Ariadne diagnostic reports. If `True` (the default), the `LatexError` message contains a formatted diagnostic with source spans. Set to `False` to use compact plain-text messages instead.
155
+ - `unicode_substitution`: A string indicating whether to substitute certain character combinations with a single Unicode symbol.
155
156
 
156
157
  **Methods:**
157
- - `convert_with_global_counter(latex: str, displaystyle: bool) -> str | LatexError`: Convert LaTeX to MathML using a global equation counter.
158
- - `convert_with_local_counter(latex: str, displaystyle: bool) -> str | LatexError`: Convert LaTeX to MathML using a local equation counter.
159
- - `reset_global_counter() -> None`: Reset the global equation counter to zero.
158
+ - `convert_with_global_state(latex: str, displaystyle: bool) -> str`: Convert LaTeX to MathML using global state. May raise `LatexError`.
159
+ - `convert_with_local_state(latex: str, displaystyle: bool) -> str`: Convert LaTeX to MathML using local state. May raise `LatexError`.
160
+ - `reset_global_state() -> None`: Reset the global state (e.g., set the equation counter to zero).
160
161
 
161
162
  ### LatexError
162
163
 
@@ -167,7 +168,7 @@ from math_core import LatexToMathML, LatexError
167
168
 
168
169
  converter = LatexToMathML()
169
170
  try:
170
- result = converter.convert_with_local_counter(r"\invalid")
171
+ result = converter.convert_with_local_state(r"\invalid")
171
172
  except LatexError as e
172
173
  print(f"Conversion failed: {e}")
173
174
  ```
@@ -188,14 +189,14 @@ def process_math(content):
188
189
  # Replace display math $$...$$; do this first to avoid conflicts with inline math delimiters
189
190
  content = re.sub(
190
191
  r"\$\$([^\$]+)\$\$",
191
- lambda m: converter.convert_with_local_counter(m.group(1), displaystyle=True),
192
+ lambda m: converter.convert_with_local_state(m.group(1), displaystyle=True),
192
193
  content,
193
194
  )
194
195
 
195
196
  # Replace inline math $...$
196
197
  content = re.sub(
197
198
  r"\$([^\$]+)\$",
198
- lambda m: converter.convert_with_local_counter(m.group(1), displaystyle=False),
199
+ lambda m: converter.convert_with_local_state(m.group(1), displaystyle=False),
199
200
  content,
200
201
  )
201
202
 
@@ -216,7 +217,7 @@ converter = LatexToMathML()
216
217
  @app.route("/equation/<latex>")
217
218
  def render_equation(latex):
218
219
  try:
219
- mathml = converter.convert_with_local_counter(latex, displaystyle=True)
220
+ mathml = converter.convert_with_local_state(latex, displaystyle=True)
220
221
  return render_template_string(
221
222
  "<html><body>{{ mathml|safe }}</body></html>", mathml=mathml
222
223
  )
@@ -19,7 +19,7 @@ categories = ["science"]
19
19
  exclude = ["/src/snapshots", "/tests/snapshots"]
20
20
 
21
21
  [dependencies]
22
- mathml-renderer = { path = "../mathml-renderer", package = "math-core-renderer-internal", version = "0.6.4" }
22
+ mathml-renderer = { path = "../mathml-renderer", package = "math-core-renderer-internal", version = "0.7.0" }
23
23
  serde = { workspace = true, optional = true }
24
24
  serde-tuple-vec-map = { version = "1.0.1", optional = true }
25
25
  phf = { version = "0.13.1", features = ["macros"] }
@@ -32,13 +32,13 @@ ariadne = { workspace = true, optional = true }
32
32
 
33
33
  [dev-dependencies]
34
34
  math-core = { path = ".", features = ["serde", "ariadne"] }
35
- mathml-renderer = { path = "../mathml-renderer", package = "math-core-renderer-internal", version = "0.6.4", features = ["serde"] }
35
+ mathml-renderer = { path = "../mathml-renderer", package = "math-core-renderer-internal", version = "0.7.0", features = ["serde"] }
36
36
  insta = { version = "1.47.2", features = ["default", "ron"] }
37
37
  regex = "1.12.3"
38
38
  minijinja = "2.20.0"
39
39
 
40
40
  [features]
41
- serde = ["dep:serde", "dep:serde-tuple-vec-map"]
41
+ serde = ["dep:serde", "dep:serde-tuple-vec-map", "mathml-renderer/serde"]
42
42
  ariadne = ["dep:ariadne"]
43
43
 
44
44
  [lints]
@@ -60,6 +60,13 @@ You can download precompiled binaries from the GitHub Release page. Alternativel
60
60
  cargo install math-core-cli
61
61
  ```
62
62
 
63
+ Basic usage is this:
64
+
65
+ ```sh
66
+ mathcore --write article.html
67
+ ```
68
+ where `--write` indicates that the input file should be overwritten.
69
+
63
70
  You can see an explanation of the CLI interface with
64
71
  ```sh
65
72
  mathcore --help
@@ -9,6 +9,7 @@ fn main() {
9
9
  // Chrome bugs:
10
10
  r#"\widehat x, \widehat{xxxx}"#,
11
11
  r#"\widetilde x, \widetilde{xxxx}"#,
12
+ r#"\utilde x, \utilde{xxxx}"#,
12
13
  r#"\widecheck x, \widecheck{xxxx}"#,
13
14
  r#"\overline x, \overline{xxxx}"#,
14
15
  r#"\underline x, \underline{xxxx}"#,
@@ -33,8 +34,9 @@ fn main() {
33
34
  "<code>{}</code><p>\n{}\n</p>",
34
35
  input,
35
36
  converter
36
- .convert_with_local_counter(input, MathDisplay::Block)
37
+ .convert_with_local_state(input, MathDisplay::Block)
37
38
  .expect(input)
39
+ .mathml
38
40
  )
39
41
  })
40
42
  .collect::<Vec<_>>()
@@ -1,4 +1,4 @@
1
- use math_core::{LatexToMathML, MathCoreConfig, MathDisplay, PrettyPrint};
1
+ use math_core::{LatexToMathML, MathCoreConfig, MathDisplay, PrettyPrint, UnicodeSubstitution};
2
2
 
3
3
  fn main() {
4
4
  let inputs = vec![
@@ -65,6 +65,7 @@ fn main() {
65
65
 
66
66
  let converter = LatexToMathML::new(MathCoreConfig {
67
67
  pretty_print: PrettyPrint::Always,
68
+ unicode_substitution: UnicodeSubstitution::Never,
68
69
  ..Default::default()
69
70
  })
70
71
  .unwrap();
@@ -75,8 +76,9 @@ fn main() {
75
76
  "<code>{}</code><p>\n{}\n</p>",
76
77
  input,
77
78
  converter
78
- .convert_with_local_counter(input, MathDisplay::Block)
79
+ .convert_with_local_state(input, MathDisplay::Block)
79
80
  .expect(input)
81
+ .mathml
80
82
  )
81
83
  })
82
84
  .collect::<Vec<_>>()
@@ -49,8 +49,8 @@ fn mathml(state: &State, latex: &str) -> Option<Value> {
49
49
  .map_err(|_| eprintln!("[error] couldn't get lock for converter"))
50
50
  .ok()
51
51
  .and_then(|mut c| {
52
- c.convert_with_global_counter(latex, MathDisplay::Block)
53
- .map(Value::from)
52
+ c.convert_with_global_state(latex, MathDisplay::Block)
53
+ .map(|r| Value::from(r.mathml))
54
54
  .ok()
55
55
  })
56
56
  }
@@ -1,7 +1,7 @@
1
1
  use mathml_renderer::{
2
2
  arena::Arena,
3
- ast::{Node, RowAttrs},
4
- attribute::{MathSpacing, OpAttrs, Style, TextTransform},
3
+ ast::Node,
4
+ attribute::{MathSpacing, OpAttrs, RowAttrs, Style, TextTransform},
5
5
  symbol::{self, MathMLOperator, OrdCategory, OrdLike, Rel, RelCategory},
6
6
  };
7
7