Math rendering and editing in pure Flutter.

Overview

Flutter Math

Build Status codecov Pub Version

Math equation rendering in pure Dart & Flutter.

This project aims to achieve maximum compatibility and fidelity with regard to the KaTeX project, while maintaining the performance advantage of Dart and Flutter. A further UnicodeMath-style equation editing support will be experimented in the future.

The TeX parser is a Dart port of the KaTeX parser. There are only a few unsupported features and parsing differences compared to the original KaTeX parser. List of some unsupported features can be found here.

Online Demo

Rendering Samples

x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}

Example1

i\hbar\frac{\partial}{\partial t}\Psi(\vec x,t) = -\frac{\hbar}{2m}\nabla^2\Psi(\vec x,t)+ V(\vec x)\Psi(\vec x,t)

Example2

\hat f(\xi) = \int_{-\infty}^\infty f(x)e^{- 2\pi i \xi x}\mathrm{d}x

Example3

How to use

Add flutter_math to your pubspec.yaml dependencies

Mobile

Currently only Android platform has been tested. If you encounter any issues with iOS, please file them.

Web

Web support is added in v0.1.6. It is tested for DomCanvas backend. In general it should behave largely the same with mobile. It is expected to break with CanvasKit backend. Check out the Online Demo

API usage (v0.2.0)

The usage is straightforward. Just Math.tex(r'\frac a b'). There is also optional arguments of TexParserSettings settings, which corresponds to Settings in KaTeX and support a subset of its features.

Display-style equations:

Math.tex(r'\frac a b', mathStyle: MathStyle.display) // Default

In-line equations

Math.tex(r'\frac a b', mathStyle: MathStyle.text)

The default size of the equation is obtained from the build context. If you wish to specify the size, you can use textStyle. Note: this parameter will also change how big 1cm/1pt/1inch is rendered on the screen. If you wish to specify the size of those absolute units, use logicalPpi

Math.tex(
  r'\frac a b',
  textStyle: TextStyle(fontSize: 42),
  // logicalPpi: MathOptions.defaultLogicalPpiFor(42),
)

There is also a selectable variant SelectableMath that creates selectable and copy-able equations on both mobile and web. (EXPERIMENTAL) Users can select part of the equation and obtain the encoded TeX strings. The usage is similar to Flutter's SelectableText.

SelectableMath.tex(r'\frac a b', textStyle: TextStyle(fontSize: 42))

If you would like to display custom styled error message, you should use onErrorFallback parameter. You can also process the errors in this function. But beware this function is called in build function.

Math.tex(
  r'\garbled $tring', 
  textStyle: TextStyle(color: Colors.green),
  onErrorFallback: (err) => Container(
    color: Colors.red,
    child: Text(err.messageWithType, style: TextStyle(color: Colors.yellow)),
  ),
)

If you wish to have more granularity dealing with equations, you can manually invoke the parser and supply AST into the widget.

SyntaxTree ast;
try {
  ast = SyntaxTree(greenRoot: TexParser(r'\frac a b', TexParserSettings()).parse());
} on ParseException catch (e) {
  // Handle my error here
}

SelectableMath(
  ast: ast,
  mathStyle: MathStyle.text,
  textStyle: TextStyle(fontSize: 42),
)

Line Breaking

Credits

This project is possible thanks to the inspirations and resources from the KaTeX Project, MathJax, Zefyr, and CaTeX.

Goals

  • : TeX math parsing (See design doc)
  • : AST rendering in flutter
  • : Selectable widget
  • : TeX output (WIP)
  • : UnicodeMath parsing and encoding
  • : UnicodeMath-style editing
  • : Breakable equations
  • : MathML parsing and encoding
Comments
  • Wrapping

    Wrapping

    Hey @znjameswu ! Awesome library! Thanks for making such amount of work publicly available!

    Currently the whole equation is rendered on a single line, are you planning (or is there already) a built-in support for wrapping?

    Thanks! Have a great day!

    enhancement 
    opened by VadimOsovsky 24
  • 0.2.0 API Redesign

    0.2.0 API Redesign

    Current 0.1.x's API design is more of a makeshift design that has a lot of oversight and redundancy which is later proved to be not so useful. As the development for follow-up feature goes deeper and I'm having a better understanding for the API demand, it is probably the time to stablize the API and make some unavoidable breakings. The proposed API change takes inspirations from other projects from zefyr and CaTeX.

    Widget variants

    The first part is to break up widgets into MathView, MathSelectable, and (future) MathEditable, instead of one FlutterMath. This will avoid extra performance cost and API surface when only MathView is needed.

    FlutterMath will be deprecated and then removed.

    TextStyle over Options

    TextStyle will be adopted as the parameter in exposed APIs to replace Options. This will have several implications:

    1. TextStyle.fontSize will be the logical pixel count of 1 cssEm (which is the fontSize passed to Text widget under MathStyle.display and normal size). This will affect all relative length units such as mu, etc. A constant defaultMathFontSize will be provided.
    2. Another parameter lpPerInch will be used to decide the length of absolute units. If lpPerInch is null, then absolute units will follow relative units and resize on different TextStyle.fontSize (Just like current baseSizeMultiplier's behavior). A function double defaultLpPerInch(double fontSize) will be provided to calculate the effective lpPerInch when set to null.
    3. As such, baseSizeMultiplier will be removed.

    The final API will look like

    MathView.fromTex(
      r'\frac a b',
      style: TextStyle(fontSize: 42),
      // parserSettings: TexSettings(),
      // lpPerInch: defaultLpPerInch(42),
      onErrorFallback: (err) => Text(err.toString()),
    )
    

    Renaming classes

    Some old classnames are prone to naming collision in user code. The following will be an incomplete list of renaming: Options -> MathOptions Settings -> TexSettings SizeMode -> MathSize

    Grouping exports

    Now exports will be grouped into three libraries package:flutter_math/widgets.dart exports basic widgets package:flutter_math/ast.dart exports AST nodes and necessary tooling package:flutter_math/tex.dart exports TeX parser and useful settings

    Updating Plan

    Aside from the variant widget proposal, all other changes are breaking.

    Currently MathSelectable and a bunch of optimizations is in the works. Widget variants, MathSelectable and those optimizations will land in 0.1.9. 0.1.9 will also mark FlutterMath as deprecated. However, none of these will be breaking.

    After 0.1.9 is rolled, 0.2.0 will come out very shortly, with all the above breaking changes. 0.2.0 will also remove FlutterMath.

    opened by znjameswu 17
  • Overflow in `cases` environment

    Overflow in `cases` environment

    Hey,

    First, thank you for this great plugin ! I'm currently trying to implement it in my app alongside flutter_widget_from_html_core. But everytime I'm using the cases environment, I get a RenderLine overflowed of 16 pixels error.

    (the second overflow error is due to #8)

    The Math widget is inserted as an inline widget and its parent is a Column widget.

    opened by Skyost 8
  • Closes #37 Hot fix for Flutter 2.0 stable version

    Closes #37 Hot fix for Flutter 2.0 stable version

    @znjameswu this resolves #37 to fix the currently broken version of this package on the latest Flutter stable. Can you please review and accept pull request.

    opened by walsha2 6
  • Alignment in line breaking mode

    Alignment in line breaking mode

    Hey,

    I've followed the instructions here to implement the line breaking feature in my app. It really suits my needs, but there's a little caveat using a Wrap widget in order to display Tex break parts : some parts are not aligned. Here are some examples :

    Screenshot_1 Screenshot_2 Screenshot_3

    Is there a way to align the Math widgets in a Wrap ?

    Thanks !

    opened by Skyost 6
  • Null safety migration

    Null safety migration

    The manual nnbd migration turns out to be easier than I had thought. Currently all tests are passing on the nnbd branch.

    The prerelease version will be published once the following dependencies have migrated:

    • provider
    • flutter_svg
    • tuple (currently replaced with an internal implementation)
    wait-for-upstream 
    opened by znjameswu 6
  • Merge flutter_math_fork (containing Flutter 2.0 compatibility changes)

    Merge flutter_math_fork (containing Flutter 2.0 compatibility changes)

    As flutter_math has not been maintained for the past few months, we decided to fork it into flutter_math_fork in order to publish it as a compatible Pub package.

    The Pub dependency is the following:

    flutter_math_fork: ^3.0.0
    

    We do not intend to maintain this fork in the long-term. Instead, we would like to merge this effort back into the original repo, which is why this branch will be kept in sync.

    opened by creativecreatorormaybenot 5
  • Math.tex(r'\frac a b') will throws an error

    Math.tex(r'\frac a b') will throws an error

    Math.tex(r'\frac a b'); Math.tex(r'\frac a b', mathStyle: MathStyle.display); Math.tex(r'\frac a b', mathStyle: MathStyle.text);

    The above code all will throw a same error: NoSuchMethodError: The getter 'color' was called on null. Receiver: null Tried calling: color

    My development environment is win10+vscode.

    opened by panmengma 5
  • Special characters are unsupported

    Special characters are unsupported

    If you try to use special characters like ä or Ö in a FlutterMath widget, it will not work.

    It seems like the KaTeX fonts need to support that as it works in KaTeX. What do you think @znjameswu 😃

    opened by creativecreatorormaybenot 4
  • Divider line isn't changing color along with the text.

    Divider line isn't changing color along with the text.

    Hi,

    The divider line isn't changing color along with the text, it always displays black.

    Code:

      final String content = r'\left \| \overrightarrow{F}\right \|= K \frac{\left | Q_1\cdot Q_2 \right |}{d^2}';
    
      var math = FlutterMath.fromTexString(content,
          settings: Settings(
            colorIsTextColor: true,
          ),
          options: Options.displayOptions.withColor(Colors.orange));
    

    Output: image

    Thanks for the plugin, awesome work.

    opened by RaulMarquezInclan 3
  • Error when trying to run Flutter 2

    Error when trying to run Flutter 2

    Just upgraded my Flutter SDK to the new version (Flutter 2) and I get and error when trying to run the project or build an apk:

    flutter_math: ^0.2.1
    
    ~$ flutter --version
    Flutter 2.0.0 • channel stable • https://github.com/flutter/flutter.git   
    Framework • revision 60bd88df91 (24 hours ago) • 2021-03-03 09:12:17 -0800
    Engine • revision 40441def69
    Tools • Dart 2.12.0
    
    /C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_math-0.2.1/lib/src/widgets/selection/overlay.dart:302:46: Error: Too few positional arguments: 8 required, 7 given.
            child: selectionControls.buildToolbar
    
    opened by doble-d 2
  • Unsanitized build exception detected: Unsupported operation: Temporary node CrNode encountered..Please report this error with correponding input.

    Unsanitized build exception detected: Unsupported operation: Temporary node CrNode encountered..Please report this error with correponding input.

    Error Message: Unsanitized build exception detected: Unsupported operation: Temporary node CrNode encountered..Please report this error with correponding input.

    Corresponding Input: \textsf{For any three sets X, Y, and Z, }\X\cap(Y\cup Z)=?

    flutter_tex package successfully renders the above input, hence the above input may be assumed as a VALID input. I am not using the flutter_tex package because it is too slow, and resource hungry.

    opened by naveedjamali 0
  • failed build with flutter 2.5.3

    failed build with flutter 2.5.3

    --- xcodebuild: WARNING: Using the first of multiple matching destinations: { platform:macOS, arch:x86_64, id:5B5D3D31-4199-58BB-A20C-ED2BB1C54620 } { platform:macOS, name:Any Mac } /usr/local/Caskroom/flutter/2.2.2/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_math-0.3.0-nullsafety.1/lib/src/widgets/selectable.dart:407:7: Error: The non-abstract class 'InternalSelectableMathState' is missing implementations for these members:

    • TextSelectionDelegate.userUpdateTextEditingValue Try to either
    • provide an implementation,
    • inherit an implementation from a superclass or mixin,
    • mark the class as abstract, or
    • provide a 'noSuchMethod' implementation.

    class InternalSelectableMathState extends State ^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/local/Caskroom/flutter/2.2.2/flutter/packages/flutter/lib/src/services/text_input.dart:842:8: Context: 'TextSelectionDelegate.userUpdateTextEditingValue' is defined here. void userUpdateTextEditingValue(TextEditingValue value, SelectionChangedCause cause); ^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/local/Caskroom/flutter/2.2.2/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_math-0.3.0-nullsafety.1/lib/src/widgets/selection/overlay_manager.dart:84:8: Error: The method 'SelectionOverlayManagerMixin.hideToolbar' has fewer positional arguments than those of overridden method 'TextSelectionDelegate.hideToolbar'. void hideToolbar() { ^ /usr/local/Caskroom/flutter/2.2.2/flutter/packages/flutter/lib/src/services/text_input.dart:849:8: Context: This is the overridden method ('hideToolbar'). void hideToolbar([bool hideHandles = true]); ^ /usr/local/Caskroom/flutter/2.2.2/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_math-0.3.0-nullsafety.1/lib/src/widgets/selectable.dart:407:7: Error: Applying the mixin 'SelectionOverlayManagerMixin' to 'State with AutomaticKeepAliveClientMixin, FocusManagerMixin, SelectionManagerMixin' introduces an erroneous override of 'hideToolbar'. class InternalSelectableMathState extends State ^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/local/Caskroom/flutter/2.2.2/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_math-0.3.0-nullsafety.1/lib/src/widgets/selection/overlay_manager.dart:84:8: Context: The method 'SelectionOverlayManagerMixin.hideToolbar' has fewer positional arguments than those of overridden method 'TextSelectionDelegate.hideToolbar'. void hideToolbar() { ^ /usr/local/Caskroom/flutter/2.2.2/flutter/packages/flutter/lib/src/services/text_input.dart:849:8: Context: This is the overridden method ('hideToolbar'). void hideToolbar([bool hideHandles = true]); ^ /usr/local/Caskroom/flutter/2.2.2/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_math-0.3.0-nullsafety.1/lib/src/widgets/selectable.dart:407:7: Error: The implementation of 'hideToolbar' in the non-abstract class 'InternalSelectableMathState' does not conform to its interface. class InternalSelectableMathState extends State ^^^^^^^^^^^^^^^^^^^^^^^^^^^ /usr/local/Caskroom/flutter/2.2.2/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_math-0.3.0-nullsafety.1/lib/src/widgets/selectable.dart:407:7: Context: The method 'State with AutomaticKeepAliveClientMixin, FocusManagerMixin, SelectionManagerMixin, SelectionOverlayManagerMixin.hideToolbar' has fewer positional arguments than those of overridden method 'TextSelectionDelegate.hideToolbar'. class InternalSelectableMathState extends State ^ /usr/local/Caskroom/flutter/2.2.2/flutter/packages/flutter/lib/src/services/text_input.dart:849:8: Context: This is the overridden method ('hideToolbar'). void hideToolbar([bool hideHandles = true]); ^ /usr/local/Caskroom/flutter/2.2.2/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_math-0.3.0-nullsafety.1/lib/src/widgets/selection/overlay.dart:301:47: Error: Too few positional arguments: 8 required, 7 given. child: selectionControls!.buildToolbar( ^

    Command PhaseScriptExecution failed with a nonzero exit code note: Using new build system note: Planning note: Build preparation complete note: Building targets in dependency order ** BUILD FAILED **

    opened by Mon-ius 2
  • how to take line breaking?

    how to take line breaking?

    at first, thanks for sharing such a powerful plugin!! In my project, need to render Latex, and so choose this plugin! i am a tyro, now i can render Latex string, but have a big question -- how to take line breaking? two cases: 1.latex string is wider then screen width 2.one latex string has multi-math expression In Math.tex( ).texBreak().parts, how can we make custom line breaking policy? i did not get the key! thanks for any help~~

    opened by Sunia2021 0
  • Wrapping text

    Wrapping text

    I have a latex code something like this

    \text{Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy te}

    \begin{array}{l} \text { Let } f(x, y)=x^{y}+y^{x} \ \text { Then, } \frac{\partial f}{\partial x}=y x^{y-1}+y^{x} \log _{e} y ; \text { Similarly }, \frac{\partial f}{\partial y}=x^{y} \log _{e} x+x y^{x-1} \ \therefore \quad \frac{d y}{d x}=-\frac{\partial f / \partial x}{\partial f / \partial y}=-\frac{y^{x} \log _{e} y+y^{y-1}}{x^{y} \log _{e} x+x y^{x-1}} \end{array}

    Is there a way to break the text

    opened by hfactorcode 0
A Flutter plugin that makes it easier to make floating/overlay windows for Android with pure Flutter

flutter_floatwing A Flutter plugin that makes it easier to make floating/overlay windows for Android with pure Flutter. Android only Features Pure Flu

Zoe 116 Dec 21, 2022
A pure flutter toast library

oktoast A library for flutter. A pure dart toast Library. You can completely customize the style of toast. 中文博客介绍 Screenshot Default Custom GIF Versio

OpenFlutter 438 Dec 24, 2022
A light-weight Emoji 📦 for Dart & Flutter with all up-to-date emojis written in pure Dart 😄 . Made from 💯% ☕ with ❤️!

dart_emoji ?? A light-weight Emoji ?? for Dart & Flutter with all up-to-date emojis written in pure Dart ?? . Made from ?? % ☕ with ❤️ ! This is a for

Gatch 18 Mar 22, 2022
Custom Flutter widgets that makes Checkbox and Radio Buttons much cleaner and easier.

custom_radio_grouped_button Custom Radio Buttons and Grouped Check Box Button Custom Flutter widgets that makes Checkbox and Radio Buttons much cleane

Ketan Choyal 144 Sep 23, 2022
Custom widgets and utils using Flutter framework widgets and Dart language

reuse_widgets_and_utils The custom widgets and utils using Flutter framework widgets and Dart programming language. Getting Started This project is a

null 1 Oct 29, 2021
The SpannableGrid is a Flutter widget that allows its cells to span columns and rows and supports moving cells inside the grid.

Spannable Grid The SpannableGrid is a Flutter widget that allows its cells to span columns and rows and supports moving cells inside the grid. Feature

Evgeny Cherkasov 17 Nov 7, 2022
PlutoGrid is a dataGrid that can be controlled by the keyboard on desktop and web. Of course, it works well on Android and IOS.

PlutoGrid is a dataGrid that can be controlled by the keyboard on desktop and web.

Manki Kim 453 Jan 4, 2023
Customizable Material and Cupertino buttons with progress indicators and more

future_button Customizable Material and Cupertino buttons with progress indicators and more.

Erzhan 33 Oct 13, 2022
A widget that can be dragged and scrolled in a single gesture and snapped to a list of extents.

Sliding Sheet A widget that can be dragged and scrolled in a single gesture and snapped to a list of extents. Click here to view the full example. Ins

null 396 Mar 10, 2022
React hooks for Flutter. Hooks are a new kind of object that manages a Widget life-cycles. They are used to increase code sharing between widgets and as a complete replacement for StatefulWidget.

English | Português Flutter Hooks A Flutter implementation of React hooks: https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889 Ho

Remi Rousselet 2.6k Dec 29, 2022
Flutter debug helper widget with common and custom actions

Flutter debug helper widget with common and custom actions

Stanislav Ilin 43 Dec 7, 2022
A draggable Flutter widget that makes implementing a Sliding up and fully-stretchable much easier.

Draggable Home A draggable Flutter widget that makes implementing a Sliding up and fully-stretchable much easier! Based on the Scaffold and Sliver. Us

Devs On Flutter 106 Dec 12, 2022
Flutter widgets and themes implementing the current macOS design language.

macos_ui Flutter widgets and themes implementing the current macOS design language. NOTE: This package depends on the excellent native_context_menu pl

Reuben Turner 1.1k Jan 7, 2023
Flutter widget for fetching, caching and refetching asynchronous data.

Flutter library for fetching, caching and invalidating asynchronous data Quick Features Fetch asynchronous data Data invalidation Optimistic response

null 32 Dec 24, 2022
A collection of pixel-perfect iOS-styled components and properties for Flutter, following the official guidelines.

cupertinew ⚠️ Experimental and work in progress ⚠️ A collection of pixel-perfect iOS-styled components and properties for Flutter, following the offic

null 30 Nov 10, 2022
This repo is for anything that can be reusable in flutter like custom widgets 🟥, animations 🌟and more

Flutter Shortcuts This repo is for anything that can be reusable in flutter like custom widgets ?? , animations ?? and more. How to Use Just get the f

Abdelrahman Mostafa Elmarakby 91 Dec 3, 2022
A flutter carousel widget, support infinite scroll, and custom child widget.

carousel_slider A carousel slider widget. Features Infinite scroll Custom child widgets Auto play Supported platforms Flutter Android Flutter iOS Flut

Bart T 1 Nov 25, 2021
RFlutter Alert is super customizable and easy-to-use alert/popup dialogs for Flutter.

RFlutter Alert is super customizable and easy-to-use alert/popup dialogs for Flutter. You may create reusable alert styles or add buttons as much as you want with ease.

Ratel 362 Jan 1, 2023
A package for flutter to use alert and toast within one line code.

easy_alert A package for flutter to use alert and toast within one line code. Getting Started Add easy_alert: to your pubspec.yaml, and run flutt

null 34 Jun 25, 2021