Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
228 changes: 105 additions & 123 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
# SwiftMath

`SwiftMath` provides a full Swift implementation of [iosMath](https://travis-ci.org/kostub/iosMath)
for displaying beautifully rendered math equations in iOS and MacOS applications. It typesets formulae written
using LaTeX in a `UILabel` equivalent class. It uses the same typesetting rules as LaTeX and
so the equations are rendered exactly as LaTeX would render them.
**SwiftMath** delivers an elegant, comprehensive Swift implementation of [iosMath](https://travis-ci.org/kostub/iosMath),
enabling the pristine rendering of mathematical equations within iOS and macOS applications. This sophisticated framework
typesets LaTeX formulae within a native `UILabel`-equivalent interface, meticulously adhering to LaTeX's canonical
typesetting algorithms to ensure pixel-perfect mathematical notation.

Please also check out [SwiftMathDemo](https://github.com/mgriebling/SwiftMathDemo.git) for examples of how to use `SwiftMath`
from SwiftUI.
For exemplary demonstrations of **SwiftMath** integration with SwiftUI, we invite you to explore
[SwiftMathDemo](https://github.com/mgriebling/SwiftMathDemo.git).

`SwiftMath` is similar to [MathJax](https://www.mathjax.org) or
[KaTeX](https://github.com/Khan/KaTeX) for the web but for native iOS or MacOS
applications without having to use a `UIWebView` and Javascript. More
importantly, it is significantly faster than using a `UIWebView`.
**SwiftMath** represents the native application paradigm of what [MathJax](https://www.mathjax.org) and
[KaTeX](https://github.com/Khan/KaTeX) accomplish for web environments—delivering professional mathematical
typesetting without the overhead of `UIWebView` or JavaScript dependencies. The performance advantages are
substantial, offering dramatically superior rendering speeds compared to web-based alternatives.

`SwiftMath` is a Swift translation of the latest `iosMath` v0.9.5 release but includes bug fixes
and enhancements like a new \lbar (lambda bar) character and cyrillic alphabet support.
The original `iosMath` test suites have also been translated to Swift and run without errors.
Note: Error test conditions are ignored to avoid tagging everything with silly `throw`s.
Please let me know of any bugs or bug fixes that you find.
This framework represents a meticulous Swift reimagining of `iosMath` v0.9.5, enhanced with refined bug fixes
and distinguished extensions including the lambda bar (`\lbar`) character and comprehensive Cyrillic alphabet support.
The comprehensive test suites from the original `iosMath` implementation have been faithfully translated and execute
flawlessly. We graciously welcome contributions regarding any discoveries of issues or improvements.

`SwiftMath` prepackages everything needed for direct access via the Swift Package Manager.
**SwiftMath** arrives as a turnkey solution, elegantly packaged for seamless integration via the Swift Package Manager.

## Examples
Here are screenshots of some formulae that were rendered with this library:
## Exemplary Demonstrations
The following showcase exquisitely typeset mathematical expressions rendered through this library:

```LaTeX
x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}
Expand Down Expand Up @@ -53,42 +52,39 @@ f(x) = \int\limits_{-\infty}^\infty\!\hat f(\xi)\,e^{2 \pi i \xi x}\,\mathrm{d}\
![Ramanujan Identity](img/ramanujan-light.png#gh-light-mode-only)
![Ramanujan Identity](img/ramanujan-dark.png#gh-dark-mode-only)

More examples are included in [EXAMPLES](EXAMPLES.md)
Additional sophisticated examples are curated in [EXAMPLES](EXAMPLES.md)

## Fonts
Here are previews of the included fonts:
## Typography
Previews of the distinguished font collection:

![](img/FontsPreview.png#gh-dark-mode-only)
![](img/FontsPreviewLight.png#gh-light-mode-only)

## Requirements
`SwiftMath` works on iOS 11+ or MacOS 12+. It depends
on the following Apple frameworks:
## System Requirements
**SwiftMath** is architected for iOS 11+ and macOS 12+, leveraging the following essential Apple frameworks:

* Foundation.framework
* CoreGraphics.framework
* QuartzCore.framework
* CoreText.framework

Additionally for iOS it requires:
* UIKit.framework

Additionally for MacOS it requires:
* AppKit.framework
Platform-specific dependencies:
* **iOS**: UIKit.framework
* **macOS**: AppKit.framework

## Installation

### Swift Package
### Swift Package Manager

`SwiftMath` is available from [SwiftMath](https://github.com/mgriebling/SwiftMath.git).
To use it in your code, just add the https://github.com/mgriebling/SwiftMath.git path to
XCode's package manager.
**SwiftMath** is elegantly distributed via [Swift Package Manager](https://github.com/mgriebling/SwiftMath.git).
To integrate it into your project, simply incorporate the repository URL `https://github.com/mgriebling/SwiftMath.git`
through Xcode's Package Dependencies interface.

## Usage

The library provides a class `MTMathUILabel` which is a `UIView` that
supports rendering math equations. To display an equation simply create
an `MTMathUILabel` as follows:
The framework provides the `MTMathUILabel` class—a sophisticated `UIView` subclass
engineered for rendering mathematical equations. To display an equation, instantiate
an `MTMathUILabel` as demonstrated:

```swift

Expand All @@ -98,10 +94,10 @@ let label = MTMathUILabel()
label.latex = "x = \\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}"

```
Adding `MTMathUILabel` as a sub-view of your `UIView` will render the
quadratic formula example shown above.
Incorporating `MTMathUILabel` as a subview within your `UIView` hierarchy will elegantly
render the quadratic formula as illustrated above.

The following code creates a SwiftUI component called `MathView` encapsulating the MTMathUILabel:
The following implementation demonstrates a SwiftUI `MathView` component that encapsulates `MTMathUILabel`:

```swift
import SwiftUI
Expand Down Expand Up @@ -130,7 +126,7 @@ struct MathView: UIViewRepresentable {
}
```

For code that works with SwiftUI running natively under MacOS use the following:
For native macOS SwiftUI integration, employ the following `NSViewRepresentable` implementation:

```swift
import SwiftUI
Expand Down Expand Up @@ -160,158 +156,144 @@ struct MathView: NSViewRepresentable {
}
```

### Included Features
This is a list of formula types that the library currently supports:
### Comprehensive Feature Set
The framework provides extensive support for the following mathematical notation categories:

* Simple algebraic equations
* Algebraic equations of arbitrary complexity
* Fractions and continued fractions
* Exponents and subscripts
* Trigonometric formulae
* Square roots and n-th roots
* Calculus symbos - limits, derivatives, integrals
* Big operators (e.g. product, sum)
* Big delimiters (using \\left and \\right)
* Radical expressions (square roots and n-th roots)
* Calculus notation—limits, derivatives, integrals
* Large operators (e.g., product, summation)
* Extensible delimiters (via `\left` and `\right`)
* Greek alphabet
* Combinatorics (\\binom, \\choose etc.)
* Geometry symbols (e.g. angle, congruence etc.)
* Combinatorial notation (`\binom`, `\choose`, etc.)
* Geometric symbols (angles, congruence, etc.)
* Ratios, proportions, percentages
* Math spacing
* Overline and underline
* Math accents
* Mathematical spacing
* Overlines and underlines
* Mathematical accents
* Matrices
* Equation alignment
* Change bold, roman, caligraphic and other font styles (\\bf, \\text, etc.)
* Most commonly used math symbols
* Colors for both text and background
* Typographic style variations (bold, roman, calligraphic via `\bf`, `\text`, etc.)
* Comprehensive mathematical symbol library
* Customizable text and background colors

Note: SwiftMath only supports the commands in LaTeX's math mode. There is
also no language support for other than west European langugages and some
Cyrillic characters. There would be two ways to support more languages:
**Note:** **SwiftMath** exclusively implements LaTeX's mathematical mode commands. Language support
is presently limited to Western European languages and select Cyrillic characters. To extend
linguistic capabilities, consider either:

1) Find a math font compatible with `SwiftMath` that contains all the glyphs
for that language.
2) Add support to `SwiftMath` for standard Unicode fonts that contain all
langauge glyphs.
1. Identifying a mathematically-compatible OpenType font containing requisite glyphs, or
2. Architecting support for standard Unicode fonts with comprehensive glyph coverage.

Of these two, the first is much easier. However, if you want a challenge,
try to tackle the second option.
While the former approach proves considerably more straightforward, the latter presents an
intriguing technical challenge for ambitious contributors.

### Example
### Demonstration Project

The [SwiftMathDemo](https://github.com/mgriebling/SwiftMathDemo) is a SwiftUI version
of the Objective-C demo included in `iosMath` that uses `SwiftMath` as a Swift package dependency.
[SwiftMathDemo](https://github.com/mgriebling/SwiftMathDemo) presents a sophisticated SwiftUI interpretation
of the original Objective-C demonstration from `iosMath`, elegantly leveraging **SwiftMath** as a package dependency.

### Advanced configuration
### Advanced Configuration

`MTMathUILabel` supports some advanced configuration options:
`MTMathUILabel` offers refined configuration capabilities for discerning requirements:

##### Math mode
##### Mathematical Mode

You can change the mode of the `MTMathUILabel` between Display Mode
(equivalent to `$$` or `\[` in LaTeX) and Text Mode (equivalent to `$`
or `\(` in LaTeX). The default style is Display. To switch to Text
simply:
Configure `MTMathUILabel` to operate in either Display Mode
(analogous to `$$` or `\[` in LaTeX) or Text Mode (corresponding to `$`
or `\(` in LaTeX). Display Mode is the default configuration. To transition to Text Mode:

```swift
label.labelMode = .text
```

##### Text Alignment
The default alignment of the equations is left. This can be changed to
center or right as follows:
Equations default to left alignment. This may be elegantly adjusted to center or right positioning:

```swift
label.textAlignment = .center
```

##### Font size
The default font-size is 30pt. You can change it as follows:
##### Font Size
The default typeface size is 30pt. Adjust as desired:

```swift
label.fontSize = 25
```
##### Font
The default font is *Latin Modern Math*. This can be changed as:
##### Typeface Selection
The framework defaults to the distinguished *Latin Modern Math* typeface. Alternative fonts may be specified:

```swift
label.font = MTFontManager.fontmanager.termesFont(withSize:20)
```

This project has 12 fonts bundled with it, but you can use any OTF math
font. A python script is included that generates the `.plist` files
required for an `.otf` font to work with `SwiftMath`. If you generate
(and test) any other fonts please contribute them back to this project for
others to benefit.

This distribution encompasses 12 meticulously curated fonts, though any OpenType mathematical
font may be employed. An accompanying Python utility generates the requisite `.plist` configuration
files for integrating additional `.otf` fonts with **SwiftMath**. We enthusiastically welcome
contributions of validated font configurations to benefit the broader community.

**Note:** The `KpMath-Light`, `KpMath-Sans`, and `Asana` typefaces presently exhibit rendering
anomalies with particularly large radical expressions. This appears attributable to incomplete
glyph offset specifications within the font definitions. Community contributions addressing
this limitation would be most welcome.

Note: The `KpMath-Light`, `KpMath-Sans`, `Asana` fonts currently incorrectly
render very large radicals. It appears that the font files do
not properly define the offsets required to typeset these glyphs. If
anyone can fix this, it would be greatly appreciated.

##### Text Color
The default color of the rendered equation is black. You can change
it to any other color as follows:
##### Color Customization
Rendered equations default to black. Customize the color palette as desired:

```swift
label.textColor = .red
```

It is also possible to set different colors for different parts of the
equation. Just access the `displayList` field and set the `textColor`
of the underlying displays of which you want to change the color.
For granular control, selectively colorize specific equation components by accessing
the `displayList` property and configuring the `textColor` attribute of individual display elements.

##### Custom Commands
You can define your own commands that are not already predefined. This is
similar to macros is LaTeX. To define your own command use:
##### Custom Command Definition
Extend the framework's vocabulary by defining bespoke commands analogous to LaTeX macros:

```swift
MTMathAtomFactory.addLatexSymbol("lcm", value: MTMathAtomFactory.operator(withName: "lcm", limits: false))
```

This creates an `\lcm` command that can be used in the LaTeX.
This registers a custom `\lcm` operator available for use within LaTeX expressions.

##### Content Insets
The `MTMathUILabel` has `contentInsets` for finer control of placement of the
equation in relation to the view.

If you need to set it you can do as follows:
`MTMathUILabel` provides `contentInsets` for precise spatial control over equation positioning
within the view bounds. Configure as needed:

```swift
label.contentInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 20)
```

##### Error handling
##### Error Handling

If the LaTeX text given to `MTMathUILabel` is
invalid or if it contains commands that aren't currently supported then
an error message will be displayed instead of the label.
When `MTMathUILabel` encounters invalid LaTeX syntax or unsupported commands,
it gracefully displays an error message in lieu of rendering.

This error can be programmatically retrieved as `label.error`. If you
prefer not to display anything then set:
Access diagnostic information programmatically via `label.error`. To suppress
inline error display:

```swift
label.displayErrorInline = true
label.displayErrorInline = false
```

## Future Enhancements
## Roadmap & Future Enhancements

Note this is not a complete implementation of LaTeX math mode. There are
some important pieces that are missing and will be included in future
updates. This includes:
While comprehensive, the current implementation does not yet encompass the entirety of
LaTeX's mathematical mode. Planned enhancements for future releases include:

* Support for explicit big delimiters (bigl, bigr etc.)
* Addition of missing plain TeX commands
* Explicit large delimiter support (`\bigl`, `\bigr`, etc.)
* Additional plain TeX command coverage

## License

`SwiftMath` is available under the MIT license. See the [LICENSE](./LICENSE)
file for more info.
**SwiftMath** is distributed under the permissive MIT license. Consult the [LICENSE](./LICENSE)
file for comprehensive terms.

### Fonts
This distribution contains the following fonts. These fonts are
licensed as follows:
### Font Licensing
This distribution incorporates the following professionally crafted typefaces, each governed
by their respective licenses:
* Latin Modern Math:
[GUST Font License](GUST-FONT-LICENSE.txt)
* Tex Gyre Termes:
Expand Down