ModeMath 0.9.0
See the version list below for details.
dotnet add package ModeMath --version 0.9.0
NuGet\Install-Package ModeMath -Version 0.9.0
<PackageReference Include="ModeMath" Version="0.9.0" />
<PackageVersion Include="ModeMath" Version="0.9.0" />
<PackageReference Include="ModeMath" />
paket add ModeMath --version 0.9.0
#r "nuget: ModeMath, 0.9.0"
#:package ModeMath@0.9.0
#addin nuget:?package=ModeMath&version=0.9.0
#tool nuget:?package=ModeMath&version=0.9.0
ModeMath
Mathematical formula display and editing for .NET, rendered with SkiaSharp.
A formula is an MA: a tree of what is written, not of what it means. Layout places one at a font size, and Painter draws what was placed onto an SKCanvas.
open ModeMath
let formula =
match Latex.Read @"\frac{-b \pm \sqrt{b^2 - 4ac}}{2a}" with
| Ok ma -> ma
| Error error -> failwith error.Message
let placed = (Layout 24f<px>).Of formula
use painter = Painter.Embedded()
painter.Draw(placed, canvas, 0f<px>, placed.Ascent, paint)
examples/ shows what renders, a picture of each formula against its name and size. The formulas themselves are in tools/RenderExamples/Examples.fs.
Editing
Editor holds a formula with a cursor in it, and the states it stood at before. Press answers whether the key was wanted, leaving a caller free to pass on the ones it turns down, and Undo and Redo step through the edits, a run of characters going in one go.
let editor = Editor(Layout 24f<px>, MA.Empty)
for key in [ MathKey.Character 'x'; MathKey.Superscript; MathKey.Character '2' ] do
editor.Press key |> ignore
editor.Click(x, y)
let bounds = editor.State.Bounds
painter.Draw(editor.State.Cursor, canvas, -bounds.X, bounds.Y + bounds.Thickness, paint)
A formula with a cursor in it is placed by its Bounds rather than by what it draws, since the cursor stands where no atom does: at either end of the line, and above a numerator or below a denominator. They hold both, and hold still as the cursor moves through the formula.
EditorState is the value underneath: every key answers with a new state rather than changing this one, so a caller that would rather keep its own history holds whichever states it likes.
An opening bracket is drawn faint until its closing one is typed, a run of letters spelling a name becomes what it names — a function, the radical sqrt opens, or the mark degree gives — and a formula can be built from MA directly instead.
LaTeX
Latex.Read takes a math-mode string and Latex.Write gives one back, every argument in braces. What is not understood is refused with the position it stands at, rather than guessed at, and a character the font cannot draw is refused there too, so a formula that was read always lays out. One built from MA in code can hold a character the font has no glyph for, and MA.Undrawable is the characters it would fail on.
\color and \textcolor name their colours from a Palette, which a caller may replace to give a name a colour of its own.
let palette = Palette.Default.With("green", Color.FromArgb(255, 130, 212, 20))
let formula = Latex.Read(@"\color{green}{x}", palette)
Fonts
Latin Modern Math, cut down to the glyphs ModeMath draws, and AMS Capital Blackboard Bold are carried inside the assembly along with the licences they are redistributed under. fonts/README.md says where each came from and how the metrics beside them are generated.
Acknowledgements
ModeMath is inspired by CSharpMath. Most of the formulas in examples/ are taken from its rendering tests, and the typesetting is checked against those. ModeMath has no plan to work with any text outside of math mode, so for a LaTeX renderer that includes both text and maths you should use CSharpMath.
Licence
MIT, in LICENSE. The two fonts keep their own: the GUST Font Licence and the SIL Open Font Licence, both carried in fonts/.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- FSharp.Core (>= 10.1.300)
- SkiaSharp (>= 3.119.4)
- Summatic.FSUtils (>= 0.3.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.16.0 | 52 | 9/9/2026 |
| 0.15.0 | 100 | 9/5/2026 |
| 0.14.0 | 91 | 9/2/2026 |
| 0.13.0 | 110 | 9/2/2026 |
| 0.12.0 | 108 | 8/29/2026 |
| 0.11.0 | 104 | 8/25/2026 |
| 0.10.0 | 99 | 8/24/2026 |
| 0.9.0 | 97 | 8/24/2026 |
| 0.8.0 | 97 | 8/24/2026 |
| 0.7.0 | 106 | 8/24/2026 |
| 0.6.0 | 103 | 8/24/2026 |
| 0.5.0 | 99 | 8/24/2026 |
| 0.4.0 | 103 | 8/24/2026 |
| 0.3.0 | 101 | 8/23/2026 |
| 0.2.0 | 100 | 8/23/2026 |
| 0.1.0 | 100 | 8/23/2026 |