Turn your standard NSTextView or UITextView into a Soulver-like notepad calculator

What's New



First release of SoulverTextKit


Swift 5.3 Platform Platform

SoulverTextKit lets you add a line-by-line calculation feature to any NSTextView or UITextView. It uses SoulverCore for number crunching, which also provides unit conversions, date & times calculations, and more.


  • Xcode 11+
  • Swift 5+

Supported Platforms

  • macOS 10.14.4+
  • iOS/iPadOS 13+


SoulverTextKit is distributed using the Swift Package Manager. To install it into a project, simply add it as a dependency within your Package.swift manifest:

let package = Package(
    dependencies: [
        .package(url: "", from: "0.0.1")

Or add the package in Xcode.


There are 3 steps to integrate SoulverTextKit in your project. Examples for both NSTextView & UITextView are provided in this repository.

Step 1

Import SoulverTextKit in your text view delegate

import SoulverTextKit

Step 2

Create an instance variable of ParagraphCalculator and initialize it with your TextView's NSTextStorage and NSTextContainer:

    @IBOutlet var textView: NSTextView!
    var paragraphCalculator: SoulverTextKit.ParagraphCalculator!

    override func viewDidLoad() {
        self.paragraphCalculator = ParagraphCalculator(answerPosition: .afterEquals, textStorage: self.textView.textStorage, textContainer: self.textView.textContainer)

Step 3

Implement NS/UITextView textDidChange and NSLayoutManager didChangeGeometry delegate methods

    func textDidChange(_ notification: Notification) {
        // Let us know when the text changes, so we can evaluate any changed lines if necessary
    func layoutManager(_ layoutManager: NSLayoutManager, textContainer: NSTextContainer, didChangeGeometryFrom oldSize: NSSize) {

        // Let us know when the text view changes size, so we can change update the formatting if necessary

Step 4 (optional)

Prevent the user editing the result of a paragraph

    func textView(_ textView: NSTextView, shouldChangeTextIn affectedCharRange: NSRange, replacementString: String?) -> Bool {

        // Check with us to see if the user should be able to edit parts of the paragraph.        
        switch paragraphCalculator.shouldAllowReplacementFor(affectedCharRange: affectedCharRange, replacementString: replacementString) {
        case .allow:
            return true
        case .deny:
            return false
        case .setIntertionPoint(range: let range):
            return false


There are 3 built-in styles for calculation paragraphs: afterTab, afterPipe and afterEquals. Choose your preferred style when creating the ParagraphCalculator.

After Tab

After Pipe

After Equals


Copyright (c) 2021 Zac Cohan. SoulverTextKit is distributed under the MIT License. The use of the SoulverCore math engine in commercial software requires a special license. You can also modify ParagraphCalculator to use another math engine like Math.js or Expression.


  • Swift Tools 5.3.0
View More Packages from this Author


Last updated: Thu Feb 08 2024 19:38:09 GMT-1000 (Hawaii-Aleutian Standard Time)