├── img ├── log.png ├── st.png ├── amgm.png ├── cases.png ├── cross.png ├── limit.png ├── long.png ├── square.png ├── trig.png ├── calculus.png ├── demorgan.png ├── lorentz.png ├── maxwell.png ├── standard.png ├── stirling.png ├── matrixmult.png ├── quadratic.png ├── ramanujan.png ├── cauchyschwarz.png ├── gaussintegral.png ├── schroedinger.png └── cauchyintegral.png ├── fonts ├── xits-math.otf ├── latinmodern-math.otf ├── texgyretermes-math.otf ├── GUST-FONT-LICENSE.txt ├── README-TeX-Gyre-Termes-Math.txt ├── README-Latin-Modern-Math.txt ├── OFL.txt └── math_table_to_plist.py ├── iosMathTests ├── en.lproj │ └── InfoPlist.strings └── iosMathTests-Info.plist ├── MathFontBundle ├── en.lproj │ └── InfoPlist.strings └── MathFontBundle-Info.plist ├── iosMathExample ├── en.lproj │ └── InfoPlist.strings ├── example │ ├── Default.png │ ├── Default@2x.png │ ├── Default-568h@2x.png │ ├── ViewController.h │ ├── main.m │ ├── AppDelegate.h │ └── AppDelegate.m ├── iosMath-Info.plist └── View.xib ├── iosMath.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── iosMath.xcscheme ├── MacOSMath.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcshareddata │ └── xcschemes │ │ └── MacOSMath.xcscheme └── project.pbxproj ├── iosMath.xcworkspace ├── xcshareddata │ └── IDEWorkspaceChecks.plist └── contents.xcworkspacedata ├── iosMath ├── render │ ├── UIColor+HexString.h │ ├── NSColor+HexString.h │ ├── MTLabel.h │ ├── NSView+backgroundColor.h │ ├── NSBezierPath+addLineToPoint.h │ ├── NSBezierPath+addLineToPoint.m │ ├── internal │ │ ├── MTTypesetter.h │ │ ├── MTFont+Internal.h │ │ ├── MTMathListDisplayInternal.h │ │ ├── MTFontMathTable.h │ │ └── MTFontMathTable.m │ ├── MTFont.h │ ├── NSView+backgroundColor.m │ ├── UIColor+HexString.m │ ├── MTLabel.m │ ├── NSColor+HexString.m │ ├── MTFontManager.h │ ├── MTConfig.h │ ├── MTFontManager.m │ ├── MTFont.m │ ├── MTMathUILabel.h │ ├── MTMathUILabel.m │ └── MTMathListDisplay.h ├── IosMath.h └── lib │ ├── MTUnicode.h │ ├── MTUnicode.m │ ├── MTMathListBuilder.h │ ├── MTMathListIndex.h │ ├── MTMathAtomFactory.h │ ├── MTMathListIndex.m │ └── MTMathList.h ├── Podfile.lock ├── MacOSMathExample ├── AppDelegate.h ├── main.m ├── AppDelegate.m ├── Info.plist └── Assets.xcassets │ └── AppIcon.appiconset │ └── Contents.json ├── .travis.yml ├── Podfile ├── LICENSE ├── Package.swift ├── iosMath.podspec ├── .gitignore ├── CHANGELOG.md ├── EXAMPLES.md └── README.md /img/log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/log.png -------------------------------------------------------------------------------- /img/st.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/st.png -------------------------------------------------------------------------------- /img/amgm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/amgm.png -------------------------------------------------------------------------------- /img/cases.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/cases.png -------------------------------------------------------------------------------- /img/cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/cross.png -------------------------------------------------------------------------------- /img/limit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/limit.png -------------------------------------------------------------------------------- /img/long.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/long.png -------------------------------------------------------------------------------- /img/square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/square.png -------------------------------------------------------------------------------- /img/trig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/trig.png -------------------------------------------------------------------------------- /img/calculus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/calculus.png -------------------------------------------------------------------------------- /img/demorgan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/demorgan.png -------------------------------------------------------------------------------- /img/lorentz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/lorentz.png -------------------------------------------------------------------------------- /img/maxwell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/maxwell.png -------------------------------------------------------------------------------- /img/standard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/standard.png -------------------------------------------------------------------------------- /img/stirling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/stirling.png -------------------------------------------------------------------------------- /fonts/xits-math.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/fonts/xits-math.otf -------------------------------------------------------------------------------- /img/matrixmult.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/matrixmult.png -------------------------------------------------------------------------------- /img/quadratic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/quadratic.png -------------------------------------------------------------------------------- /img/ramanujan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/ramanujan.png -------------------------------------------------------------------------------- /img/cauchyschwarz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/cauchyschwarz.png -------------------------------------------------------------------------------- /img/gaussintegral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/gaussintegral.png -------------------------------------------------------------------------------- /img/schroedinger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/schroedinger.png -------------------------------------------------------------------------------- /iosMathTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /MathFontBundle/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /img/cauchyintegral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/img/cauchyintegral.png -------------------------------------------------------------------------------- /iosMathExample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /fonts/latinmodern-math.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/fonts/latinmodern-math.otf -------------------------------------------------------------------------------- /fonts/texgyretermes-math.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/fonts/texgyretermes-math.otf -------------------------------------------------------------------------------- /iosMathExample/example/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/iosMathExample/example/Default.png -------------------------------------------------------------------------------- /iosMathExample/example/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/iosMathExample/example/Default@2x.png -------------------------------------------------------------------------------- /iosMathExample/example/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kostub/iosMath/HEAD/iosMathExample/example/Default-568h@2x.png -------------------------------------------------------------------------------- /iosMath.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MacOSMath.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /iosMath.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /iosMath/render/UIColor+HexString.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+HexString.h 3 | // iosMath 4 | // 5 | // Created by Markus Sähn on 21/03/2017. 6 | // 7 | // 8 | 9 | #if TARGET_OS_IPHONE 10 | 11 | @interface UIColor (HexString) 12 | 13 | + (UIColor *)colorFromHexString:(NSString *)hexString; 14 | 15 | @end 16 | #endif 17 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - iosMath (0.9.4) 3 | 4 | DEPENDENCIES: 5 | - iosMath (from `./`) 6 | 7 | EXTERNAL SOURCES: 8 | iosMath: 9 | :path: "./" 10 | 11 | SPEC CHECKSUMS: 12 | iosMath: f7a6cbadf9d836d2149c2a84c435b1effc244cba 13 | 14 | PODFILE CHECKSUM: bade56080a0531a08830155fc215a0a5b44dd183 15 | 16 | COCOAPODS: 1.7.0 17 | -------------------------------------------------------------------------------- /iosMath/render/NSColor+HexString.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSColor+HexString.h 3 | // iosMath 4 | // 5 | // Created by Markus Sähn on 21/03/2017. 6 | // 7 | // 8 | 9 | #include 10 | 11 | #if !TARGET_OS_IPHONE 12 | #import 13 | 14 | @interface NSColor (HexString) 15 | 16 | + (NSColor *)colorFromHexString:(NSString *)hexString; 17 | 18 | @end 19 | #endif 20 | -------------------------------------------------------------------------------- /iosMath.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /MacOSMathExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // MacOSMath 4 | // 5 | // Created by 安志钢 on 17-01-08. 6 | // Copyright © 2017年 安志钢. All rights reserved. 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | #import 13 | 14 | @interface AppDelegate : NSObject 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /MacOSMathExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MacOSMath 4 | // 5 | // Created by 安志钢 on 17-01-08. 6 | // Copyright © 2017年 安志钢. All rights reserved. 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | #import 13 | 14 | int main(int argc, const char * argv[]) { 15 | return NSApplicationMain(argc, argv); 16 | } 17 | -------------------------------------------------------------------------------- /iosMath/IosMath.h: -------------------------------------------------------------------------------- 1 | // 2 | // IosMath.h 3 | // iosMath 4 | // 5 | // Created by MARIO ANDHIKA on 8/28/15. 6 | // Copyright (C) 2015 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | 11 | #import 12 | #import 13 | #import 14 | #import 15 | -------------------------------------------------------------------------------- /iosMath/lib/MTUnicode.h: -------------------------------------------------------------------------------- 1 | // 2 | // MTUnicode.h 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/16/14. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | #import 13 | 14 | 15 | @interface NSString (Unicode) 16 | 17 | - (NSUInteger) unicodeLength; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /iosMath/render/MTLabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // MTLabel.h 3 | // MacOSMath 4 | // 5 | // Created by 安志钢 on 17-01-09. 6 | // 7 | // This software may be modified and distributed under the terms of the 8 | // MIT license. See the LICENSE file for details. 9 | // 10 | 11 | #include 12 | 13 | #if !TARGET_OS_IPHONE 14 | @import AppKit; 15 | 16 | @interface MTLabel : NSTextField 17 | 18 | @property (strong) NSString *text; 19 | 20 | @end 21 | #endif 22 | -------------------------------------------------------------------------------- /iosMathExample/example/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/29/13. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | #import 13 | 14 | @interface ViewController : UIViewController 15 | 16 | @property (weak, nonatomic) IBOutlet UIScrollView *scrollView; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /iosMath/render/NSView+backgroundColor.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSView+backgroundColor.h 3 | // MacOSMath 4 | // 5 | // Created by 安志钢 on 17-01-09. 6 | // 7 | // This software may be modified and distributed under the terms of the 8 | // MIT license. See the LICENSE file for details. 9 | // 10 | 11 | #include 12 | 13 | #if !TARGET_OS_IPHONE 14 | #import 15 | 16 | @interface NSView (backgroundColor) 17 | 18 | @property (strong) NSColor *backgroundColor; 19 | 20 | @end 21 | #endif 22 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode7.3 3 | before_install: 4 | - gem install cocoapods # Since Travis is not always on latest version 5 | xcode_workspace: iosMath.xcworkspace # path to your xcodeproj folder 6 | xcode_scheme: 7 | - iosMath 8 | - MacOSMath 9 | xcode_sdk: 10 | - iphonesimulator9.3 11 | - macosx10.11 12 | matrix: 13 | exclude: 14 | - xcode_scheme: iosMath 15 | xcode_sdk: macosx10.11 16 | - xcode_scheme: MacOSMath 17 | xcode_sdk: iphonesimulator9.3 18 | -------------------------------------------------------------------------------- /iosMath/render/NSBezierPath+addLineToPoint.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSBezierPath+addLineToPoint.h 3 | // MacOSMath 4 | // 5 | // Created by 安志钢 on 17-01-09. 6 | // 7 | // This software may be modified and distributed under the terms of the 8 | // MIT license. See the LICENSE file for details. 9 | // 10 | 11 | #include 12 | 13 | #if !TARGET_OS_IPHONE 14 | #import 15 | 16 | @interface NSBezierPath (addLineToPoint) 17 | 18 | - (void)addLineToPoint:(CGPoint)point; 19 | 20 | @end 21 | #endif 22 | -------------------------------------------------------------------------------- /iosMath/render/NSBezierPath+addLineToPoint.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSBezierPath+addLineToPoint.m 3 | // MacOSMath 4 | // 5 | // Created by 安志钢 on 17-01-09. 6 | // 7 | // This software may be modified and distributed under the terms of the 8 | // MIT license. See the LICENSE file for details. 9 | // 10 | 11 | #import "NSBezierPath+addLineToPoint.h" 12 | 13 | #if !TARGET_OS_IPHONE 14 | @implementation NSBezierPath (addLineToPoint) 15 | 16 | - (void)addLineToPoint:(CGPoint)point 17 | { 18 | [self lineToPoint:point]; 19 | } 20 | 21 | @end 22 | #endif 23 | -------------------------------------------------------------------------------- /iosMathExample/example/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/26/13. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | #import 13 | 14 | #import "AppDelegate.h" 15 | 16 | int main(int argc, char *argv[]) 17 | { 18 | @autoreleasepool { 19 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Needed due to 2 | # http://stackoverflow.com/questions/33395675/cocoapods-file-reference-is-a-member-of-multiple-groups 3 | workspace 'iosMath.xcworkspace' 4 | 5 | install! 'cocoapods', :deterministic_uuids => false 6 | 7 | target 'iosMathExample' do 8 | project 'iosMath.xcodeproj' 9 | pod 'iosMath', :path => './' 10 | end 11 | 12 | target 'iosMathTests' do 13 | project 'iosMath.xcodeproj' 14 | pod 'iosMath', :path => './' 15 | end 16 | 17 | target 'MacOSMath' do 18 | project 'MacOSMath.xcodeproj' 19 | pod 'iosMath', :path => './' 20 | end 21 | -------------------------------------------------------------------------------- /iosMathExample/example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/26/13. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | #import 13 | 14 | @interface AppDelegate : UIResponder 15 | 16 | @property (strong, nonatomic) UIWindow *window; 17 | 18 | @property (strong, nonatomic) UIViewController *viewController; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /iosMath/lib/MTUnicode.m: -------------------------------------------------------------------------------- 1 | // 2 | // MTUnicode.m 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/16/14. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | #import "MTUnicode.h" 13 | 14 | @implementation NSString (Unicode) 15 | 16 | 17 | - (NSUInteger)unicodeLength 18 | { 19 | // Each unicode char is represented as 4 bytes in utf-32. 20 | return [self lengthOfBytesUsingEncoding:NSUTF32StringEncoding] / 4; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /iosMath/render/internal/MTTypesetter.h: -------------------------------------------------------------------------------- 1 | // 2 | // MTTypesetter.h 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 6/21/16. 6 | // 7 | // This software may be modified and distributed under the terms of the 8 | // MIT license. See the LICENSE file for details. 9 | // 10 | 11 | @import Foundation; 12 | 13 | #import "MTMathListDisplay.h" 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | /// This class does all the LaTeX typesetting logic. 18 | /// For ADVANCED use only. 19 | @interface MTTypesetter : NSObject 20 | 21 | /// Renders a MTMathList as a list of displays. 22 | + (MTMathListDisplay*) createLineForMathList:(MTMathList*) mathList font:(MTFont*) font style:(MTLineStyle) style; 23 | 24 | @end 25 | 26 | NS_ASSUME_NONNULL_END 27 | -------------------------------------------------------------------------------- /iosMath/render/MTFont.h: -------------------------------------------------------------------------------- 1 | // 2 | // MTFont.h 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 5/18/16. 6 | // 7 | // This software may be modified and distributed under the terms of the 8 | // MIT license. See the LICENSE file for details. 9 | // 10 | 11 | @import CoreText; 12 | @import CoreGraphics; 13 | @import Foundation; 14 | 15 | /** MTFont wraps the inconvenient distinction between CTFont and CGFont as well 16 | as the data loaded from the math table. 17 | */ 18 | @interface MTFont : NSObject 19 | 20 | /** Returns a copy of this font but with a different size. */ 21 | - (nonnull MTFont*) copyFontWithSize:(CGFloat) size; 22 | 23 | /** The size of this font in points. */ 24 | @property (nonatomic, readonly) CGFloat fontSize; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /iosMathTests/iosMathTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /iosMath/render/NSView+backgroundColor.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSView+backgroundColor.m 3 | // MacOSMath 4 | // 5 | // Created by 安志钢 on 17-01-09. 6 | // 7 | // This software may be modified and distributed under the terms of the 8 | // MIT license. See the LICENSE file for details. 9 | // 10 | 11 | #import "NSView+backgroundColor.h" 12 | 13 | #if !TARGET_OS_IPHONE 14 | @implementation NSView (backgroundColor) 15 | 16 | - (NSColor *)backgroundColor 17 | { 18 | if (self.layer.backgroundColor == nil) { 19 | return [NSColor clearColor]; 20 | } 21 | return [NSColor colorWithCGColor:self.layer.backgroundColor]; 22 | } 23 | 24 | - (void)setBackgroundColor:(NSColor *)backgroundColor 25 | { 26 | self.layer.backgroundColor = [NSColor clearColor].CGColor; 27 | [self setWantsLayer:YES]; 28 | } 29 | 30 | @end 31 | #endif 32 | -------------------------------------------------------------------------------- /iosMath/render/UIColor+HexString.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+HexString.m 3 | // iosMath 4 | // 5 | // Created by Markus Sähn on 21/03/2017. 6 | // 7 | // 8 | 9 | #import "UIColor+HexString.h" 10 | 11 | #if TARGET_OS_IPHONE 12 | 13 | @implementation UIColor (HexString) 14 | 15 | + (UIColor *)colorFromHexString:(NSString *)hexString { 16 | if ([hexString isEqualToString:@""]) { 17 | return nil; 18 | } 19 | 20 | if ([hexString characterAtIndex:0] != '#') { 21 | return nil; 22 | } 23 | 24 | unsigned rgbValue = 0; 25 | 26 | NSScanner *scanner = [NSScanner scannerWithString:hexString]; 27 | if ([hexString characterAtIndex:0] == '#') { 28 | [scanner setScanLocation:1]; 29 | } 30 | 31 | [scanner scanHexInt:&rgbValue]; 32 | return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0]; 33 | } 34 | 35 | @end 36 | #endif 37 | -------------------------------------------------------------------------------- /iosMath/render/MTLabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // MTLabel.m 3 | // MacOSMath 4 | // 5 | // Created by 安志钢 on 17-01-09. 6 | // 7 | // This software may be modified and distributed under the terms of the 8 | // MIT license. See the LICENSE file for details. 9 | // 10 | 11 | #import "MTLabel.h" 12 | 13 | #if !TARGET_OS_IPHONE 14 | @implementation MTLabel 15 | 16 | @synthesize bezeled, drawsBackground, editable, selectable, stringValue; 17 | 18 | - (instancetype)init 19 | { 20 | self = [super init]; 21 | 22 | if (self != nil) { 23 | super.bezeled = NO; 24 | super.drawsBackground = NO; 25 | super.editable = NO; 26 | super.selectable = NO; 27 | } 28 | 29 | return self; 30 | } 31 | 32 | #pragma mark - Customized getter and setter methods for property text. 33 | - (NSString *)text 34 | { 35 | return super.stringValue; 36 | } 37 | 38 | - (void)setText:(NSString *)text 39 | { 40 | super.stringValue = text; 41 | } 42 | 43 | @end 44 | #endif 45 | -------------------------------------------------------------------------------- /MacOSMathExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // MacOSMath 4 | // 5 | // Created by 安志钢 on 17-01-08. 6 | // Copyright © 2017年 安志钢. All rights reserved. 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | #import "AppDelegate.h" 13 | #import "MTMathUILabel.h" 14 | 15 | @interface AppDelegate () 16 | 17 | @property (weak) IBOutlet NSWindow *window; 18 | @property (weak) IBOutlet MTMathUILabel *screen; 19 | @property (weak) IBOutlet NSTextField *inputTextField; 20 | 21 | @end 22 | 23 | @implementation AppDelegate 24 | 25 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification 26 | { 27 | // Insert code here to initialize your application 28 | } 29 | 30 | 31 | - (void)applicationWillTerminate:(NSNotification *)aNotification 32 | { 33 | // Insert code here to tear down your application 34 | } 35 | 36 | - (IBAction)clickUpdateButton:(NSButton *)sender 37 | { 38 | self.screen.latex = self.inputTextField.stringValue; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 MathChat 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /iosMath/render/NSColor+HexString.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSColor+HexString.m 3 | // iosMath 4 | // 5 | // Created by Markus Sähn on 21/03/2017. 6 | // 7 | // 8 | 9 | #import "NSColor+HexString.h" 10 | 11 | #if !TARGET_OS_IPHONE 12 | @implementation NSColor (HexString) 13 | 14 | + (NSColor *)colorFromHexString:(NSString *)hexString { 15 | if ([hexString isEqualToString:@""]) { 16 | return nil; 17 | } 18 | 19 | if ([hexString characterAtIndex:0] != '#') { 20 | return nil; 21 | } 22 | 23 | unsigned rgbValue = 0; 24 | 25 | NSScanner *scanner = [NSScanner scannerWithString:hexString]; 26 | if ([hexString characterAtIndex:0] == '#') { 27 | [scanner setScanLocation:1]; 28 | } 29 | 30 | [scanner scanHexInt:&rgbValue]; 31 | // NOTE: red:green:blue:alpha: in AppKit/NSColor.h is NS_AVAILABLE_MAC(10_9), unavailable for macOS 10.8 . 32 | // Older method name colorWithSRGBRed::green:blue:alpha: works. 33 | return [NSColor colorWithSRGBRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0]; 34 | } 35 | 36 | @end 37 | #endif 38 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.2 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "iosMath", 8 | products: [ 9 | // Products define the executables and libraries produced by a package, and make them visible to other packages. 10 | .library( 11 | name: "iosMath", 12 | targets: ["iosMath"]), 13 | ], 14 | dependencies: [ 15 | // Dependencies declare other packages that this package depends on. 16 | // .package(url: /* package url */, from: "1.0.0"), 17 | ], 18 | targets: [ 19 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 20 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 21 | .target( 22 | name: "iosMath", 23 | dependencies: [], 24 | path: "./"), 25 | .testTarget( 26 | name: "iosMathTests", 27 | dependencies: ["iosMath"]), 28 | ] 29 | ) 30 | -------------------------------------------------------------------------------- /MacOSMathExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2017年 安志钢. All rights reserved. 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /MacOSMathExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /iosMath/render/internal/MTFont+Internal.h: -------------------------------------------------------------------------------- 1 | // 2 | // MTFont+Internal.h 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 5/20/16. 6 | // 7 | // This software may be modified and distributed under the terms of the 8 | // MIT license. See the LICENSE file for details. 9 | // 10 | 11 | #import "MTFont.h" 12 | #import "MTFontMathTable.h" 13 | 14 | /** This category add functions to MTFont that are meant to be internal 15 | to this library for rendering purposes. */ 16 | @interface MTFont (Internal) 17 | 18 | /** Load the font with a given name. This is the designated initializer. */ 19 | - (nonnull instancetype) initFontWithName:(nonnull NSString*) name size:(CGFloat) size; 20 | 21 | /** Access to the raw CTFontRef if needed. */ 22 | @property (nonatomic, readonly, nonnull) CTFontRef ctFont; 23 | 24 | /** The font math table. */ 25 | @property (nonatomic, readonly, nonnull) MTFontMathTable* mathTable; 26 | 27 | /** Returns the name of the given glyph or null if the glyph 28 | is not associated with the font. */ 29 | - (nullable NSString*) getGlyphName:(CGGlyph) glyph; 30 | 31 | /** Returns a glyph associated with the given name. */ 32 | - (CGGlyph) getGlyphWithName:(nonnull NSString*) glyphName; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /iosMath.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "iosMath" 3 | s.version = "0.9.5" 4 | s.summary = "Math equation rendering for iOS and OS X" 5 | s.description = <<-DESC 6 | iosMath is a library for typesetting math formulas in iOS and OS X using 7 | CoreText. It renders formulae written in latex in a UILabel equivalent 8 | class using the same typsetting rules as latex. This enables displaying 9 | beautifully rendered math equations in iOS/MacOS applications. 10 | DESC 11 | s.homepage = "https://github.com/kostub/iosMath" 12 | s.license = { :type => "MIT", :file => "LICENSE" } 13 | s.author = { "Kostub Deshmukh" => "kostub@gmail.com" } 14 | s.ios.deployment_target = '6.0' 15 | s.osx.deployment_target = '10.8' 16 | s.source = { :git => "https://github.com/kostub/iosMath.git", :tag => s.version.to_s } 17 | s.source_files = 'iosMath/**/*.{h,m}' 18 | s.private_header_files = 'iosMath/render/internal/*.h' 19 | s.resource_bundles = { 20 | 'mathFonts' => [ 'fonts/*.otf', 'fonts/*.plist' ] 21 | } 22 | s.frameworks = "CoreGraphics", "QuartzCore", "CoreText" 23 | s.ios.frameworks = "UIKit" 24 | s.osx.frameworks = "AppKit" 25 | s.requires_arc = true 26 | end 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData 8 | .DS_Store 9 | 10 | ## Various settings 11 | *.pbxuser 12 | !default.pbxuser 13 | *.mode1v3 14 | !default.mode1v3 15 | *.mode2v3 16 | !default.mode2v3 17 | *.perspectivev3 18 | !default.perspectivev3 19 | xcuserdata 20 | 21 | ## Other 22 | *.xccheckout 23 | *.moved-aside 24 | *.xcuserstate 25 | *.xcscmblueprint 26 | 27 | ## Obj-C/Swift specific 28 | *.hmap 29 | *.ipa 30 | 31 | # CocoaPods 32 | # 33 | # We recommend against adding the Pods directory to your .gitignore. However 34 | # you should judge for yourself, the pros and cons are mentioned at: 35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 36 | # 37 | Pods/ 38 | 39 | # Carthage 40 | # 41 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 42 | # Carthage/Checkouts 43 | 44 | Carthage/Build 45 | 46 | # fastlane 47 | # 48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 49 | # screenshots whenever they are needed. 50 | # For more information about the recommended setup visit: 51 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md 52 | 53 | fastlane/report.xml 54 | fastlane/screenshots 55 | -------------------------------------------------------------------------------- /MathFontBundle/MathFontBundle-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIconFile 8 | 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | CFPlugInDynamicRegisterFunction 24 | 25 | CFPlugInDynamicRegistration 26 | NO 27 | CFPlugInFactories 28 | 29 | 00000000-0000-0000-0000-000000000000 30 | MyFactoryFunction 31 | 32 | CFPlugInTypes 33 | 34 | 00000000-0000-0000-0000-000000000000 35 | 36 | 00000000-0000-0000-0000-000000000000 37 | 38 | 39 | CFPlugInUnloadFunction 40 | 41 | NSHumanReadableCopyright 42 | Copyright © 2014 MathChat. 43 | 44 | 45 | -------------------------------------------------------------------------------- /iosMath/render/MTFontManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // MTFontManager.h 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/30/13. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | @import Foundation; 13 | 14 | #import "MTFont.h" 15 | 16 | /** A manager to load font files from disc and keep them 17 | in memory. */ 18 | @interface MTFontManager : NSObject 19 | 20 | /** Get the singleton instance of MTFontManager. */ 21 | + (nonnull instancetype) fontManager; 22 | 23 | /** Returns the default font, which is Latin Modern Math with 20pt */ 24 | - (nonnull MTFont*) defaultFont; 25 | 26 | /** Load a font with the given name. For the font to load, there 27 | must be a .otf file with the given name and a .plist file containing 28 | the math table data. The math table can be extracted using math_table_to_plist 29 | python script. 30 | @param name The name of the font file. 31 | @param size The size of the font to return. 32 | */ 33 | - (nonnull MTFont*) fontWithName:(nonnull NSString*) name size:(CGFloat) size; 34 | 35 | /** Helper function to return the Xits Math font. */ 36 | - (nonnull MTFont*) xitsFontWithSize:(CGFloat) size; 37 | 38 | /** Helper function to return the Tex Gyre Termes Math font. */ 39 | - (nonnull MTFont*) termesFontWithSize:(CGFloat) size; 40 | 41 | /** Helper function to return the Latin Modern Math font. */ 42 | - (nonnull MTFont*) latinModernFontWithSize:(CGFloat) size; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /fonts/GUST-FONT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | % This is a preliminary version (2006-09-30), barring acceptance from 2 | % the LaTeX Project Team and other feedback, of the GUST Font License. 3 | % (GUST is the Polish TeX Users Group, http://www.gust.org.pl) 4 | % 5 | % For the most recent version of this license see 6 | % http://www.gust.org.pl/fonts/licenses/GUST-FONT-LICENSE.txt 7 | % or 8 | % http://tug.org/fonts/licenses/GUST-FONT-LICENSE.txt 9 | % 10 | % This work may be distributed and/or modified under the conditions 11 | % of the LaTeX Project Public License, either version 1.3c of this 12 | % license or (at your option) any later version. 13 | % 14 | % Please also observe the following clause: 15 | % 1) it is requested, but not legally required, that derived works be 16 | % distributed only after changing the names of the fonts comprising this 17 | % work and given in an accompanying "manifest", and that the 18 | % files comprising the Work, as listed in the manifest, also be given 19 | % new names. Any exceptions to this request are also given in the 20 | % manifest. 21 | % 22 | % We recommend the manifest be given in a separate file named 23 | % MANIFEST-.txt, where is some unique identification 24 | % of the font family. If a separate "readme" file accompanies the Work, 25 | % we recommend a name of the form README-.txt. 26 | % 27 | % The latest version of the LaTeX Project Public License is in 28 | % http://www.latex-project.org/lppl.txt and version 1.3c or later 29 | % is part of all distributions of LaTeX version 2006/05/20 or later. 30 | 31 | -------------------------------------------------------------------------------- /iosMath/render/MTConfig.h: -------------------------------------------------------------------------------- 1 | // 2 | // MTConfig.h 3 | // MacOSMath 4 | // 5 | // Created by 安志钢 on 17-01-09. 6 | // 7 | // This software may be modified and distributed under the terms of the 8 | // MIT license. See the LICENSE file for details. 9 | // 10 | 11 | // Make TARGET_OS_IPHONE macro visible. 12 | #include 13 | 14 | // Type definitions. 15 | #if TARGET_OS_IPHONE 16 | // TARGET_OS_MAC is defined as 1 for both Mac OS and iOS, 17 | // so TARGET_OS_IPHONE is reliable. 18 | @import UIKit; 19 | #import "UIColor+HexString.h" 20 | 21 | typedef UIView MTView; 22 | typedef UIColor MTColor; 23 | typedef UIBezierPath MTBezierPath; 24 | typedef UIEdgeInsets MTEdgeInsets; 25 | typedef UILabel MTLabel; 26 | typedef CGRect MTRect; 27 | 28 | #define MTEdgeInsetsZero UIEdgeInsetsZero 29 | #define MTGraphicsGetCurrentContext() UIGraphicsGetCurrentContext() 30 | 31 | #else 32 | @import AppKit; 33 | #import "NSBezierPath+addLineToPoint.h" 34 | #import "NSView+backgroundColor.h" 35 | #import "NSColor+HexString.h" 36 | #import "MTLabel.h" 37 | 38 | typedef NSView MTView; 39 | typedef NSColor MTColor; 40 | typedef NSBezierPath MTBezierPath; 41 | typedef NSEdgeInsets MTEdgeInsets; 42 | typedef NSRect MTRect; 43 | 44 | // For backward compatibility, DO NOT use NSEdgeInsetsZero (Available from OS X 10.10). 45 | #define MTEdgeInsetsZero (NSEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f)); 46 | #define MTGraphicsGetCurrentContext() ([[NSGraphicsContext currentContext] graphicsPort]) 47 | 48 | #endif // TARGET_OS_IPHONE 49 | -------------------------------------------------------------------------------- /iosMathExample/iosMath-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /iosMath/render/MTFontManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // MTFontManager.m 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/30/13. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | #import "MTFontManager.h" 13 | #import "MTFont+Internal.h" 14 | 15 | const int kDefaultFontSize = 20; 16 | 17 | @interface MTFontManager () 18 | 19 | @property (nonatomic, nonnull) NSMutableDictionary* nameToFontMap; 20 | 21 | @end 22 | 23 | @implementation MTFontManager 24 | 25 | + (instancetype) fontManager 26 | { 27 | static MTFontManager* manager = nil; 28 | if (manager == nil) { 29 | manager = [MTFontManager new]; 30 | } 31 | return manager; 32 | } 33 | 34 | - (instancetype)init 35 | { 36 | self = [super init]; 37 | if (self) { 38 | self.nameToFontMap = [[NSMutableDictionary alloc] init]; 39 | } 40 | return self; 41 | } 42 | 43 | - (MTFont *)fontWithName:(NSString *)name size:(CGFloat)size 44 | { 45 | MTFont* f = self.nameToFontMap[name]; 46 | if (!f) { 47 | f = [[MTFont alloc] initFontWithName:name size:size]; 48 | self.nameToFontMap[name] = f; 49 | } 50 | if (f.fontSize == size) { 51 | return f; 52 | } else { 53 | return [f copyFontWithSize:size]; 54 | } 55 | } 56 | 57 | - (MTFont *)latinModernFontWithSize:(CGFloat)size 58 | { 59 | return [self fontWithName:@"latinmodern-math" size:size]; 60 | } 61 | 62 | - (MTFont *)xitsFontWithSize:(CGFloat)size 63 | { 64 | return [self fontWithName:@"xits-math" size:size]; 65 | } 66 | 67 | - (MTFont *)termesFontWithSize:(CGFloat)size 68 | { 69 | return [self fontWithName:@"texgyretermes-math" size:size]; 70 | } 71 | 72 | - (MTFont *)defaultFont 73 | { 74 | return [self latinModernFontWithSize:kDefaultFontSize]; 75 | } 76 | 77 | @end 78 | -------------------------------------------------------------------------------- /iosMathExample/example/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/26/13. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | #import "AppDelegate.h" 13 | #import "ViewController.h" 14 | 15 | @implementation AppDelegate 16 | 17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 18 | { 19 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 20 | // Override point for customization after application launch. 21 | self.window.backgroundColor = [UIColor whiteColor]; 22 | self.viewController = [[ViewController alloc] initWithNibName:@"View" bundle:nil]; 23 | self.window.rootViewController = self.viewController; 24 | [self.window makeKeyAndVisible]; 25 | return YES; 26 | } 27 | 28 | - (void)applicationWillResignActive:(UIApplication *)application 29 | { 30 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 31 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 32 | } 33 | 34 | - (void)applicationDidEnterBackground:(UIApplication *)application 35 | { 36 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 37 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 38 | } 39 | 40 | - (void)applicationWillEnterForeground:(UIApplication *)application 41 | { 42 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 43 | } 44 | 45 | - (void)applicationDidBecomeActive:(UIApplication *)application 46 | { 47 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 48 | } 49 | 50 | - (void)applicationWillTerminate:(UIApplication *)application 51 | { 52 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /MacOSMath.xcodeproj/xcshareddata/xcschemes/MacOSMath.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /iosMath/lib/MTMathListBuilder.h: -------------------------------------------------------------------------------- 1 | // 2 | // MTMathListBuilder.h 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/28/13. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | @import Foundation; 13 | 14 | #import "MTMathList.h" 15 | 16 | FOUNDATION_EXPORT NSString *const _Nonnull MTParseError; 17 | 18 | /** `MTMathListBuilder` is a class for parsing LaTeX into an `MTMathList` that 19 | can be rendered and processed mathematically. 20 | */ 21 | @interface MTMathListBuilder : NSObject 22 | 23 | /** Contains any error that occurred during parsing. */ 24 | @property (nonatomic, readonly, nullable) NSError* error; 25 | 26 | /** Create a `MTMathListBuilder` for the given string. After instantiating the 27 | `MTMathListBuilder, use `build` to build the mathlist. Create a new `MTMathListBuilder` 28 | for each string that needs to be parsed. Do not reuse the object. 29 | @param str The LaTeX string to be used to build the `MTMathList` 30 | */ 31 | - (nonnull instancetype) initWithString:(nonnull NSString*) str NS_DESIGNATED_INITIALIZER; 32 | - (nonnull instancetype) init NS_UNAVAILABLE; 33 | 34 | /// Builds a mathlist from the given string. Returns nil if there is an error. 35 | - (nullable MTMathList*) build; 36 | 37 | /** Construct a math list from a given string. If there is parse error, returns 38 | nil. To retrieve the error use the function `[MTMathListBuilder buildFromString:error:]`. 39 | */ 40 | + (nullable MTMathList*) buildFromString:(nonnull NSString*) str; 41 | 42 | /** Construct a math list from a given string. If there is an error while 43 | constructing the string, this returns nil. The error is returned in the 44 | `error` parameter. 45 | */ 46 | + (nullable MTMathList*) buildFromString:(nonnull NSString*) str error:( NSError* _Nullable * _Nullable) error; 47 | 48 | /// This converts the MTMathList to LaTeX. 49 | + (nonnull NSString*) mathListToString:(nonnull MTMathList*) ml; 50 | 51 | /** 52 | @typedef MTParseErrors 53 | @brief The error encountered when parsing a LaTeX string. 54 | 55 | The `code` in the `NSError` is one of the following indiciating why the LaTeX string 56 | could not be parsed. 57 | */ 58 | typedef NS_ENUM(NSUInteger, MTParseErrors) { 59 | /// The braces { } do not match. 60 | MTParseErrorMismatchBraces = 1, 61 | /// A command in the string is not recognized. 62 | MTParseErrorInvalidCommand, 63 | /// An expected character such as ] was not found. 64 | MTParseErrorCharacterNotFound, 65 | /// The \left or \right command was not followed by a delimiter. 66 | MTParseErrorMissingDelimiter, 67 | /// The delimiter following \left or \right was not a valid delimiter. 68 | MTParseErrorInvalidDelimiter, 69 | /// There is no \right corresponding to the \left command. 70 | MTParseErrorMissingRight, 71 | /// There is no \left corresponding to the \right command. 72 | MTParseErrorMissingLeft, 73 | /// The environment given to the \begin command is not recognized 74 | MTParseErrorInvalidEnv, 75 | /// A command is used which is only valid inside a \begin,\end environment 76 | MTParseErrorMissingEnv, 77 | /// There is no \begin corresponding to the \end command. 78 | MTParseErrorMissingBegin, 79 | /// There is no \end corresponding to the \begin command. 80 | MTParseErrorMissingEnd, 81 | /// The number of columns do not match the environment 82 | MTParseErrorInvalidNumColumns, 83 | /// Internal error, due to a programming mistake. 84 | MTParseErrorInternalError, 85 | /// Limit control applied incorrectly 86 | MTParseErrorInvalidLimits, 87 | }; 88 | 89 | @end 90 | -------------------------------------------------------------------------------- /iosMath/render/MTFont.m: -------------------------------------------------------------------------------- 1 | // 2 | // MTFont.m 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 5/18/16. 6 | // 7 | // This software may be modified and distributed under the terms of the 8 | // MIT license. See the LICENSE file for details. 9 | // 10 | 11 | #import "MTFont.h" 12 | #import "MTFont+Internal.h" 13 | 14 | @interface MTFont () 15 | 16 | @property (nonatomic, assign) CGFontRef defaultCGFont; 17 | @property (nonatomic, assign) CTFontRef ctFont; 18 | @property (nonatomic, strong) MTFontMathTable* mathTable; 19 | @property (nonatomic, strong) NSDictionary* rawMathTable; 20 | 21 | @end 22 | 23 | @implementation MTFont 24 | 25 | - (instancetype)initFontWithName:(NSString *)name size:(CGFloat)size 26 | { 27 | self = [super init]; 28 | if (self != nil) { 29 | // CTFontCreateWithName does not load the complete math font, it only has about half the glyphs of the full math font. 30 | // In particular it does not have the math italic characters which breaks our variable rendering. 31 | // So we first load a CGFont from the file and then convert it to a CTFont. 32 | 33 | NSBundle* bundle = [MTFont fontBundle]; 34 | NSString* fontPath = [bundle pathForResource:name ofType:@"otf"]; 35 | CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename(fontPath.UTF8String); 36 | _defaultCGFont = CGFontCreateWithDataProvider(fontDataProvider); 37 | CFRelease(fontDataProvider); 38 | 39 | _ctFont = CTFontCreateWithGraphicsFont(self.defaultCGFont, size, nil, nil); 40 | 41 | NSString* mathTablePlist = [bundle pathForResource:name ofType:@"plist"]; 42 | NSDictionary* dict = [NSDictionary dictionaryWithContentsOfFile:mathTablePlist]; 43 | self.rawMathTable = dict; 44 | self.mathTable = [[MTFontMathTable alloc] initWithFont:self mathTable:_rawMathTable]; 45 | } 46 | return self; 47 | } 48 | 49 | - (void)setDefaultCGFont:(CGFontRef)defaultCGFont 50 | { 51 | if (_defaultCGFont != nil) { 52 | CFRelease(_defaultCGFont); 53 | } 54 | if (defaultCGFont != nil) { 55 | CFRetain(defaultCGFont); 56 | } 57 | _defaultCGFont = defaultCGFont; 58 | } 59 | 60 | - (void)setCtFont:(CTFontRef)ctFont { 61 | if (_ctFont != nil) { 62 | CFRelease(_ctFont); 63 | } 64 | if (ctFont != nil) { 65 | CFRetain(ctFont); 66 | } 67 | _ctFont = ctFont; 68 | } 69 | 70 | + (NSBundle*) fontBundle 71 | { 72 | // Uses bundle for class so that this can be access by the unit tests. 73 | return [NSBundle bundleWithURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"mathFonts" withExtension:@"bundle"]]; 74 | } 75 | 76 | - (MTFont *)copyFontWithSize:(CGFloat)size 77 | { 78 | MTFont* copyFont = [[[self class] alloc] init]; 79 | copyFont.defaultCGFont = self.defaultCGFont; 80 | CTFontRef newCtFont = CTFontCreateWithGraphicsFont(self.defaultCGFont, size, nil, nil); 81 | copyFont.ctFont = newCtFont; 82 | copyFont.rawMathTable = self.rawMathTable; 83 | copyFont.mathTable = [[MTFontMathTable alloc] initWithFont:copyFont mathTable:copyFont.rawMathTable]; 84 | CFRelease(newCtFont); 85 | return copyFont; 86 | } 87 | 88 | -(NSString*) getGlyphName:(CGGlyph) glyph 89 | { 90 | NSString* name = CFBridgingRelease(CGFontCopyGlyphNameForGlyph(self.defaultCGFont, glyph)); 91 | return name; 92 | } 93 | 94 | - (CGGlyph)getGlyphWithName:(NSString *)glyphName 95 | { 96 | return CGFontGetGlyphWithGlyphName(self.defaultCGFont, (__bridge CFStringRef) glyphName); 97 | } 98 | 99 | - (CGFloat)fontSize 100 | { 101 | return CTFontGetSize(self.ctFont); 102 | } 103 | 104 | - (void)dealloc 105 | { 106 | self.defaultCGFont=nil; 107 | self.ctFont=nil; 108 | } 109 | @end 110 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Changelog 2 | 3 | ### v0.9.5 (2019-06-03) 4 | * Add colorbox command (#121) 5 | * Cyrillic support (#108) 6 | * When there is only one element in row, an array error is reported. (#111) 7 | * Fix: on macOS 10.13, NSSegmentItemImageView returns nil for layer.backgroundColor. Need to check for this and return a default color (clear) 8 | * Added textrm (#61) 9 | 10 | ### v0.9.4 (2017-05-07) 11 | * Support for color (\\textcolor) (Thanks to Markus) 12 | * Fix issue with cramped style in tables (Thanks to Jacob) 13 | 14 | ### v0.9.3 (2017-01-22) 15 | * Support for changing font styles: (\\mathrm, \\mathcal, \\mathbf etc.) 16 | * Support for the \\text command. 17 | * Fix issue with \\$ not being rendered correctly. 18 | * Support for \\limits and \\nolimits 19 | 20 | ### v0.9.2 (2017-01-11) 21 | * Support for MacOS (Thanks to AnZhg) 22 | * Better AutoLayout support (Thanks to zhubofei) 23 | * Support for custom defined commands. 24 | * Bug fixes for error label. 25 | * Removing error logging (Thanks to saagarjha) 26 | * API changes: 27 | * Replace `padding` fields with `contentInsets` in `MTMathUILabel`. 28 | 29 | ### v0.9.1 (2016-10-17) 30 | * Support for constructing arbitrarily tall delimiters and radicals. 31 | * Fix placement of limits on large operators for the XITS font. 32 | * Allow MTMathUILabel to be used in the interface builder. 33 | 34 | ### v0.9.0 (2016-08-29) 35 | * Added support for matrix environments (matrix, pmatrix, bmatrix, 36 | Bmatrix, vmatrix, Vmatrix) 37 | * Added support for equation alignment (eqalign, displaylines, gather, 38 | split, aligned, eqnarray) 39 | * Added support for the \\\\ command to split long equations 40 | * Added support for math accents (e.g. \\hat, \\tilde etc.) 41 | * Added support for `cases` environment. 42 | * Added support for style commands (e.g. \\displaystyle etc.) 43 | * Improve rendering of square roots and large symbols 44 | * API changes: 45 | * Updated API for `MTMathAtomFactory`. 46 | * Rename `MTLargeGlyphDisplay` to `MTGlyphDisplay` 47 | 48 | ### v0.8.4 (2016-08-10) 49 | * Fix crash for \\epsilon and \\varrho 50 | * Add commands: \\mho, \\angstrom and \\AA 51 | 52 | ### v0.8.3 (2016-07-31) 53 | * Add `textColor` field to `MTMathUILabel` to set the color of the 54 | rendered equation. 55 | * Fixed issue with height of tall radicals set incorrectly. 56 | 57 | ### v0.8.2 (2016-07-23) 58 | * Support for \\overline and \\underline 59 | * Includes math spacing: \\, \\; \\> \\! \\quad \\qquad \\' ' 60 | 61 | ### v0.8.1 (2016-07-17) 62 | * Added support for binomials 63 | * New commands supported: \\over, \\atop, \\choose, \\brack, \\brace, 64 | \\binom. 65 | 66 | ### v0.8.0 (2016-07-09) 67 | * Added support for \\left and \\right 68 | * New API for constructing `MTMathList` 69 | * Improved LaTeX error reporting 70 | * Made internal rendering functions and APIs private 71 | * Nullability annotations for using with Swift 72 | * Improved documentation 73 | * Tests for rendering 74 | 75 | ### v0.7.3 (2016-05-28) 76 | * Moved all font-related files into their own bundle. 77 | 78 | ### v0.7.2 (2016-05-27) 79 | * Added `MTMathListIndex` 80 | 81 | ### v0.7.1 (2016-05-25) 82 | * Improved documentation. 83 | * Added `latex` property to set the latex directly on MTMathUILabel. 84 | * Improved error handling. 85 | 86 | ### v0.7.0 (2016-05-24) 87 | 88 | * Support for multiple fonts. 89 | * Includes large operators (\\sum, \\prod) 90 | * Includes arrow symbols 91 | * Includes showing limits (\\lim etc.) 92 | * Includes integrals 93 | * Added italic correction 94 | 95 | #### API Changes: 96 | The `MTFontManager` API has been rewritten. 97 | Introduce `MTFont` class to represent a font for the label. 98 | 99 | This release contains backwards incompatible API changes. 100 | 101 | ### v0.6.3 (2016-05-15) 102 | * Include `MTFontManager` in public API. 103 | 104 | ### v0.6.2 (2016-05-13) 105 | * Fix issues with Greek letters being incorrect. 106 | * Many common math symbols added. 107 | * Improved example program. 108 | * Minor rendering fixes. 109 | 110 | ### v0.6.1 (2016-05-12) 111 | * Fix the bundle to work correctly with Cocoapods. 112 | 113 | ### v0.6.0 (2016-05-12) 114 | * Inital public release. 115 | 116 | -------------------------------------------------------------------------------- /iosMath/render/MTMathUILabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // MathUILabel.h 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/26/13. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | @import CoreText; 13 | 14 | // Compatibility of iOS and Mac OS. 15 | #import "MTConfig.h" 16 | 17 | #import "MTFont.h" 18 | #import "MTMathList.h" 19 | #import "MTMathListDisplay.h" 20 | 21 | /** 22 | @typedef MTMathUILabelMode 23 | @brief Different display styles supported by the `MTMathUILabel`. 24 | 25 | @note: The only significant difference between the two modes is how fractions 26 | and limits on large operators are displayed. 27 | */ 28 | typedef NS_ENUM(unsigned int, MTMathUILabelMode) { 29 | /// Display mode. Equivalent to $$ in TeX 30 | kMTMathUILabelModeDisplay, 31 | /// Text mode. Equivalent to $ in TeX. 32 | kMTMathUILabelModeText 33 | }; 34 | 35 | /** 36 | @typedef MTTextAlignment 37 | @brief Horizontal text alignment for `MTMathUILabel`. 38 | */ 39 | typedef NS_ENUM(unsigned int, MTTextAlignment) { 40 | /// Align left. 41 | kMTTextAlignmentLeft, 42 | /// Align center. 43 | kMTTextAlignmentCenter, 44 | /// Align right. 45 | kMTTextAlignmentRight, 46 | }; 47 | 48 | /** The main view for rendering math. 49 | 50 | `MTMathLabel` accepts either a string in LaTeX or an `MTMathList` to display. Use 51 | `MTMathList` directly only if you are building it programmatically (e.g. using an 52 | editor), otherwise using LaTeX is the preferable method. 53 | 54 | The math display is centered vertically in the label. The default horizontal alignment is 55 | is left. This can be changed by setting `textAlignment`. The math is default displayed in 56 | *Display* mode. This can be changed using `labelMode`. 57 | 58 | When created it uses `[MTFontManager defaultFont]` as its font. This can be changed using 59 | the `font` parameter. 60 | */ 61 | IB_DESIGNABLE @interface MTMathUILabel : MTView 62 | 63 | /** The `MTMathList` to render. Setting this will remove any 64 | `latex` that has already been set. If `latex` has been set, this will 65 | return the parsed `MTMathList` if the `latex` parses successfully. Use this 66 | setting if the `MTMathList` has been programmatically constructed, otherwise it 67 | is preferred to use `latex`. 68 | */ 69 | @property (nonatomic, nullable) MTMathList* mathList; 70 | 71 | /** The latex string to be displayed. Setting this will remove any `mathList` that 72 | has been set. If latex has not been set, this will return the latex output for the 73 | `mathList` that is set. 74 | @see error */ 75 | @property (nonatomic, nullable) IBInspectable NSString* latex; 76 | 77 | /** This contains any error that occurred when parsing the latex. */ 78 | @property (nonatomic, readonly, nullable) NSError* error; 79 | 80 | /** If true, if there is an error it displays the error message inline. Default true. */ 81 | @property (nonatomic) BOOL displayErrorInline; 82 | 83 | /** The MTFont to use for rendering. */ 84 | @property (nonatomic, nonnull) MTFont* font; 85 | 86 | /** Convenience method to just set the size of the font without changing the fontface. */ 87 | @property (nonatomic) IBInspectable CGFloat fontSize; 88 | 89 | /** This sets the text color of the rendered math formula. The default color is black. */ 90 | @property (nonatomic, nonnull) IBInspectable MTColor* textColor; 91 | 92 | /** The minimum distance from the margin of the view to the rendered math. This value is 93 | `UIEdgeInsetsZero` by default. This is useful if you need some padding between the math and 94 | the border/background color. sizeThatFits: will have its returned size increased by these insets. 95 | */ 96 | @property (nonatomic) IBInspectable MTEdgeInsets contentInsets; 97 | 98 | /** The Label mode for the label. The default mode is Display */ 99 | @property (nonatomic) MTMathUILabelMode labelMode; 100 | 101 | /** Horizontal alignment for the text. The default is align left. */ 102 | @property (nonatomic) MTTextAlignment textAlignment; 103 | 104 | /** The internal display of the MTMathUILabel. This is for advanced use only. */ 105 | @property (nonatomic, readonly, nullable) MTMathListDisplay* displayList; 106 | 107 | @end 108 | -------------------------------------------------------------------------------- /iosMath/render/internal/MTMathListDisplayInternal.h: -------------------------------------------------------------------------------- 1 | // 2 | // MTMathListDisplay+Internal.h 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 6/21/16. 6 | // 7 | // This software may be modified and distributed under the terms of the 8 | // MIT license. See the LICENSE file for details. 9 | // 10 | 11 | #import "MTMathListDisplay.h" 12 | 13 | @interface MTDisplay () 14 | 15 | @property (nonatomic) CGFloat ascent; 16 | @property (nonatomic) CGFloat descent; 17 | @property (nonatomic) CGFloat width; 18 | @property (nonatomic) NSRange range; 19 | @property (nonatomic) BOOL hasScript; 20 | 21 | @end 22 | 23 | // The Downshift protocol allows an MTDisplay to be shifted down by a given amount. 24 | @protocol DownShift 25 | 26 | @property (nonatomic) CGFloat shiftDown; 27 | 28 | @end 29 | 30 | @interface MTMathListDisplay () 31 | 32 | - (instancetype)init NS_UNAVAILABLE; 33 | 34 | - (instancetype) initWithDisplays:(NSArray*) displays range:(NSRange) range NS_DESIGNATED_INITIALIZER; 35 | 36 | @property (nonatomic, readwrite) MTLinePosition type; 37 | @property (nonatomic, readwrite) NSUInteger index; 38 | 39 | @end 40 | 41 | @interface MTCTLineDisplay () 42 | 43 | - (instancetype)initWithString:(NSAttributedString*) attrString position:(CGPoint)position range:(NSRange) range font:(MTFont*) font atoms:(NSArray*) atoms NS_DESIGNATED_INITIALIZER; 44 | 45 | - (instancetype)init NS_UNAVAILABLE; 46 | 47 | @end 48 | 49 | @interface MTFractionDisplay () 50 | 51 | - (instancetype)initWithNumerator:(MTMathListDisplay*) numerator denominator:(MTMathListDisplay*) denominator position:(CGPoint) position range:(NSRange) range NS_DESIGNATED_INITIALIZER; 52 | 53 | - (instancetype)init NS_UNAVAILABLE; 54 | 55 | @property (nonatomic) CGFloat numeratorUp; 56 | @property (nonatomic) CGFloat denominatorDown; 57 | @property (nonatomic) CGFloat linePosition; 58 | @property (nonatomic) CGFloat lineThickness; 59 | 60 | @end 61 | 62 | @interface MTRadicalDisplay () 63 | 64 | - (instancetype)initWitRadicand:(MTMathListDisplay*) radicand glpyh:(MTDisplay*) glyph position:(CGPoint) position range:(NSRange) range NS_DESIGNATED_INITIALIZER; 65 | 66 | - (void) setDegree:(MTMathListDisplay *)degree fontMetrics:(MTFontMathTable*) fontMetrics; 67 | 68 | @property (nonatomic) CGFloat topKern; 69 | @property (nonatomic) CGFloat lineThickness; 70 | 71 | @end 72 | 73 | // Rendering of an large glyph as an MTDisplay 74 | @interface MTGlyphDisplay() 75 | 76 | - (instancetype)initWithGlpyh:(CGGlyph) glyph range:(NSRange) range font:(MTFont*) font NS_DESIGNATED_INITIALIZER; 77 | 78 | @end 79 | 80 | // Rendering of a constructed glyph as an MTDisplay 81 | @interface MTGlyphConstructionDisplay : MTDisplay 82 | 83 | - (instancetype) init NS_UNAVAILABLE; 84 | - (instancetype) initWithGlyphs:(NSArray*) glyphs offsets:(NSArray*) offsets font:(MTFont*) font NS_DESIGNATED_INITIALIZER; 85 | 86 | @end 87 | 88 | @interface MTLargeOpLimitsDisplay () 89 | 90 | - (instancetype) initWithNucleus:(MTDisplay*) nucleus upperLimit:(MTMathListDisplay*) upperLimit lowerLimit:(MTMathListDisplay*) lowerLimit limitShift:(CGFloat) limitShift extraPadding:(CGFloat) extraPadding NS_DESIGNATED_INITIALIZER; 91 | 92 | - (instancetype)init NS_UNAVAILABLE; 93 | 94 | @property (nonatomic) CGFloat upperLimitGap; 95 | @property (nonatomic) CGFloat lowerLimitGap; 96 | 97 | @end 98 | 99 | @interface MTLineDisplay () 100 | 101 | - (instancetype)initWithInner:(MTMathListDisplay*) inner position:(CGPoint) position range:(NSRange) range NS_DESIGNATED_INITIALIZER; 102 | 103 | // How much the line should be moved up. 104 | @property (nonatomic) CGFloat lineShiftUp; 105 | @property (nonatomic) CGFloat lineThickness; 106 | 107 | @end 108 | 109 | @interface MTAccentDisplay () 110 | 111 | - (instancetype)initWithAccent:(MTGlyphDisplay*) glyph accentee:(MTMathListDisplay*) accentee range:(NSRange) range NS_DESIGNATED_INITIALIZER; 112 | 113 | @end 114 | 115 | 116 | @interface MTInnerDisplay () 117 | 118 | - (instancetype) initWithInner:(MTMathListDisplay*) inner leftDelimiter:(MTDisplay*) leftDelimiter rightDelimiter:(MTDisplay*) rightDelimiter atIndex:(NSUInteger) index NS_DESIGNATED_INITIALIZER; 119 | 120 | @property (nonatomic) MTMathListDisplay* inner; 121 | 122 | @property (nonatomic, nullable) MTDisplay* leftDelimiter; 123 | @property (nonatomic, nullable) MTDisplay* rightDelimiter; 124 | 125 | @property (nonatomic) NSUInteger index; 126 | 127 | @end 128 | -------------------------------------------------------------------------------- /fonts/README-TeX-Gyre-Termes-Math.txt: -------------------------------------------------------------------------------- 1 | ########################################################################### 2 | ############ The TeX Gyre Collection of Fonts ############ 3 | ########################################################################### 4 | 5 | Font: TeX Gyre Termes Math 6 | Authors: Bogus\l{}aw Jackowski, Piotr Strzelczyk and Piotr Pianowski 7 | Version: 1.543 8 | Date: 5 IX 2014 9 | 10 | License: 11 | % Copyright 2012--2014 for the TeX Gyre math extensions by B. Jackowski, 12 | % P. Strzelczyk and P. Pianowski (on behalf of TeX Users Groups). 13 | % 14 | % This work can be freely used and distributed under 15 | % the GUST Font License (GFL -- see GUST-FONT-LICENSE.txt) 16 | % which is actually an instance of the LaTeX Project Public License 17 | % (LPPL -- see http://www.latex-project.org/lppl.txt). 18 | % 19 | % This work has the maintenance status "maintained". The Current Maintainer 20 | % of this work is Bogus\l{}aw Jackowski, Piotr Strzelczyk and Piotr Pianowski. 21 | % 22 | % This work consists of the files listed 23 | % in the MANIFEST-TeX-Gyre-Termes.txt file. 24 | 25 | ########################################################################### 26 | ############ A BRIEF DESCRIPTION OF THE FONT ############ 27 | ########################################################################### 28 | 29 | TeX Gyre Termes Math is a math companion for the TeX Gyre Termes family 30 | of fonts (see http://www.gust.org.pl/projects/e-foundry/tex-gyre/) in 31 | the OpenType format. 32 | 33 | The math OTF fonts should contain a special table, MATH, described in the 34 | confidential Microsoft document "The MATH table and OpenType Features 35 | for Math Processing". Moreover, they should contain a broad collection 36 | of special characters (see "Draft Unicode Technical Report #25. 37 | UNICODE SUPPORT FOR MATHEMATICS" by Barbara Beeton, Asmus Freytag, 38 | and Murray Sargent III). In particular, math OTF scripts are expected 39 | to contain the following scripts: a basic serif script (regular, bold, 40 | italic and bold italic), a calligraphic script (regular and bold), 41 | a double-struck script, a fraktur script (regular and bold), a sans-serif 42 | script (regular, bold, oblique and bold oblique), and a monospaced script. 43 | 44 | The basic script is, obviously, TeX Gyre Termes. Symbols, namely, 45 | calligraphic, double struck, Greek, sans serif bold Greek, and Hebrew, 46 | were drawn from scratch. The main math component, that is, the math 47 | extension, was also programmed from scratch. 48 | 49 | Some scripts, however, are borrowed from other fonts (the current 50 | selection, however, may be subject to change): 51 | 52 | * The fraktur alphabets (regular and bold) is excerpted 53 | from the Leipziger Fraktur replica by Peter Wiegel 54 | ( http://www.peter-wiegel.de/Leipzig.html ) 55 | with the kind permission of the author. 56 | 57 | * The sans serif alphabets (regular, oblique, bold, and 58 | bold oblique) are excerpted from TeX Gyre Heros 59 | http://www.gust.org.pl/projects/e-foundry/tex-gyre/heros 60 | (actually, the sans serif bold Greek symbols are based 61 | on TeX Gyre Heros Greek alphabet). 62 | 63 | * The monospaced alphabet is excerpted from TeX Gyre Cursor 64 | http://www.gust.org.pl/projects/e-foundry/tex-gyre/cursor 65 | 66 | Note that the members of all the mentioned alphabets, except 67 | the main roman alphabet, should be considered symbols, not letters; 68 | symbols are not expected to occur in a text stream; instead, 69 | they are expected to appear lonely, perhaps with some embellishments 70 | like subscripts, superscripts, primes, dots above and below, etc. 71 | 72 | To produce the font, MetaType1 and the FontForge library were used: 73 | the Type1 PostScript font containing all relevant characters was 74 | generated with the MetaType1 engine, and the result was converted 75 | into the OTF format with all the necessary data structures by 76 | a Python script employing the FontForge library. 77 | 78 | Recent changes (ver. 1.502 --> ver. 1.543) comprised 79 | mainly interline settings in OTF tables (HHEA and 80 | OS/2) and the correction of the unicode slots assigned to 81 | contour integrals (glyphs `clockwise contour 82 | integral', u+2232, and `anticlockwise contour 83 | integral', u+2233, used to have swapped slots). 84 | 85 | * * * 86 | 87 | The TeX Gyre Math Project was launched and is supported by 88 | TeX USERS GROUPS (CS TUG, DANTE eV, GUST, NTG, TUG India, TUG, UK TUG). 89 | Hearty thanks to the representatives of these groups and also 90 | to all people who helped with their work, comments, ideas, 91 | remarks, bug reports, objections, hints, consolations, etc. 92 | -------------------------------------------------------------------------------- /EXAMPLES.md: -------------------------------------------------------------------------------- 1 | # iosMath Examples 2 | 3 | ## Square of sums 4 | ```LaTeX 5 | (a_1 + a_2)^2 = a_1^2 + 2a_1a_2 + a_2^2 6 | ``` 7 | 8 | ![Square Formula](img/square.png) 9 | 10 | ## Quadratic Formula 11 | ```LaTeX 12 | x = \frac{-b \pm \sqrt{b^2-4ac}}{2a} 13 | ``` 14 | 15 | ![Quadratic Formula](img/quadratic.png) 16 | 17 | ## Standard Deviation 18 | ```LaTeX 19 | \sigma = \sqrt{\frac{1}{N}\sum_{i=1}^N (x_i - \mu)^2} 20 | ``` 21 | ![Standard Deviation](img/standard.png) 22 | 23 | ## De Morgan's laws 24 | ```LaTeX 25 | \neg(P\land Q) \iff (\neg P)\lor(\neg Q) 26 | ``` 27 | 28 | ![De Morgan](img/demorgan.png) 29 | 30 | ## Log Change of Base 31 | ```LaTeX 32 | \log_b(x) = \frac{\log_a(x)}{\log_a(b)} 33 | ``` 34 | 35 | ![Log Base Change](img/log.png) 36 | 37 | ## Cosine addition 38 | ```LaTeX 39 | \cos(\theta + \varphi) = \cos(\theta)\cos(\varphi) - \sin(\theta)\sin(\varphi) 40 | ``` 41 | 42 | ![Cos Sum](img/trig.png) 43 | 44 | ## Limit e^k 45 | ```LaTeX 46 | \lim_{x\to\infty}\left(1 + \frac{k}{x}\right)^x = e^k 47 | ``` 48 | 49 | ![Limit](img/limit.png) 50 | 51 | ## Calculus 52 | ```LaTeX 53 | f(x) = \int\limits_{-\infty}^\infty\!\hat f(\xi)\,e^{2 \pi i \xi x}\,\mathrm{d}\xi 54 | ``` 55 | 56 | ![Calculus](img/calculus.png) 57 | 58 | ## Stirling Numbers of the Second Kind 59 | ```LaTeX 60 | {n \brace k} = \frac{1}{k!}\sum_{j=0}^k (-1)^{k-j}\binom{k}{j}(k-j)^n 61 | ``` 62 | 63 | ![Stirling Numbers](img/stirling.png) 64 | 65 | ## Gaussian Integral 66 | ```LaTeX 67 | \int_{-\infty}^{\infty} \! e^{-x^2} dx = \sqrt{\pi} 68 | ``` 69 | 70 | ![Gauss Integral](img/gaussintegral.png) 71 | 72 | ## Arithmetic mean, geometric mean inequality 73 | ```LaTeX 74 | \frac{1}{n}\sum_{i=1}^{n}x_i \geq \sqrt[n]{\prod_{i=1}^{n}x_i} 75 | ``` 76 | 77 | ![AM-GM](img/amgm.png) 78 | 79 | ## Cauchy-Schwarz inequality 80 | ```LaTeX 81 | \left(\sum_{k=1}^n a_k b_k \right)^2 \le \left(\sum_{k=1}^n a_k^2\right)\left(\sum_{k=1}^n b_k^2\right) 82 | ``` 83 | ![Cauchy Schwarz](img/cauchyschwarz.png) 84 | 85 | ## Cauchy integral formula 86 | ```LaTeX 87 | f^{(n)}(z_0) = \frac{n!}{2\pi i}\oint_\gamma\frac{f(z)}{(z-z_0)^{n+1}}dz 88 | ``` 89 | 90 | ![Cauchy Integral](img/cauchyintegral.png) 91 | ## Schroedinger's Equation 92 | ```LaTeX 93 | i\hbar\frac{\partial}{\partial t}\mathbf\Psi(\mathbf{x},t) = -\frac{\hbar}{2m}\nabla^2\mathbf\Psi(\mathbf{x},t) 94 | + V(\mathbf{x})\mathbf\Psi(\mathbf{x},t) 95 | ``` 96 | 97 | ![Schroedinger](img/schroedinger.png) 98 | 99 | ## Lorentz Equations 100 | Use the `gather` or `displaylines` environments to center multiple 101 | equations. 102 | ```LaTeX 103 | \begin{gather} 104 | \dot{x} = \sigma(y-x) \\ 105 | \dot{y} = \rho x - y - xz \\ 106 | \dot{z} = -\beta z + xy" 107 | \end{gather} 108 | ``` 109 | 110 | ![Lorentz](img/lorentz.png) 111 | 112 | ## Cross product 113 | ```LaTeX 114 | \vec \bf V_1 \times \vec \bf V_2 = \begin{vmatrix} 115 | \hat \imath &\hat \jmath &\hat k \\ 116 | \frac{\partial X}{\partial u} & \frac{\partial Y}{\partial u} & 0 \\ 117 | \frac{\partial X}{\partial v} & \frac{\partial Y}{\partial v} & 0 118 | \end{vmatrix} 119 | ``` 120 | 121 | ![Cross Product](img/cross.png) 122 | 123 | ## Maxwell's Equations 124 | Use the `aligned`, `eqalign` or `split` environments to align 125 | multiple equations. 126 | ```LaTeX 127 | \begin{eqalign} 128 | \nabla \cdot \vec{\bf E} & = \frac {\rho} {\varepsilon_0} \\ 129 | \nabla \cdot \vec{\bf B} & = 0 \\ 130 | \nabla \times \vec{\bf E} &= - \frac{\partial\vec{\bf B}}{\partial t} \\ 131 | \nabla \times \vec{\bf B} & = \mu_0\vec{\bf J} + \mu_0\varepsilon_0 \frac{\partial\vec{\bf E}}{\partial t} 132 | \end{eqalign} 133 | ``` 134 | 135 | ![Maxwell's Equations](img/maxwell.png) 136 | 137 | ## Matrix multiplication 138 | Supported matrix environments: `matrix`, `pmatrix`, `bmatrix`, `Bmatrix`, 139 | `vmatrix`, `Vmatrix`. 140 | ```LaTeX 141 | \begin{pmatrix} 142 | a & b\\ c & d 143 | \end{pmatrix} 144 | \begin{pmatrix} 145 | \alpha & \beta \\ \gamma & \delta 146 | \end{pmatrix} = 147 | \begin{pmatrix} 148 | a\alpha + b\gamma & a\beta + b \delta \\ 149 | c\alpha + d\gamma & c\beta + d \delta 150 | \end{pmatrix} 151 | ``` 152 | 153 | ![Matrix Multiplication](img/matrixmult.png) 154 | 155 | ## Cases 156 | ```LaTeX 157 | f(x) = \begin{cases} 158 | \frac{e^x}{2} & x \geq 0 \\ 159 | 1 & x < 0 160 | \end{cases} 161 | ``` 162 | 163 | ![Cases](img/cases.png) 164 | 165 | ## Splitting long equations 166 | ```LaTeX 167 | \frak Q(\lambda,\hat{\lambda}) = 168 | -\frac{1}{2} \mathbb P(O \mid \lambda ) \sum_s \sum_m \sum_t \gamma_m^{(s)} (t) +\\ 169 | \quad \left( \log(2 \pi ) + \log \left| \cal C_m^{(s)} \right| + 170 | \left( o_t - \hat{\mu}_m^{(s)} \right) ^T \cal C_m^{(s)-1} \right) 171 | ``` 172 | 173 | ![Long equation](img/long.png) 174 | -------------------------------------------------------------------------------- /fonts/README-Latin-Modern-Math.txt: -------------------------------------------------------------------------------- 1 | ########################################################################### 2 | ############ Latin Modern Collection of Fonts ############ 3 | ########################################################################### 4 | 5 | Font: Latin Modern Math 6 | Authors: Bogus\l{}aw Jackowski, Piotr Strzelczyk and Piotr Pianowski 7 | Version: 1.959 8 | Date: 5 IX 2014 9 | 10 | License: 11 | % Copyright 2012--2014 for the Latin Modern math extensions by B. Jackowski, 12 | % P. Strzelczyk and P. Pianowski (on behalf of TeX Users Groups). 13 | % 14 | % This work can be freely used and distributed under 15 | % the GUST Font License (GFL -- see GUST-FONT-LICENSE.txt) 16 | % which is actually an instance of the LaTeX Project Public License 17 | % (LPPL -- see http://www.latex-project.org/lppl.txt). 18 | % 19 | % This work has the maintenance status "maintained". The Current Maintainer 20 | % of this work is Bogus\l{}aw Jackowski, Piotr Strzelczyk and Piotr Pianowski. 21 | % 22 | % This work consists of the files listed 23 | % in the MANIFEST-Latin-Modern-Math.txt file. 24 | 25 | ########################################################################### 26 | ############ A BRIEF DESCRIPTION OF THE FONT ############ 27 | ########################################################################### 28 | 29 | Latin Modern Math is a math companion for the Latin Modern family 30 | of fonts (see http://www.gust.org.pl/projects/e-foundry/latin-modern) in 31 | the OpenType format. 32 | 33 | The math OTF fonts should contain a special table, MATH, described in the 34 | confidential Microsoft document "The MATH table and OpenType Features 35 | for Math Processing". Moreover, they should contain a broad collection 36 | of special characters (see "Draft Unicode Technical Report #25. 37 | UNICODE SUPPORT FOR MATHEMATICS" by Barbara Beeton, Asmus Freytag, 38 | and Murray Sargent III). In particular, math OTF fonts are expected 39 | to contain the following scripts: a basic serif script (regular, bold, 40 | italic and bold italic), a calligraphic script (regular and bold), 41 | a double-struck script, a fraktur script (regular and bold), a sans-serif 42 | script (regular, bold, oblique and bold oblique), and a monospaced script. 43 | 44 | The basic script is, obviously, Latin Modern. Some scripts, however, 45 | are borrowed from other fonts (the current selection, however, may 46 | be subject to change), belonging, however, to the "TeX circle": 47 | 48 | * the calligraphic and fraktur alphabets are excerpted from the renowned 49 | Euler family (http://en.wikipedia.org/wiki/AMS_Euler); 50 | 51 | * the double struck script is excerpted from Alan Jeffrey's bbold font 52 | (http://www.tug.org/texlive/Contents/live/texmf-dist/doc/latex/bbold/bbold.pdf) 53 | 54 | * the sans serif and monospaced alphabets are excerpted from 55 | the Latin Modern Sans and Latin Modern Mono fonts 56 | (http://www.gust.org.pl/projects/e-foundry/latin-modern); 57 | sans serif bold Greek symbols (required by the already mentioned 58 | "Unicode Technical Report #25") were prepared using D.E. Knuth's 59 | font sources with some manual tuning 60 | 61 | The main math component, that is, the math extension, was programmed 62 | from scratch, with an attempt to retain the visual compatiblility 63 | with the original D.E. Knuth's fonts. In particular, all symbols 64 | (with a few exceptions) appearing in the D.E. Knuth's "canonical" fonts 65 | have the same width (rounded) as the corresponding Knuthian ones. 66 | 67 | Note that the members of all the mentioned alphabets, except 68 | the main roman alphabet, should be considerd symbols, not letters; 69 | symbols are not expected to occur in a text stream; instead, 70 | they are expected to appear lonely, perhaps with some embellishments 71 | like subscripts, superscripts, primes, dots above and below, etc. 72 | 73 | To produce the font, MetaType1 and the FontForge library were used: 74 | the Type1 PostScript font containing all relevant characters was 75 | generated with the MetaType1 engine, and the result was converted 76 | into the OTF format with all the necessary data structures by 77 | a Python script employing the FontForge library. 78 | 79 | Recent changes (ver. 1.958 --> ver. 1.959) comprised 80 | mainly interline settings in OTF tables (HHEA and 81 | OS/2) and the correction of unicode slots assigned to 82 | the contour integrals (glyphs `clockwise contour 83 | integral', u+2232, and `anticlockwise contour 84 | integral', u+2233, used to have swapped slots). 85 | 86 | * * * 87 | 88 | The TeX Gyre Math Project was launched and is supported by 89 | TeX USERS GROUPS (CS TUG, DANTE eV, GUST, NTG, TUG India, TUG, UK TUG). 90 | Hearty thanks to the representatives of these groups and also 91 | to all people who helped with their work, comments, ideas, 92 | remarks, bug reports, objections, hints, consolations, etc. 93 | -------------------------------------------------------------------------------- /fonts/OFL.txt: -------------------------------------------------------------------------------- 1 | STIX Font License 2 | 3 | 24 May 2010 4 | 5 | Copyright (c) 2001-2010 by the STI Pub Companies, consisting of the American 6 | Institute of Physics, the American Chemical Society, the American Mathematical 7 | Society, the American Physical Society, Elsevier, Inc., and The Institute of 8 | Electrical and Electronic Engineers, Inc. (www.stixfonts.org), with Reserved 9 | Font Name STIX Fonts, STIX Fonts (TM) is a trademark of The Institute of 10 | Electrical and Electronics Engineers, Inc. 11 | 12 | Portions copyright (c) 1998-2003 by MicroPress, Inc. (www.micropress-inc.com), 13 | with Reserved Font Name TM Math. To obtain additional mathematical fonts, please 14 | contact MicroPress, Inc., 68-30 Harrow Street, Forest Hills, NY 11375, USA, 15 | Phone: (718) 575-1816. 16 | 17 | Portions copyright (c) 1990 by Elsevier, Inc. 18 | 19 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 20 | This license is copied below, and is also available with a FAQ at: 21 | http://scripts.sil.org/OFL 22 | 23 | --------------------------------------------------------------------------- 24 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 25 | --------------------------------------------------------------------------- 26 | 27 | PREAMBLE 28 | 29 | The goals of the Open Font License (OFL) are to stimulate worldwide development 30 | of collaborative font projects, to support the font creation efforts of academic 31 | and linguistic communities, and to provide a free and open framework in which 32 | fonts may be shared and improved in partnership with others. 33 | 34 | The OFL allows the licensed fonts to be used, studied, modified and redistributed 35 | freely as long as they are not sold by themselves. The fonts, including any 36 | derivative works, can be bundled, embedded, redistributed and/or sold with any 37 | software provided that any reserved names are not used by derivative works. The 38 | fonts and derivatives, however, cannot be released under any other type of license. 39 | The requirement for fonts to remain under this license does not apply to any 40 | document created using the fonts or their derivatives. 41 | 42 | DEFINITIONS 43 | 44 | "Font Software" refers to the set of files released by the Copyright Holder(s) under 45 | this license and clearly marked as such. This may include source files, build 46 | scripts and documentation. 47 | 48 | "Reserved Font Name" refers to any names specified as such after the copyright 49 | statement(s). 50 | 51 | "Original Version" refers to the collection of Font Software components as 52 | distributed by the Copyright Holder(s). 53 | 54 | "Modified Version" refers to any derivative made by adding to, deleting, or 55 | substituting -- in part or in whole -- any of the components of the Original Version, 56 | by changing formats or by porting the Font Software to a new environment. 57 | 58 | "Author" refers to any designer, engineer, programmer, technical writer or other 59 | person who contributed to the Font Software. 60 | 61 | PERMISSION & CONDITIONS 62 | 63 | Permission is hereby granted, free of charge, to any person obtaining a copy of the 64 | Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell 65 | modified and unmodified copies of the Font Software, subject to the following 66 | conditions: 67 | 68 | 1) Neither the Font Software nor any of its individual components, in Original or 69 | Modified Versions, may be sold by itself. 70 | 71 | 2) Original or Modified Versions of the Font Software may be bundled, redistributed 72 | and/or sold with any software, provided that each copy contains the above copyright 73 | notice and this license. These can be included either as stand-alone text files, 74 | human-readable headers or in the appropriate machine-readable metadata fields within 75 | text or binary files as long as those fields can be easily viewed by the user. 76 | 77 | 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless 78 | explicit written permission is granted by the corresponding Copyright Holder. This 79 | restriction only applies to the primary font name as presented to the users. 80 | 81 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall 82 | not be used to promote, endorse or advertise any Modified Version, except to 83 | acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with 84 | their explicit written permission. 85 | 86 | 5) The Font Software, modified or unmodified, in part or in whole, must be distributed 87 | entirely under this license, and must not be distributed under any other license. The 88 | requirement for fonts to remain under this license does not apply to any document 89 | created using the Font Software. 90 | 91 | TERMINATION 92 | 93 | This license becomes null and void if any of the above conditions are not met. 94 | 95 | DISCLAIMER 96 | 97 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 98 | INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 99 | PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER 100 | RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 101 | LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, 102 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR 103 | INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. 104 | -------------------------------------------------------------------------------- /iosMath.xcodeproj/xcshareddata/xcschemes/iosMath.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /iosMath/lib/MTMathListIndex.h: -------------------------------------------------------------------------------- 1 | // 2 | // MTMathListIndex.h 3 | // 4 | // Created by Kostub Deshmukh on 9/6/13. 5 | // Copyright (C) 2013 MathChat 6 | // 7 | // This software may be modified and distributed under the terms of the 8 | // MIT license. See the LICENSE file for details. 9 | // 10 | 11 | @import Foundation; 12 | 13 | /** 14 | * An index that points to a particular character in the MTMathList. The index is a LinkedList that represents 15 | * a path from the beginning of the MTMathList to reach a particular atom in the list. The next node of the path 16 | * is represented by the subIndex. The path terminates when the subIndex is nil. 17 | * 18 | * If there is a subIndex, the subIndexType denotes what branch the path takes (i.e. superscript, subscript, 19 | * numerator, denominator etc.). 20 | * e.g in the expression 25^{2/4} the index of the character 4 is represented as: 21 | * (1, superscript) -> (0, denominator) -> (0, none) 22 | * This can be interpreted as start at index 1 (i.e. the 5) go up to the superscript. 23 | * Then look at index 0 (i.e. 2/4) and go to the denominator. Then look up index 0 (i.e. the 4) which this final 24 | * index. 25 | * 26 | * The level of an index is the number of nodes in the LinkedList to get to the final path. 27 | */ 28 | @interface MTMathListIndex : NSObject 29 | 30 | /** 31 | @typedef MTMathListSubIndexType 32 | @brief The type of the subindex. 33 | 34 | The type of the subindex denotes what branch the path to the atom that this index points to takes. 35 | */ 36 | typedef NS_ENUM(unsigned int, MTMathListSubIndexType) { 37 | /// The index denotes the whole atom, subIndex is nil. 38 | kMTSubIndexTypeNone = 0, 39 | /// The position in the subindex is an index into the nucleus 40 | kMTSubIndexTypeNucleus, 41 | /// The subindex indexes into the superscript. 42 | kMTSubIndexTypeSuperscript, 43 | /// The subindex indexes into the subscript 44 | kMTSubIndexTypeSubscript, 45 | /// The subindex indexes into the numerator (only valid for fractions) 46 | kMTSubIndexTypeNumerator, 47 | /// The subindex indexes into the denominator (only valid for fractions) 48 | kMTSubIndexTypeDenominator, 49 | /// The subindex indexes into the radicand (only valid for radicals) 50 | kMTSubIndexTypeRadicand, 51 | /// The subindex indexes into the degree (only valid for radicals) 52 | kMTSubIndexTypeDegree, 53 | /// The subindex indexes into the inner list (only valid for inner) 54 | kMTSubIndexTypeInner 55 | }; 56 | 57 | 58 | /// The index of the associated atom. 59 | @property (nonatomic, readonly) NSUInteger atomIndex; 60 | /// The type of subindex, e.g. superscript, numerator etc. 61 | @property (nonatomic, readonly) MTMathListSubIndexType subIndexType; 62 | /// The index into the sublist. 63 | @property (nonatomic, readonly, nullable) MTMathListIndex* subIndex; 64 | 65 | /// Returns the previous index if present. Returns `nil` if there is no previous index. 66 | - (nullable MTMathListIndex*) previous; 67 | /// Returns the next index. 68 | - (nonnull MTMathListIndex*) next; 69 | 70 | /** 71 | * Returns true if this index represents the beginning of a line. Note there may be multiple lines in a MTMathList, 72 | * e.g. a superscript or a fraction numerator. This returns true if the innermost subindex points to the beginning of a 73 | * line. 74 | */ 75 | - (BOOL) isAtBeginningOfLine; 76 | 77 | /** Returns the type of the innermost sub index. */ 78 | - (MTMathListSubIndexType) finalSubIndexType; 79 | 80 | /** Returns true if any of the subIndexes of this index have the given type. */ 81 | - (BOOL) hasSubIndexOfType:(MTMathListSubIndexType) subIndexType; 82 | 83 | /** Creates a new index by attaching this index at the end of the current one. */ 84 | - (nonnull MTMathListIndex*) levelUpWithSubIndex:(nullable MTMathListIndex*) subIndex type:(MTMathListSubIndexType) type; 85 | /** Creates a new index by removing the last index item. If this is the last one, then returns nil. */ 86 | - (nullable MTMathListIndex*) levelDown; 87 | 88 | - (nonnull instancetype)init NS_UNAVAILABLE; 89 | - (BOOL)isEqual:(nullable id)object; 90 | - (NSUInteger)hash; 91 | - (nonnull NSString *)description; 92 | 93 | /** Factory function to create a `MTMathListIndex` with no subindexes. 94 | @param index The index of the atom that the `MTMathListIndex` points at. 95 | */ 96 | + (nonnull instancetype) level0Index:(NSUInteger) index; 97 | 98 | /** Factory function to create at `MTMathListIndex` with a given subIndex. 99 | @param location The location at which the subIndex should is present. 100 | @param subIndex The subIndex to be added. Can be nil. 101 | @param type The type of the subIndex. 102 | */ 103 | + (nonnull instancetype) indexAtLocation:(NSUInteger) location withSubIndex:(nullable MTMathListIndex*) subIndex type:(MTMathListSubIndexType) type; 104 | 105 | @end 106 | 107 | /** A range of atoms in an `MTMathList`. This is similar to `NSRange` with a start and length, except that 108 | the starting location is defined by a `MTMathListIndex` rather than an ordinary integer. 109 | */ 110 | @interface MTMathListRange : NSObject 111 | 112 | - (nonnull instancetype)init NS_UNAVAILABLE; 113 | 114 | /// Creates a valid range. 115 | + (nonnull MTMathListRange*) makeRange:(nonnull MTMathListIndex*) start length:(NSUInteger) length; 116 | /// Creates a range at level 0 from the give range. 117 | + (nonnull MTMathListRange *)makeRangeForRange:(NSRange)range; 118 | /// Makes a range of length 1 119 | + (nonnull MTMathListRange*) makeRange:(nonnull MTMathListIndex*) start; 120 | /// Makes a range of length 1 at the level 0 index start 121 | + (nonnull MTMathListRange*) makeRangeForIndex:(NSUInteger) start; 122 | 123 | /// The starting location of the range. Cannot be `nil`. 124 | @property (nonatomic, readonly, nonnull) MTMathListIndex* start; 125 | /// The size of the range. 126 | @property (nonatomic, readonly) NSUInteger length; 127 | 128 | - (nullable MTMathListRange*) subIndexRange; 129 | /// Appends the current range to range and returns the resulting range. Any elements between the two are included in the range. 130 | - (nullable MTMathListRange*) unionRange:(nonnull MTMathListRange*) range; 131 | /// Unions all ranges in the given array of ranges 132 | + (nullable MTMathListRange*) unionRanges:(nonnull NSArray*) ranges; 133 | 134 | @end 135 | -------------------------------------------------------------------------------- /iosMath/render/MTMathUILabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // MathUILabel.m 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/26/13. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | #import "MTMathUILabel.h" 13 | #import "MTMathListDisplay.h" 14 | #import "MTFontManager.h" 15 | #import "MTMathListBuilder.h" 16 | #import "MTTypesetter.h" 17 | 18 | @implementation MTMathUILabel { 19 | MTLabel* _errorLabel; 20 | } 21 | 22 | - (instancetype)initWithFrame:(CGRect)frame 23 | { 24 | self = [super initWithFrame:frame]; 25 | if (self) { 26 | [self initCommon]; 27 | } 28 | return self; 29 | } 30 | 31 | - (instancetype)initWithCoder:(NSCoder *)aDecoder 32 | { 33 | self = [super initWithCoder:aDecoder]; 34 | if (self) { 35 | [self initCommon]; 36 | } 37 | return self; 38 | } 39 | 40 | - (void) initCommon 41 | { 42 | self.layer.geometryFlipped = YES; // For ease of interaction with the CoreText coordinate system. 43 | // default font size 44 | _fontSize = 20; 45 | _contentInsets = MTEdgeInsetsZero; 46 | _labelMode = kMTMathUILabelModeDisplay; 47 | MTFont* font = [MTFontManager fontManager].defaultFont; 48 | self.font = font; 49 | _textAlignment = kMTTextAlignmentLeft; 50 | _displayList = nil; 51 | _displayErrorInline = true; 52 | self.backgroundColor = [MTColor clearColor]; 53 | 54 | _textColor = [MTColor blackColor]; 55 | _errorLabel = [[MTLabel alloc] init]; 56 | _errorLabel.hidden = YES; 57 | _errorLabel.layer.geometryFlipped = YES; 58 | _errorLabel.textColor = [MTColor redColor]; 59 | [self addSubview:_errorLabel]; 60 | } 61 | 62 | #if !TARGET_OS_IPHONE 63 | - (void)setNeedsLayout 64 | { 65 | [self setNeedsLayout:YES]; 66 | } 67 | 68 | - (void)setNeedsDisplay 69 | { 70 | [self setNeedsDisplay:YES]; 71 | } 72 | 73 | - (BOOL)isFlipped 74 | { 75 | return NO; 76 | } 77 | #endif 78 | 79 | - (void)setFont:(MTFont*)font 80 | { 81 | NSParameterAssert(font); 82 | _font = font; 83 | [self invalidateIntrinsicContentSize]; 84 | [self setNeedsLayout]; 85 | } 86 | 87 | - (void)setFontSize:(CGFloat)fontSize 88 | { 89 | _fontSize = fontSize; 90 | MTFont* font = [_font copyFontWithSize:_fontSize]; 91 | self.font = font; 92 | } 93 | 94 | - (void)setContentInsets:(MTEdgeInsets)contentInsets 95 | { 96 | _contentInsets = contentInsets; 97 | [self invalidateIntrinsicContentSize]; 98 | [self setNeedsLayout]; 99 | } 100 | 101 | - (void) setMathList:(MTMathList *)mathList 102 | { 103 | _mathList = mathList; 104 | _error = nil; 105 | _latex = [MTMathListBuilder mathListToString:mathList]; 106 | [self invalidateIntrinsicContentSize]; 107 | [self setNeedsLayout]; 108 | } 109 | 110 | - (void)setLatex:(NSString *)latex 111 | { 112 | _latex = latex; 113 | _error = nil; 114 | NSError* error = nil; 115 | _mathList = [MTMathListBuilder buildFromString:latex error:&error]; 116 | if (error) { 117 | _mathList = nil; 118 | _error = error; 119 | _errorLabel.text = error.localizedDescription; 120 | _errorLabel.frame = self.bounds; 121 | _errorLabel.hidden = !self.displayErrorInline; 122 | } else { 123 | _errorLabel.hidden = YES; 124 | } 125 | [self invalidateIntrinsicContentSize]; 126 | [self setNeedsLayout]; 127 | } 128 | 129 | - (void)setLabelMode:(MTMathUILabelMode)labelMode 130 | { 131 | _labelMode = labelMode; 132 | [self invalidateIntrinsicContentSize]; 133 | [self setNeedsLayout]; 134 | } 135 | 136 | - (void)setTextColor:(MTColor *)textColor 137 | { 138 | NSParameterAssert(textColor); 139 | _textColor = textColor; 140 | _displayList.textColor = textColor; 141 | [self setNeedsDisplay]; 142 | } 143 | 144 | - (void)setTextAlignment:(MTTextAlignment)textAlignment 145 | { 146 | _textAlignment = textAlignment; 147 | [self invalidateIntrinsicContentSize]; 148 | [self setNeedsLayout]; 149 | } 150 | 151 | - (MTLineStyle) currentStyle 152 | { 153 | switch (_labelMode) { 154 | case kMTMathUILabelModeDisplay: 155 | return kMTLineStyleDisplay; 156 | case kMTMathUILabelModeText: 157 | return kMTLineStyleText; 158 | } 159 | } 160 | 161 | // Only override drawRect: if you perform custom drawing. 162 | // An empty implementation adversely affects performance during animation. 163 | - (void)drawRect:(MTRect)rect 164 | { 165 | [super drawRect:rect]; 166 | 167 | if (!_mathList) { 168 | return; 169 | } 170 | 171 | // Drawing code 172 | CGContextRef context = MTGraphicsGetCurrentContext(); 173 | CGContextSaveGState(context); 174 | 175 | [_displayList draw:context]; 176 | 177 | CGContextRestoreGState(context); 178 | } 179 | 180 | - (void) layoutSubviews 181 | { 182 | if (_mathList) { 183 | _displayList = [MTTypesetter createLineForMathList:_mathList font:_font style:self.currentStyle]; 184 | _displayList.textColor = _textColor; 185 | 186 | // Determine x position based on alignment 187 | CGFloat textX = 0; 188 | switch (self.textAlignment) { 189 | case kMTTextAlignmentLeft: 190 | textX = self.contentInsets.left; 191 | break; 192 | case kMTTextAlignmentCenter: 193 | textX = (self.bounds.size.width - self.contentInsets.left - self.contentInsets.right - _displayList.width) / 2 + self.contentInsets.left; 194 | break; 195 | case kMTTextAlignmentRight: 196 | textX = (self.bounds.size.width - _displayList.width - self.contentInsets.right); 197 | break; 198 | } 199 | 200 | CGFloat availableHeight = self.bounds.size.height - self.contentInsets.bottom - self.contentInsets.top; 201 | // center things vertically 202 | CGFloat height = _displayList.ascent + _displayList.descent; 203 | if (height < _fontSize/2) { 204 | // Set the height to the half the size of the font 205 | height = _fontSize/2; 206 | } 207 | CGFloat textY = (availableHeight - height) / 2 + _displayList.descent + self.contentInsets.bottom; 208 | _displayList.position = CGPointMake(textX, textY); 209 | } else { 210 | _displayList = nil; 211 | } 212 | _errorLabel.frame = self.bounds; 213 | [self setNeedsDisplay]; 214 | } 215 | 216 | #if !TARGET_OS_IPHONE 217 | - (void)layout 218 | { 219 | [self layoutSubviews]; 220 | [super layout]; 221 | } 222 | #endif 223 | 224 | - (CGSize) sizeThatFits:(CGSize)size 225 | { 226 | MTMathListDisplay* displayList = nil; 227 | if (_mathList) { 228 | displayList = [MTTypesetter createLineForMathList:_mathList font:_font style:self.currentStyle]; 229 | } 230 | 231 | size.width = displayList.width + self.contentInsets.left + self.contentInsets.right; 232 | size.height = displayList.ascent + displayList.descent + self.contentInsets.top + self.contentInsets.bottom; 233 | return size; 234 | } 235 | 236 | - (CGSize) intrinsicContentSize 237 | { 238 | return [self sizeThatFits:CGSizeZero]; 239 | } 240 | 241 | @end 242 | -------------------------------------------------------------------------------- /iosMath/lib/MTMathAtomFactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // MathAtomFactory.h 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/28/13. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | #import 13 | 14 | #import "MTMathList.h" 15 | 16 | NS_ASSUME_NONNULL_BEGIN 17 | 18 | FOUNDATION_EXPORT NSString *const MTSymbolMultiplication; 19 | FOUNDATION_EXPORT NSString *const MTSymbolDivision; 20 | FOUNDATION_EXPORT NSString *const MTSymbolFractionSlash; 21 | FOUNDATION_EXPORT NSString *const MTSymbolWhiteSquare; 22 | FOUNDATION_EXPORT NSString *const MTSymbolBlackSquare; 23 | FOUNDATION_EXPORT NSString *const MTSymbolLessEqual; 24 | FOUNDATION_EXPORT NSString *const MTSymbolGreaterEqual; 25 | FOUNDATION_EXPORT NSString *const MTSymbolNotEqual; 26 | FOUNDATION_EXPORT NSString *const MTSymbolSquareRoot; 27 | FOUNDATION_EXPORT NSString *const MTSymbolCubeRoot; 28 | FOUNDATION_EXPORT NSString *const MTSymbolInfinity; 29 | FOUNDATION_EXPORT NSString *const MTSymbolAngle; 30 | FOUNDATION_EXPORT NSString *const MTSymbolDegree; 31 | 32 | /** A factory to create commonly used MTMathAtoms. */ 33 | @interface MTMathAtomFactory : NSObject 34 | 35 | /** Returns an atom for the multiplication sign. */ 36 | + (MTMathAtom*) times; // \times or * 37 | 38 | /** Returns an atom for the division sign. */ 39 | + (MTMathAtom*) divide; // \div or / 40 | 41 | #pragma mark - Placeholders 42 | 43 | /** Returns an atom which is a placeholder square. */ 44 | + (MTMathAtom*) placeholder; 45 | 46 | /** Returns a fraction with a placeholder for the numerator and denominator */ 47 | + (MTFraction*) placeholderFraction; 48 | 49 | /** Returns a square root with a placeholder as the radicand. */ 50 | + (MTRadical *)placeholderSquareRoot; 51 | 52 | /** Returns a radical with a placeholder as the radicand. */ 53 | + (MTRadical*) placeholderRadical; 54 | 55 | #pragma mark - 56 | 57 | /** Gets the atom with the right type for the given character. If an atom 58 | cannot be determined for a given character this returns nil. 59 | This function follows latex conventions for assigning types to the atoms. 60 | The following characters are not supported and will return nil: 61 | - Any non-ascii character. 62 | - Any control character or spaces (< 0x21) 63 | - Latex control chars: $ % # & ~ ' 64 | - Chars with special meaning in latex: ^ _ { } \ 65 | All other characters will have a non-nil atom returned. 66 | */ 67 | + (nullable MTMathAtom*) atomForCharacter:(unichar) ch; 68 | 69 | /** Returns a `MTMathList` with one atom per character in the given string. This function 70 | does not do any LaTeX conversion or interpretation. It simply uses `atomForCharacter` to 71 | convert the characters to atoms. Any character that cannot be converted is ignored. */ 72 | + (MTMathList*) mathListForCharacters:(NSString*) chars; 73 | 74 | /** Returns an atom with the right type for a given latex symbol (e.g. theta) 75 | If the latex symbol is unknown this will return nil. This supports LaTeX aliases as well. 76 | */ 77 | + (nullable MTMathAtom*) atomForLatexSymbolName:(NSString*) symbolName; 78 | 79 | /** Finds the name of the LaTeX symbol name for the given atom. This function is a reverse 80 | of the above function. If no latex symbol name corresponds to the atom, then this returns `nil` 81 | If nucleus of the atom is empty, then this will return `nil`. 82 | @note: This is not an exact reverse of the above in the case of aliases. If an LaTeX alias 83 | points to a given symbol, then this function will return the original symbol name and not the 84 | alias. 85 | @note: This function does not convert MathSpaces to latex command names either. 86 | */ 87 | + (nullable NSString*) latexSymbolNameForAtom:(MTMathAtom*) atom; 88 | 89 | /** Define a latex symbol for rendering. This function allows defining custom symbols that are 90 | not already present in the default set, or override existing symbols with new meaning. 91 | e.g. to define a symbol for "lcm" one can call: 92 | `[MTMathAtomFactory addLatexSymbol:@"lcm" value:[MTMathAtomFactory operatorWithName:@"lcm" limits:NO]]` */ 93 | + (void) addLatexSymbol:(NSString*) name value:(MTMathAtom*) atom; 94 | 95 | /** Returns a list of all supported lated symbols names. */ 96 | + (NSArray*) supportedLatexSymbolNames; 97 | 98 | /** Returns a large opertor for the given name. If limits is true, limits are set up on 99 | the operator and displyed differently. */ 100 | + (MTLargeOperator *)operatorWithName:(NSString *)name limits:(bool) limits; 101 | 102 | /** Returns an accent with the given name. The name of the accent is the LaTeX name 103 | such as `grave`, `hat` etc. If the name is not a recognized accent name, this 104 | returns nil. The `innerList` of the returned `MTAccent` is nil. 105 | */ 106 | + (nullable MTAccent*) accentWithName:(NSString*) accentName; 107 | 108 | /** Returns the accent name for the given accent. This is the reverse of the above 109 | function. */ 110 | +(NSString*) accentName:(MTAccent*) accent; 111 | 112 | /** Creates a new boundary atom for the given delimiter name. If the delimiter name 113 | is not recognized it returns nil. A delimiter name can be a single character such 114 | as '(' or a latex command such as 'uparrow'. 115 | @note In order to distinguish between the delimiter '|' and the delimiter '\|' the delimiter '\|' 116 | the has been renamed to '||'. 117 | */ 118 | +(nullable MTMathAtom*) boundaryAtomForDelimiterName:(NSString*) delimiterName; 119 | 120 | /** Returns the delimiter name for a boundary atom. This is a reverse of the above function. 121 | If the atom is not a boundary atom or if the delimiter value is unknown this returns `nil`. 122 | @note This is not an exact reverse of the above function. Some delimiters have two names (e.g. 123 | `<` and `langle`) and this function always returns the shorter name. 124 | */ 125 | + (nullable NSString*) delimiterNameForBoundaryAtom:(MTMathAtom*) boundary; 126 | 127 | /** Returns a font style associated with the name. If none is found returns NSNotFound. */ 128 | + (MTFontStyle) fontStyleWithName:(NSString*) fontName; 129 | 130 | /** Returns the latex font name for a given style. */ 131 | + (NSString*) fontNameForStyle:(MTFontStyle) fontStyle; 132 | 133 | /** Returns a fraction with the given numerator and denominator. */ 134 | + (MTFraction*) fractionWithNumerator:(MTMathList*) num denominator:(MTMathList*) denom; 135 | 136 | /** Simplification of above function when numerator and denominator are simple strings. 137 | This function uses `mathListForCharacters` to convert the strings to `MTMathList`s. */ 138 | + (MTFraction*) fractionWithNumeratorStr:(NSString*) numStr denominatorStr:(NSString*) denomStr; 139 | 140 | /** Builds a table for a given environment with the given rows. Returns a `MTMathAtom` containing the 141 | table and any other atoms necessary for the given environment. Returns nil and sets error 142 | if the table could not be built. 143 | @param env The environment to use to build the table. If the env is nil, then the default table is built. 144 | @note The reason this function returns a `MTMathAtom` and not a `MTMathTable` is because some 145 | matrix environments are have builtin delimiters added to the table and hence are returned as inner atoms. 146 | */ 147 | + (nullable MTMathAtom*) tableWithEnvironment:(nullable NSString*) env rows:(NSArray*>*) rows error:(NSError**) error; 148 | @end 149 | 150 | NS_ASSUME_NONNULL_END 151 | -------------------------------------------------------------------------------- /iosMath/render/MTMathListDisplay.h: -------------------------------------------------------------------------------- 1 | // 2 | // MTLine.h 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/27/13. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | @import Foundation; 13 | @import QuartzCore; 14 | 15 | // This header file is imported by Foudation. 16 | //#include 17 | 18 | #import "MTConfig.h" 19 | 20 | #import "MTFont.h" 21 | #import "MTMathList.h" 22 | 23 | NS_ASSUME_NONNULL_BEGIN 24 | 25 | /// The base class for rendering a math equation. 26 | @interface MTDisplay : NSObject 27 | 28 | /// Draws itself in the given graphics context. 29 | - (void) draw:(CGContextRef) context; 30 | /// Gets the bounding rectangle for the MTDisplay 31 | - (CGRect) displayBounds; 32 | 33 | /// For debugging. Shows the object in quick look in Xcode. 34 | #if TARGET_OS_IPHONE 35 | - (id) debugQuickLookObject; 36 | #endif 37 | 38 | /// The distance from the axis to the top of the display 39 | @property (nonatomic, readonly) CGFloat ascent; 40 | /// The distance from the axis to the bottom of the display 41 | @property (nonatomic, readonly) CGFloat descent; 42 | /// The width of the display 43 | @property (nonatomic, readonly) CGFloat width; 44 | /// Position of the display with respect to the parent view or display. 45 | @property (nonatomic) CGPoint position; 46 | /// The range of characters supported by this item 47 | @property (nonatomic, readonly) NSRange range; 48 | /// Whether the display has a subscript/superscript following it. 49 | @property (nonatomic, readonly) BOOL hasScript; 50 | /// The text color for this display 51 | @property (nonatomic, nullable) MTColor *textColor; 52 | // The local color, if the color was mutated local with the color 53 | // command 54 | @property (nonatomic, nullable) MTColor *localTextColor; 55 | /// The background color for this display. 56 | @property (nonatomic, nullable) MTColor *localBackgroundColor; 57 | @end 58 | 59 | /// A rendering of a single CTLine as an MTDisplay 60 | @interface MTCTLineDisplay : MTDisplay 61 | 62 | - (instancetype)init NS_UNAVAILABLE; 63 | 64 | /// The CTLine being displayed 65 | @property (nonatomic, readonly) CTLineRef line; 66 | /// The attributed string used to generate the CTLineRef. Note setting this does not reset the dimensions of 67 | /// the display. So set only when 68 | @property (nonatomic) NSAttributedString* attributedString; 69 | 70 | /// An array of MTMathAtoms that this CTLine displays. Used for indexing back into the MTMathList 71 | @property (nonatomic, readonly) NSArray* atoms; 72 | 73 | @end 74 | 75 | /// An MTLine is a rendered form of MTMathList in one line. 76 | /// It can render itself using the draw method. 77 | @interface MTMathListDisplay : MTDisplay 78 | 79 | - (instancetype)init NS_UNAVAILABLE; 80 | 81 | /** 82 | @typedef MTLinePosition 83 | @brief The type of position for a line, i.e. subscript/superscript or regular. 84 | */ 85 | typedef NS_ENUM(unsigned int, MTLinePosition) { 86 | /// Regular 87 | kMTLinePositionRegular, 88 | /// Positioned at a subscript 89 | kMTLinePositionSubscript, 90 | /// Positioned at a superscript 91 | kMTLinePositionSuperscript, 92 | /// Positioned at an inner 93 | kMTLinePositionInner 94 | }; 95 | 96 | /// Where the line is positioned 97 | @property (nonatomic, readonly) MTLinePosition type; 98 | /// An array of MTDisplays which are positioned relative to the position of the 99 | /// the current display. 100 | @property (nonatomic, readonly) NSArray* subDisplays; 101 | /// If a subscript or superscript this denotes the location in the parent MTList. For a 102 | /// regular list this is NSNotFound 103 | @property (nonatomic, readonly) NSUInteger index; 104 | 105 | @end 106 | 107 | /// Rendering of an MTFraction as an MTDisplay 108 | @interface MTFractionDisplay : MTDisplay 109 | 110 | - (instancetype)init NS_UNAVAILABLE; 111 | 112 | /** A display representing the numerator of the fraction. It's position is relative 113 | to the parent and is not treated as a sub-display. 114 | */ 115 | @property (nonatomic, readonly) MTMathListDisplay* numerator; 116 | /** A display representing the denominator of the fraction. It's position is relative 117 | to the parent is not treated as a sub-display. 118 | */ 119 | @property (nonatomic, readonly) MTMathListDisplay* denominator; 120 | 121 | @end 122 | 123 | /// Rendering of an MTRadical as an MTDisplay 124 | @interface MTRadicalDisplay : MTDisplay 125 | 126 | - (instancetype)init NS_UNAVAILABLE; 127 | 128 | /** A display representing the radicand of the radical. It's position is relative 129 | to the parent is not treated as a sub-display. 130 | */ 131 | @property (nonatomic, readonly) MTMathListDisplay* radicand; 132 | /** A display representing the degree of the radical. It's position is relative 133 | to the parent is not treated as a sub-display. 134 | */ 135 | @property (nonatomic, readonly, nullable) MTMathListDisplay* degree; 136 | 137 | @end 138 | 139 | /// Rendering a glyph as a display 140 | @interface MTGlyphDisplay : MTDisplay 141 | 142 | - (instancetype)init NS_UNAVAILABLE; 143 | 144 | @end 145 | 146 | /// Rendering a large operator with limits as an MTDisplay 147 | @interface MTLargeOpLimitsDisplay : MTDisplay 148 | 149 | - (instancetype)init NS_UNAVAILABLE; 150 | 151 | /** A display representing the upper limit of the large operator. It's position is relative 152 | to the parent is not treated as a sub-display. 153 | */ 154 | @property (nonatomic, readonly, nullable) MTMathListDisplay* upperLimit; 155 | /** A display representing the lower limit of the large operator. It's position is relative 156 | to the parent is not treated as a sub-display. 157 | */ 158 | @property (nonatomic, readonly, nullable) MTMathListDisplay* lowerLimit; 159 | 160 | @end 161 | 162 | /// Rendering of an list with an overline or underline 163 | @interface MTLineDisplay : MTDisplay 164 | 165 | - (instancetype)init NS_UNAVAILABLE; 166 | 167 | /** A display representing the inner list that is underlined. It's position is relative 168 | to the parent is not treated as a sub-display. 169 | */ 170 | @property (nonatomic, readonly) MTMathListDisplay* inner; 171 | 172 | @end 173 | 174 | /// Rendering an accent as a display 175 | @interface MTAccentDisplay : MTDisplay 176 | 177 | - (instancetype)init NS_UNAVAILABLE; 178 | 179 | /** A display representing the inner list that is accented. It's position is relative 180 | to the parent is not treated as a sub-display. 181 | */ 182 | @property (nonatomic, readonly) MTMathListDisplay* accentee; 183 | 184 | /** A display representing the accent. It's position is relative to the current display. 185 | */ 186 | @property (nonatomic, readonly) MTGlyphDisplay* accent; 187 | 188 | @end 189 | 190 | /// Rendering of an list with delimiters 191 | @interface MTInnerDisplay : MTDisplay 192 | 193 | - (instancetype)init NS_UNAVAILABLE; 194 | 195 | /** A display representing the inner list that can be wrapped in delimiters. 196 | It's position is relative to the parent is not treated as a sub-display. 197 | */ 198 | @property (nonatomic, readonly) MTMathListDisplay* inner; 199 | 200 | /** A display representing the delimiters. Their position is relative 201 | to the parent are not treated as a sub-display. 202 | */ 203 | @property (nonatomic, readonly, nullable) MTDisplay* leftDelimiter; 204 | @property (nonatomic, readonly, nullable) MTDisplay* rightDelimiter; 205 | 206 | /// Denotes the location in the parent MTList. 207 | @property (nonatomic, readonly) NSUInteger index; 208 | 209 | @end 210 | 211 | NS_ASSUME_NONNULL_END 212 | -------------------------------------------------------------------------------- /fonts/math_table_to_plist.py: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/python3 2 | import plistlib 3 | import sys 4 | from fontTools.ttLib import TTFont 5 | 6 | def usage(code): 7 | print('Usage math_table_to_plist.py ') 8 | sys.exit(code) 9 | 10 | def process_font(font_file, out_file): 11 | font = TTFont(font_file) 12 | math_table = font['MATH'].table 13 | constants = get_constants(math_table) 14 | italic_c = get_italic_correction(math_table) 15 | v_variants = get_v_variants(math_table) 16 | h_variants = get_h_variants(math_table) 17 | assembly = get_v_assembly(math_table) 18 | accents = get_accent_attachments(math_table) 19 | pl = { 20 | "version" : "1.3", 21 | "constants": constants, 22 | "v_variants" : v_variants, 23 | "h_variants" : h_variants, 24 | "italic" : italic_c, 25 | "accents" : accents, 26 | "v_assembly" : assembly } 27 | ofile = open(out_file, 'w+b') 28 | plistlib.dump(pl, ofile) 29 | ofile.close() 30 | 31 | def get_constants(math_table): 32 | constants = math_table.MathConstants 33 | if constants is None: 34 | raise 'Cannot find MathConstants in MATH table' 35 | 36 | int_consts = [ 'ScriptPercentScaleDown', 37 | 'ScriptScriptPercentScaleDown', 38 | 'DelimitedSubFormulaMinHeight', 39 | 'DisplayOperatorMinHeight', 40 | 'RadicalDegreeBottomRaisePercent'] 41 | consts = { c : getattr(constants, c) for c in int_consts } 42 | 43 | record_consts = [ 'MathLeading', 44 | 'AxisHeight', 45 | 'AccentBaseHeight', 46 | 'FlattenedAccentBaseHeight', 47 | 'SubscriptShiftDown', 48 | 'SubscriptTopMax', 49 | 'SubscriptBaselineDropMin', 50 | 'SuperscriptShiftUp', 51 | 'SuperscriptShiftUpCramped', 52 | 'SuperscriptBottomMin', 53 | 'SuperscriptBaselineDropMax', 54 | 'SubSuperscriptGapMin', 55 | 'SuperscriptBottomMaxWithSubscript', 56 | 'SpaceAfterScript', 57 | 'UpperLimitGapMin', 58 | 'UpperLimitBaselineRiseMin', 59 | 'LowerLimitGapMin', 60 | 'LowerLimitBaselineDropMin', 61 | 'StackTopShiftUp', 62 | 'StackTopDisplayStyleShiftUp', 63 | 'StackBottomShiftDown', 64 | 'StackBottomDisplayStyleShiftDown', 65 | 'StackGapMin', 66 | 'StackDisplayStyleGapMin', 67 | 'StretchStackTopShiftUp', 68 | 'StretchStackBottomShiftDown', 69 | 'StretchStackGapAboveMin', 70 | 'StretchStackGapBelowMin', 71 | 'FractionNumeratorShiftUp', 72 | 'FractionNumeratorDisplayStyleShiftUp', 73 | 'FractionDenominatorShiftDown', 74 | 'FractionDenominatorDisplayStyleShiftDown', 75 | 'FractionNumeratorGapMin', 76 | 'FractionNumDisplayStyleGapMin', 77 | 'FractionRuleThickness', 78 | 'FractionDenominatorGapMin', 79 | 'FractionDenomDisplayStyleGapMin', 80 | 'SkewedFractionHorizontalGap', 81 | 'SkewedFractionVerticalGap', 82 | 'OverbarVerticalGap', 83 | 'OverbarRuleThickness', 84 | 'OverbarExtraAscender', 85 | 'UnderbarVerticalGap', 86 | 'UnderbarRuleThickness', 87 | 'UnderbarExtraDescender', 88 | 'RadicalVerticalGap', 89 | 'RadicalDisplayStyleVerticalGap', 90 | 'RadicalRuleThickness', 91 | 'RadicalExtraAscender', 92 | 'RadicalKernBeforeDegree', 93 | 'RadicalKernAfterDegree', 94 | ] 95 | consts_2 = { c : getattr(constants, c).Value for c in record_consts } 96 | consts.update(consts_2) 97 | 98 | variants = math_table.MathVariants 99 | consts['MinConnectorOverlap'] = variants.MinConnectorOverlap 100 | return consts 101 | 102 | def get_italic_correction(math_table): 103 | glyph_info = math_table.MathGlyphInfo 104 | if glyph_info is None: 105 | raise "Cannot find MathGlyphInfo in MATH table." 106 | italic = glyph_info.MathItalicsCorrectionInfo 107 | if italic is None: 108 | raise "Cannot find Italic Correction in GlyphInfo" 109 | 110 | glyphs = italic.Coverage.glyphs 111 | count = italic.ItalicsCorrectionCount 112 | records = italic.ItalicsCorrection 113 | italic_dict = {} 114 | for i in range(count): 115 | name = glyphs[i] 116 | record = records[i] 117 | if record.DeviceTable is not None: 118 | raise "Don't know how to process device table for italic correction." 119 | italic_dict[name] = record.Value 120 | return italic_dict 121 | 122 | def get_accent_attachments(math_table): 123 | glyph_info = math_table.MathGlyphInfo 124 | if glyph_info is None: 125 | raise "Cannot find MathGlyphInfo in MATH table." 126 | attach = glyph_info.MathTopAccentAttachment 127 | if attach is None: 128 | raise "Cannot find Top Accent Attachment in GlyphInfo" 129 | 130 | glyphs = attach.TopAccentCoverage.glyphs 131 | count = attach.TopAccentAttachmentCount 132 | records = attach.TopAccentAttachment 133 | attach_dict = {} 134 | for i in range(count): 135 | name = glyphs[i] 136 | record = records[i] 137 | if record.DeviceTable is not None: 138 | raise "Don't know how to process device table for accent attachment." 139 | attach_dict[name] = record.Value 140 | return attach_dict 141 | 142 | def get_v_variants(math_table): 143 | variants = math_table.MathVariants 144 | vglyphs = variants.VertGlyphCoverage.glyphs 145 | vconstruction = variants.VertGlyphConstruction 146 | count = variants.VertGlyphCount 147 | variant_dict = {} 148 | for i in range(count): 149 | name = vglyphs[i] 150 | record = vconstruction[i] 151 | glyph_variants = [x.VariantGlyph for x in 152 | record.MathGlyphVariantRecord] 153 | variant_dict[name] = glyph_variants 154 | return variant_dict 155 | 156 | def get_h_variants(math_table): 157 | variants = math_table.MathVariants 158 | hglyphs = variants.HorizGlyphCoverage.glyphs 159 | hconstruction = variants.HorizGlyphConstruction 160 | count = variants.HorizGlyphCount 161 | variant_dict = {} 162 | for i in range(count): 163 | name = hglyphs[i] 164 | record = hconstruction[i] 165 | glyph_variants = [x.VariantGlyph for x in 166 | record.MathGlyphVariantRecord] 167 | variant_dict[name] = glyph_variants 168 | return variant_dict 169 | 170 | def get_v_assembly(math_table): 171 | variants = math_table.MathVariants 172 | vglyphs = variants.VertGlyphCoverage.glyphs 173 | vconstruction = variants.VertGlyphConstruction 174 | count = variants.VertGlyphCount 175 | assembly_dict = {} 176 | for i in range(count): 177 | name = vglyphs[i] 178 | record = vconstruction[i] 179 | assembly = record.GlyphAssembly 180 | if assembly is not None: 181 | # There is an assembly for this glyph 182 | italic = assembly.ItalicsCorrection.Value 183 | parts = [part_dict(part) for part in assembly.PartRecords] 184 | assembly_dict[name] = { 185 | "italic" : assembly.ItalicsCorrection.Value, 186 | "parts" : parts } 187 | return assembly_dict 188 | 189 | def part_dict(part): 190 | return { 191 | "glyph": part.glyph, 192 | "startConnector" : part.StartConnectorLength, 193 | "endConnector" : part.EndConnectorLength, 194 | "advance" : part.FullAdvance, 195 | "extender" : (part.PartFlags == 1) } 196 | 197 | def main(): 198 | if len(sys.argv) != 3: 199 | usage(1) 200 | font_file = sys.argv[1] 201 | plist_file = sys.argv[2] 202 | process_font(font_file, plist_file) 203 | 204 | if __name__ == '__main__': 205 | main() 206 | -------------------------------------------------------------------------------- /iosMath/lib/MTMathListIndex.m: -------------------------------------------------------------------------------- 1 | // 2 | // MTMathListIndex.m 3 | // 4 | // Created by Kostub Deshmukh on 9/6/13. 5 | // Copyright (C) 2013 MathChat 6 | // 7 | // This software may be modified and distributed under the terms of the 8 | // MIT license. See the LICENSE file for details. 9 | // 10 | 11 | #import "MTMathListIndex.h" 12 | 13 | #pragma mark - MTMathListIndex 14 | 15 | @interface MTMathListIndex () 16 | 17 | @property (nonatomic, readwrite) NSUInteger atomIndex; 18 | @property (nonatomic, readwrite) MTMathListSubIndexType subIndexType; 19 | @property (nonatomic, readwrite, nullable) MTMathListIndex* subIndex; 20 | 21 | @end 22 | 23 | @implementation MTMathListIndex 24 | 25 | + (id)level0Index:(NSUInteger)index 26 | { 27 | MTMathListIndex* mlIndex = [MTMathListIndex new]; 28 | mlIndex.atomIndex = index; 29 | return mlIndex; 30 | } 31 | 32 | + (instancetype)indexAtLocation:(NSUInteger)location withSubIndex:(MTMathListIndex *)subIndex type:(MTMathListSubIndexType)type 33 | { 34 | MTMathListIndex* index = [self level0Index:location]; 35 | index.subIndexType = type; 36 | index.subIndex = subIndex; 37 | return index; 38 | } 39 | 40 | - (MTMathListIndex *)levelUpWithSubIndex:(MTMathListIndex *)subIndex type:(MTMathListSubIndexType)type 41 | { 42 | if (self.subIndexType == kMTSubIndexTypeNone) { 43 | return [MTMathListIndex indexAtLocation:self.atomIndex withSubIndex:subIndex type:type]; 44 | } 45 | // we have to recurse 46 | return [MTMathListIndex indexAtLocation:self.atomIndex withSubIndex:[self.subIndex levelUpWithSubIndex:subIndex type:type] type:self.subIndexType]; 47 | } 48 | 49 | - (MTMathListIndex *)levelDown 50 | { 51 | if (self.subIndexType == kMTSubIndexTypeNone) { 52 | return nil; 53 | } 54 | // recurse 55 | MTMathListIndex* subIndexDown = self.subIndex.levelDown; 56 | if (subIndexDown) { 57 | return [MTMathListIndex indexAtLocation:self.atomIndex withSubIndex:subIndexDown type:self.subIndexType]; 58 | } else { 59 | return [MTMathListIndex level0Index:self.atomIndex]; 60 | } 61 | } 62 | 63 | - (MTMathListIndex *)previous 64 | { 65 | if (self.subIndexType == kMTSubIndexTypeNone) { 66 | if (self.atomIndex > 0) { 67 | return [MTMathListIndex level0Index:self.atomIndex - 1]; 68 | } 69 | } else { 70 | MTMathListIndex* prevSubIndex = self.subIndex.previous; 71 | if (prevSubIndex) { 72 | return [MTMathListIndex indexAtLocation:self.atomIndex withSubIndex:prevSubIndex type:self.subIndexType]; 73 | } 74 | } 75 | return nil; 76 | } 77 | 78 | - (MTMathListIndex *)next 79 | { 80 | if (self.subIndexType == kMTSubIndexTypeNone) { 81 | return [MTMathListIndex level0Index:self.atomIndex + 1]; 82 | } else if (self.subIndexType == kMTSubIndexTypeNucleus) { 83 | return [MTMathListIndex indexAtLocation:self.atomIndex + 1 withSubIndex:self.subIndex type:self.subIndexType]; 84 | } else { 85 | return [MTMathListIndex indexAtLocation:self.atomIndex withSubIndex:self.subIndex.next type:self.subIndexType]; 86 | } 87 | } 88 | 89 | - (BOOL)hasSubIndexOfType:(MTMathListSubIndexType)subIndexType 90 | { 91 | if (self.subIndexType == subIndexType) { 92 | return true; 93 | } else { 94 | return [self.subIndex hasSubIndexOfType:subIndexType]; 95 | } 96 | } 97 | 98 | - (BOOL) isAtBeginningOfLine 99 | { 100 | return (self.finalIndex == 0); 101 | } 102 | 103 | 104 | - (BOOL)isAtSameLevel:(MTMathListIndex *)other 105 | { 106 | if (self.subIndexType != other.subIndexType) { 107 | return false; 108 | } else if (self.subIndexType == kMTSubIndexTypeNone) { 109 | // No subindexes, they are at the same level. 110 | return true; 111 | } else if (self.atomIndex != other.atomIndex) { 112 | // the subindexes are used in different atoms 113 | return false; 114 | } else { 115 | return [self.subIndex isAtSameLevel:other.subIndex]; 116 | } 117 | } 118 | 119 | - (NSUInteger) finalIndex 120 | { 121 | if (self.subIndexType == kMTSubIndexTypeNone) { 122 | return self.atomIndex; 123 | } else { 124 | return self.subIndex.finalIndex; 125 | } 126 | } 127 | 128 | - (MTMathListSubIndexType) finalSubIndexType 129 | { 130 | if (self.subIndex.subIndex) { 131 | return [self.subIndex finalSubIndexType]; 132 | } else { 133 | return self.subIndexType; 134 | } 135 | } 136 | 137 | - (NSString *)description 138 | { 139 | if (self.subIndex) { 140 | return [NSString stringWithFormat:@"[%lu, %d:%@]", (unsigned long)self.atomIndex, self.subIndexType, self.subIndex]; 141 | } 142 | return [NSString stringWithFormat:@"[%lu]", (unsigned long)self.atomIndex]; 143 | } 144 | 145 | - (BOOL)isEqualToIndex:(MTMathListIndex *)index 146 | { 147 | if (self.atomIndex != index.atomIndex || self.subIndexType != index.subIndexType) { 148 | return NO; 149 | } 150 | if (self.subIndex) { 151 | return [self.subIndex isEqual:index.subIndex]; 152 | } else { 153 | return (index.subIndex == nil); 154 | } 155 | } 156 | 157 | - (BOOL) isEqual:(id) anObject 158 | { 159 | if (self == anObject) { 160 | return YES; 161 | } 162 | if (!anObject || ![anObject isKindOfClass:[self class]]) { 163 | return NO; 164 | } 165 | return [self isEqualToIndex:anObject]; 166 | } 167 | 168 | - (NSUInteger) hash 169 | { 170 | const int prime = 31; 171 | NSUInteger hash = self.atomIndex; 172 | hash = hash * prime + self.subIndexType; 173 | hash = hash * prime + self.subIndex.hash; 174 | return hash; 175 | } 176 | 177 | @end 178 | 179 | @interface MTMathListRange () 180 | 181 | - (instancetype)initWithStart:(MTMathListIndex*) start length:(NSUInteger) length NS_DESIGNATED_INITIALIZER; 182 | 183 | @end 184 | 185 | @implementation MTMathListRange 186 | 187 | - (instancetype)initWithStart:(MTMathListIndex*) start length:(NSUInteger) length 188 | { 189 | self = [super init]; 190 | if (self) { 191 | _start = start; 192 | _length = length; 193 | } 194 | return self; 195 | } 196 | 197 | + (MTMathListRange *)makeRange:(MTMathListIndex *)start length:(NSUInteger)length 198 | { 199 | return [[MTMathListRange alloc] initWithStart:start length:length]; 200 | } 201 | 202 | + (MTMathListRange *)makeRange:(MTMathListIndex *)start 203 | { 204 | return [self makeRange:start length:1]; 205 | } 206 | 207 | + (MTMathListRange *)makeRangeForIndex:(NSUInteger)start 208 | { 209 | return [self makeRange:[MTMathListIndex level0Index:start]]; 210 | } 211 | 212 | + (MTMathListRange *)makeRangeForRange:(NSRange)range 213 | { 214 | return [self makeRange:[MTMathListIndex level0Index:range.location] length:range.length]; 215 | } 216 | 217 | - (NSString *)description 218 | { 219 | return [NSString stringWithFormat:@"(%@, %lu)", self.start, (unsigned long)self.length]; 220 | } 221 | 222 | - (MTMathListRange *)subIndexRange 223 | { 224 | if (self.start.subIndexType != kMTSubIndexTypeNone) { 225 | return [MTMathListRange makeRange:self.start.subIndex length:self.length]; 226 | } 227 | return nil; 228 | } 229 | 230 | - (NSRange) finalRange 231 | { 232 | return NSMakeRange(self.start.finalIndex, self.length); 233 | } 234 | 235 | - (MTMathListRange *)unionRange:(MTMathListRange *)range 236 | { 237 | if (![self.start isAtSameLevel:range.start]) { 238 | NSAssert(false, @"Cannot union ranges at different levels: %@, %@", self, range); 239 | return nil; 240 | } 241 | 242 | NSRange r1 = self.finalRange; 243 | NSRange r2 = range.finalRange; 244 | NSRange unionRange = NSUnionRange(r1, r2); 245 | MTMathListIndex* start; 246 | if (unionRange.location == r1.location) { 247 | start = self.start; 248 | } else { 249 | assert(unionRange.location == r2.location); 250 | start = range.start; 251 | } 252 | return [MTMathListRange makeRange:start length:unionRange.length]; 253 | } 254 | 255 | + (MTMathListRange *)unionRanges:(NSArray *)ranges 256 | { 257 | NSAssert((ranges.count > 0), @"Need to union at least one range"); 258 | 259 | MTMathListRange* unioned = ranges[0]; 260 | for (int i = 1; i < ranges.count; i++) { 261 | MTMathListRange* next = ranges[i]; 262 | [unioned unionRange:next]; 263 | } 264 | return unioned; 265 | } 266 | 267 | @end 268 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iosMath 2 | 3 | [![Build Status](http://img.shields.io/travis/kostub/iosMath.svg?style=flat)](https://travis-ci.org/kostub/iosMath) 4 | [![Version](https://img.shields.io/cocoapods/v/iosMath.svg?style=flat)](http://cocoapods.org/pods/iosMath) 5 | [![License](https://img.shields.io/cocoapods/l/iosMath.svg?style=flat)](http://cocoapods.org/pods/iosMath) 6 | [![Platform](https://img.shields.io/cocoapods/p/iosMath.svg?style=flat)](http://cocoapods.org/pods/iosMath) 7 | 8 | `iosMath` is a library for displaying beautifully rendered math equations 9 | in iOS and MacOS applications. It typesets formulae written using the LaTeX in 10 | a `UILabel` equivalent class. It uses the same typesetting rules as LaTeX and 11 | so the equations are rendered exactly as LaTeX would render them. 12 | 13 | It is similar to [MathJax](https://www.mathjax.org) or 14 | [KaTeX](https://github.com/Khan/KaTeX) for the web but for native iOS or MacOS 15 | applications without having to use a `UIWebView` and Javascript. More 16 | importantly, it is significantly faster than using a `UIWebView`. 17 | 18 | ## Examples 19 | Here are screenshots of some formulae that you could render with this 20 | library: 21 | 22 | ![Quadratic Formula](img/quadratic.png) 23 | 24 | ![Calculus](img/calculus.png) 25 | 26 | ![AM-GM](img/amgm.png) 27 | 28 | ![Ramanujan Identity](img/ramanujan.png) 29 | 30 | The [EXAMPLES.md](./EXAMPLES.md) file contains more examples. 31 | 32 | ## Requirements 33 | `iosMath` works on iOS 6+ or MacOS 10.8+ and requires ARC to build. It depends 34 | on the following Apple frameworks: 35 | 36 | * Foundation.framework 37 | * CoreGraphics.framework 38 | * QuartzCore.framework 39 | * CoreText.framework 40 | 41 | Additionally for iOS it requires: 42 | * UIKit.framework 43 | 44 | Additionally for MacOS it requires: 45 | * AppKit.framework 46 | 47 | ## Installation 48 | 49 | ### Cocoapods 50 | 51 | iosMath is available through [CocoaPods](http://cocoapods.org). To install 52 | it: 53 | 54 | 1. Add a entry for iosMath to your Podfile: `pod 'iosMath'`. 55 | 2. Install the pod by running `pod install`. 56 | 57 | ### Static library 58 | 59 | You can also add iosMath as a static library to your project or 60 | workspace. 61 | 62 | 1. Download the [latest code version](https://github.com/kostub/iosMath/downloads) or add the 63 | repository as a git submodule to your git-tracked project. 64 | 2. Open your project in Xcode, then drag and drop 65 | `iosMath.xcodeproj` onto your project or workspace (use the 66 | "Product Navigator view"). 67 | 3. Select your target and go to the Build phases tab. In the Link Binary 68 | With Libraries section select the add button. On the sheet find and 69 | add `libIosMath.a`. You might also need to add `iosMath` to 70 | the Target Dependencies list. 71 | 4. Add the `MathFontBundle` to the list of `Copy Bundle Resources`. 72 | 5. Include IosMath wherever you need it with `#import `. 73 | 74 | ## Usage 75 | 76 | The library provides a class `MTMathUILabel` which is a `UIView` that 77 | supports rendering math equations. To display an equation simply create 78 | an `MTMathUILabel` as follows: 79 | 80 | ```objective-c 81 | #import "MTMathUILabel.h" 82 | 83 | MTMathUILabel* label = [[MTMathUILabel alloc] init]; 84 | label.latex = @"x = \\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}"; 85 | 86 | ``` 87 | Adding `MTMathUILabel` as a sub-view of your `UIView` as will render the 88 | quadratic formula example shown above. 89 | 90 | ### Included Features 91 | This is a list of formula types that the library currently supports: 92 | 93 | * Simple algebraic equations 94 | * Fractions and continued fractions 95 | * Exponents and subscripts 96 | * Trigonometric formulae 97 | * Square roots and n-th roots 98 | * Calculus symbos - limits, derivatives, integrals 99 | * Big operators (e.g. product, sum) 100 | * Big delimiters (using \\left and \\right) 101 | * Greek alphabet 102 | * Combinatorics (\\binom, \\choose etc.) 103 | * Geometry symbols (e.g. angle, congruence etc.) 104 | * Ratios, proportions, percents 105 | * Math spacing 106 | * Overline and underline 107 | * Math accents 108 | * Matrices 109 | * Equation alignment 110 | * Change bold, roman, caligraphic and other font styles (\\bf, \\text, etc.) 111 | * Most commonly used math symbols 112 | * Colors 113 | 114 | ### Example 115 | 116 | There is a sample app included in this project that shows how to use the 117 | app and the different equations that you can render. To run the sample 118 | app, clone the repository, and run `pod install` first. Then on iOS run the 119 | __iosMathExample__ app. For MacOS run the __MacOSMath__ app. 120 | 121 | ### Advanced configuration 122 | 123 | `MTMathUILabel` supports some advanced configuration options: 124 | 125 | ##### Math mode 126 | 127 | You can change the mode of the `MTMathUILabel` between Display Mode 128 | (equivalent to `$$` or `\[` in LaTeX) and Text Mode (equivalent to `$` 129 | or `\(` in LaTeX). The default style is Display. To switch to Text 130 | simply: 131 | 132 | ```objective-c 133 | label.labelMode = kMTMathUILabelModeText; 134 | ``` 135 | 136 | ##### Text Alignment 137 | The default alignment of the equations is left. This can be changed to 138 | center or right as follows: 139 | 140 | ```objective-c 141 | label.textAlignment = kMTTextAlignmentCenter; 142 | ``` 143 | 144 | ##### Font size 145 | The default font-size is 20pt. You can change it as follows: 146 | 147 | ```objective-c 148 | label.fontSize = 30; 149 | ``` 150 | ##### Font 151 | The default font is *Latin Modern Math*. This can be changed as: 152 | 153 | ```objective-c 154 | label.font = [[MTFontManager fontManager] termesFontWithSize:20]; 155 | ``` 156 | 157 | This project has 3 fonts bundled with it, but you can use any OTF math 158 | font. 159 | 160 | ##### Color 161 | The default color of the rendered equation is black. You can change 162 | it to any other color as follows: 163 | 164 | ```objective-c 165 | label.textColor = [UIColor redColor]; 166 | ``` 167 | 168 | It is also possible to set different colors for different parts of the 169 | equation. Just access the `displayList` field and set the `textColor` 170 | on the underlying displays that you want to change the color of. 171 | 172 | ##### Custom Commands 173 | You can define your own commands that are not already predefined. This is 174 | similar to macros is LaTeX. To define your own command use: 175 | 176 | ```objective-c 177 | [MTMathAtomFactory addLatexSymbol:@"lcm" 178 | value:[MTMathAtomFactory operatorWithName:@"lcm" limits:NO]]; 179 | ``` 180 | 181 | This creates a `\lcm` command that can be used in the LaTeX. 182 | 183 | ##### Content Insets 184 | The `MTMathUILabel` has `contentInsets` for finer control of placement of the 185 | equation in relation to the view. 186 | 187 | If you need to set it you can do as follows: 188 | 189 | ```objective-c 190 | label.contentInsets = UIEdgeInsetsMake(0, 10, 0, 20); 191 | ``` 192 | 193 | ##### Error handling 194 | 195 | If the LaTeX text given to `MTMathUILabel` is 196 | invalid or if it contains commands that aren't currently supported then 197 | an error message will be displayed instead of the label. 198 | 199 | This error can be programmatically retrieved as `label.error`. If you 200 | prefer not to display anything then set: 201 | 202 | ```objective-c 203 | label.displayErrorInline = NO; 204 | ``` 205 | 206 | ## Future Enhancements 207 | 208 | Note this is not a complete implementation of LaTeX math mode. There are 209 | some important pieces that are missing and will be included in future 210 | updates. This includes: 211 | 212 | * Support for explicit big delimiters (bigl, bigr etc.) 213 | * Addition of missing plain TeX commands 214 | 215 | ## Related Projects 216 | 217 | For people looking for things beyond just rendering math, there are two 218 | related projects: 219 | 220 | * [MathEditor](https://github.com/kostub/MathEditor): A WYSIWYG editor 221 | for math equations on iOS. 222 | * [MathSolver](https://github.com/kostub/MathSolver): A library for 223 | solving math equations. 224 | 225 | ## License 226 | 227 | iosMath is available under the MIT license. See the [LICENSE](./LICENSE) 228 | file for more info. 229 | 230 | ### Fonts 231 | This distribution contains the following fonts. These fonts are 232 | licensed as follows: 233 | * Latin Modern Math: 234 | [GUST Font License](./fonts/GUST-FONT-LICENSE.txt) 235 | * Tex Gyre Termes: 236 | [GUST Font License](./fonts/GUST-FONT-LICENSE.txt) 237 | * [XITS Math](https://github.com/khaledhosny/xits-math): 238 | [Open Font License](./fonts/OFL.txt) 239 | -------------------------------------------------------------------------------- /iosMath/render/internal/MTFontMathTable.h: -------------------------------------------------------------------------------- 1 | // 2 | // MTFontMathTable.h 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/28/13. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | @import Foundation; 13 | @import CoreText; 14 | 15 | @class MTFont; 16 | 17 | /** MTGlyphPart represents a part of a glyph used for assembling a large vertical or horizontal 18 | glyph. */ 19 | @interface MTGlyphPart : NSObject 20 | 21 | /// The glyph that represents this part 22 | @property (nonatomic, readonly) CGGlyph glyph; 23 | 24 | /// Full advance width/height for this part, in the direction of the extension in points. 25 | @property (nonatomic, readonly) CGFloat fullAdvance; 26 | 27 | /// Advance width/ height of the straight bar connector material at the beginning of the glyph in points. 28 | @property (nonatomic, readonly) CGFloat startConnectorLength; 29 | 30 | /// Advance width/ height of the straight bar connector material at the end of the glyph in points. 31 | @property (nonatomic, readonly) CGFloat endConnectorLength; 32 | 33 | /// If this part is an extender. If set, the part can be skipped or repeated. 34 | @property (nonatomic, readonly) BOOL isExtender; 35 | 36 | @end 37 | 38 | /** This class represents the Math table of an open type font. 39 | 40 | The math table is documented here: https://www.microsoft.com/typography/otspec/math.htm 41 | 42 | How the constants in this class affect the display is documented here: 43 | http://www.tug.org/TUGboat/tb30-1/tb94vieth.pdf 44 | 45 | @note We don't parse the math table from the open type font. Rather we parse it 46 | in python and convert it to a .plist file which is easily consumed by this class. 47 | This approach is preferable to spending an inordinate amount of time figuring out 48 | how to parse the returned NSData object using the open type rules. 49 | 50 | @remark This class is not meant to be used outside of this library. 51 | */ 52 | @interface MTFontMathTable : NSObject 53 | 54 | - (nonnull instancetype) initWithFont:(nonnull MTFont*) font mathTable:(nonnull NSDictionary*) mathTable NS_DESIGNATED_INITIALIZER; 55 | - (nonnull instancetype) init NS_UNAVAILABLE; 56 | 57 | /** MU unit in points */ 58 | @property (nonatomic, readonly) CGFloat muUnit; 59 | 60 | // Math Font Metrics from the opentype specification 61 | #pragma mark Fractions 62 | @property (nonatomic, readonly) CGFloat fractionNumeratorDisplayStyleShiftUp; // \sigma_8 in TeX 63 | @property (nonatomic, readonly) CGFloat fractionNumeratorShiftUp; // \sigma_9 in TeX 64 | @property (nonatomic, readonly) CGFloat fractionDenominatorDisplayStyleShiftDown; // \sigma_11 in TeX 65 | @property (nonatomic, readonly) CGFloat fractionDenominatorShiftDown; // \sigma_12 in TeX 66 | @property (nonatomic, readonly) CGFloat fractionNumeratorDisplayStyleGapMin; // 3 * \xi_8 in TeX 67 | @property (nonatomic, readonly) CGFloat fractionNumeratorGapMin; // \xi_8 in TeX 68 | @property (nonatomic, readonly) CGFloat fractionDenominatorDisplayStyleGapMin; // 3 * \xi_8 in TeX 69 | @property (nonatomic, readonly) CGFloat fractionDenominatorGapMin; // \xi_8 in TeX 70 | @property (nonatomic, readonly) CGFloat fractionRuleThickness; // \xi_8 in TeX 71 | @property (nonatomic, readonly) CGFloat fractionDelimiterDisplayStyleSize; // \sigma_20 in TeX 72 | @property (nonatomic, readonly) CGFloat fractionDelimiterSize; // \sigma_21 in TeX 73 | 74 | #pragma mark Stacks 75 | @property (nonatomic, readonly) CGFloat stackTopDisplayStyleShiftUp; // \sigma_8 in TeX 76 | @property (nonatomic, readonly) CGFloat stackTopShiftUp; // \sigma_10 in TeX 77 | @property (nonatomic, readonly) CGFloat stackDisplayStyleGapMin; // 7 \xi_8 in TeX 78 | @property (nonatomic, readonly) CGFloat stackGapMin; // 3 \xi_8 in TeX 79 | @property (nonatomic, readonly) CGFloat stackBottomDisplayStyleShiftDown; // \sigma_11 in TeX 80 | @property (nonatomic, readonly) CGFloat stackBottomShiftDown; // \sigma_12 in TeX 81 | 82 | #pragma mark super/sub scripts 83 | 84 | @property (nonatomic, readonly) CGFloat superscriptShiftUp; // \sigma_13, \sigma_14 in TeX 85 | @property (nonatomic, readonly) CGFloat superscriptShiftUpCramped; // \sigma_15 in TeX 86 | @property (nonatomic, readonly) CGFloat subscriptShiftDown; // \sigma_16, \sigma_17 in TeX 87 | @property (nonatomic, readonly) CGFloat superscriptBaselineDropMax; // \sigma_18 in TeX 88 | @property (nonatomic, readonly) CGFloat subscriptBaselineDropMin; // \sigma_19 in TeX 89 | @property (nonatomic, readonly) CGFloat superscriptBottomMin; // 1/4 \sigma_5 in TeX 90 | @property (nonatomic, readonly) CGFloat subscriptTopMax; // 4/5 \sigma_5 in TeX 91 | @property (nonatomic, readonly) CGFloat subSuperscriptGapMin; // 4 \xi_8 in TeX 92 | @property (nonatomic, readonly) CGFloat superscriptBottomMaxWithSubscript; // 4/5 \sigma_5 in TeX 93 | 94 | @property (nonatomic, readonly) CGFloat spaceAfterScript; 95 | 96 | #pragma mark radicals 97 | @property (nonatomic, readonly) CGFloat radicalExtraAscender; // \xi_8 in Tex 98 | @property (nonatomic, readonly) CGFloat radicalRuleThickness; // \xi_8 in Tex 99 | @property (nonatomic, readonly) CGFloat radicalDisplayStyleVerticalGap; // \xi_8 + 1/4 \sigma_5 in Tex 100 | @property (nonatomic, readonly) CGFloat radicalVerticalGap; // 5/4 \xi_8 in Tex 101 | @property (nonatomic, readonly) CGFloat radicalKernBeforeDegree; // 5 mu in Tex 102 | @property (nonatomic, readonly) CGFloat radicalKernAfterDegree; // -10 mu in Tex 103 | @property (nonatomic, readonly) CGFloat radicalDegreeBottomRaisePercent; // 60% in Tex 104 | 105 | #pragma mark Limits 106 | @property (nonatomic, readonly) CGFloat upperLimitBaselineRiseMin; // \xi_11 in TeX 107 | @property (nonatomic, readonly) CGFloat upperLimitGapMin; // \xi_9 in TeX 108 | @property (nonatomic, readonly) CGFloat lowerLimitGapMin; // \xi_10 in TeX 109 | @property (nonatomic, readonly) CGFloat lowerLimitBaselineDropMin; // \xi_12 in TeX 110 | @property (nonatomic, readonly) CGFloat limitExtraAscenderDescender; // \xi_13 in TeX, not present in OpenType so we always set it to 0. 111 | 112 | #pragma mark Underline 113 | @property (nonatomic, readonly) CGFloat underbarVerticalGap; // 3 \xi_8 in TeX 114 | @property (nonatomic, readonly) CGFloat underbarRuleThickness; // \xi_8 in TeX 115 | @property (nonatomic, readonly) CGFloat underbarExtraDescender; // \xi_8 in TeX 116 | 117 | #pragma mark Overline 118 | @property (nonatomic, readonly) CGFloat overbarVerticalGap; // 3 \xi_8 in TeX 119 | @property (nonatomic, readonly) CGFloat overbarRuleThickness; // \xi_8 in TeX 120 | @property (nonatomic, readonly) CGFloat overbarExtraAscender; // \xi_8 in TeX 121 | 122 | #pragma mark Constants 123 | 124 | @property (nonatomic, readonly) CGFloat axisHeight; // \sigma_22 in TeX 125 | @property (nonatomic, readonly) CGFloat scriptScaleDown; 126 | @property (nonatomic, readonly) CGFloat scriptScriptScaleDown; 127 | 128 | #pragma mark Accent 129 | 130 | @property (nonatomic, readonly) CGFloat accentBaseHeight; // \fontdimen5 in TeX (x-height) 131 | 132 | #pragma mark Variants 133 | 134 | /** Returns an NSArray of all the vertical variants of the glyph if any. If 135 | there are no variants for the glyph, the array contains the given glyph. */ 136 | - (nonnull NSArray*) getVerticalVariantsForGlyph:(CGGlyph) glyph; 137 | 138 | /** Returns an NSArray of all the horizontal variants of the glyph if any. If 139 | there are no variants for the glyph, the array contains the given glyph. */ 140 | - (nonnull NSArray*) getHorizontalVariantsForGlyph:(CGGlyph) glyph; 141 | 142 | /** Returns a larger vertical variant of the given glyph if any. 143 | If there is no larger version, this returns the current glyph. 144 | */ 145 | - (CGGlyph) getLargerGlyph:(CGGlyph) glyph; 146 | 147 | #pragma mark Italic Correction 148 | 149 | /** Returns the italic correction for the given glyph if any. If there 150 | isn't any this returns 0. */ 151 | - (CGFloat) getItalicCorrection:(CGGlyph) glyph; 152 | 153 | #pragma mark Accents 154 | 155 | /** Returns the adjustment to the top accent for the given glyph if any. 156 | If there isn't any this returns -1. */ 157 | - (CGFloat) getTopAccentAdjustment:(CGGlyph) glyph; 158 | 159 | #pragma mark Glyph Construction 160 | 161 | /** Minimum overlap of connecting glyphs during glyph construction */ 162 | @property (nonatomic, readonly) CGFloat minConnectorOverlap; 163 | 164 | /** Returns an array of the glyph parts to be used for constructing vertical variants 165 | of this glyph. If there is no glyph assembly defined, returns nil. */ 166 | - (nullable NSArray*) getVerticalGlyphAssemblyForGlyph:(CGGlyph) glyph; 167 | 168 | @end 169 | -------------------------------------------------------------------------------- /iosMathExample/View.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /iosMath/render/internal/MTFontMathTable.m: -------------------------------------------------------------------------------- 1 | // 2 | // MTFontMathTable.m 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/28/13. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | #import "MTFontMathTable.h" 13 | #import "MTFont.h" 14 | #import "MTFont+Internal.h" 15 | 16 | 17 | @interface MTGlyphPart () 18 | 19 | @property (nonatomic) CGGlyph glyph; 20 | @property (nonatomic) CGFloat fullAdvance; 21 | @property (nonatomic) CGFloat startConnectorLength; 22 | @property (nonatomic) CGFloat endConnectorLength; 23 | @property (nonatomic) BOOL isExtender; 24 | 25 | @end 26 | 27 | @implementation MTGlyphPart 28 | 29 | @end 30 | 31 | @interface MTFontMathTable () 32 | 33 | // The font for this math table. 34 | @property (nonatomic, readonly, weak) MTFont* font; 35 | 36 | @end 37 | 38 | @implementation MTFontMathTable { 39 | NSUInteger _unitsPerEm; 40 | CGFloat _fontSize; 41 | NSDictionary* _Nonnull _mathTable; 42 | } 43 | 44 | - (instancetype)initWithFont:(nonnull MTFont*) font mathTable:(nonnull NSDictionary*) mathTable 45 | { 46 | self = [super init]; 47 | if (self) { 48 | NSParameterAssert(font); 49 | NSParameterAssert(font.ctFont); 50 | _font = font; 51 | // do domething with font 52 | _unitsPerEm = CTFontGetUnitsPerEm(font.ctFont); 53 | _fontSize = font.fontSize; 54 | _mathTable = mathTable; 55 | if (![@"1.3" isEqualToString:_mathTable[@"version"]]) { 56 | // Invalid version 57 | @throw [NSException exceptionWithName:NSInternalInconsistencyException 58 | reason:[NSString stringWithFormat:@"Invalid version of math table plist: %@", _mathTable[@"version"]] 59 | userInfo:nil]; 60 | } 61 | } 62 | return self; 63 | } 64 | 65 | - (CGFloat) fontUnitsToPt:(int) fontUnits 66 | { 67 | return fontUnits * _fontSize / _unitsPerEm; 68 | } 69 | 70 | - (CGFloat)muUnit 71 | { 72 | return _fontSize/18; 73 | } 74 | 75 | static NSString* const kConstants = @"constants"; 76 | 77 | - (CGFloat) constantFromTable:(NSString*) constName 78 | { 79 | NSDictionary* consts = (NSDictionary*) _mathTable[kConstants]; 80 | NSNumber* val = (NSNumber*)consts[constName]; 81 | return [self fontUnitsToPt:val.intValue]; 82 | } 83 | 84 | - (CGFloat) percentFromTable:(NSString*) percentName 85 | { 86 | NSDictionary* consts = (NSDictionary*) _mathTable[kConstants]; 87 | NSNumber* val = (NSNumber*)consts[percentName]; 88 | return val.floatValue / 100; 89 | } 90 | 91 | #pragma mark - Fractions 92 | - (CGFloat)fractionNumeratorDisplayStyleShiftUp 93 | { 94 | return [self constantFromTable:@"FractionNumeratorDisplayStyleShiftUp"]; 95 | } 96 | 97 | - (CGFloat)fractionNumeratorShiftUp 98 | { 99 | return [self constantFromTable:@"FractionNumeratorShiftUp"]; 100 | } 101 | 102 | - (CGFloat)fractionDenominatorDisplayStyleShiftDown 103 | { 104 | return [self constantFromTable:@"FractionDenominatorDisplayStyleShiftDown"]; 105 | } 106 | 107 | - (CGFloat)fractionDenominatorShiftDown 108 | { 109 | return [self constantFromTable:@"FractionDenominatorShiftDown"]; 110 | } 111 | 112 | - (CGFloat)fractionNumeratorDisplayStyleGapMin 113 | { 114 | return [self constantFromTable:@"FractionNumDisplayStyleGapMin"]; 115 | } 116 | 117 | - (CGFloat)fractionNumeratorGapMin 118 | { 119 | return [self constantFromTable:@"FractionNumeratorGapMin"]; 120 | } 121 | 122 | - (CGFloat)fractionDenominatorDisplayStyleGapMin 123 | { 124 | return [self constantFromTable:@"FractionDenomDisplayStyleGapMin"]; 125 | } 126 | 127 | - (CGFloat)fractionDenominatorGapMin 128 | { 129 | return [self constantFromTable:@"FractionDenominatorGapMin"]; 130 | } 131 | 132 | - (CGFloat)fractionRuleThickness 133 | { 134 | return [self constantFromTable:@"FractionRuleThickness"]; 135 | } 136 | 137 | - (CGFloat) skewedFractionHorizontalGap 138 | { 139 | return [self constantFromTable:@"SkewedFractionHorizontalGap"]; 140 | } 141 | 142 | - (CGFloat) skewedFractionVerticalGap 143 | { 144 | return [self constantFromTable:@"SkewedFractionVerticalGap"]; 145 | } 146 | 147 | #pragma mark Non-standard 148 | 149 | // FractionDelimiterSize and FractionDelimiterDisplayStyleSize are not constants 150 | // specified in the OpenType Math specification. Rather these are proposed LuaTeX extensions 151 | // for the TeX parameters \sigma_20 (delim1) and \sigma_21 (delim2). Since these do not 152 | // exist in the fonts that we have, we use the same approach as LuaTeX and use the fontSize 153 | // to determine these values. The constants used are the same as LuaTeX and KaTeX and match the 154 | // metrics values of the original TeX fonts. 155 | // Note: An alternative approach is to use DelimitedSubFormulaMinHeight for \sigma21 and use a factor 156 | // of 2 to get \sigma 20 as proposed in Vieth paper. 157 | // The XeTeX implementation sets \sigma21 = fontSize and \sigma20 = DelimitedSubFormulaMinHeight which 158 | // will produce smaller delimiters. 159 | // Of all the approaches we've implemented LuaTeX's approach since it mimics LaTeX most accurately. 160 | - (CGFloat) fractionDelimiterSize 161 | { 162 | return 1.01 * _fontSize; 163 | } 164 | 165 | - (CGFloat) fractionDelimiterDisplayStyleSize 166 | { 167 | // Modified constant from 2.4 to 2.39, it matches KaTeX and looks better. 168 | return 2.39 * _fontSize; 169 | } 170 | 171 | #pragma mark - Sub/Superscripts 172 | 173 | - (CGFloat)superscriptShiftUp 174 | { 175 | return [self constantFromTable:@"SuperscriptShiftUp"]; 176 | } 177 | 178 | - (CGFloat)superscriptShiftUpCramped 179 | { 180 | return [self constantFromTable:@"SuperscriptShiftUpCramped"]; 181 | } 182 | 183 | - (CGFloat)subscriptShiftDown 184 | { 185 | return [self constantFromTable:@"SubscriptShiftDown"]; 186 | } 187 | 188 | - (CGFloat)superscriptBaselineDropMax 189 | { 190 | return [self constantFromTable:@"SuperscriptBaselineDropMax"]; 191 | } 192 | 193 | - (CGFloat)subscriptBaselineDropMin 194 | { 195 | return [self constantFromTable:@"SubscriptBaselineDropMin"]; 196 | } 197 | 198 | - (CGFloat)superscriptBottomMin 199 | { 200 | return [self constantFromTable:@"SuperscriptBottomMin"]; 201 | } 202 | 203 | - (CGFloat)subscriptTopMax 204 | { 205 | return [self constantFromTable:@"SubscriptTopMax"]; 206 | } 207 | 208 | - (CGFloat)subSuperscriptGapMin 209 | { 210 | return [self constantFromTable:@"SubSuperscriptGapMin"]; 211 | } 212 | 213 | - (CGFloat)superscriptBottomMaxWithSubscript 214 | { 215 | return [self constantFromTable:@"SuperscriptBottomMaxWithSubscript"]; 216 | } 217 | 218 | - (CGFloat) spaceAfterScript 219 | { 220 | return [self constantFromTable:@"SpaceAfterScript"]; 221 | } 222 | 223 | #pragma mark - Radicals 224 | 225 | - (CGFloat)radicalRuleThickness 226 | { 227 | return [self constantFromTable:@"RadicalRuleThickness"]; 228 | } 229 | 230 | - (CGFloat)radicalExtraAscender 231 | { 232 | return [self constantFromTable:@"RadicalExtraAscender"]; 233 | } 234 | 235 | - (CGFloat)radicalVerticalGap 236 | { 237 | return [self constantFromTable:@"RadicalVerticalGap"]; 238 | } 239 | 240 | - (CGFloat)radicalDisplayStyleVerticalGap 241 | { 242 | return [self constantFromTable:@"RadicalDisplayStyleVerticalGap"]; 243 | } 244 | 245 | - (CGFloat)radicalKernBeforeDegree 246 | { 247 | return [self constantFromTable:@"RadicalKernBeforeDegree"]; 248 | } 249 | 250 | - (CGFloat)radicalKernAfterDegree 251 | { 252 | return [self constantFromTable:@"RadicalKernAfterDegree"]; 253 | } 254 | 255 | - (CGFloat)radicalDegreeBottomRaisePercent 256 | { 257 | return [self percentFromTable:@"RadicalDegreeBottomRaisePercent"]; 258 | } 259 | 260 | #pragma mark - Limits 261 | 262 | - (CGFloat)upperLimitGapMin 263 | { 264 | return [self constantFromTable:@"UpperLimitGapMin"]; 265 | } 266 | 267 | - (CGFloat)upperLimitBaselineRiseMin 268 | { 269 | return [self constantFromTable:@"UpperLimitBaselineRiseMin"]; 270 | } 271 | 272 | - (CGFloat)lowerLimitGapMin 273 | { 274 | return [self constantFromTable:@"LowerLimitGapMin"]; 275 | } 276 | 277 | - (CGFloat)lowerLimitBaselineDropMin 278 | { 279 | return [self constantFromTable:@"LowerLimitBaselineDropMin"]; 280 | } 281 | 282 | - (CGFloat)limitExtraAscenderDescender 283 | { 284 | // not present in OpenType fonts. 285 | return 0; 286 | } 287 | 288 | #pragma mark - Constants 289 | 290 | -(CGFloat)axisHeight 291 | { 292 | return [self constantFromTable:@"AxisHeight"]; 293 | } 294 | 295 | - (CGFloat)scriptScaleDown 296 | { 297 | return [self percentFromTable:@"ScriptPercentScaleDown"]; 298 | } 299 | 300 | - (CGFloat)scriptScriptScaleDown 301 | { 302 | return [self percentFromTable:@"ScriptScriptPercentScaleDown"]; 303 | } 304 | 305 | - (CGFloat) mathLeading 306 | { 307 | return [self constantFromTable:@"MathLeading"]; 308 | } 309 | 310 | - (CGFloat) delimitedSubFormulaMinHeight 311 | { 312 | return [self constantFromTable:@"DelimitedSubFormulaMinHeight"]; 313 | } 314 | 315 | #pragma mark - Accents 316 | 317 | - (CGFloat) accentBaseHeight 318 | { 319 | return [self constantFromTable:@"AccentBaseHeight"]; 320 | } 321 | 322 | - (CGFloat) flattenedAccentBaseHeight 323 | { 324 | return [self constantFromTable:@"FlattenedAccentBaseHeight"]; 325 | } 326 | 327 | #pragma mark - Large Operators 328 | 329 | - (CGFloat) displayOperatorMinHeight 330 | { 331 | return [self constantFromTable:@"DisplayOperatorMinHeight"]; 332 | } 333 | 334 | #pragma mark - Over and Underbar 335 | 336 | - (CGFloat) overbarExtraAscender 337 | { 338 | return [self constantFromTable:@"OverbarExtraAscender"]; 339 | } 340 | 341 | - (CGFloat) overbarRuleThickness 342 | { 343 | return [self constantFromTable:@"OverbarRuleThickness"]; 344 | } 345 | 346 | - (CGFloat) overbarVerticalGap 347 | { 348 | return [self constantFromTable:@"OverbarVerticalGap"]; 349 | } 350 | 351 | - (CGFloat) underbarExtraDescender 352 | { 353 | return [self constantFromTable:@"UnderbarExtraDescender"]; 354 | } 355 | 356 | - (CGFloat) underbarRuleThickness 357 | { 358 | return [self constantFromTable:@"UnderbarRuleThickness"]; 359 | } 360 | 361 | - (CGFloat) underbarVerticalGap 362 | { 363 | return [self constantFromTable:@"UnderbarVerticalGap"]; 364 | } 365 | 366 | #pragma mark - Stacks 367 | 368 | -(CGFloat) stackBottomDisplayStyleShiftDown { 369 | return [self constantFromTable:@"StackBottomDisplayStyleShiftDown"]; 370 | } 371 | 372 | - (CGFloat) stackBottomShiftDown { 373 | return [self constantFromTable:@"StackBottomShiftDown"]; 374 | } 375 | 376 | - (CGFloat) stackDisplayStyleGapMin { 377 | return [self constantFromTable:@"StackDisplayStyleGapMin"]; 378 | } 379 | 380 | - (CGFloat) stackGapMin { 381 | return [self constantFromTable:@"StackGapMin"]; 382 | } 383 | 384 | - (CGFloat) stackTopDisplayStyleShiftUp { 385 | return [self constantFromTable:@"StackTopDisplayStyleShiftUp"]; 386 | } 387 | 388 | - (CGFloat) stackTopShiftUp { 389 | return [self constantFromTable:@"StackTopShiftUp"]; 390 | } 391 | 392 | - (CGFloat) stretchStackBottomShiftDown { 393 | return [self constantFromTable:@"StretchStackBottomShiftDown"]; 394 | } 395 | 396 | - (CGFloat) stretchStackGapAboveMin { 397 | return [self constantFromTable:@"StretchStackGapAboveMin"]; 398 | } 399 | 400 | - (CGFloat) stretchStackGapBelowMin { 401 | return [self constantFromTable:@"StretchStackGapBelowMin"]; 402 | } 403 | 404 | - (CGFloat) stretchStackTopShiftUp { 405 | return [self constantFromTable:@"StretchStackTopShiftUp"]; 406 | } 407 | 408 | #pragma mark - Variants 409 | 410 | static NSString* const kVertVariants = @"v_variants"; 411 | static NSString* const kHorizVariants = @"h_variants"; 412 | 413 | - (NSArray*) getVerticalVariantsForGlyph:(CGGlyph) glyph 414 | { 415 | NSDictionary* variants = (NSDictionary*) _mathTable[kVertVariants]; 416 | return [self getVariantsForGlyph:glyph inDictionary:variants]; 417 | } 418 | 419 | - (NSArray*) getHorizontalVariantsForGlyph:(CGGlyph) glyph 420 | { 421 | NSDictionary* variants = (NSDictionary*) _mathTable[kHorizVariants]; 422 | return [self getVariantsForGlyph:glyph inDictionary:variants]; 423 | } 424 | 425 | - (NSArray*) getVariantsForGlyph:(CGGlyph) glyph inDictionary:(NSDictionary*) variants 426 | { 427 | NSString* glyphName = [self.font getGlyphName:glyph]; 428 | NSArray* variantGlyphs = (NSArray*) variants[glyphName]; 429 | NSMutableArray* glyphArray = [NSMutableArray arrayWithCapacity:variantGlyphs.count]; 430 | if (!variantGlyphs) { 431 | // There are no extra variants, so just add the current glyph to it. 432 | CGGlyph glyph = [self.font getGlyphWithName:glyphName]; 433 | [glyphArray addObject:@(glyph)]; 434 | return glyphArray; 435 | } 436 | for (NSString* glyphVariantName in variantGlyphs) { 437 | CGGlyph variantGlyph = [self.font getGlyphWithName:glyphVariantName]; 438 | [glyphArray addObject:@(variantGlyph)]; 439 | } 440 | return glyphArray; 441 | } 442 | 443 | - (CGGlyph) getLargerGlyph:(CGGlyph) glyph 444 | { 445 | NSDictionary* variants = (NSDictionary*) _mathTable[kVertVariants]; 446 | NSString* glyphName = [self.font getGlyphName:glyph]; 447 | NSArray* variantGlyphs = (NSArray*) variants[glyphName]; 448 | if (!variantGlyphs) { 449 | // There are no extra variants, so just returnt the current glyph. 450 | return glyph; 451 | } 452 | // Find the first variant with a different name. 453 | for (NSString* glyphVariantName in variantGlyphs) { 454 | if (![glyphVariantName isEqualToString:glyphName]) { 455 | CGGlyph variantGlyph = [self.font getGlyphWithName:glyphVariantName]; 456 | return variantGlyph; 457 | } 458 | } 459 | // We did not find any variants of this glyph so return it. 460 | return glyph; 461 | } 462 | 463 | #pragma mark - Italic Correction 464 | 465 | static NSString* const kItalic = @"italic"; 466 | 467 | - (CGFloat)getItalicCorrection:(CGGlyph)glyph 468 | { 469 | NSDictionary* italics = (NSDictionary*) _mathTable[kItalic]; 470 | NSString* glyphName = [self.font getGlyphName:glyph]; 471 | NSNumber* val = (NSNumber*) italics[glyphName]; 472 | // if val is nil, this returns 0. 473 | return [self fontUnitsToPt:val.intValue]; 474 | } 475 | 476 | #pragma mark - Top Accent Adjustment 477 | 478 | static NSString* const kAccents = @"accents"; 479 | - (CGFloat) getTopAccentAdjustment:(CGGlyph) glyph 480 | { 481 | NSDictionary* accents = (NSDictionary*) _mathTable[kAccents]; 482 | NSString* glyphName = [self.font getGlyphName:glyph]; 483 | NSNumber* val = (NSNumber*) accents[glyphName]; 484 | if (val != nil) { 485 | return [self fontUnitsToPt:val.intValue]; 486 | } else { 487 | // If no top accent is defined then it is the center of the advance width. 488 | CGSize advances; 489 | CTFontGetAdvancesForGlyphs(self.font.ctFont, kCTFontHorizontalOrientation, &glyph, &advances, 1); 490 | return advances.width/2; 491 | } 492 | } 493 | 494 | #pragma mark - Glyph Assembly 495 | 496 | - (CGFloat)minConnectorOverlap 497 | { 498 | return [self constantFromTable:@"MinConnectorOverlap"]; 499 | } 500 | 501 | static NSString* const kVertAssembly = @"v_assembly"; 502 | static NSString* const kAssemblyParts = @"parts"; 503 | 504 | - (NSArray *)getVerticalGlyphAssemblyForGlyph:(CGGlyph)glyph 505 | { 506 | NSDictionary* assemblyTable = (NSDictionary*) _mathTable[kVertAssembly]; 507 | NSString* glyphName = [self.font getGlyphName:glyph]; 508 | NSDictionary* assemblyInfo = (NSDictionary*) assemblyTable[glyphName]; 509 | if (!assemblyInfo) { 510 | // No vertical assembly defined for glyph 511 | return nil; 512 | } 513 | NSArray* parts = (NSArray*) assemblyInfo[kAssemblyParts]; 514 | if (!parts) { 515 | // parts should always have been defined, but if it isn't return nil 516 | return nil; 517 | } 518 | NSMutableArray* rv = [NSMutableArray array]; 519 | for (NSDictionary* partInfo in parts) { 520 | MTGlyphPart* part = [[MTGlyphPart alloc] init]; 521 | NSNumber* adv = (NSNumber*) partInfo[@"advance"]; 522 | part.fullAdvance = [self fontUnitsToPt:adv.intValue]; 523 | NSNumber* end = (NSNumber*) partInfo[@"endConnector"]; 524 | part.endConnectorLength = [self fontUnitsToPt:end.intValue]; 525 | NSNumber* start = (NSNumber*) partInfo[@"startConnector"]; 526 | part.startConnectorLength = [self fontUnitsToPt:start.intValue]; 527 | NSNumber* ext = (NSNumber*) partInfo[@"extender"]; 528 | part.isExtender = ext.boolValue; 529 | NSString* glyphName = (NSString*) partInfo[@"glyph"]; 530 | part.glyph = [self.font getGlyphWithName:glyphName]; 531 | 532 | [rv addObject:part]; 533 | } 534 | return rv; 535 | } 536 | 537 | @end 538 | -------------------------------------------------------------------------------- /iosMath/lib/MTMathList.h: -------------------------------------------------------------------------------- 1 | // 2 | // MathList.h 3 | // iosMath 4 | // 5 | // Created by Kostub Deshmukh on 8/26/13. 6 | // Copyright (C) 2013 MathChat 7 | // 8 | // This software may be modified and distributed under the terms of the 9 | // MIT license. See the LICENSE file for details. 10 | // 11 | 12 | @import Foundation; 13 | @import CoreGraphics; 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @class MTMathList; 18 | 19 | /** 20 | @typedef MTMathAtomType 21 | @brief The type of atom in a `MTMathList`. 22 | 23 | The type of the atom determines how it is rendered, and spacing between the atoms. 24 | */ 25 | typedef NS_ENUM(NSUInteger, MTMathAtomType) 26 | { 27 | /// A number or text in ordinary format - Ord in TeX 28 | kMTMathAtomOrdinary = 1, 29 | /// A number - Does not exist in TeX 30 | kMTMathAtomNumber, 31 | /// A variable (i.e. text in italic format) - Does not exist in TeX 32 | kMTMathAtomVariable, 33 | /// A large operator such as (sin/cos, integral etc.) - Op in TeX 34 | kMTMathAtomLargeOperator, 35 | /// A binary operator - Bin in TeX 36 | kMTMathAtomBinaryOperator, 37 | /// A unary operator - Does not exist in TeX. 38 | kMTMathAtomUnaryOperator, 39 | /// A relation, e.g. = > < etc. - Rel in TeX 40 | kMTMathAtomRelation, 41 | /// Open brackets - Open in TeX 42 | kMTMathAtomOpen, 43 | /// Close brackets - Close in TeX 44 | kMTMathAtomClose, 45 | /// An fraction e.g 1/2 - generalized fraction noad in TeX 46 | kMTMathAtomFraction, 47 | /// A radical operator e.g. sqrt(2) 48 | kMTMathAtomRadical, 49 | /// Punctuation such as , - Punct in TeX 50 | kMTMathAtomPunctuation, 51 | /// A placeholder square for future input. Does not exist in TeX 52 | kMTMathAtomPlaceholder, 53 | /// An inner atom, i.e. an embedded math list - Inner in TeX 54 | kMTMathAtomInner, 55 | /// An underlined atom - Under in TeX 56 | kMTMathAtomUnderline, 57 | /// An overlined atom - Over in TeX 58 | kMTMathAtomOverline, 59 | /// An accented atom - Accent in TeX 60 | kMTMathAtomAccent, 61 | 62 | // Atoms after this point do not support subscripts or superscripts 63 | 64 | /// A left atom - Left & Right in TeX. We don't need two since we track boundaries separately. 65 | kMTMathAtomBoundary = 101, 66 | 67 | // Atoms after this are non-math TeX nodes that are still useful in math mode. They do not have 68 | // the usual structure. 69 | 70 | /// Spacing between math atoms. This denotes both glue and kern for TeX. We do not 71 | /// distinguish between glue and kern. 72 | kMTMathAtomSpace = 201, 73 | /// Denotes style changes during rendering. 74 | kMTMathAtomStyle, 75 | kMTMathAtomColor, 76 | kMTMathAtomColorbox, 77 | 78 | // Atoms after this point are not part of TeX and do not have the usual structure. 79 | 80 | /// An table atom. This atom does not exist in TeX. It is equivalent to the TeX command 81 | /// halign which is handled outside of the TeX math rendering engine. We bring it into our 82 | /// math typesetting to handle matrices and other tables. 83 | kMTMathAtomTable = 1001, 84 | }; 85 | 86 | /** 87 | @typedef MTFontStyle 88 | @brief The font style of a character. 89 | 90 | The fontstyle of the atom determines what style the character is rendered in. This only applies to atoms 91 | of type kMTMathAtomVariable and kMTMathAtomNumber. None of the other atom types change their font style. 92 | */ 93 | typedef NS_ENUM(NSUInteger, MTFontStyle) 94 | { 95 | /// The default latex rendering style. i.e. variables are italic and numbers are roman. 96 | kMTFontStyleDefault = 0, 97 | /// Roman font style i.e. \mathrm 98 | kMTFontStyleRoman, 99 | /// Bold font style i.e. \mathbf 100 | kMTFontStyleBold, 101 | /// Caligraphic font style i.e. \mathcal 102 | kMTFontStyleCaligraphic, 103 | /// Typewriter (monospace) style i.e. \mathtt 104 | kMTFontStyleTypewriter, 105 | /// Italic style i.e. \mathit 106 | kMTFontStyleItalic, 107 | /// San-serif font i.e. \mathss 108 | kMTFontStyleSansSerif, 109 | /// Fractur font i.e \mathfrak 110 | kMTFontStyleFraktur, 111 | /// Blackboard font i.e. \mathbb 112 | kMTFontStyleBlackboard, 113 | /// Bold italic 114 | kMTFontStyleBoldItalic, 115 | }; 116 | 117 | /** A `MTMathAtom` is the basic unit of a math list. Each atom represents a single character 118 | or mathematical operator in a list. However certain atoms can represent more complex structures 119 | such as fractions and radicals. Each atom has a type which determines how the atom is rendered and 120 | a nucleus. The nucleus contains the character(s) that need to be rendered. However the nucleus may 121 | be empty for certain types of atoms. An atom has an optional subscript or superscript which represents 122 | the subscript or superscript that is to be rendered. 123 | 124 | Certain types of atoms inherit from `MTMathAtom` and may have additional fields. 125 | */ 126 | @interface MTMathAtom : NSObject 127 | 128 | /// Do not use init. Use `atomWithType:value:` to instantiate atoms. 129 | - (instancetype)init NS_UNAVAILABLE; 130 | 131 | /** Factory function to create an atom with a given type and value. 132 | @param type The type of the atom to instantiate. 133 | @param value The value of the atoms nucleus. The value is ignored for fractions and radicals. 134 | */ 135 | + (instancetype) atomWithType: (MTMathAtomType) type value:(NSString*) value; 136 | 137 | /** Returns a string representation of the MTMathAtom */ 138 | @property (nonatomic, readonly) NSString *stringValue; 139 | 140 | /** The type of the atom. */ 141 | @property (nonatomic) MTMathAtomType type; 142 | /** The nucleus of the atom. */ 143 | @property (nonatomic, copy) NSString* nucleus; 144 | /** An optional superscript. */ 145 | @property (nonatomic, nullable) MTMathList* superScript; 146 | /** An optional subscript. */ 147 | @property (nonatomic, nullable) MTMathList* subScript; 148 | /** The font style to be used for the atom. */ 149 | @property (nonatomic) MTFontStyle fontStyle; 150 | 151 | /** Returns true if this atom allows scripts (sub or super). */ 152 | - (bool) scriptsAllowed; 153 | 154 | /// If this atom was formed by fusion of multiple atoms, then this stores the list of atoms that were fused to create this one. 155 | /// This is used in the finalizing and preprocessing steps. 156 | @property (nonatomic, readonly, nullable) NSArray* fusedAtoms; 157 | 158 | /// The index range in the MTMathList this MTMathAtom tracks. This is used by the finalizing and preprocessing steps 159 | /// which fuse MTMathAtoms to track the position of the current MTMathAtom in the original list. 160 | @property (nonatomic, readonly) NSRange indexRange; 161 | 162 | /// Fuse the given atom with this one by combining their nucleii. 163 | - (void) fuse:(MTMathAtom*) atom; 164 | 165 | /// Makes a deep copy of the atom 166 | - (id)copyWithZone:(nullable NSZone *)zone; 167 | 168 | /// Returns a finalized copy of the atom 169 | - (instancetype) finalized; 170 | 171 | @end 172 | 173 | /** An atom of type fraction. This atom has a numerator and denominator. */ 174 | @interface MTFraction : MTMathAtom 175 | 176 | /// Creates an empty fraction with a rule. 177 | - (instancetype)init; 178 | 179 | /// Creates an empty fraction with the given value of hasRule. 180 | - (instancetype)initWithRule:(BOOL) hasRule NS_DESIGNATED_INITIALIZER; 181 | 182 | /// Numerator of the fraction 183 | @property (nonatomic) MTMathList* numerator; 184 | /// Denominator of the fraction 185 | @property (nonatomic) MTMathList* denominator; 186 | 187 | /**If true, the fraction has a rule (i.e. a line) between the numerator and denominator. 188 | The default value is true. */ 189 | @property (nonatomic, readonly) BOOL hasRule; 190 | 191 | /** An optional delimiter for a fraction on the left. */ 192 | @property (nonatomic, nullable) NSString* leftDelimiter; 193 | /** An optional delimiter for a fraction on the right. */ 194 | @property (nonatomic, nullable) NSString* rightDelimiter; 195 | 196 | @end 197 | 198 | /** An atom of type radical (square root). */ 199 | @interface MTRadical : MTMathAtom 200 | 201 | /// Creates an empty radical 202 | - (instancetype)init NS_DESIGNATED_INITIALIZER; 203 | 204 | /// Denotes the term under the square root sign 205 | @property (nonatomic, nullable) MTMathList* radicand; 206 | 207 | /// Denotes the degree of the radical, i.e. the value to the top left of the radical sign 208 | /// This can be null if there is no degree. 209 | @property (nonatomic, nullable) MTMathList* degree; 210 | 211 | @end 212 | 213 | /** A `MTMathAtom` of type `kMTMathAtomLargeOperator`. */ 214 | @interface MTLargeOperator : MTMathAtom 215 | 216 | /** Designated initializer. Initialize a large operator with the given 217 | value and setting for limits. 218 | */ 219 | - (instancetype) initWithValue:(NSString*) value limits:(BOOL) limits NS_DESIGNATED_INITIALIZER; 220 | 221 | /** Indicates whether the limits (if present) should be displayed 222 | above and below the operator in display mode. If limits is false 223 | then the limits (if present) and displayed like a regular subscript/superscript. 224 | */ 225 | @property (nonatomic) BOOL limits; 226 | 227 | @end 228 | 229 | /** An inner atom. This denotes an atom which contains a math list inside it. An inner atom 230 | has optional boundaries. Note: Only one boundary may be present, it is not required to have 231 | both. */ 232 | @interface MTInner : MTMathAtom 233 | 234 | /// Creates an empty inner 235 | - (instancetype)init NS_DESIGNATED_INITIALIZER; 236 | 237 | /// The inner math list 238 | @property (nonatomic, nullable) MTMathList* innerList; 239 | /// The left boundary atom. This must be a node of type kMTMathAtomBoundary 240 | @property (nonatomic, nullable) MTMathAtom* leftBoundary; 241 | /// The right boundary atom. This must be a node of type kMTMathAtomBoundary 242 | @property (nonatomic, nullable) MTMathAtom* rightBoundary; 243 | 244 | @end 245 | 246 | /** An atom with a line over the contained math list. */ 247 | @interface MTOverLine : MTMathAtom 248 | 249 | /// Creates an empty over 250 | - (instancetype)init NS_DESIGNATED_INITIALIZER; 251 | 252 | /// The inner math list 253 | @property (nonatomic, nullable) MTMathList* innerList; 254 | 255 | @end 256 | 257 | /** An atom with a line under the contained math list. */ 258 | @interface MTUnderLine : MTMathAtom 259 | 260 | /// Creates an empty under 261 | - (instancetype)init NS_DESIGNATED_INITIALIZER; 262 | 263 | /// The inner math list 264 | @property (nonatomic, nullable) MTMathList* innerList; 265 | 266 | @end 267 | 268 | /** An atom with an accent. */ 269 | @interface MTAccent : MTMathAtom 270 | 271 | /** Creates a new `MTAccent` with the given value as the accent. 272 | */ 273 | - (instancetype)initWithValue:(NSString*) value NS_DESIGNATED_INITIALIZER; 274 | 275 | /// The mathlist under the accent. 276 | @property (nonatomic, nullable) MTMathList* innerList; 277 | 278 | @end 279 | 280 | /** An atom representing space. 281 | @note None of the usual fields of the `MTMathAtom` apply even though this 282 | class inherits from `MTMathAtom`. i.e. it is meaningless to have a value 283 | in the nucleus, subscript or superscript fields. */ 284 | @interface MTMathSpace : MTMathAtom 285 | 286 | /** Creates a new `MTMathSpace` with the given spacing. 287 | @param space The amount of space in mu units. 288 | */ 289 | - (instancetype) initWithSpace:(CGFloat) space NS_DESIGNATED_INITIALIZER; 290 | 291 | /** The amount of space represented by this object in mu units. */ 292 | @property (nonatomic, readonly) CGFloat space; 293 | 294 | @end 295 | 296 | /** 297 | @typedef MTLineStyle 298 | @brief Styling of a line of math 299 | */ 300 | typedef NS_ENUM(unsigned int, MTLineStyle) { 301 | /// Display style 302 | kMTLineStyleDisplay, 303 | /// Text style (inline) 304 | kMTLineStyleText, 305 | /// Script style (for sub/super scripts) 306 | kMTLineStyleScript, 307 | /// Script script style (for scripts of scripts) 308 | kMTLineStyleScriptScript 309 | }; 310 | 311 | /** An atom representing a style change. 312 | @note None of the usual fields of the `MTMathAtom` apply even though this 313 | class inherits from `MTMathAtom`. i.e. it is meaningless to have a value 314 | in the nucleus, subscript or superscript fields. */ 315 | @interface MTMathStyle : MTMathAtom 316 | 317 | /** Creates a new `MTMathStyle` with the given style. 318 | @param style The style to be applied to the rest of the list. 319 | */ 320 | - (instancetype) initWithStyle:(MTLineStyle) style NS_DESIGNATED_INITIALIZER; 321 | 322 | /** The style represented by this object. */ 323 | @property (nonatomic, readonly) MTLineStyle style; 324 | 325 | @end 326 | 327 | /** An atom representing an color element. 328 | @note None of the usual fields of the `MTMathAtom` apply even though this 329 | class inherits from `MTMathAtom`. i.e. it is meaningless to have a value 330 | in the nucleus, subscript or superscript fields. */ 331 | @interface MTMathColor : MTMathAtom 332 | 333 | /// Creates an empty color with a nil environment 334 | - (instancetype) init NS_DESIGNATED_INITIALIZER; 335 | 336 | /** The style represented by this object. */ 337 | @property (nonatomic, nullable) NSString* colorString; 338 | 339 | /// The inner math list 340 | @property (nonatomic, nullable) MTMathList* innerList; 341 | 342 | @end 343 | 344 | /** An atom representing an colorbox element. 345 | @note None of the usual fields of the `MTMathAtom` apply even though this 346 | class inherits from `MTMathAtom`. i.e. it is meaningless to have a value 347 | in the nucleus, subscript or superscript fields. */ 348 | @interface MTMathColorbox : MTMathAtom 349 | 350 | /// Creates an empty color with a nil environment 351 | - (instancetype) init NS_DESIGNATED_INITIALIZER; 352 | 353 | /** The style represented by this object. */ 354 | @property (nonatomic, nullable) NSString* colorString; 355 | 356 | /// The inner math list 357 | @property (nonatomic, nullable) MTMathList* innerList; 358 | 359 | @end 360 | 361 | /** An atom representing an table element. This atom is not like other 362 | atoms and is not present in TeX. We use it to represent the `\halign` command 363 | in TeX with some simplifications. This is used for matrices, equation 364 | alignments and other uses of multiline environments. 365 | 366 | The cells in the table are represented as a two dimensional array of 367 | `MTMathList` objects. The `MTMathList`s could be empty to denote a missing 368 | value in the cell. Additionally an array of alignments indicates how each 369 | column will be aligned. 370 | */ 371 | @interface MTMathTable : MTMathAtom 372 | 373 | /** 374 | @typedef MTColumnAlignment 375 | @brief Alignment for a column of MTMathTable 376 | */ 377 | typedef NS_ENUM(NSInteger, MTColumnAlignment) { 378 | /// Align left. 379 | kMTColumnAlignmentLeft, 380 | /// Align center. 381 | kMTColumnAlignmentCenter, 382 | /// Align right. 383 | kMTColumnAlignmentRight, 384 | }; 385 | 386 | /// Creates an empty table with a nil environment 387 | - (instancetype)init; 388 | 389 | /// Creates a table with a given environment 390 | - (instancetype)initWithEnvironment:(nullable NSString*) env NS_DESIGNATED_INITIALIZER; 391 | 392 | /// The alignment for each column (left, right, center). The default alignment 393 | /// for a column (if not set) is center. 394 | @property (nonatomic, nonnull, readonly) NSArray* alignments; 395 | /// The cells in the table as a two dimensional array. 396 | @property (nonatomic, nonnull, readonly) NSArray*>* cells; 397 | /// The name of the environment that this table denotes. 398 | @property (nonatomic, nullable) NSString* environment; 399 | 400 | /// Spacing between each column in mu units. 401 | @property (nonatomic) CGFloat interColumnSpacing; 402 | /// Additional spacing between rows in jots (one jot is 0.3 times font size). 403 | /// If the additional spacing is 0, then normal row spacing is used are used. 404 | @property (nonatomic) CGFloat interRowAdditionalSpacing; 405 | 406 | /// Set the value of a given cell. The table is automatically resized to contain this cell. 407 | - (void) setCell:(MTMathList*) list forRow:(NSInteger) row column:(NSInteger) column; 408 | 409 | /// Set the alignment of a particular column. The table is automatically resized to 410 | /// contain this column and any new columns added have their alignment set to center. 411 | - (void) setAlignment:(MTColumnAlignment) alignment forColumn:(NSInteger) column; 412 | 413 | /// Gets the alignment for a given column. If the alignment is not specified it defaults 414 | /// to center. 415 | - (MTColumnAlignment) getAlignmentForColumn:(NSInteger) column; 416 | 417 | /// Number of columns in the table. 418 | - (NSUInteger) numColumns; 419 | 420 | /// Number of rows in the table. 421 | - (NSUInteger) numRows; 422 | 423 | @end 424 | 425 | /** A representation of a list of math objects. 426 | 427 | This list can be constructed directly or built with 428 | the help of the MTMathListBuilder. It is not required that the mathematics represented make sense 429 | (i.e. this can represent something like "x 2 = +". This list can be used for display using MTLine 430 | or can be a list of tokens to be used by a parser after finalizedMathList is called. 431 | 432 | @note This class is for ADVANCED usage only. 433 | */ 434 | @interface MTMathList : NSObject 435 | 436 | /** Create a `MTMathList` given a list of atoms. The list of atoms should be 437 | terminated by `nil`. 438 | */ 439 | + (instancetype) mathListWithAtoms:(MTMathAtom*) firstAtom, ... NS_REQUIRES_NIL_TERMINATION; 440 | 441 | /** Create a `MTMathList` given a list of atoms. */ 442 | + (instancetype) mathListWithAtomsArray:(NSArray*) atoms; 443 | 444 | /// A list of MathAtoms 445 | @property (nonatomic, readonly) NSArray<__kindof MTMathAtom*>* atoms; 446 | 447 | /** Initializes an empty math list. */ 448 | - (instancetype) init NS_DESIGNATED_INITIALIZER; 449 | 450 | /** Add an atom to the end of the list. 451 | @param atom The atom to be inserted. This cannot be `nil` and cannot have the type `kMTMathAtomBoundary`. 452 | @throws NSException if the atom is of type `kMTMathAtomBoundary` 453 | @throws NSInvalidArgumentException if the atom is `nil` */ 454 | - (void) addAtom:(MTMathAtom*) atom; 455 | 456 | /** Inserts an atom at the given index. If index is already occupied, the objects at index and beyond are 457 | shifted by adding 1 to their indices to make room. 458 | 459 | @param atom The atom to be inserted. This cannot be `nil` and cannot have the type `kMTMathAtomBoundary`. 460 | @param index The index where the atom is to be inserted. The index should be less than or equal to the 461 | number of elements in the math list. 462 | @throws NSException if the atom is of type kMTMathAtomBoundary 463 | @throws NSInvalidArgumentException if the atom is nil 464 | @throws NSRangeException if the index is greater than the number of atoms in the math list. */ 465 | - (void) insertAtom:(MTMathAtom *)atom atIndex:(NSUInteger) index; 466 | 467 | /** Append the given list to the end of the current list. 468 | @param list The list to append. 469 | */ 470 | - (void) append:(MTMathList*) list; 471 | 472 | /** Removes the last atom from the math list. If there are no atoms in the list this does nothing. */ 473 | - (void) removeLastAtom; 474 | 475 | /** Removes the atom at the given index. 476 | @param index The index at which to remove the atom. Must be less than the number of atoms 477 | in the list. 478 | */ 479 | - (void) removeAtomAtIndex:(NSUInteger) index; 480 | 481 | /** Removes all the atoms within the given range. */ 482 | - (void) removeAtomsInRange:(NSRange) range; 483 | 484 | /// converts the MTMathList to a string form. Note: This is not the LaTeX form. 485 | @property (nonatomic, readonly) NSString *stringValue; 486 | 487 | /// Create a new math list as a final expression and update atoms 488 | /// by combining like atoms that occur together and converting unary operators to binary operators. 489 | /// This function does not modify the current MTMathList 490 | - (MTMathList*) finalized; 491 | 492 | /// Makes a deep copy of the list 493 | - (id)copyWithZone:(nullable NSZone *)zone; 494 | 495 | @end 496 | 497 | NS_ASSUME_NONNULL_END 498 | -------------------------------------------------------------------------------- /MacOSMath.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 26123D5D1E230E2F007A742A /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 26123D421E230D1F007A742A /* MainMenu.xib */; }; 11 | 26123D5E1E230E3E007A742A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 26123D401E230D10007A742A /* AppDelegate.m */; }; 12 | 26123D5F1E230E3E007A742A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 26123D451E230D44007A742A /* main.m */; }; 13 | 26123D621E230E5D007A742A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26123D611E230E5D007A742A /* Foundation.framework */; }; 14 | 26123D641E230E64007A742A /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26123D631E230E64007A742A /* AppKit.framework */; }; 15 | 26123D661E230E6C007A742A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26123D651E230E6C007A742A /* CoreGraphics.framework */; }; 16 | 26123D681E230E72007A742A /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26123D671E230E72007A742A /* CoreText.framework */; }; 17 | 26123D6A1E230E78007A742A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26123D691E230E78007A742A /* QuartzCore.framework */; }; 18 | D0BD0CD8F17DD64F1CD97F02 /* libPods-MacOSMath.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A369C2D9AD493F2ABA76EF1C /* libPods-MacOSMath.a */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | 26123D3F1E230D10007A742A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = MacOSMathExample/AppDelegate.h; sourceTree = ""; }; 23 | 26123D401E230D10007A742A /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = MacOSMathExample/AppDelegate.m; sourceTree = ""; }; 24 | 26123D411E230D10007A742A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = MacOSMathExample/Assets.xcassets; sourceTree = ""; }; 25 | 26123D431E230D1F007A742A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = MacOSMathExample/Base.lproj/MainMenu.xib; sourceTree = ""; }; 26 | 26123D441E230D2D007A742A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = MacOSMathExample/Info.plist; sourceTree = ""; }; 27 | 26123D451E230D44007A742A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = main.m; path = MacOSMathExample/main.m; sourceTree = ""; }; 28 | 26123D4B1E230D80007A742A /* MacOSMath.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MacOSMath.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 26123D611E230E5D007A742A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 30 | 26123D631E230E64007A742A /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 31 | 26123D651E230E6C007A742A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 32 | 26123D671E230E72007A742A /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; }; 33 | 26123D691E230E78007A742A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 34 | 5C5FFD05171A4E4DDD124552 /* Pods-MacOSMath.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MacOSMath.release.xcconfig"; path = "Pods/Target Support Files/Pods-MacOSMath/Pods-MacOSMath.release.xcconfig"; sourceTree = ""; }; 35 | 724A2FB140C9614157026EDF /* Pods-MacOSMath.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MacOSMath.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MacOSMath/Pods-MacOSMath.debug.xcconfig"; sourceTree = ""; }; 36 | A369C2D9AD493F2ABA76EF1C /* libPods-MacOSMath.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-MacOSMath.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | /* End PBXFileReference section */ 38 | 39 | /* Begin PBXFrameworksBuildPhase section */ 40 | 26123D481E230D80007A742A /* Frameworks */ = { 41 | isa = PBXFrameworksBuildPhase; 42 | buildActionMask = 2147483647; 43 | files = ( 44 | 26123D6A1E230E78007A742A /* QuartzCore.framework in Frameworks */, 45 | 26123D681E230E72007A742A /* CoreText.framework in Frameworks */, 46 | 26123D661E230E6C007A742A /* CoreGraphics.framework in Frameworks */, 47 | 26123D641E230E64007A742A /* AppKit.framework in Frameworks */, 48 | 26123D621E230E5D007A742A /* Foundation.framework in Frameworks */, 49 | D0BD0CD8F17DD64F1CD97F02 /* libPods-MacOSMath.a in Frameworks */, 50 | ); 51 | runOnlyForDeploymentPostprocessing = 0; 52 | }; 53 | /* End PBXFrameworksBuildPhase section */ 54 | 55 | /* Begin PBXGroup section */ 56 | 26123D461E230D48007A742A /* Supporting Files */ = { 57 | isa = PBXGroup; 58 | children = ( 59 | 26123D451E230D44007A742A /* main.m */, 60 | ); 61 | name = "Supporting Files"; 62 | sourceTree = ""; 63 | }; 64 | 26123D4C1E230D80007A742A /* Products */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 26123D4B1E230D80007A742A /* MacOSMath.app */, 68 | ); 69 | name = Products; 70 | sourceTree = ""; 71 | }; 72 | 26123D601E230E5D007A742A /* Frameworks */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | 26123D691E230E78007A742A /* QuartzCore.framework */, 76 | 26123D671E230E72007A742A /* CoreText.framework */, 77 | 26123D651E230E6C007A742A /* CoreGraphics.framework */, 78 | 26123D631E230E64007A742A /* AppKit.framework */, 79 | 26123D611E230E5D007A742A /* Foundation.framework */, 80 | A369C2D9AD493F2ABA76EF1C /* libPods-MacOSMath.a */, 81 | ); 82 | name = Frameworks; 83 | sourceTree = ""; 84 | }; 85 | 267EC26D1E230CB400E34886 = { 86 | isa = PBXGroup; 87 | children = ( 88 | 26123D3F1E230D10007A742A /* AppDelegate.h */, 89 | 26123D401E230D10007A742A /* AppDelegate.m */, 90 | 26123D411E230D10007A742A /* Assets.xcassets */, 91 | 26123D421E230D1F007A742A /* MainMenu.xib */, 92 | 26123D441E230D2D007A742A /* Info.plist */, 93 | 26123D461E230D48007A742A /* Supporting Files */, 94 | 26123D4C1E230D80007A742A /* Products */, 95 | 26123D601E230E5D007A742A /* Frameworks */, 96 | F86DF2EFDC1C28185FF1FFA8 /* Pods */, 97 | ); 98 | sourceTree = ""; 99 | }; 100 | F86DF2EFDC1C28185FF1FFA8 /* Pods */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 724A2FB140C9614157026EDF /* Pods-MacOSMath.debug.xcconfig */, 104 | 5C5FFD05171A4E4DDD124552 /* Pods-MacOSMath.release.xcconfig */, 105 | ); 106 | name = Pods; 107 | sourceTree = ""; 108 | }; 109 | /* End PBXGroup section */ 110 | 111 | /* Begin PBXNativeTarget section */ 112 | 26123D4A1E230D80007A742A /* MacOSMath */ = { 113 | isa = PBXNativeTarget; 114 | buildConfigurationList = 26123D5A1E230D80007A742A /* Build configuration list for PBXNativeTarget "MacOSMath" */; 115 | buildPhases = ( 116 | 8F9D374876485E2879D1DA44 /* [CP] Check Pods Manifest.lock */, 117 | 26123D471E230D80007A742A /* Sources */, 118 | 26123D481E230D80007A742A /* Frameworks */, 119 | 26123D491E230D80007A742A /* Resources */, 120 | 2CE45346B6FE841608881E74 /* [CP] Copy Pods Resources */, 121 | ); 122 | buildRules = ( 123 | ); 124 | dependencies = ( 125 | ); 126 | name = MacOSMath; 127 | productName = MacOSMath; 128 | productReference = 26123D4B1E230D80007A742A /* MacOSMath.app */; 129 | productType = "com.apple.product-type.application"; 130 | }; 131 | /* End PBXNativeTarget section */ 132 | 133 | /* Begin PBXProject section */ 134 | 267EC26E1E230CB400E34886 /* Project object */ = { 135 | isa = PBXProject; 136 | attributes = { 137 | LastUpgradeCheck = 0940; 138 | TargetAttributes = { 139 | 26123D4A1E230D80007A742A = { 140 | CreatedOnToolsVersion = 8.1; 141 | ProvisioningStyle = Automatic; 142 | }; 143 | }; 144 | }; 145 | buildConfigurationList = 267EC2711E230CB400E34886 /* Build configuration list for PBXProject "MacOSMath" */; 146 | compatibilityVersion = "Xcode 3.2"; 147 | developmentRegion = English; 148 | hasScannedForEncodings = 0; 149 | knownRegions = ( 150 | en, 151 | Base, 152 | ); 153 | mainGroup = 267EC26D1E230CB400E34886; 154 | productRefGroup = 26123D4C1E230D80007A742A /* Products */; 155 | projectDirPath = ""; 156 | projectRoot = ""; 157 | targets = ( 158 | 26123D4A1E230D80007A742A /* MacOSMath */, 159 | ); 160 | }; 161 | /* End PBXProject section */ 162 | 163 | /* Begin PBXResourcesBuildPhase section */ 164 | 26123D491E230D80007A742A /* Resources */ = { 165 | isa = PBXResourcesBuildPhase; 166 | buildActionMask = 2147483647; 167 | files = ( 168 | 26123D5D1E230E2F007A742A /* MainMenu.xib in Resources */, 169 | ); 170 | runOnlyForDeploymentPostprocessing = 0; 171 | }; 172 | /* End PBXResourcesBuildPhase section */ 173 | 174 | /* Begin PBXShellScriptBuildPhase section */ 175 | 2CE45346B6FE841608881E74 /* [CP] Copy Pods Resources */ = { 176 | isa = PBXShellScriptBuildPhase; 177 | buildActionMask = 2147483647; 178 | files = ( 179 | ); 180 | inputPaths = ( 181 | "${SRCROOT}/Pods/Target Support Files/Pods-MacOSMath/Pods-MacOSMath-resources.sh", 182 | "${PODS_CONFIGURATION_BUILD_DIR}/iosMath-macOS10.8/mathFonts.bundle", 183 | ); 184 | name = "[CP] Copy Pods Resources"; 185 | outputPaths = ( 186 | "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/mathFonts.bundle", 187 | ); 188 | runOnlyForDeploymentPostprocessing = 0; 189 | shellPath = /bin/sh; 190 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-MacOSMath/Pods-MacOSMath-resources.sh\"\n"; 191 | showEnvVarsInLog = 0; 192 | }; 193 | 8F9D374876485E2879D1DA44 /* [CP] Check Pods Manifest.lock */ = { 194 | isa = PBXShellScriptBuildPhase; 195 | buildActionMask = 2147483647; 196 | files = ( 197 | ); 198 | inputPaths = ( 199 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 200 | "${PODS_ROOT}/Manifest.lock", 201 | ); 202 | name = "[CP] Check Pods Manifest.lock"; 203 | outputPaths = ( 204 | "$(DERIVED_FILE_DIR)/Pods-MacOSMath-checkManifestLockResult.txt", 205 | ); 206 | runOnlyForDeploymentPostprocessing = 0; 207 | shellPath = /bin/sh; 208 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 209 | showEnvVarsInLog = 0; 210 | }; 211 | /* End PBXShellScriptBuildPhase section */ 212 | 213 | /* Begin PBXSourcesBuildPhase section */ 214 | 26123D471E230D80007A742A /* Sources */ = { 215 | isa = PBXSourcesBuildPhase; 216 | buildActionMask = 2147483647; 217 | files = ( 218 | 26123D5E1E230E3E007A742A /* AppDelegate.m in Sources */, 219 | 26123D5F1E230E3E007A742A /* main.m in Sources */, 220 | ); 221 | runOnlyForDeploymentPostprocessing = 0; 222 | }; 223 | /* End PBXSourcesBuildPhase section */ 224 | 225 | /* Begin PBXVariantGroup section */ 226 | 26123D421E230D1F007A742A /* MainMenu.xib */ = { 227 | isa = PBXVariantGroup; 228 | children = ( 229 | 26123D431E230D1F007A742A /* Base */, 230 | ); 231 | name = MainMenu.xib; 232 | sourceTree = ""; 233 | }; 234 | /* End PBXVariantGroup section */ 235 | 236 | /* Begin XCBuildConfiguration section */ 237 | 26123D5B1E230D80007A742A /* Debug */ = { 238 | isa = XCBuildConfiguration; 239 | baseConfigurationReference = 724A2FB140C9614157026EDF /* Pods-MacOSMath.debug.xcconfig */; 240 | buildSettings = { 241 | ALWAYS_SEARCH_USER_PATHS = NO; 242 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 243 | CLANG_ANALYZER_NONNULL = YES; 244 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 245 | CLANG_CXX_LIBRARY = "libc++"; 246 | CLANG_ENABLE_MODULES = YES; 247 | CLANG_ENABLE_OBJC_ARC = YES; 248 | CLANG_WARN_BOOL_CONVERSION = YES; 249 | CLANG_WARN_CONSTANT_CONVERSION = YES; 250 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 251 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 252 | CLANG_WARN_EMPTY_BODY = YES; 253 | CLANG_WARN_ENUM_CONVERSION = YES; 254 | CLANG_WARN_INFINITE_RECURSION = YES; 255 | CLANG_WARN_INT_CONVERSION = YES; 256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 257 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 258 | CLANG_WARN_UNREACHABLE_CODE = YES; 259 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 260 | CODE_SIGN_IDENTITY = "-"; 261 | COMBINE_HIDPI_IMAGES = YES; 262 | COPY_PHASE_STRIP = NO; 263 | DEBUG_INFORMATION_FORMAT = dwarf; 264 | ENABLE_STRICT_OBJC_MSGSEND = YES; 265 | ENABLE_TESTABILITY = YES; 266 | GCC_C_LANGUAGE_STANDARD = gnu99; 267 | GCC_DYNAMIC_NO_PIC = NO; 268 | GCC_NO_COMMON_BLOCKS = YES; 269 | GCC_OPTIMIZATION_LEVEL = 0; 270 | GCC_PREPROCESSOR_DEFINITIONS = ( 271 | "DEBUG=1", 272 | "$(inherited)", 273 | ); 274 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 275 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 276 | GCC_WARN_UNDECLARED_SELECTOR = YES; 277 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 278 | GCC_WARN_UNUSED_FUNCTION = YES; 279 | GCC_WARN_UNUSED_VARIABLE = YES; 280 | INFOPLIST_FILE = MacOSMathExample/Info.plist; 281 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 282 | MACOSX_DEPLOYMENT_TARGET = 10.8; 283 | MTL_ENABLE_DEBUG_INFO = YES; 284 | ONLY_ACTIVE_ARCH = YES; 285 | PRODUCT_BUNDLE_IDENTIFIER = AnZhg.MacOSMath; 286 | PRODUCT_NAME = "$(TARGET_NAME)"; 287 | SDKROOT = macosx; 288 | }; 289 | name = Debug; 290 | }; 291 | 26123D5C1E230D80007A742A /* Release */ = { 292 | isa = XCBuildConfiguration; 293 | baseConfigurationReference = 5C5FFD05171A4E4DDD124552 /* Pods-MacOSMath.release.xcconfig */; 294 | buildSettings = { 295 | ALWAYS_SEARCH_USER_PATHS = NO; 296 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 297 | CLANG_ANALYZER_NONNULL = YES; 298 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 299 | CLANG_CXX_LIBRARY = "libc++"; 300 | CLANG_ENABLE_MODULES = YES; 301 | CLANG_ENABLE_OBJC_ARC = YES; 302 | CLANG_WARN_BOOL_CONVERSION = YES; 303 | CLANG_WARN_CONSTANT_CONVERSION = YES; 304 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 305 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 306 | CLANG_WARN_EMPTY_BODY = YES; 307 | CLANG_WARN_ENUM_CONVERSION = YES; 308 | CLANG_WARN_INFINITE_RECURSION = YES; 309 | CLANG_WARN_INT_CONVERSION = YES; 310 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 311 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 312 | CLANG_WARN_UNREACHABLE_CODE = YES; 313 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 314 | CODE_SIGN_IDENTITY = "-"; 315 | COMBINE_HIDPI_IMAGES = YES; 316 | COPY_PHASE_STRIP = NO; 317 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 318 | ENABLE_NS_ASSERTIONS = NO; 319 | ENABLE_STRICT_OBJC_MSGSEND = YES; 320 | GCC_C_LANGUAGE_STANDARD = gnu99; 321 | GCC_NO_COMMON_BLOCKS = YES; 322 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 323 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 324 | GCC_WARN_UNDECLARED_SELECTOR = YES; 325 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 326 | GCC_WARN_UNUSED_FUNCTION = YES; 327 | GCC_WARN_UNUSED_VARIABLE = YES; 328 | INFOPLIST_FILE = MacOSMathExample/Info.plist; 329 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 330 | MACOSX_DEPLOYMENT_TARGET = 10.8; 331 | MTL_ENABLE_DEBUG_INFO = NO; 332 | PRODUCT_BUNDLE_IDENTIFIER = AnZhg.MacOSMath; 333 | PRODUCT_NAME = "$(TARGET_NAME)"; 334 | SDKROOT = macosx; 335 | }; 336 | name = Release; 337 | }; 338 | 267EC2721E230CB400E34886 /* Debug */ = { 339 | isa = XCBuildConfiguration; 340 | buildSettings = { 341 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 342 | CLANG_WARN_BOOL_CONVERSION = YES; 343 | CLANG_WARN_COMMA = YES; 344 | CLANG_WARN_CONSTANT_CONVERSION = YES; 345 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 346 | CLANG_WARN_EMPTY_BODY = YES; 347 | CLANG_WARN_ENUM_CONVERSION = YES; 348 | CLANG_WARN_INFINITE_RECURSION = YES; 349 | CLANG_WARN_INT_CONVERSION = YES; 350 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 351 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 352 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 353 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 354 | CLANG_WARN_STRICT_PROTOTYPES = YES; 355 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 356 | CLANG_WARN_UNREACHABLE_CODE = YES; 357 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 358 | ENABLE_STRICT_OBJC_MSGSEND = YES; 359 | ENABLE_TESTABILITY = YES; 360 | GCC_NO_COMMON_BLOCKS = YES; 361 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 362 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 363 | GCC_WARN_UNDECLARED_SELECTOR = YES; 364 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 365 | GCC_WARN_UNUSED_FUNCTION = YES; 366 | GCC_WARN_UNUSED_VARIABLE = YES; 367 | MACOSX_DEPLOYMENT_TARGET = 10.8; 368 | ONLY_ACTIVE_ARCH = YES; 369 | SDKROOT = macosx; 370 | }; 371 | name = Debug; 372 | }; 373 | 267EC2731E230CB400E34886 /* Release */ = { 374 | isa = XCBuildConfiguration; 375 | buildSettings = { 376 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 377 | CLANG_WARN_BOOL_CONVERSION = YES; 378 | CLANG_WARN_COMMA = YES; 379 | CLANG_WARN_CONSTANT_CONVERSION = YES; 380 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 381 | CLANG_WARN_EMPTY_BODY = YES; 382 | CLANG_WARN_ENUM_CONVERSION = YES; 383 | CLANG_WARN_INFINITE_RECURSION = YES; 384 | CLANG_WARN_INT_CONVERSION = YES; 385 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 386 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 387 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 388 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 389 | CLANG_WARN_STRICT_PROTOTYPES = YES; 390 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 391 | CLANG_WARN_UNREACHABLE_CODE = YES; 392 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 393 | ENABLE_STRICT_OBJC_MSGSEND = YES; 394 | GCC_NO_COMMON_BLOCKS = YES; 395 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 396 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 397 | GCC_WARN_UNDECLARED_SELECTOR = YES; 398 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 399 | GCC_WARN_UNUSED_FUNCTION = YES; 400 | GCC_WARN_UNUSED_VARIABLE = YES; 401 | MACOSX_DEPLOYMENT_TARGET = 10.8; 402 | SDKROOT = macosx; 403 | }; 404 | name = Release; 405 | }; 406 | /* End XCBuildConfiguration section */ 407 | 408 | /* Begin XCConfigurationList section */ 409 | 26123D5A1E230D80007A742A /* Build configuration list for PBXNativeTarget "MacOSMath" */ = { 410 | isa = XCConfigurationList; 411 | buildConfigurations = ( 412 | 26123D5B1E230D80007A742A /* Debug */, 413 | 26123D5C1E230D80007A742A /* Release */, 414 | ); 415 | defaultConfigurationIsVisible = 0; 416 | defaultConfigurationName = Release; 417 | }; 418 | 267EC2711E230CB400E34886 /* Build configuration list for PBXProject "MacOSMath" */ = { 419 | isa = XCConfigurationList; 420 | buildConfigurations = ( 421 | 267EC2721E230CB400E34886 /* Debug */, 422 | 267EC2731E230CB400E34886 /* Release */, 423 | ); 424 | defaultConfigurationIsVisible = 0; 425 | defaultConfigurationName = Release; 426 | }; 427 | /* End XCConfigurationList section */ 428 | }; 429 | rootObject = 267EC26E1E230CB400E34886 /* Project object */; 430 | } 431 | --------------------------------------------------------------------------------