Skip to content

Latest commit

History

1,195 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Cross-platform LaTeX rendering!


CSharpMath icon

CSharpMath is a C# port of the wonderful iosMath LaTeX engine.
The icon is a product of this library.

Current releaseNuGet release shieldGitHub release shieldGitHub release date shieldGitHub commits since last release shield
Current prereleaseNuGet pre-release shieldGitHub pre-release shieldGitHub pre-release date shieldGitHub commits since last prerelease shield

NuGet downloads shieldGitHub contributors shieldGitHub license shieldGitHub last commit shield [GitHub Build workflow shield [GitHub Test workflow shieldcodecov.io badge

Average time to resolve an issuePercentage of issues still openIssues welcomePull Requests welcome❤

Platform support

Xamarin.Forms (CSharpMath.Forms) support via SkiaSharp (CSharpMath.SkiaSharp) was added in v0.1.

Avalonia (CSharpMath.Avalonia) support was also added in v0.4.

For Windows platforms, use https://github.com/ForNeVeR/wpf-math.

For Unity3D, use https://assetstore.unity.com/packages/tools/gui/texdraw-51426. (paid: USD$50)

The above projects are independent of CSharpMath.

Usage and Examples

To get started, do something like this:

1. CSharpMath.SkiaSharp

varpainter=CSharpMath.SkiaSharp.MathPainter();painter.LaTeX=@"\frac\sqrt23";paiinter.Draw(someCanvas);

This is used by CSharpMath.Forms below.

2. CSharpMath.Forms

<ContentPagexmlns="http://xamarin.com/schemas/2014/forms"xmlns:math="clr-namespace:CSharpMath.Forms;assembly=CSharpMath.Forms"x:Class="Namespace.Class">
<math:MathViewx:Name="View"HorizontalOptions="FillAndExpand"VerticalOptions="FillAndExpand">
\frac\sqrt23
</math:MathView>
</ContentPage>

or:

varview=newCSharpMath.Forms.MathView();view.HorizontalOptions=view.VerticalOptions=LayoutOptions.FillAndExpand;view.LaTeX=@"\frac\sqrt23";someLayout.Children.Add(view);

See an example project

AndroidWindows UWP
1+1Panning a viewColors!

3. CSharpMath.Avalonia

<UserControlxmlns="https://github.com/avaloniaui"xmlns:math="clr-namespace:CSharpMath.Avalonia;assembly=CSharpMath.Avalonia"x:Class="Namespace.Class">
<math:MathViewLaTeX="x + 2 \sqrt{x} + 1 = (\sqrt x+1)^2" />
</UserControl>

or:

varview=newCSharpMath.Avalonia.MathView();view.LaTeX=@"\frac\sqrt23";somePanel.Children.Add(view);

See an example project

MathViewPage

But I want a button instead!

For Xamarin.Forms, you can make use of CSharpMath.Forms.MathButton to make a clickable math button. It wraps a MathView inside and will use its properties to draw math on the button.

<ContentPagexmlns="http://xamarin.com/schemas/2014/forms"xmlns:math="clr-namespace:CSharpMath.Forms;assembly=CSharpMath.Forms"x:Class="Namespace.Class">
<math:MathButtonx:Name="MathButton">
<math:MathViewx:Name="MathView">
\frac\sqrt23
</math:MathView>
</math:MathButton>
</ContentPage>

For Avalonia, Avalonia.Controls.Button already supports arbitrary content. Use it instead.

<UserControlxmlns="https://github.com/avaloniaui"xmlns:math="clr-namespace:CSharpMath.Avalonia;assembly=CSharpMath.Avalonia"x:Class="Namespace.Class">
<Buttonx:Name="MathButton">
<math:MathViewx:Name="MathView">
\frac\sqrt23
</math:MathView>
</Button>
</UserControl>

But I want to display a majority of normal text with a minority of math!

CSharpMath also provides a TextView exactly for this purpose. You can use $, \( and \) to delimit inline math and $$, \[ and \] to delimit display math. There is also a TextButton for the Xamarin.Forms equivalent of MathButton. Xamarin.Forms:

<ContentPagexmlns="http://xamarin.com/schemas/2014/forms"xmlns:math="clr-namespace:CSharpMath.Forms;assembly=CSharpMath.Forms"x:Class="Namespace.Class">
<math:TextViewLaTeX="Text text text text text \( \frac{\sqrt a}{b} \) text text text text text" />
</ContentPage>

Avalonia:

<UserControlxmlns="https://github.com/avaloniaui"xmlns:math="clr-namespace:CSharpMath.Avalonia;assembly=CSharpMath.Avalonia"x:Class="Namespace.Class">
<math:TextViewLaTeX="Text text text text text \( \frac{\sqrt a}{b} \) text text text text text" />
</UserControl>
Xamarin.FormsAvalonia
Xamarin.FormsAvalonia

What about rendering to an image instead of displaying in a view?

Warning: There are still some rough edges on image rendering to be resolved, such as this and this. However, it is already usable for the majority of cases.

For SkiaSharp:

usingCSharpMath.SkiaSharp;varpainter=newMathPainter{LaTeX=@"\frac23"};// or TextPainterusingvarpng=painter.DrawAsStream();// or painter.DrawAsStream(format: SkiaSharp.SKEncodedImageFormat.Jpeg) for JPEG// or painter.DrawAsStream(format: SkiaSharp.SKEncodedImageFormat.Gif) for GIF// or painter.DrawAsStream(format: SkiaSharp.SKEncodedImageFormat.Bmp) for BMP// or... you get it.

For Xamarin.Forms:

usingCSharpMath.SkiaSharp;varpainter=someMathView.Painter;// or someTextView.Painterusingvarpng=painter.DrawAsStream();// or painter.DrawAsStream(format: SkiaSharp.SKEncodedImageFormat.Jpeg) for JPEG// or painter.DrawAsStream(format: SkiaSharp.SKEncodedImageFormat.Gif) for GIF// or painter.DrawAsStream(format: SkiaSharp.SKEncodedImageFormat.Bmp) for BMP// or... you get it.

For Avalonia:

usingCSharpMath.Avalonia;varpainter=someMathView.Painter;// or someTextView.Painter// Due to limitations of the Avalonia API, you can only render as PNG to a target streampainter.DrawAsPng(someStream);
Cell 1Cell 2Cell 3
Cell 4Cell 5Cell 6
Cell 7Cell 8Cell 9

This looks great and all, but is there a way to edit and evaluate the math?

Yes! You can use a CSharpMath.Rendering.FrontEnd.MathKeyboard to process key presses and generate a CSharpMath.Atom.MathList or a LaTeX string. You can then call CSharpMath.Evaluation.Evaluate to get a CSharpMath.Evaluation.MathItem, which can be a CSharpMath.Evaluation.MathItem.Entity containing an AngouriMath.Entity that you can simplify, a CSharpMath.Evaluation.Comma containing a comma-delimited collection of CSharpMath.Evaluation.MathItem, or a CSharpMath.Evaluation.MathItem.SetNode containing an AngouriMath.Core.SetNode. For all uses of an AngouriMath.Entity or an AngouriMath.Core.SetNode, check out https://github.com/asc-community/AngouriMath.

NOTE: CSharpMath.Evaluation is not released yet. It will be part of the 0.5.0 update.

varkeyboard=newCSharpMath.Rendering.FrontEnd.MathKeyboard();keyboard.KeyPress(CSharpMath.Editor.MathKeyboardInput.Sine,CSharpMath.Editor.MathKeyboardInput.SmallTheta);var(math,error)=CSharpMath.Evaluation.Evaluate(keyboard.MathList);if(error!=null){/*Handle invalid input by displaying error which is a string*/}elseswitch(math){caseCSharpMath.Evaluation.MathItem.Entity{Content:varentity}:// entity is an AngouriMath.EntityvarsimplifiedEntity=entity.Simplify();break;caseCSharpMath.Evaluation.MathItem.Commacomma:// comma is a System.Collections.Generic.IEnumerable<CSharpMath.Evaluation.MathItem>break;caseCSharpMath.Evaluation.MathItem.Set{Content:varset}:// set is an AngouriMath.Core.Setbreak;}

or more conveniently:

varkeyboard=newCSharpMath.Rendering.FrontEnd.MathKeyboard();keyboard.KeyPress(CSharpMath.Editor.MathKeyboardInput.Sine,CSharpMath.Editor.MathKeyboardInput.SmallTheta);// Displays errors as red text, also automatically chooses between// simplifying an expression and solving an equation depending on the presence of an equals signvarresultLaTeX=CSharpMath.Evaluation.Interpret(keyboard.MathList);
Analyzing an expressionSolving an equation
Analyzing an expressionSolving an equation

Opting in to the nightly feed

For those who wish to be even more updated than prereleases, you can opt in to the nightly feed which is updated whenever the master branch has a new commit.

  1. Log in to GitHub
  2. Generate a new token (a 40-digit hexadecimal number) in https://github.com/settings/tokens/new with the read:packages scope
  3. Create a new file called NuGet.Config or nuget.config in the same folder as your solution with content
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<addkey="CSharpMathNightly"value="https://nuget.pkg.github.com/verybadcat/index.json" />
</packageSources>
<packageSourceCredentials>
<CSharpMathNightly>
<addkey="Username"value="USERNAME" />
<addkey="ClearTextPassword"value="TOKEN" />
</CSharpMathNightly>
</packageSourceCredentials>
</configuration>
  1. Replace USERNAME in the above file with your GitHub username and TOKEN with your generated token.
  2. Open a package webpage in https://github.com/verybadcat/CSharpMath/packages
  3. Insert the following into your .csproj:
<ItemGroup>
<PackageReferenceInclude="PACKAGE"Version="VERSION" />
</ItemGroup>
  1. Replace PACKAGE in the above file by the package name in the webpage, e.g. CSharpMath.SkiaSharp, and VERSION by the version in the webpage, e.g. 0.4.2-ci-9db8a6dec29202804764fab9d6f7f19e43c3c083. The 40-digit hexadecimal number at the end of the version is the Git commit that was the package was built on. CI versions for a version are older than that version, aka chronologically 0.4.2-ci-xxx0.4.20.4.3-ci-xxx0.5.00.5.1-ci-xxx.

SourceLink for CI packages

Unfortunately, non-NuGet.org feeds do not support .snupkgs, so you will have to download all the packages yourself.

  1. Go to https://github.com/verybadcat/CSharpMath/actions?query=workflow%3ABuild
  2. Open the latest build
  3. Download artifacts
  4. Extract the files to a folder
  5. Add the folder as a local NuGet feed to Visual Studio according to https://docs.microsoft.com/en-gb/nuget/consume-packages/install-use-packages-visual-studio#package-sources

Project structure

Project structure

Major processes of drawing LaTeX

Major processes of drawing LaTeX

Extending to more platforms

There are a few ways to extend this to more platforms: (Hopefully, you would not need to touch the core typesetting engine. If you do, we would consider that a bug.)

1. Branching off from CSharpMath.Rendering (recommended)

As CSharpMath.Rendering provides font lookup through the Typography library, you would only need to write adapter classes to connect this library to your chosen graphics library.

You would have to implement ICanvas and feed it into the Draw method of MathPainter.

2. Forking from CSharpMath the project

This path would require the most effort to implement, but allows you to plug in any font library and graphics library.

You would have to define your own TypesettingContext and write an implementation of IGraphicsContext.

The TypesettingContext in turn has several components, including choosing a font.

3. Building on top of CSharpMath.SkiaSharp

You can extend this library to other SkiaSharp-supported platforms by feeding the SKCanvas given in the OnPaintSurface override of a SkiaSharp view into the Draw method of MathPainter.

Project needs

We need more contributors! Maybe you can contribute something to this repository. Whether they are bug reports, feature proposals or pull requests, you are welcome to send them to us. We are sure that we will take a look at them!

Here is an idea list if you cannot think of anything right now:

  • A new example for the Example projects (please open pull requests straight away)
  • A new LaTeX command (please link documentation of it)
  • A new front end (please describe what it is and why should it be supported)
  • A new math syntax (please describe what it is and why should it be supported)

License

CSharpMath is licensed by the MIT license.

DependencyUsed byLicense
Typography projectCSharpMath.RenderingMIT
AngouriMath projectCSharpMath.EvaluationMIT
Latin Modern Math fontCSharpMath.RenderingGUST Font License
Cyrillic Modern fontCSharpMath.RenderingSIL Open Font License
AMS Capital Blackboard Bold font (extracted by @Happypig375 from the amsfonts package)CSharpMath.RenderingSIL Open Font License
ComicNeue fontCSharpMath.Rendering.Tests, CSharpMath.Xaml.TestsSIL Open Font License

Authors

@verybadcat

@Happypig375

@charlesroddie

@FoggyFinder

Thanks for reading.

About

LaTeX. in C#. (ported from the wonderful iosMath project).

Topics

Resources

Contributing

Stars

448 stars

Watchers

20 watching

Forks

Releases

Packages

Used by

Contributors

Languages