{"id":13871895,"url":"https://github.com/soulverteam/SoulverCore","last_synced_at":"2025-07-16T01:32:21.238Z","repository":{"id":43476054,"uuid":"241419047","full_name":"soulverteam/SoulverCore","owner":"soulverteam","description":"A powerful Swift framework for evaluating natural language math expressions","archived":false,"fork":false,"pushed_at":"2024-10-15T05:39:20.000Z","size":567352,"stargazers_count":875,"open_issues_count":0,"forks_count":34,"subscribers_count":10,"default_branch":"master","last_synced_at":"2024-11-21T07:03:35.716Z","etag":null,"topics":["calculations","calculator","currency","currency-converter","currency-rates","date-calculator","date-parser","datetime","expression-evaluator","math-engine","math-expressions","mathematical-expressions","natural-language","natural-language-processing","notepad-calculator","soulver","swift","timezone"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/soulverteam.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-02-18T17:05:51.000Z","updated_at":"2024-11-18T18:29:34.000Z","dependencies_parsed_at":"2023-02-10T00:15:38.366Z","dependency_job_id":"ab8c5ff2-c892-439b-968b-f028df7a7b58","html_url":"https://github.com/soulverteam/SoulverCore","commit_stats":{"total_commits":87,"total_committers":3,"mean_commits":29.0,"dds":0.04597701149425293,"last_synced_commit":"62c9ead07b8a304f381334430bffa84409f533d6"},"previous_names":[],"tags_count":58,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soulverteam%2FSoulverCore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soulverteam%2FSoulverCore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soulverteam%2FSoulverCore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soulverteam%2FSoulverCore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/soulverteam","download_url":"https://codeload.github.com/soulverteam/SoulverCore/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226090029,"owners_count":17572113,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calculations","calculator","currency","currency-converter","currency-rates","date-calculator","date-parser","datetime","expression-evaluator","math-engine","math-expressions","mathematical-expressions","natural-language","natural-language-processing","notepad-calculator","soulver","swift","timezone"],"created_at":"2024-08-05T23:00:29.725Z","updated_at":"2025-07-16T01:32:21.226Z","avatar_url":"https://github.com/soulverteam.png","language":"Swift","readme":"![SoulverCore Icon](SoulverCoreIcon.png)\n\n# What is SoulverCore?\n\nSoulverCore is a natural language math engine used by the popular notepad calculator [Soulver](https://soulver.app).\n\nThe primary design goals of SoulverCore are:\n- Sensible defaults for most use cases (the same defaults used by Soulver)\n- A high level of extensibility (set variables, add new units, \u0026 define custom natural language functions)\n- Exceptional performance (7k-13k calculations/second on Apple Silicon chips)\n\nWhen considering SoulverCore for your project, note the following:\n- SoulverCore is written in Swift and works across all Apple platforms\n- SoulverCore has zero 3rd party dependencies\n- SoulverCore is exactly the same math library used inside the shipping version of Soulver (available for Mac since 2005)\n\n## Requirements\n- Xcode 15+\n- Swift 5.9+\n- SoulverCore is distributed as a binary framework (.xcframework) and includes builds for macOS (universal), iOS/iPadOS, and Mac Catalyst.\n- The minimum system requirements are macOS 10.15 Catalina \u0026 iOS 13 (the first releases to support Swift Concurrency features)\n\n## Installation using the Swift Package Manager (SPM)\n\nIn Xcode, go File \u003e Swift Packages \u003e Add Package Dependency, and paste in the URL of this repository (https://github.com/soulverteam/SoulverCore).\n\n## Manual Installation\n\nClone this repository, and drag `SoulverCore.xcframework` into the `Frameworks, Libraries, and Embedded Content` section of the General settings for your Mac or iOS target.\n\n## Getting Started\n\nTo calculate the result of a single expression, use a `Calculator` object:\n\n```swift\nimport SoulverCore\n\nlet calculator = Calculator(customization: .standard)\nlet result = calculator.calculate(\"123 + 456\")\nprint(\"The answer is \\(result.stringValue)\") // prints 579\n```\n\nSoulverCore can perform all sorts of calculations, including unit conversions, date \u0026 calendar math, rate calculations, percentage phrase functions, time zone conversions, and much more. It also cleverly ignores \"meaningless\" words:\n\n```swift\ncalculator.calculate(\"$10 for lunch + 15% tip\") // $11.50\ncalculator.calculate(\"65 kg in pounds\") // 143.3 lb\ncalculator.calculate(\"40 as % of 90\") // 44.44%\ncalculator.calculate(\"$150 is 25% on what\") // $120\ncalculator.calculate(\"$25/hour * 14 hours of work\") // $350.00\ncalculator.calculate(\"January 30 2020 + 3 months 2 weeks 5 days\") // May 19, 2020\ncalculator.calculate(\"9:35am in New York to Japan\") // 10:35 pm\ncalculator.calculate(\"$25k over 10 years at 7.5%\") // $51,525.79 (compound interest)\n\n```\n\n## Variables\n\nUse a `VariableList` to set values for words or phrases in your expression:\n\n```swift\nlet variableList = VariableList(variables:\n    [\n        Variable(name: \"a\", value: \"123\"),\n        Variable(name: \"b\", value: \"456\"),\n    ]\n)\ncalculator.calculate(\"a + b\", with: variableList) // 579        \n```\n\n## Locale Settings\n\nSoulverCore respects the decimal separator and thousands separator of the system locale. Alternatively, you can convert the standard EngineCustomization to another locale:\n\n```swift\n\nlet europeanLocale = Locale(identifier: \"en_DE\")\nlet localizedCustomization = EngineCustomization.standard.convertTo(locale: europeanLocale)\n\nlet calculator = Calculator(customization: localizedCustomization)\n\n /// In Germany a comma is used as a decimal separator\ncalculator.calculate(\"1,2 + 3,4\") // 4,6\n```\n\n## Output Formatting\n\nUse a `FormattingPreferences` to customize the way your result is formatted (how many decimal places to include, should the thousands separator be inserted, etc).\n\n```swift\nvar formattingPreferences = FormattingPreferences()\nformattingPreferences.dp = 2 // decimal places\ncalculator.formattingPreferences = formattingPreferences\n\ncalculator.calculate(\"π\") // 3.14\n```\n\n## Live Real-World \u0026 Crypto-Currency Rates\n\nThe `.standard` `EngineCustomization` uses hard-coded rates for 190 real-world \u0026 crypto-currencies. You can (and should) provide SoulverCore with up-to-date rates by setting the `currencyRateProvider` on your `EngineCustomization` to an object that conforms to `CurrencyRateProvider`.\n\nSoulverCore includes one `CurrencyRateProvider` you can use to fetch rates from the [European Central Bank](https://www.ecb.europa.eu/stats/eurofxref/) for 33 popular fiat currencies.\n\n```swift\n/// This is a currency rate provider that fetches 33 popular fiat currencies from the European Central Bank, no API key required\nlet ecbCurrencyRateProvider = ECBCurrencyRateProvider()\n\n/// Create a customization with this rate provider\nvar customizationWithLiveCurrencyRates = EngineCustomization.standard\ncustomizationWithLiveCurrencyRates.currencyRateProvider = ecbCurrencyRateProvider\n\n/// Create a calculator that uses this customization\nlet calculator = Calculator(customization: customizationWithLiveCurrencyRates)\n\n/// Update to the latest rates...\necbCurrencyRateProvider.updateRates { success in\n    \n    if success {\n        // The standard customization will now have access to the latest currency rates\n        let result = calculator.calculate(\"10 USD in EUR\")\n        print(result.stringValue)\n    }\n\n}\n\n```\n \nYou can create your own object that conforms to `CurrencyRateProvider` to provide rates for the currency codes you support. The `CurrencyRateProvider` protocol has a single method that returns the amount of a given currency that 1.0 USD can buy:\n\n```swift\nfunc rateFor(request: CurrencyRateRequest) -\u003e Decimal? {\n\n\tlet currencyCode = request.currencyCode // EUR, GBP, BTC, etc\n\n\t/// - Return an up-to-date rate in the form of how much 1 USD can purchase of the requested currency (i.e 1 USD = x EUR?)\n\t/// - If your rates are in terms of how much USD the requested currency can purchase (i.e 1 EUR = x USD?), remember to take the inverse by dividing 1 by your rate\n            \n\treturn \u003c# Currency Rate #\u003e\n}\n````\n\nRates are only requested from a `CurrencyRateProvider` at evaluation-time, so you don't need to recreate or `Calculator` with a new `EngineCustomization` when your currency rate data source is updated. However you must reevaluate your line or expression: the latest rates for any currencies used will be fetched from your provider, if necessary.\n\n## Custom Units\n\nYou can add custom units to an `EngineCustomization` object required by the initializer on `Calculator`\n\n```swift\n\n/// A good omakase EngineCustomization (the same used by Soulver.app)\nvar customization: EngineCustomization = .standard\n\n/// Set an array of custom units defined in terms of an existing unit in SoulverCore\ncustomization.customUnits = [\n    CustomUnit(name: \"parrots\", definition: 15, equivalentUnit: .centimeters),\n    CustomUnit(name: \"python\", definition: 570, equivalentUnit: .centimeters)\n]\n\n/// Create a Calculator using this customization\nlet calculator = Calculator(customization: customization)\n\n/// python and parrots are now recognized as units\ncalculator.calculate(\"1 python in parrots\") // 38 parrots\n```\n\n## Custom Functions\n\nThe syntax of a function in SoulverCore is flexible. We support traditional C-style \"func(x)\" functions, Swift-style \"calculate(withParameter: x)\" functions, or even natural phrases like \"calculate x\". \n\nYou can add custom functions objects to the `EngineCustomization` required by the initializer on `Calculator`. Here is an example of a custom function that takes 1 off a given number:\n\n```swift\n\n/// Get the default Engine Customization\nvar customization: EngineCustomization = .standard\n\n/// A prototype expression is an example of what the user will type to invoke your function\n/// - For example, the following function will trigger for any phrase with the form 'number before x', where x is some number\n\ncustomization.customFunctions = [CustomFunction(prototypeExpression: \"number before 9\", handler: { parameters in\n    \n    guard let parameterDecimalValue = parameters[0].decimalValue else {\n        return EvaluationResult.none\n    }\n    \n    return .decimal(parameterDecimalValue - 1.0)\n    \n})]\n\nlet calculator = Calculator(customization: customization)\nlet result = calculator.calculate(\"number before 35\")\n\nprint(result.stringValue) // prints '34'\n```\n\n## Variable Declarations\n\nA variable declaration is any phrase followed by equals and a value (i.e, \"total expenses = 123\").   \n\nVariable declarations are off by default, but can be enabled on your `EngineCustomization` and used on `Calculator` and `LineCollection`.\n\n```swift\n\n/// Get the default Engine Customization\nvar customization: EngineCustomization = .standard\n\n/// Add the variable declarations feature\ncustomization.featureFlags.variableDeclarations = true\n\n/// Use this customization with a new Calculator object\nlet calculator = Calculator(customization: customization)\n_ = calculator.calculate(\"discount = 10%\")\nlet result = calculator.calculate(\"$45k - discount\") // $40,500.00\n\n````\n\n## Performance\nCalculations are evaluated by SoulverCore in less than half a millisecond ⚡️! So, while SoulverCore classes are thread-safe, it's so fast that there is typically no need to perform single calculations off the main thread of your application.\n\n## Localizations\n\nIn addition to English, SoulverCore is fully localized into German, Russian, French, Spanish \u0026 simplified Chinese. \n\nThe various number \u0026 date formats of these various locales are also fully supported.\n\nAlso note that non-English languages are *additive*, meaning that, for instance, a German user would be able to use both English \u0026 German syntaxes.\n\n## More information\n\nYou can browse the complete documentation for SoulverCore [here](https://soulverteam.github.io/SoulverCore-Documentation/documentation/soulvercore/).\n\nAlternatively, a [DocC archive](https://developer.apple.com/documentation/docc) compatibile with Xcode or [Dash](https://kapeli.com/dash) is also available for [download](https://github.com/SoulverTeam/SoulverCore/releases/latest/download/SoulverCore.doccarchive.zip).\n\n## See Also\n\n__Natural language date parsing from strings__\n\nSoulverCore includes a powerful natural language date parsing engine that is much more versatile than Foundation's `DataDetector`.\n\nSee [NaturalLanguageDateParsing](https://github.com/soulverteam/NaturalLanguageDateParsing) to learn about how SoulverCore can help you parse natural language dates out of strings, and can be used to add a natural language date input field to your scheduling or calendar app (similar to features found in [Things](https://culturedcode.com/things/support/articles/9780167/) and [Fantastical](https://flexibits.com/fantastical-ios/help/adding)).\n\n__Data extraction from strings__\n\nSee [SoulverStringParsing](https://github.com/soulverteam/SoulverStringParsing) to learn about how SoulverCore can help you parse data out from strings in a type-safe way. It uses a natural and memorable syntax that's much more user friendly than regex for many tasks.\n\n__Adding calculation capabilities to an NSTextView or UITextView__\n\nSee the [SoulverTextKit](https://github.com/soulverteam/SoulverTextKit) project for an example of how to integrate the SoulverCore math engine into a standard macOS or iOS text view.\n\n## Kinds of apps using SoulverCore\n\n#### Spotlight Replacements\n- [Lacona](https://lacona.app)\n\n#### Notepads\n- [FSNotes](https://fsnot.es)\n\n#### Shortcut Action Providers\n- [Actions](https://github.com/sindresorhus/Actions)\n\n## Licence\n\nYou may use SoulverCore in personal or private projects. Please [email us](mailto:contact@soulver.app) if you wish to use SoulverCore in a publicly available, or commercial project.\n\nWe have various options available depending on your user base size, including a free license (with attribution). \n","funding_links":[],"categories":["Swift"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoulverteam%2FSoulverCore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoulverteam%2FSoulverCore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoulverteam%2FSoulverCore/lists"}