├── .gitignore ├── .travis.yml ├── Classes ├── NSMutableAttributedString+Typeset.h ├── NSMutableAttributedString+Typeset.m ├── NSString+Typeset.h ├── NSString+Typeset.m ├── NSValue+Range.h ├── NSValue+Range.m ├── Typeset.h ├── TypesetKit+Color.h ├── TypesetKit+Color.m ├── TypesetKit+Match.h ├── TypesetKit+Match.m ├── TypesetKit.h ├── TypesetKit.m ├── UIFont+Weight.h ├── UIFont+Weight.m ├── UILabel+Typeset.h ├── UILabel+Typeset.m ├── UITextField+Typeset.h ├── UITextField+Typeset.m ├── UITextView+Typeset.h ├── UITextView+Typeset.m └── metamacros.h ├── LICENSE ├── README.md ├── Typeset.podspec ├── Typeset.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── apple.xcuserdatad │ └── xcschemes │ ├── Typeset.xcscheme │ └── xcschememanagement.plist ├── Typeset ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── ViewController.h ├── ViewController.m └── main.m ├── TypesetTests ├── Info.plist └── TypesetTests.m ├── fastlane ├── Fastfile ├── README.md └── actions │ ├── git_commit_all.rb │ └── sync_build_number_to_git.rb └── images ├── 1.png ├── Demo.png ├── Typeset.gif └── Typeset.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | .DS_Store 20 | .idea 21 | 22 | fastlane/report.xml 23 | 24 | iOSInjectionProject 25 | 26 | # CocoaPods 27 | # 28 | # We recommend against adding the Pods directory to your .gitignore. However 29 | # you should judge for yourself, the pros and cons are mentioned at: 30 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 31 | # 32 | #Pods/ 33 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | before_install: 3 | - export LANG=en_US.UTF-8 4 | - env 5 | - locale 6 | 7 | osx_image: xcode7.3 8 | 9 | script: 10 | - pod lib lint 11 | -------------------------------------------------------------------------------- /Classes/NSMutableAttributedString+Typeset.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableAttributedString+Typeset.h 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/26. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class TypesetKit; 12 | 13 | @interface NSMutableAttributedString (Typeset) 14 | 15 | - (TypesetKit *)typeset; 16 | 17 | - (NSMutableAttributedString *(^)(id))append; 18 | 19 | - (NSMutableAttributedString *)bold; 20 | 21 | - (NSMutableAttributedString *(^)(UIColor *))color; 22 | - (NSMutableAttributedString *(^)(NSUInteger))hexColor; 23 | - (NSMutableAttributedString *(^)(NSUInteger))fontSize; 24 | - (NSMutableAttributedString *(^)(NSString *))fontName; 25 | - (NSMutableAttributedString *(^)(NSString *, CGFloat))font; 26 | 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Classes/NSMutableAttributedString+Typeset.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableAttributedString+Typeset.m 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/26. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import "NSMutableAttributedString+Typeset.h" 10 | #import "TypesetKit.h" 11 | #import 12 | 13 | @implementation NSMutableAttributedString (Typeset) 14 | 15 | - (TypesetKit *)typeset { 16 | TypesetKit *typeset = objc_getAssociatedObject(self, @selector(typeset)); 17 | if (!typeset) { 18 | typeset = [[TypesetKit alloc] init]; 19 | typeset.string = [[NSMutableAttributedString alloc] initWithAttributedString:self]; 20 | objc_setAssociatedObject(self, @selector(typeset), typeset, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 21 | } 22 | return typeset; 23 | } 24 | 25 | - (NSMutableAttributedString *(^)(id))append { 26 | return ^(id string) { 27 | if (!string) return self; 28 | NSAssert([string isKindOfClass:[NSString class]] || 29 | [string isKindOfClass:[NSAttributedString class]] || 30 | [string isKindOfClass:[NSMutableAttributedString class]], @"String passed into this method should be NSString,NSAttributedString or NSMutableAttributedString."); 31 | 32 | NSMutableAttributedString *mas = [[NSMutableAttributedString alloc] init]; 33 | if ([string isKindOfClass:[NSString class]]) { 34 | mas = [[NSMutableAttributedString alloc] initWithString:string]; 35 | } else if ([string isKindOfClass:[NSAttributedString class]]) { 36 | mas = [[NSMutableAttributedString alloc] initWithAttributedString:string]; 37 | } else { 38 | mas = (NSMutableAttributedString *)string; 39 | } 40 | [self appendAttributedString:mas]; 41 | return self; 42 | }; 43 | } 44 | 45 | - (NSMutableAttributedString *)bold { 46 | return self.typeset.bold.string; 47 | } 48 | 49 | - (NSMutableAttributedString *(^)(UIColor *))color { 50 | return ^(UIColor *color) { 51 | return self.typeset.color(color).string; 52 | }; 53 | } 54 | 55 | - (NSMutableAttributedString *(^)(NSUInteger))hexColor { 56 | return ^(NSUInteger hexColor) { 57 | return self.typeset.hexColor(hexColor).string; 58 | }; 59 | } 60 | 61 | - (NSMutableAttributedString *(^)(NSUInteger))fontSize { 62 | return ^(NSUInteger fontSize) { 63 | return self.typeset.fontSize(fontSize).string; 64 | }; 65 | } 66 | 67 | - (NSMutableAttributedString *(^)(NSString *))fontName { 68 | return ^(NSString *fontName) { 69 | return self.typeset.fontName(fontName).string; 70 | }; 71 | } 72 | 73 | - (NSMutableAttributedString *(^)(NSString *, CGFloat))font { 74 | return ^(NSString *fontName, CGFloat fontSize) { 75 | return self.typeset.font(fontName, fontSize).string; 76 | }; 77 | } 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /Classes/NSString+Typeset.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Typeset.h 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/25. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class TypesetKit; 12 | 13 | @interface NSString (Typeset) 14 | 15 | - (TypesetKit *)typeset; 16 | 17 | - (NSMutableAttributedString *)bold; 18 | 19 | - (NSMutableAttributedString *)black; 20 | - (NSMutableAttributedString *)darkGray; 21 | - (NSMutableAttributedString *)lightGray; 22 | - (NSMutableAttributedString *)white; 23 | - (NSMutableAttributedString *)gray; 24 | - (NSMutableAttributedString *)red; 25 | - (NSMutableAttributedString *)green; 26 | - (NSMutableAttributedString *)blue; 27 | - (NSMutableAttributedString *)cyan; 28 | - (NSMutableAttributedString *)yellow; 29 | - (NSMutableAttributedString *)magenta; 30 | - (NSMutableAttributedString *)orange; 31 | - (NSMutableAttributedString *)purple; 32 | - (NSMutableAttributedString *)brown; 33 | - (NSMutableAttributedString *)clear; 34 | 35 | - (NSMutableAttributedString *(^)(UIColor *))color; 36 | - (NSMutableAttributedString *(^)(NSUInteger))hexColor; 37 | - (NSMutableAttributedString *(^)(NSUInteger))fontSize; 38 | - (NSMutableAttributedString *(^)(NSString *))fontName; 39 | - (NSMutableAttributedString *(^)(NSString *, CGFloat))font; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /Classes/NSString+Typeset.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Typeset.m 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/25. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import "NSString+Typeset.h" 10 | #import "TypesetKit.h" 11 | #import "TypesetKit+Color.h" 12 | #import 13 | 14 | @implementation NSString (Typeset) 15 | 16 | - (TypesetKit *)typeset { 17 | TypesetKit *typeset = objc_getAssociatedObject(self, @selector(typeset)); 18 | if (!typeset) { 19 | typeset = [[TypesetKit alloc] init]; 20 | objc_setAssociatedObject(self, @selector(typeset), typeset, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 21 | } 22 | typeset.string = [[NSMutableAttributedString alloc] initWithString:self]; 23 | return typeset; 24 | } 25 | 26 | - (NSMutableAttributedString *)bold { 27 | return self.typeset.bold.string; 28 | } 29 | 30 | - (NSMutableAttributedString *)black { 31 | return self.typeset.black.string; 32 | } 33 | 34 | - (NSMutableAttributedString *)darkGray { 35 | return self.typeset.darkGray.string; 36 | } 37 | 38 | - (NSMutableAttributedString *)lightGray { 39 | return self.typeset.lightGray.string; 40 | } 41 | 42 | - (NSMutableAttributedString *)white { 43 | return self.typeset.white.string; 44 | } 45 | 46 | - (NSMutableAttributedString *)gray { 47 | return self.typeset.gray.string; 48 | } 49 | 50 | - (NSMutableAttributedString *)red { 51 | return self.typeset.red.string; 52 | } 53 | 54 | - (NSMutableAttributedString *)green { 55 | return self.typeset.green.string; 56 | } 57 | 58 | - (NSMutableAttributedString *)blue { 59 | return self.typeset.blue.string; 60 | } 61 | 62 | - (NSMutableAttributedString *)cyan { 63 | return self.typeset.cyan.string; 64 | } 65 | 66 | - (NSMutableAttributedString *)yellow { 67 | return self.typeset.yellow.string; 68 | } 69 | 70 | - (NSMutableAttributedString *)magenta { 71 | return self.typeset.magenta.string; 72 | } 73 | 74 | - (NSMutableAttributedString *)orange { 75 | return self.typeset.orange.string; 76 | } 77 | 78 | - (NSMutableAttributedString *)purple { 79 | return self.typeset.purple.string; 80 | } 81 | 82 | - (NSMutableAttributedString *)brown { 83 | return self.typeset.brown.string; 84 | } 85 | 86 | - (NSMutableAttributedString *)clear { 87 | return self.typeset.clear.string; 88 | } 89 | 90 | - (NSMutableAttributedString *(^)(UIColor *))color { 91 | return ^(UIColor *color) { 92 | return self.typeset.color(color).string; 93 | }; 94 | } 95 | 96 | - (NSMutableAttributedString *(^)(NSUInteger))hexColor { 97 | return ^(NSUInteger hexColor) { 98 | return self.typeset.hexColor(hexColor).string; 99 | }; 100 | } 101 | 102 | - (NSMutableAttributedString *(^)(NSUInteger))fontSize { 103 | return ^(NSUInteger fontSize) { 104 | return self.typeset.fontSize(fontSize).string; 105 | }; 106 | } 107 | 108 | - (NSMutableAttributedString *(^)(NSString *))fontName { 109 | return ^(NSString *fontName) { 110 | return self.typeset.fontName(fontName).string; 111 | }; 112 | } 113 | 114 | - (NSMutableAttributedString *(^)(NSString *, CGFloat))font { 115 | return ^(NSString *fontName, CGFloat fontSize) { 116 | return self.typeset.font(fontName, fontSize).string; 117 | }; 118 | } 119 | 120 | @end 121 | -------------------------------------------------------------------------------- /Classes/NSValue+Range.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSValue+Range.h 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/29. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSValue (Range) 12 | 13 | + (NSValue *)valueWithLocation:(NSUInteger)location length:(NSUInteger)length; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Classes/NSValue+Range.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSValue+Range.m 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/29. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import "NSValue+Range.h" 10 | 11 | @implementation NSValue (Range) 12 | 13 | + (NSValue *)valueWithLocation:(NSUInteger)location length:(NSUInteger)length { 14 | return [NSValue valueWithRange:NSMakeRange(location, length)]; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Classes/Typeset.h: -------------------------------------------------------------------------------- 1 | // 2 | // Typeset.h 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/25. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #ifndef Typesetting_Typesetting_h 10 | #define Typesetting_Typesetting_h 11 | 12 | #import "TypesetKit.h" 13 | #import "TypesetKit+Color.h" 14 | #import "TypesetKit+Match.h" 15 | #import "NSString+Typeset.h" 16 | #import "NSMutableAttributedString+Typeset.h" 17 | 18 | #import "UILabel+Typeset.h" 19 | #import "UITextField+Typeset.h" 20 | #import "UITextView+Typeset.h" 21 | 22 | #define TSBlock(block) ^(NSString *s) { return s.typeset.block.string; } 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /Classes/TypesetKit+Color.h: -------------------------------------------------------------------------------- 1 | // 2 | // TypesetKit+Color.h 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/25. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import "TypesetKit.h" 10 | 11 | @interface TypesetKit (Color) 12 | 13 | - (TypesetKit *)black; 14 | - (TypesetKit *)darkGray; 15 | - (TypesetKit *)lightGray; 16 | - (TypesetKit *)white; 17 | - (TypesetKit *)gray; 18 | - (TypesetKit *)red; 19 | - (TypesetKit *)green; 20 | - (TypesetKit *)blue; 21 | - (TypesetKit *)cyan; 22 | - (TypesetKit *)yellow; 23 | - (TypesetKit *)magenta; 24 | - (TypesetKit *)orange; 25 | - (TypesetKit *)purple; 26 | - (TypesetKit *)brown; 27 | - (TypesetKit *)clear; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Classes/TypesetKit+Color.m: -------------------------------------------------------------------------------- 1 | // 2 | // TypesetKit+Color.m 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/25. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import "TypesetKit+Color.h" 10 | 11 | @implementation TypesetKit (Color) 12 | 13 | - (TypesetKit *)black { 14 | return self.color([UIColor blackColor]); 15 | } 16 | 17 | - (TypesetKit *)darkGray { 18 | return self.color([UIColor darkGrayColor]); 19 | } 20 | 21 | - (TypesetKit *)lightGray { 22 | return self.color([UIColor lightGrayColor]); 23 | } 24 | 25 | - (TypesetKit *)white { 26 | return self.color([UIColor whiteColor]); 27 | } 28 | 29 | - (TypesetKit *)gray { 30 | return self.color([UIColor grayColor]); 31 | } 32 | 33 | - (TypesetKit *)red { 34 | return self.color([UIColor redColor]); 35 | } 36 | 37 | - (TypesetKit *)green { 38 | return self.color([UIColor greenColor]); 39 | } 40 | 41 | - (TypesetKit *)blue { 42 | return self.color([UIColor blueColor]); 43 | } 44 | 45 | - (TypesetKit *)cyan { 46 | return self.color([UIColor cyanColor]); 47 | } 48 | 49 | - (TypesetKit *)yellow { 50 | return self.color([UIColor yellowColor]); 51 | } 52 | 53 | - (TypesetKit *)magenta { 54 | return self.color([UIColor magentaColor]); 55 | } 56 | 57 | - (TypesetKit *)orange { 58 | return self.color([UIColor orangeColor]); 59 | } 60 | 61 | - (TypesetKit *)purple { 62 | return self.color([UIColor purpleColor]); 63 | } 64 | 65 | - (TypesetKit *)brown { 66 | return self.color([UIColor brownColor]); 67 | } 68 | 69 | - (TypesetKit *)clear { 70 | return self.color([UIColor clearColor]); 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /Classes/TypesetKit+Match.h: -------------------------------------------------------------------------------- 1 | // 2 | // TypesetKit+Match.h 3 | // Typeset 4 | // 5 | // Created by Draveness on 16/4/18. 6 | // Copyright © 2016年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TypesetKit (Match) 12 | 13 | - (TypesetUIntegerBlock)from; 14 | - (TypesetUIntegerBlock)to; 15 | - (TypesetUIntegerBlock)location; 16 | - (TypesetUIntegerBlock)length; 17 | - (TypesetRangeBlock)range; 18 | - (TypesetStringBlock)match; 19 | - (TypesetStringBlock)matchLast; 20 | - (TypesetMatchBlock)matchWithOptions; 21 | - (TypesetStringBlock)matchAll; 22 | - (TypesetMatchBlock)matchAllWithOptions; 23 | 24 | - (TypesetStringBlock)matchAllWithPattern; 25 | - (TypesetBlock(NSString *, NSRegularExpressionOptions))matchAllWithPatternAndOptions; 26 | 27 | - (TypesetKit *)matchNumbers; 28 | - (TypesetKit *)matchLetters; 29 | - (TypesetStringBlock)matchLanguage; 30 | - (TypesetKit *)matchChinese; 31 | 32 | - (TypesetKit *)all; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Classes/TypesetKit+Match.m: -------------------------------------------------------------------------------- 1 | // 2 | // TypesetKit+Match.m 3 | // Typeset 4 | // 5 | // Created by Draveness on 16/4/18. 6 | // Copyright © 2016年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import "TypesetKit+Match.h" 10 | #import "NSValue+Range.h" 11 | 12 | @interface TypesetKit () 13 | 14 | @property (nonatomic, strong) NSMutableArray *attributeRanges; 15 | 16 | @property (nonatomic, assign) NSInteger attributeFrom; 17 | @property (nonatomic, assign) NSInteger attributeTo; 18 | 19 | @property (nonatomic, assign) NSInteger attributeLocation; 20 | @property (nonatomic, assign) NSInteger attributeLength; 21 | 22 | @property (nonatomic, strong) NSMutableParagraphStyle *paragraphStyle; 23 | 24 | @end 25 | 26 | @implementation TypesetKit (Match) 27 | 28 | - (void)removeAllAttributeRanges { 29 | [self.attributeRanges removeAllObjects]; 30 | self.paragraphStyle = nil; 31 | } 32 | 33 | #pragma mark - Range Construct 34 | 35 | - (TypesetUIntegerBlock)from { 36 | return ^(NSUInteger from) { 37 | if (self.attributeTo != -1) { 38 | [self removeAllAttributeRanges]; 39 | [self.attributeRanges addObject:[NSValue valueWithLocation:from length:self.attributeTo - from]]; 40 | } 41 | self.attributeFrom = from; 42 | return self; 43 | }; 44 | } 45 | 46 | - (TypesetUIntegerBlock)to { 47 | return ^(NSUInteger to) { 48 | if (self.attributeFrom != -1) { 49 | [self removeAllAttributeRanges]; 50 | [self.attributeRanges addObject:[NSValue valueWithLocation:self.attributeFrom length:to - self.attributeFrom]]; 51 | } 52 | self.attributeTo = to; 53 | return self; 54 | }; 55 | } 56 | 57 | - (TypesetUIntegerBlock)location { 58 | return ^(NSUInteger location) { 59 | if (self.attributeLength != -1) { 60 | [self removeAllAttributeRanges]; 61 | [self.attributeRanges addObject:[NSValue valueWithLocation:location length:self.attributeLength]]; 62 | } 63 | self.attributeLocation = location; 64 | return self; 65 | }; 66 | } 67 | 68 | - (TypesetUIntegerBlock)length { 69 | return ^(NSUInteger length) { 70 | if (self.attributeLocation != -1) { 71 | [self removeAllAttributeRanges]; 72 | [self.attributeRanges addObject:[NSValue valueWithLocation:self.attributeLocation length:length]]; 73 | } 74 | self.attributeLength = length; 75 | return self; 76 | }; 77 | } 78 | 79 | - (TypesetRangeBlock)range { 80 | return ^(NSRange range) { 81 | [self removeAllAttributeRanges]; 82 | [self.attributeRanges addObject:[NSValue valueWithRange:range]]; 83 | return self; 84 | }; 85 | } 86 | 87 | #pragma mark - Match String 88 | 89 | - (TypesetStringBlock)matchAll { 90 | return ^(NSString *substring) { 91 | return self.matchAllWithOptions(substring, 0); 92 | }; 93 | } 94 | 95 | - (TypesetMatchBlock)matchAllWithOptions { 96 | return ^(NSString *substring, NSStringCompareOptions options) { 97 | NSRange range = [self.string.string rangeOfString:substring options:options]; 98 | [self removeAllAttributeRanges]; 99 | [self.attributeRanges addObject:[NSValue valueWithRange:range]]; 100 | while (range.length != 0) { 101 | NSInteger location = range.location + range.length; 102 | NSInteger length = self.string.length - location; 103 | range = [self.string.string rangeOfString:substring options:options range:NSMakeRange(location, length)]; 104 | [self.attributeRanges addObject:[NSValue valueWithRange:range]]; 105 | } 106 | return self; 107 | }; 108 | } 109 | 110 | - (TypesetStringBlock)match { 111 | return ^(NSString *substring) { 112 | return self.matchWithOptions(substring, 0); 113 | }; 114 | } 115 | 116 | - (TypesetStringBlock)matchLast { 117 | return ^(NSString *substring) { 118 | return self.matchWithOptions(substring, NSBackwardsSearch); 119 | }; 120 | } 121 | 122 | - (TypesetMatchBlock)matchWithOptions { 123 | return ^(NSString *substring, NSStringCompareOptions options) { 124 | NSRange range = [self.string.string rangeOfString:substring options:options]; 125 | [self removeAllAttributeRanges]; 126 | [self.attributeRanges addObject:[NSValue valueWithRange:range]]; 127 | return self; 128 | }; 129 | } 130 | 131 | - (TypesetKit *)all { 132 | [self removeAllAttributeRanges]; 133 | [self.attributeRanges addObject:[NSValue valueWithLocation:0 length:self.string.length]]; 134 | return self; 135 | } 136 | 137 | #pragma mark - MatchWithPattern 138 | 139 | - (TypesetBlock(NSString *, NSRegularExpressionOptions))matchAllWithPatternAndOptions { 140 | return ^(NSString *pattern, NSRegularExpressionOptions options) { 141 | return [self matchAllWithPattern:pattern options:options]; 142 | }; 143 | } 144 | 145 | - (TypesetStringBlock)matchAllWithPattern { 146 | return ^(NSString *pattern) { 147 | return [self matchAllWithPattern:pattern options:0]; 148 | }; 149 | } 150 | 151 | - (TypesetKit *)matchNumbers { 152 | return [self matchAllWithPattern:@"\\d+" options:0]; 153 | } 154 | 155 | - (TypesetKit *)matchLetters { 156 | return [self matchAllWithPattern:@"[a-zA-Z]+" options:0]; 157 | } 158 | 159 | - (TypesetStringBlock)matchLanguage { 160 | return ^(NSString *language) { 161 | return [self matchAllWithPattern:[NSString stringWithFormat:@"\\p{script=%@}", language] options:0]; 162 | }; 163 | } 164 | 165 | - (TypesetKit *)matchChinese { 166 | return self.matchLanguage(@"Han"); 167 | } 168 | 169 | #pragma mark - Helper 170 | 171 | - (TypesetKit *)matchWithPattern:(NSString *)pattern options:(NSRegularExpressionOptions)options { 172 | NSError *regError; 173 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern 174 | options:options 175 | error:®Error]; 176 | if (regError) NSLog(@"%@",regError.localizedDescription); 177 | 178 | [self removeAllAttributeRanges]; 179 | NSRange range = NSMakeRange(0, self.string.string.length); 180 | NSRange resultRange = [regex rangeOfFirstMatchInString:self.string.string 181 | options:0 range:range]; 182 | [self.attributeRanges addObject:[NSValue valueWithRange:resultRange]]; 183 | return self; 184 | } 185 | 186 | - (TypesetKit *)matchAllWithPattern:(NSString *)pattern options:(NSRegularExpressionOptions)options { 187 | NSError *regError; 188 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern 189 | options:options 190 | error:®Error]; 191 | if (regError) NSLog(@"%@",regError.localizedDescription); 192 | 193 | [self removeAllAttributeRanges]; 194 | NSRange range = NSMakeRange(0, self.string.string.length); 195 | [regex enumerateMatchesInString:self.string.string 196 | options:0 range:range 197 | usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) { 198 | [self.attributeRanges addObject:[NSValue valueWithRange:result.range]]; 199 | }]; 200 | return self; 201 | } 202 | 203 | @end 204 | -------------------------------------------------------------------------------- /Classes/TypesetKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // TypesetKit.h 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/25. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "metamacros.h" 11 | 12 | #define Typeset($string) ( $string ? $string.typeset : @"".typeset ) 13 | 14 | #define TypesetBlock(...) TypesetKit *(^)(__VA_ARGS__) 15 | 16 | #define TypesetUIntegerBlock TypesetBlock(NSUInteger) 17 | #define TypesetIntegerBlock TypesetBlock(NSInteger) 18 | #define TypesetCGFloatBlock TypesetBlock(CGFloat) 19 | #define TypesetRangeBlock TypesetBlock(NSRange) 20 | #define TypesetStringBlock TypesetBlock(NSString *) 21 | #define TypesetObjectBlock TypesetBlock(id) 22 | #define TypesetColorBlock TypesetBlock(UIColor *) 23 | #define TypesetFontBlock TypesetBlock(NSString *, CGFloat) 24 | #define TypesetMatchBlock TypesetBlock(NSString *, NSStringCompareOptions) 25 | 26 | #define TSAttributedString(...) _TSAttributedString(metamacro_argcount(__VA_ARGS__), __VA_ARGS__) 27 | 28 | NSMutableAttributedString *_TSAttributedString(int size, ...); 29 | 30 | @interface TypesetKit : NSObject 31 | 32 | @property (nonatomic, strong) NSMutableAttributedString *string; 33 | 34 | - (TypesetColorBlock)color; 35 | - (TypesetUIntegerBlock)hexColor; 36 | 37 | - (TypesetStringBlock)fontName; 38 | - (TypesetCGFloatBlock)fontSize; 39 | - (TypesetFontBlock)font; 40 | - (TypesetKit *)regular; 41 | - (TypesetKit *)light; 42 | - (TypesetKit *)bold; 43 | - (TypesetKit *)italic; 44 | - (TypesetKit *)thin; 45 | 46 | - (TypesetBlock(NSUnderlineStyle))strikeThrough; 47 | 48 | - (TypesetColorBlock)strikeThroughColor; 49 | 50 | - (TypesetCGFloatBlock)baseline; 51 | 52 | - (TypesetBlock(NSUnderlineStyle))underline; 53 | 54 | - (TypesetColorBlock)underlineColor; 55 | 56 | - (TypesetStringBlock)link; 57 | 58 | - (TypesetObjectBlock)append; 59 | 60 | - (TypesetUIntegerBlock)ligature; 61 | 62 | - (TypesetCGFloatBlock)kern; 63 | 64 | - (TypesetColorBlock)strokeColor; 65 | 66 | - (TypesetCGFloatBlock)strokeWidth; 67 | 68 | - (TypesetBlock(NSShadow *))shadow; 69 | 70 | - (TypesetStringBlock)textEffect; 71 | 72 | - (TypesetCGFloatBlock)obliqueness; 73 | 74 | - (TypesetCGFloatBlock)expansion; 75 | 76 | // NSMutableParagraphStyle 77 | - (TypesetBlock(NSLineBreakMode))lineBreakMode; 78 | - (TypesetBlock(NSTextAlignment))alignment; 79 | - (TypesetBlock(NSTextAlignment))textAlignment; 80 | - (TypesetCGFloatBlock)lineSpacing; 81 | - (TypesetCGFloatBlock)paragraphSpacing; 82 | - (TypesetCGFloatBlock)headIndent; 83 | - (TypesetCGFloatBlock)tailIndent; 84 | - (TypesetCGFloatBlock)minimumLineHeight; 85 | - (TypesetCGFloatBlock)maximumLineHeight; 86 | - (TypesetCGFloatBlock)lineHeightMultiple; 87 | - (TypesetCGFloatBlock)paragraphSpacingBefore; 88 | - (TypesetCGFloatBlock)hyphenationFactor; 89 | - (TypesetCGFloatBlock)defaultTabInterval; 90 | - (TypesetBlock(NSWritingDirection))baseWritingDirection; 91 | - (TypesetBlock(BOOL))allowsDefaultTighteningForTruncation; 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /Classes/TypesetKit.m: -------------------------------------------------------------------------------- 1 | // 2 | // TypesetKit.m 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/25. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import "TypesetKit.h" 10 | #import "UIFont+Weight.h" 11 | 12 | #define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0] 13 | 14 | @interface TypesetKit () 15 | 16 | @property (nonatomic, strong) NSMutableArray *attributeRanges; 17 | 18 | @property (nonatomic, assign) NSInteger attributeFrom; 19 | @property (nonatomic, assign) NSInteger attributeTo; 20 | 21 | @property (nonatomic, assign) NSInteger attributeLocation; 22 | @property (nonatomic, assign) NSInteger attributeLength; 23 | 24 | @property (nonatomic, strong) NSMutableParagraphStyle *paragraphStyle; 25 | 26 | @end 27 | 28 | @implementation TypesetKit 29 | 30 | NSMutableAttributedString *_TSAttributedString(int size, ...) { 31 | va_list vl; 32 | va_start(vl, size); 33 | NSMutableAttributedString *result = [[NSMutableAttributedString alloc] init]; 34 | for (NSUInteger i = 0; i < size; i++) { 35 | id string = va_arg(vl, id); 36 | NSMutableAttributedString *mas = [TypesetKit convertToMutableAttributedString:string]; 37 | [result appendAttributedString:mas]; 38 | } 39 | return result; 40 | } 41 | 42 | - (void)setString:(NSMutableAttributedString *)string { 43 | _string = string; 44 | 45 | self.attributeRanges = [NSMutableArray arrayWithObject:[NSValue valueWithRange:NSMakeRange(0, self.string.length)]]; 46 | self.attributeFrom = -1; 47 | self.attributeTo = -1; 48 | self.attributeLocation = -1; 49 | self.attributeLength = -1; 50 | 51 | } 52 | 53 | - (TypesetColorBlock)color { 54 | return ^(UIColor *color) { 55 | for (NSValue *value in self.attributeRanges) { 56 | NSRange range = [value rangeValue]; 57 | [self.string addAttribute:NSForegroundColorAttributeName value:color range:range]; 58 | } 59 | return self; 60 | }; 61 | } 62 | 63 | - (TypesetUIntegerBlock)hexColor { 64 | return ^(NSUInteger hexColor) { 65 | for (NSValue *value in self.attributeRanges) { 66 | NSRange range = [value rangeValue]; 67 | [self.string addAttribute:NSForegroundColorAttributeName value:UIColorFromRGB(hexColor) range:range]; 68 | } 69 | return self; 70 | }; 71 | } 72 | 73 | - (TypesetCGFloatBlock)baseline { 74 | return ^(CGFloat baseline) { 75 | for (NSValue *value in self.attributeRanges) { 76 | NSRange range = [value rangeValue]; 77 | [self.string addAttribute:NSBaselineOffsetAttributeName value:@(baseline) range:range]; 78 | } 79 | return self; 80 | }; 81 | } 82 | 83 | - (TypesetBlock(NSUnderlineStyle))strikeThrough { 84 | return ^(NSUnderlineStyle strikeThroughStyle) { 85 | for (NSValue *value in self.attributeRanges) { 86 | NSRange range = [value rangeValue]; 87 | [self.string addAttribute:NSStrikethroughStyleAttributeName value:@(strikeThroughStyle) range:range]; 88 | } 89 | return self; 90 | }; 91 | } 92 | 93 | - (TypesetColorBlock)strikeThroughColor { 94 | return ^(UIColor *strikeThroughColor) { 95 | for (NSValue *value in self.attributeRanges) { 96 | NSRange range = [value rangeValue]; 97 | [self.string addAttribute:NSStrikethroughColorAttributeName value:strikeThroughColor range:range]; 98 | } 99 | return self; 100 | }; 101 | } 102 | 103 | - (TypesetFontBlock)font { 104 | return ^(NSString *fontName, CGFloat fontSize) { 105 | for (NSValue *value in self.attributeRanges) { 106 | NSRange range = [value rangeValue]; 107 | UIFont* font = [UIFont fontWithName:fontName 108 | size:fontSize]; 109 | [self.string addAttribute:NSFontAttributeName value:font range:range]; 110 | } 111 | return self; 112 | }; 113 | } 114 | 115 | - (TypesetStringBlock)fontName { 116 | return ^(NSString *fontName) { 117 | if (self.string.length) { 118 | for (NSValue *value in self.attributeRanges) { 119 | NSRange range = [value rangeValue]; 120 | UIFont *font = [self.string attribute:NSFontAttributeName atIndex:0 effectiveRange:&range]; 121 | range = [value rangeValue]; 122 | CGFloat size = font.pointSize; 123 | [self.string addAttribute:NSFontAttributeName value:[UIFont fontWithName:fontName size:size] range:range]; 124 | } 125 | } 126 | 127 | return self; 128 | }; 129 | } 130 | 131 | - (TypesetKit *)changeFontWeight:(TSFontWeight)fontWeight { 132 | if (self.string.length) { 133 | for (NSValue *value in self.attributeRanges) { 134 | NSRange range = [value rangeValue]; 135 | UIFont *font = [self.string attribute:NSFontAttributeName atIndex:0 effectiveRange:&range]; 136 | range = [value rangeValue]; 137 | 138 | if (!font) { 139 | font = [UIFont systemFontOfSize:17]; 140 | } 141 | font = [font fontWithFontWeight:fontWeight]; 142 | [self.string addAttribute:NSFontAttributeName value:font range:range]; 143 | } 144 | } 145 | return self; 146 | } 147 | 148 | - (TypesetKit *)regular { 149 | return [self changeFontWeight:TSFontWeightRegular]; 150 | } 151 | 152 | - (TypesetKit *)light { 153 | return [self changeFontWeight:TSFontWeightLight]; 154 | } 155 | 156 | - (TypesetKit *)bold { 157 | return [self changeFontWeight:TSFontWeightBold]; 158 | } 159 | 160 | - (TypesetKit *)italic { 161 | return [self changeFontWeight:TSFontWeightItalic]; 162 | } 163 | 164 | - (TypesetKit *)thin { 165 | return [self changeFontWeight:TSFontWeightThin]; 166 | } 167 | 168 | - (TypesetCGFloatBlock)fontSize { 169 | return ^(CGFloat fontSize) { 170 | if (self.string.length) { 171 | for (NSValue *value in self.attributeRanges) { 172 | NSRange range = [value rangeValue]; 173 | UIFont *font = [self.string attribute:NSFontAttributeName atIndex:0 effectiveRange:&range]; 174 | range = [value rangeValue]; 175 | if (!font) { 176 | font = [UIFont systemFontOfSize:17]; 177 | } 178 | font = [UIFont systemFontOfSize:fontSize]; 179 | [self.string addAttribute:NSFontAttributeName value:font range:range]; 180 | } 181 | } 182 | 183 | return self; 184 | }; 185 | } 186 | 187 | - (TypesetBlock(NSUnderlineStyle))underline { 188 | return ^(NSUnderlineStyle underline) { 189 | for (NSValue *value in self.attributeRanges) { 190 | NSRange range = [value rangeValue]; 191 | [self.string addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:underline] range:range]; 192 | } 193 | return self; 194 | }; 195 | } 196 | 197 | - (TypesetColorBlock)underlineColor { 198 | return ^(UIColor *underlineColor) { 199 | for (NSValue *value in self.attributeRanges) { 200 | NSRange range = [value rangeValue]; 201 | [self.string addAttribute:NSUnderlineColorAttributeName value:underlineColor range:range]; 202 | } 203 | return self; 204 | }; 205 | } 206 | 207 | - (TypesetStringBlock)link { 208 | return ^(NSString *url) { 209 | for (NSValue *value in self.attributeRanges) { 210 | NSRange range = [value rangeValue]; 211 | [self.string addAttribute:NSLinkAttributeName value:url range:range]; 212 | } 213 | return self; 214 | }; 215 | } 216 | 217 | - (TypesetObjectBlock)append { 218 | return ^(id string) { 219 | if (!string) return self; 220 | 221 | NSMutableAttributedString *mas = [TypesetKit convertToMutableAttributedString:string]; 222 | 223 | [self.string appendAttributedString:mas]; 224 | return self; 225 | }; 226 | } 227 | 228 | - (TypesetUIntegerBlock)ligature { 229 | return ^(NSUInteger ligature) { 230 | for (NSValue *value in self.attributeRanges) { 231 | NSRange range = [value rangeValue]; 232 | [self.string addAttribute:NSLigatureAttributeName value:@(ligature) range:range]; 233 | } 234 | return self; 235 | }; 236 | } 237 | 238 | - (TypesetCGFloatBlock)kern { 239 | return ^(CGFloat kern) { 240 | for (NSValue *value in self.attributeRanges) { 241 | NSRange range = [value rangeValue]; 242 | 243 | [self.string addAttribute:NSKernAttributeName value:@(kern) range:range]; 244 | } 245 | return self; 246 | }; 247 | } 248 | 249 | 250 | - (TypesetColorBlock)strokeColor { 251 | return ^(UIColor *strokeColor) { 252 | for (NSValue *value in self.attributeRanges) { 253 | NSRange range = [value rangeValue]; 254 | 255 | [self.string addAttribute:NSStrokeColorAttributeName value:strokeColor range:range]; 256 | } 257 | return self; 258 | }; 259 | } 260 | 261 | - (TypesetCGFloatBlock)strokeWidth { 262 | return ^(CGFloat strokeWidth) { 263 | for (NSValue *value in self.attributeRanges) { 264 | NSRange range = [value rangeValue]; 265 | 266 | [self.string addAttribute:NSStrokeWidthAttributeName value:@(strokeWidth) range:range]; 267 | } 268 | return self; 269 | }; 270 | } 271 | 272 | - (TypesetBlock(NSShadow *))shadow { 273 | return ^(NSShadow *shadow) { 274 | for (NSValue *value in self.attributeRanges) { 275 | NSRange range = [value rangeValue]; 276 | 277 | [self.string addAttribute:NSShadowAttributeName value:shadow range:range]; 278 | } 279 | return self; 280 | }; 281 | } 282 | 283 | - (TypesetStringBlock)textEffect { 284 | return ^(NSString *textEffect) { 285 | for (NSValue *value in self.attributeRanges) { 286 | NSRange range = [value rangeValue]; 287 | 288 | [self.string addAttribute:NSTextEffectAttributeName value:textEffect range:range]; 289 | } 290 | return self; 291 | }; 292 | } 293 | 294 | - (TypesetCGFloatBlock)obliqueness { 295 | return ^(CGFloat obliqueness) { 296 | for (NSValue *value in self.attributeRanges) { 297 | NSRange range = [value rangeValue]; 298 | 299 | [self.string addAttribute:NSObliquenessAttributeName value:@(obliqueness) range:range]; 300 | } 301 | return self; 302 | }; 303 | } 304 | 305 | - (TypesetCGFloatBlock)expansion { 306 | return ^(CGFloat expansion) { 307 | for (NSValue *value in self.attributeRanges) { 308 | NSRange range = [value rangeValue]; 309 | 310 | [self.string addAttribute:NSExpansionAttributeName value:@(expansion) range:range]; 311 | } 312 | return self; 313 | }; 314 | } 315 | 316 | - (TypesetBlock(NSTextAttachment *))textAttachment { 317 | return ^(NSTextAttachment *textAttachment) { 318 | for (NSValue *value in self.attributeRanges) { 319 | NSRange range = [value rangeValue]; 320 | 321 | [self.string addAttribute:NSAttachmentAttributeName value:textAttachment range:range]; 322 | } 323 | return self; 324 | }; 325 | } 326 | 327 | #pragma mark - NSParagraphStyle 328 | 329 | #define NSParagraphStyleReturnBlock(type, attribute) \ 330 | ^(type attribute) { \ 331 | for (NSValue *value in self.attributeRanges) { \ 332 | NSRange range = [value rangeValue]; \ 333 | \ 334 | self.paragraphStyle.attribute = attribute; \ 335 | [self.string addAttribute:NSParagraphStyleAttributeName value:self.paragraphStyle range:range]; \ 336 | } \ 337 | return self; \ 338 | } 339 | 340 | - (TypesetBlock(NSLineBreakMode))lineBreakMode { 341 | return NSParagraphStyleReturnBlock(NSLineBreakMode, lineBreakMode); 342 | } 343 | 344 | - (TypesetBlock(NSTextAlignment))alignment { 345 | return NSParagraphStyleReturnBlock(NSTextAlignment, alignment); 346 | } 347 | 348 | - (TypesetBlock(NSTextAlignment))textAlignment { 349 | return self.alignment; 350 | } 351 | 352 | - (TypesetCGFloatBlock)lineSpacing { 353 | return NSParagraphStyleReturnBlock(CGFloat, lineSpacing); 354 | } 355 | 356 | - (TypesetCGFloatBlock)paragraphSpacing { 357 | return NSParagraphStyleReturnBlock(CGFloat, paragraphSpacing); 358 | } 359 | 360 | - (TypesetCGFloatBlock)headIndent { 361 | return NSParagraphStyleReturnBlock(CGFloat, headIndent); 362 | } 363 | 364 | - (TypesetCGFloatBlock)tailIndent { 365 | return NSParagraphStyleReturnBlock(CGFloat, tailIndent); 366 | } 367 | 368 | - (TypesetCGFloatBlock)minimumLineHeight { 369 | return NSParagraphStyleReturnBlock(CGFloat, minimumLineHeight); 370 | } 371 | 372 | - (TypesetCGFloatBlock)maximumLineHeight { 373 | return NSParagraphStyleReturnBlock(CGFloat, maximumLineHeight); 374 | } 375 | 376 | - (TypesetCGFloatBlock)lineHeightMultiple { 377 | return NSParagraphStyleReturnBlock(CGFloat, lineHeightMultiple); 378 | } 379 | 380 | - (TypesetCGFloatBlock)paragraphSpacingBefore { 381 | return NSParagraphStyleReturnBlock(CGFloat, paragraphSpacingBefore); 382 | } 383 | 384 | - (TypesetCGFloatBlock)hyphenationFactor { 385 | return NSParagraphStyleReturnBlock(CGFloat, hyphenationFactor); 386 | } 387 | 388 | - (TypesetCGFloatBlock)defaultTabInterval { 389 | return NSParagraphStyleReturnBlock(CGFloat, defaultTabInterval); 390 | } 391 | 392 | - (TypesetBlock(NSWritingDirection))baseWritingDirection { 393 | return NSParagraphStyleReturnBlock(NSWritingDirection, baseWritingDirection); 394 | } 395 | 396 | - (TypesetBlock(BOOL))allowsDefaultTighteningForTruncation { 397 | return NSParagraphStyleReturnBlock(BOOL, allowsDefaultTighteningForTruncation); 398 | } 399 | 400 | - (NSMutableParagraphStyle *)paragraphStyle { 401 | if (!_paragraphStyle) { 402 | _paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 403 | } 404 | return _paragraphStyle; 405 | } 406 | 407 | + (NSMutableAttributedString *)convertToMutableAttributedString:(id)string { 408 | NSAssert([string isKindOfClass:[NSString class]] || 409 | [string isKindOfClass:[NSAttributedString class]] || 410 | [string isKindOfClass:[NSMutableAttributedString class]], @"String passed into this method should be NSString,NSAttributedString or NSMutableAttributedString."); 411 | NSMutableAttributedString *mas = [[NSMutableAttributedString alloc] init]; 412 | if ([string isKindOfClass:[NSString class]]) { 413 | mas = [[NSMutableAttributedString alloc] initWithString:string]; 414 | } else if ([string isKindOfClass:[NSAttributedString class]]) { 415 | mas = [[NSMutableAttributedString alloc] initWithAttributedString:string]; 416 | } else { 417 | mas = (NSMutableAttributedString *)string; 418 | } 419 | return mas; 420 | } 421 | 422 | @end 423 | -------------------------------------------------------------------------------- /Classes/UIFont+Weight.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIFont+Weight.h 3 | // Typeset 4 | // 5 | // Created by Draveness on 16/3/31. 6 | // Copyright © 2016年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, TSFontWeight) { 12 | TSFontWeightRegular, 13 | TSFontWeightThin, 14 | TSFontWeightBold, 15 | TSFontWeightItalic, 16 | TSFontWeightLight 17 | }; 18 | 19 | @interface UIFont (Weight) 20 | 21 | - (UIFont *)fontWithFontWeight:(TSFontWeight)weight; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Classes/UIFont+Weight.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIFont+Weight.m 3 | // Typeset 4 | // 5 | // Created by Draveness on 16/3/31. 6 | // Copyright © 2016年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import "UIFont+Weight.h" 10 | 11 | @implementation UIFont (Weight) 12 | 13 | 14 | - (BOOL)containsFontWeight { 15 | NSArray *weights = @[@"Thin", @"Bold", @"Italic", @"Light"]; 16 | for (NSString *weight in weights) { 17 | if ([self.fontName containsString:weight]) { 18 | return YES; 19 | } 20 | } 21 | return NO; 22 | } 23 | 24 | - (TSFontWeight)fontWeight { 25 | NSArray *weights = self.fontWeightDictionary.allValues; 26 | __block TSFontWeight fontWeight = TSFontWeightRegular; 27 | [weights enumerateObjectsUsingBlock:^(NSString * _Nonnull weight, NSUInteger idx, BOOL * _Nonnull stop) { 28 | if ([self.fontName containsString:weight]) { 29 | fontWeight = idx; 30 | *stop = YES; 31 | } 32 | }]; 33 | return fontWeight; 34 | } 35 | 36 | - (UIFont *)fontWithFontWeight:(TSFontWeight)weight { 37 | NSString *name = self.fontName; 38 | for (NSString *fontWeight in self.fontWeightDictionary.allValues) { 39 | // STHeitiJ-Regular to STHeitiJ-Thin if weight == TSFontWeightLight 40 | name = [name stringByReplacingOccurrencesOfString:fontWeight withString:self.fontWeightDictionary[@(weight)]]; 41 | } 42 | 43 | BOOL containWeight = NO; 44 | for (NSString *fontWeight in self.fontWeightDictionary.allValues) { 45 | if ([name containsString:fontWeight]) { 46 | containWeight = YES; 47 | break; 48 | } 49 | } 50 | 51 | if ([self fontWeight] == TSFontWeightRegular && !containWeight) { 52 | // STHeitiJ to STHeitiJ-Thin if weight == TSFontWeightLight 53 | name = [name stringByAppendingFormat:@"-%@", self.fontWeightDictionary[@(weight)]]; 54 | } 55 | 56 | if (weight == TSFontWeightRegular) { 57 | // STHeitiJ-Thin to STHeitiJ if weight == TSFontWeightRegular 58 | for (NSString *fontWeight in self.fontWeightDictionary.allValues) { 59 | name = [name stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"-%@", fontWeight] withString:@""]; 60 | } 61 | 62 | // if STHeitiJ not exist, append -Regular 63 | UIFont *regularFont = [UIFont fontWithName:name size:self.pointSize]; 64 | if (!regularFont) { 65 | name = [name stringByAppendingString:@"-Regular"]; 66 | } 67 | } 68 | 69 | UIFont *result = [UIFont fontWithName:name size:self.pointSize]; 70 | 71 | return result ? result : self; 72 | } 73 | 74 | - (NSDictionary *)fontWeightDictionary { 75 | return @{ 76 | @(TSFontWeightRegular): @"Regular", 77 | @(TSFontWeightThin): @"Thin", 78 | @(TSFontWeightLight): @"Light", 79 | @(TSFontWeightItalic): @"Italic", 80 | @(TSFontWeightBold): @"Bold" 81 | }; 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /Classes/UILabel+Typeset.h: -------------------------------------------------------------------------------- 1 | // 2 | // UILabel+Typeset.h 3 | // Typeset 4 | // 5 | // Created by Draveness on 16/3/31. 6 | // Copyright © 2016年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UILabel (Typeset) 12 | 13 | @property (nonatomic, copy) NSAttributedString *(^typesetBlock)(NSString *string); 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Classes/UILabel+Typeset.m: -------------------------------------------------------------------------------- 1 | // 2 | // UILabel+Typeset.m 3 | // Typeset 4 | // 5 | // Created by Draveness on 16/3/31. 6 | // Copyright © 2016年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import "UILabel+Typeset.h" 10 | #import 11 | 12 | @implementation UILabel (Typeset) 13 | 14 | + (void)load { 15 | static dispatch_once_t onceToken; 16 | dispatch_once(&onceToken, ^{ 17 | Class class = [self class]; 18 | 19 | SEL originalSelector = @selector(setText:); 20 | SEL swizzledSelector = @selector(typeset_setText:); 21 | 22 | Method originalMethod = class_getInstanceMethod(class, originalSelector); 23 | Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); 24 | 25 | BOOL didAddMethod = 26 | class_addMethod(class, 27 | originalSelector, 28 | method_getImplementation(swizzledMethod), 29 | method_getTypeEncoding(swizzledMethod)); 30 | 31 | if (didAddMethod) { 32 | class_replaceMethod(class, 33 | swizzledSelector, 34 | method_getImplementation(originalMethod), 35 | method_getTypeEncoding(originalMethod)); 36 | } else { 37 | method_exchangeImplementations(originalMethod, swizzledMethod); 38 | } 39 | }); 40 | } 41 | 42 | - (void)typeset_setText:(NSString *)text { 43 | if (self.typesetBlock && text) { 44 | self.attributedText = self.typesetBlock(text); 45 | } else { 46 | [self typeset_setText:text]; 47 | } 48 | } 49 | 50 | - (NSAttributedString *(^)(NSString *))typesetBlock { 51 | return objc_getAssociatedObject(self, @selector(typesetBlock)); 52 | } 53 | 54 | - (void)setTypesetBlock:(NSAttributedString *(^)(NSString *))typesetBlock { 55 | if (self.text && typesetBlock) self.attributedText = typesetBlock(self.text); 56 | objc_setAssociatedObject(self, @selector(typesetBlock), [typesetBlock copy], OBJC_ASSOCIATION_COPY_NONATOMIC); 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /Classes/UITextField+Typeset.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITextField+Typeset.h 3 | // Typeset 4 | // 5 | // Created by Draveness on 16/4/5. 6 | // Copyright © 2016年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UITextField (Typeset) 12 | 13 | @property (nonatomic, copy) NSAttributedString *(^typesetBlock)(NSString *string); 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Classes/UITextField+Typeset.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // UITextField+Typeset.m 4 | // Typeset 5 | // 6 | // Created by Draveness on 16/4/5. 7 | // Copyright © 2016年 DeltaX. All rights reserved. 8 | // 9 | 10 | #import "UITextField+Typeset.h" 11 | #import 12 | 13 | @implementation UITextField (Typeset) 14 | 15 | + (void)load { 16 | static dispatch_once_t onceToken; 17 | dispatch_once(&onceToken, ^{ 18 | Class class = [self class]; 19 | 20 | SEL originalSelector = @selector(setText:); 21 | SEL swizzledSelector = @selector(typeset_setText:); 22 | 23 | Method originalMethod = class_getInstanceMethod(class, originalSelector); 24 | Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); 25 | 26 | BOOL didAddMethod = 27 | class_addMethod(class, 28 | originalSelector, 29 | method_getImplementation(swizzledMethod), 30 | method_getTypeEncoding(swizzledMethod)); 31 | 32 | if (didAddMethod) { 33 | class_replaceMethod(class, 34 | swizzledSelector, 35 | method_getImplementation(originalMethod), 36 | method_getTypeEncoding(originalMethod)); 37 | } else { 38 | method_exchangeImplementations(originalMethod, swizzledMethod); 39 | } 40 | }); 41 | } 42 | 43 | - (void)typeset_setText:(NSString *)text { 44 | if (self.typesetBlock && text) { 45 | self.attributedText = self.typesetBlock(text); 46 | } else { 47 | [self typeset_setText:text]; 48 | } 49 | } 50 | 51 | - (NSAttributedString *(^)(NSString *))typesetBlock { 52 | return objc_getAssociatedObject(self, @selector(typesetBlock)); 53 | } 54 | 55 | - (void)setTypesetBlock:(NSAttributedString *(^)(NSString *))typesetBlock { 56 | if (self.text && typesetBlock) self.attributedText = typesetBlock(self.text); 57 | 58 | // Call textFieldDidChange: method when text changed 59 | [self addTarget:self 60 | action:@selector(textFieldDidChange:) 61 | forControlEvents:UIControlEventEditingChanged]; 62 | objc_setAssociatedObject(self, @selector(typesetBlock), [typesetBlock copy], OBJC_ASSOCIATION_COPY_NONATOMIC); 63 | } 64 | 65 | - (void)textFieldDidChange:(UITextField *)textField { 66 | if (textField.typesetBlock && textField.text) { 67 | textField.attributedText = textField.typesetBlock(textField.text); 68 | } 69 | } 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /Classes/UITextView+Typeset.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITextView+Typeset.h 3 | // Typeset 4 | // 5 | // Created by Draveness on 7/24/16. 6 | // Copyright © 2016 DeltaX. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UITextView (Typeset) 12 | 13 | @property (nonatomic, copy) NSAttributedString *(^typesetBlock)(NSString *string); 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Classes/UITextView+Typeset.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITextView+Typeset.m 3 | // Typeset 4 | // 5 | // Created by Draveness on 7/24/16. 6 | // Copyright © 2016 DeltaX. All rights reserved. 7 | // 8 | 9 | #import "UITextView+Typeset.h" 10 | #import 11 | #import 12 | 13 | @implementation UITextView (Typeset) 14 | 15 | + (void)load { 16 | static dispatch_once_t onceToken; 17 | dispatch_once(&onceToken, ^{ 18 | Class class = [self class]; 19 | 20 | SEL originalSelector = @selector(setText:); 21 | SEL swizzledSelector = @selector(typeset_setText:); 22 | 23 | Method originalMethod = class_getInstanceMethod(class, originalSelector); 24 | Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); 25 | 26 | BOOL didAddMethod = 27 | class_addMethod(class, 28 | originalSelector, 29 | method_getImplementation(swizzledMethod), 30 | method_getTypeEncoding(swizzledMethod)); 31 | 32 | if (didAddMethod) { 33 | class_replaceMethod(class, 34 | swizzledSelector, 35 | method_getImplementation(originalMethod), 36 | method_getTypeEncoding(originalMethod)); 37 | } else { 38 | method_exchangeImplementations(originalMethod, swizzledMethod); 39 | } 40 | }); 41 | 42 | } 43 | 44 | - (void)typeset_setText:(NSString *)text { 45 | if (self.typesetBlock && text) { 46 | self.attributedText = self.typesetBlock(text); 47 | } else { 48 | [self typeset_setText:text]; 49 | } 50 | } 51 | 52 | - (NSAttributedString *(^)(NSString *))typesetBlock { 53 | return objc_getAssociatedObject(self, @selector(typesetBlock)); 54 | } 55 | 56 | - (void)setTypesetBlock:(NSAttributedString *(^)(NSString *))typesetBlock { 57 | if (self.text && typesetBlock) self.attributedText = typesetBlock(self.text); 58 | 59 | // Call textViewDidChange: method when text changed 60 | [[NSNotificationCenter defaultCenter] addObserver:self 61 | selector:@selector(textViewDidChange:) 62 | name:UITextViewTextDidChangeNotification 63 | object:self]; 64 | 65 | objc_setAssociatedObject(self, @selector(typesetBlock), [typesetBlock copy], OBJC_ASSOCIATION_COPY_NONATOMIC); 66 | } 67 | 68 | - (void)textViewDidChange:(NSNotification *)notification { 69 | UITextView *textView = notification.object; 70 | 71 | if (textView.typesetBlock && textView.text) { 72 | textView.attributedText = textView.typesetBlock(textView.text); 73 | } 74 | } 75 | 76 | 77 | @end 78 | 79 | @interface UITextViewTypesetHelper : NSObject 80 | 81 | @end 82 | 83 | @implementation UITextViewTypesetHelper 84 | 85 | + (void)load { 86 | // Swizzle dealoc to remove observer when current object is deallocated. 87 | Class classToSwizzle = [UITextView class]; 88 | // NSString *className = NSStringFromClass(classToSwizzle); 89 | SEL deallocSelector = sel_registerName("dealloc"); 90 | 91 | __block void (*originalDealloc)(__unsafe_unretained id, SEL) = NULL; 92 | 93 | id newDealloc = ^(__unsafe_unretained id objSelf) { 94 | 95 | if (![objSelf respondsToSelector:@selector(removeObserver:)]) { 96 | return; 97 | } 98 | 99 | [objSelf removeObserver:self]; 100 | 101 | if (originalDealloc == NULL) { 102 | struct objc_super superInfo = { 103 | .receiver = objSelf, 104 | .super_class = class_getSuperclass(classToSwizzle) 105 | }; 106 | 107 | void (*msgSend)(struct objc_super *, SEL) = (__typeof__(msgSend))objc_msgSendSuper; 108 | msgSend(&superInfo, deallocSelector); 109 | } else { 110 | originalDealloc(objSelf, deallocSelector); 111 | } 112 | }; 113 | 114 | IMP newDeallocIMP = imp_implementationWithBlock(newDealloc); 115 | 116 | if (!class_addMethod(classToSwizzle, deallocSelector, newDeallocIMP, "v@:")) { 117 | // The class already contains a method implementation. 118 | Method deallocMethod = class_getInstanceMethod(classToSwizzle, deallocSelector); 119 | 120 | // We need to store original implementation before setting new implementation 121 | // in case method is called at the time of setting. 122 | originalDealloc = (void(*)(__unsafe_unretained id, SEL))method_getImplementation(deallocMethod); 123 | 124 | // We need to store original implementation again, in case it just changed. 125 | originalDealloc = (void(*)(__unsafe_unretained id, SEL))method_setImplementation(deallocMethod, newDeallocIMP); 126 | } 127 | } 128 | 129 | @end 130 | -------------------------------------------------------------------------------- /Classes/metamacros.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Macros for metaprogramming 3 | * ExtendedC 4 | * 5 | * Copyright (C) 2012 Justin Spahr-Summers 6 | * Released under the MIT license 7 | */ 8 | 9 | #ifndef EXTC_METAMACROS_H 10 | #define EXTC_METAMACROS_H 11 | 12 | 13 | /** 14 | * Executes one or more expressions (which may have a void type, such as a call 15 | * to a function that returns no value) and always returns true. 16 | */ 17 | #define metamacro_exprify(...) \ 18 | ((__VA_ARGS__), true) 19 | 20 | /** 21 | * Returns a string representation of VALUE after full macro expansion. 22 | */ 23 | #define metamacro_stringify(VALUE) \ 24 | metamacro_stringify_(VALUE) 25 | 26 | /** 27 | * Returns A and B concatenated after full macro expansion. 28 | */ 29 | #define metamacro_concat(A, B) \ 30 | metamacro_concat_(A, B) 31 | 32 | /** 33 | * Returns the Nth variadic argument (starting from zero). At least 34 | * N + 1 variadic arguments must be given. N must be between zero and twenty, 35 | * inclusive. 36 | */ 37 | #define metamacro_at(N, ...) \ 38 | metamacro_concat(metamacro_at, N)(__VA_ARGS__) 39 | 40 | /** 41 | * Returns the number of arguments (up to twenty) provided to the macro. At 42 | * least one argument must be provided. 43 | * 44 | * Inspired by P99: http://p99.gforge.inria.fr 45 | */ 46 | #define metamacro_argcount(...) \ 47 | metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 48 | 49 | /** 50 | * Identical to #metamacro_foreach_cxt, except that no CONTEXT argument is 51 | * given. Only the index and current argument will thus be passed to MACRO. 52 | */ 53 | #define metamacro_foreach(MACRO, SEP, ...) \ 54 | metamacro_foreach_cxt(metamacro_foreach_iter, SEP, MACRO, __VA_ARGS__) 55 | 56 | /** 57 | * For each consecutive variadic argument (up to twenty), MACRO is passed the 58 | * zero-based index of the current argument, CONTEXT, and then the argument 59 | * itself. The results of adjoining invocations of MACRO are then separated by 60 | * SEP. 61 | * 62 | * Inspired by P99: http://p99.gforge.inria.fr 63 | */ 64 | #define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \ 65 | metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__) 66 | 67 | /** 68 | * Identical to #metamacro_foreach_cxt. This can be used when the former would 69 | * fail due to recursive macro expansion. 70 | */ 71 | #define metamacro_foreach_cxt_recursive(MACRO, SEP, CONTEXT, ...) \ 72 | metamacro_concat(metamacro_foreach_cxt_recursive, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__) 73 | 74 | /** 75 | * In consecutive order, appends each variadic argument (up to twenty) onto 76 | * BASE. The resulting concatenations are then separated by SEP. 77 | * 78 | * This is primarily useful to manipulate a list of macro invocations into instead 79 | * invoking a different, possibly related macro. 80 | */ 81 | #define metamacro_foreach_concat(BASE, SEP, ...) \ 82 | metamacro_foreach_cxt(metamacro_foreach_concat_iter, SEP, BASE, __VA_ARGS__) 83 | 84 | /** 85 | * Iterates COUNT times, each time invoking MACRO with the current index 86 | * (starting at zero) and CONTEXT. The results of adjoining invocations of MACRO 87 | * are then separated by SEP. 88 | * 89 | * COUNT must be an integer between zero and twenty, inclusive. 90 | */ 91 | #define metamacro_for_cxt(COUNT, MACRO, SEP, CONTEXT) \ 92 | metamacro_concat(metamacro_for_cxt, COUNT)(MACRO, SEP, CONTEXT) 93 | 94 | /** 95 | * Returns the first argument given. At least one argument must be provided. 96 | * 97 | * This is useful when implementing a variadic macro, where you may have only 98 | * one variadic argument, but no way to retrieve it (for example, because \c ... 99 | * always needs to match at least one argument). 100 | * 101 | * @code 102 | 103 | #define varmacro(...) \ 104 | metamacro_head(__VA_ARGS__) 105 | 106 | * @endcode 107 | */ 108 | #define metamacro_head(...) \ 109 | metamacro_head_(__VA_ARGS__, 0) 110 | 111 | /** 112 | * Returns every argument except the first. At least two arguments must be 113 | * provided. 114 | */ 115 | #define metamacro_tail(...) \ 116 | metamacro_tail_(__VA_ARGS__) 117 | 118 | /** 119 | * Returns the first N (up to twenty) variadic arguments as a new argument list. 120 | * At least N variadic arguments must be provided. 121 | */ 122 | #define metamacro_take(N, ...) \ 123 | metamacro_concat(metamacro_take, N)(__VA_ARGS__) 124 | 125 | /** 126 | * Removes the first N (up to twenty) variadic arguments from the given argument 127 | * list. At least N variadic arguments must be provided. 128 | */ 129 | #define metamacro_drop(N, ...) \ 130 | metamacro_concat(metamacro_drop, N)(__VA_ARGS__) 131 | 132 | /** 133 | * Decrements VAL, which must be a number between zero and twenty, inclusive. 134 | * 135 | * This is primarily useful when dealing with indexes and counts in 136 | * metaprogramming. 137 | */ 138 | #define metamacro_dec(VAL) \ 139 | metamacro_at(VAL, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) 140 | 141 | /** 142 | * Increments VAL, which must be a number between zero and twenty, inclusive. 143 | * 144 | * This is primarily useful when dealing with indexes and counts in 145 | * metaprogramming. 146 | */ 147 | #define metamacro_inc(VAL) \ 148 | metamacro_at(VAL, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) 149 | 150 | /** 151 | * If A is equal to B, the next argument list is expanded; otherwise, the 152 | * argument list after that is expanded. A and B must be numbers between zero 153 | * and twenty, inclusive. Additionally, B must be greater than or equal to A. 154 | * 155 | * @code 156 | 157 | // expands to true 158 | metamacro_if_eq(0, 0)(true)(false) 159 | 160 | // expands to false 161 | metamacro_if_eq(0, 1)(true)(false) 162 | 163 | * @endcode 164 | * 165 | * This is primarily useful when dealing with indexes and counts in 166 | * metaprogramming. 167 | */ 168 | #define metamacro_if_eq(A, B) \ 169 | metamacro_concat(metamacro_if_eq, A)(B) 170 | 171 | /** 172 | * Identical to #metamacro_if_eq. This can be used when the former would fail 173 | * due to recursive macro expansion. 174 | */ 175 | #define metamacro_if_eq_recursive(A, B) \ 176 | metamacro_concat(metamacro_if_eq_recursive, A)(B) 177 | 178 | /** 179 | * Returns 1 if N is an even number, or 0 otherwise. N must be between zero and 180 | * twenty, inclusive. 181 | * 182 | * For the purposes of this test, zero is considered even. 183 | */ 184 | #define metamacro_is_even(N) \ 185 | metamacro_at(N, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1) 186 | 187 | /** 188 | * Returns the logical NOT of B, which must be the number zero or one. 189 | */ 190 | #define metamacro_not(B) \ 191 | metamacro_at(B, 1, 0) 192 | 193 | // IMPLEMENTATION DETAILS FOLLOW! 194 | // Do not write code that depends on anything below this line. 195 | #define metamacro_stringify_(VALUE) # VALUE 196 | #define metamacro_concat_(A, B) A ## B 197 | #define metamacro_foreach_iter(INDEX, MACRO, ARG) MACRO(INDEX, ARG) 198 | #define metamacro_head_(FIRST, ...) FIRST 199 | #define metamacro_tail_(FIRST, ...) __VA_ARGS__ 200 | #define metamacro_consume_(...) 201 | #define metamacro_expand_(...) __VA_ARGS__ 202 | 203 | // implemented from scratch so that metamacro_concat() doesn't end up nesting 204 | #define metamacro_foreach_concat_iter(INDEX, BASE, ARG) metamacro_foreach_concat_iter_(BASE, ARG) 205 | #define metamacro_foreach_concat_iter_(BASE, ARG) BASE ## ARG 206 | 207 | // metamacro_at expansions 208 | #define metamacro_at0(...) metamacro_head(__VA_ARGS__) 209 | #define metamacro_at1(_0, ...) metamacro_head(__VA_ARGS__) 210 | #define metamacro_at2(_0, _1, ...) metamacro_head(__VA_ARGS__) 211 | #define metamacro_at3(_0, _1, _2, ...) metamacro_head(__VA_ARGS__) 212 | #define metamacro_at4(_0, _1, _2, _3, ...) metamacro_head(__VA_ARGS__) 213 | #define metamacro_at5(_0, _1, _2, _3, _4, ...) metamacro_head(__VA_ARGS__) 214 | #define metamacro_at6(_0, _1, _2, _3, _4, _5, ...) metamacro_head(__VA_ARGS__) 215 | #define metamacro_at7(_0, _1, _2, _3, _4, _5, _6, ...) metamacro_head(__VA_ARGS__) 216 | #define metamacro_at8(_0, _1, _2, _3, _4, _5, _6, _7, ...) metamacro_head(__VA_ARGS__) 217 | #define metamacro_at9(_0, _1, _2, _3, _4, _5, _6, _7, _8, ...) metamacro_head(__VA_ARGS__) 218 | #define metamacro_at10(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) metamacro_head(__VA_ARGS__) 219 | #define metamacro_at11(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) metamacro_head(__VA_ARGS__) 220 | #define metamacro_at12(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) metamacro_head(__VA_ARGS__) 221 | #define metamacro_at13(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, ...) metamacro_head(__VA_ARGS__) 222 | #define metamacro_at14(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, ...) metamacro_head(__VA_ARGS__) 223 | #define metamacro_at15(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, ...) metamacro_head(__VA_ARGS__) 224 | #define metamacro_at16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) metamacro_head(__VA_ARGS__) 225 | #define metamacro_at17(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) metamacro_head(__VA_ARGS__) 226 | #define metamacro_at18(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, ...) metamacro_head(__VA_ARGS__) 227 | #define metamacro_at19(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, ...) metamacro_head(__VA_ARGS__) 228 | #define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) metamacro_head(__VA_ARGS__) 229 | 230 | // metamacro_foreach_cxt expansions 231 | #define metamacro_foreach_cxt0(MACRO, SEP, CONTEXT) 232 | #define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0) 233 | 234 | #define metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \ 235 | metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) \ 236 | SEP \ 237 | MACRO(1, CONTEXT, _1) 238 | 239 | #define metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \ 240 | metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \ 241 | SEP \ 242 | MACRO(2, CONTEXT, _2) 243 | 244 | #define metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ 245 | metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \ 246 | SEP \ 247 | MACRO(3, CONTEXT, _3) 248 | 249 | #define metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ 250 | metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ 251 | SEP \ 252 | MACRO(4, CONTEXT, _4) 253 | 254 | #define metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ 255 | metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ 256 | SEP \ 257 | MACRO(5, CONTEXT, _5) 258 | 259 | #define metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ 260 | metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ 261 | SEP \ 262 | MACRO(6, CONTEXT, _6) 263 | 264 | #define metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ 265 | metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ 266 | SEP \ 267 | MACRO(7, CONTEXT, _7) 268 | 269 | #define metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ 270 | metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ 271 | SEP \ 272 | MACRO(8, CONTEXT, _8) 273 | 274 | #define metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ 275 | metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ 276 | SEP \ 277 | MACRO(9, CONTEXT, _9) 278 | 279 | #define metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ 280 | metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ 281 | SEP \ 282 | MACRO(10, CONTEXT, _10) 283 | 284 | #define metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ 285 | metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ 286 | SEP \ 287 | MACRO(11, CONTEXT, _11) 288 | 289 | #define metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ 290 | metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ 291 | SEP \ 292 | MACRO(12, CONTEXT, _12) 293 | 294 | #define metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ 295 | metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ 296 | SEP \ 297 | MACRO(13, CONTEXT, _13) 298 | 299 | #define metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ 300 | metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ 301 | SEP \ 302 | MACRO(14, CONTEXT, _14) 303 | 304 | #define metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ 305 | metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ 306 | SEP \ 307 | MACRO(15, CONTEXT, _15) 308 | 309 | #define metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ 310 | metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ 311 | SEP \ 312 | MACRO(16, CONTEXT, _16) 313 | 314 | #define metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ 315 | metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ 316 | SEP \ 317 | MACRO(17, CONTEXT, _17) 318 | 319 | #define metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ 320 | metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ 321 | SEP \ 322 | MACRO(18, CONTEXT, _18) 323 | 324 | #define metamacro_foreach_cxt20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \ 325 | metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ 326 | SEP \ 327 | MACRO(19, CONTEXT, _19) 328 | 329 | // metamacro_foreach_cxt_recursive expansions 330 | #define metamacro_foreach_cxt_recursive0(MACRO, SEP, CONTEXT) 331 | #define metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0) 332 | 333 | #define metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \ 334 | metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) \ 335 | SEP \ 336 | MACRO(1, CONTEXT, _1) 337 | 338 | #define metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \ 339 | metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \ 340 | SEP \ 341 | MACRO(2, CONTEXT, _2) 342 | 343 | #define metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ 344 | metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \ 345 | SEP \ 346 | MACRO(3, CONTEXT, _3) 347 | 348 | #define metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ 349 | metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ 350 | SEP \ 351 | MACRO(4, CONTEXT, _4) 352 | 353 | #define metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ 354 | metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ 355 | SEP \ 356 | MACRO(5, CONTEXT, _5) 357 | 358 | #define metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ 359 | metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ 360 | SEP \ 361 | MACRO(6, CONTEXT, _6) 362 | 363 | #define metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ 364 | metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ 365 | SEP \ 366 | MACRO(7, CONTEXT, _7) 367 | 368 | #define metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ 369 | metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ 370 | SEP \ 371 | MACRO(8, CONTEXT, _8) 372 | 373 | #define metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ 374 | metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ 375 | SEP \ 376 | MACRO(9, CONTEXT, _9) 377 | 378 | #define metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ 379 | metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ 380 | SEP \ 381 | MACRO(10, CONTEXT, _10) 382 | 383 | #define metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ 384 | metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ 385 | SEP \ 386 | MACRO(11, CONTEXT, _11) 387 | 388 | #define metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ 389 | metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ 390 | SEP \ 391 | MACRO(12, CONTEXT, _12) 392 | 393 | #define metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ 394 | metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ 395 | SEP \ 396 | MACRO(13, CONTEXT, _13) 397 | 398 | #define metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ 399 | metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ 400 | SEP \ 401 | MACRO(14, CONTEXT, _14) 402 | 403 | #define metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ 404 | metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ 405 | SEP \ 406 | MACRO(15, CONTEXT, _15) 407 | 408 | #define metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ 409 | metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ 410 | SEP \ 411 | MACRO(16, CONTEXT, _16) 412 | 413 | #define metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ 414 | metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ 415 | SEP \ 416 | MACRO(17, CONTEXT, _17) 417 | 418 | #define metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ 419 | metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ 420 | SEP \ 421 | MACRO(18, CONTEXT, _18) 422 | 423 | #define metamacro_foreach_cxt_recursive20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \ 424 | metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ 425 | SEP \ 426 | MACRO(19, CONTEXT, _19) 427 | 428 | // metamacro_for_cxt expansions 429 | #define metamacro_for_cxt0(MACRO, SEP, CONTEXT) 430 | #define metamacro_for_cxt1(MACRO, SEP, CONTEXT) MACRO(0, CONTEXT) 431 | 432 | #define metamacro_for_cxt2(MACRO, SEP, CONTEXT) \ 433 | metamacro_for_cxt1(MACRO, SEP, CONTEXT) \ 434 | SEP \ 435 | MACRO(1, CONTEXT) 436 | 437 | #define metamacro_for_cxt3(MACRO, SEP, CONTEXT) \ 438 | metamacro_for_cxt2(MACRO, SEP, CONTEXT) \ 439 | SEP \ 440 | MACRO(2, CONTEXT) 441 | 442 | #define metamacro_for_cxt4(MACRO, SEP, CONTEXT) \ 443 | metamacro_for_cxt3(MACRO, SEP, CONTEXT) \ 444 | SEP \ 445 | MACRO(3, CONTEXT) 446 | 447 | #define metamacro_for_cxt5(MACRO, SEP, CONTEXT) \ 448 | metamacro_for_cxt4(MACRO, SEP, CONTEXT) \ 449 | SEP \ 450 | MACRO(4, CONTEXT) 451 | 452 | #define metamacro_for_cxt6(MACRO, SEP, CONTEXT) \ 453 | metamacro_for_cxt5(MACRO, SEP, CONTEXT) \ 454 | SEP \ 455 | MACRO(5, CONTEXT) 456 | 457 | #define metamacro_for_cxt7(MACRO, SEP, CONTEXT) \ 458 | metamacro_for_cxt6(MACRO, SEP, CONTEXT) \ 459 | SEP \ 460 | MACRO(6, CONTEXT) 461 | 462 | #define metamacro_for_cxt8(MACRO, SEP, CONTEXT) \ 463 | metamacro_for_cxt7(MACRO, SEP, CONTEXT) \ 464 | SEP \ 465 | MACRO(7, CONTEXT) 466 | 467 | #define metamacro_for_cxt9(MACRO, SEP, CONTEXT) \ 468 | metamacro_for_cxt8(MACRO, SEP, CONTEXT) \ 469 | SEP \ 470 | MACRO(8, CONTEXT) 471 | 472 | #define metamacro_for_cxt10(MACRO, SEP, CONTEXT) \ 473 | metamacro_for_cxt9(MACRO, SEP, CONTEXT) \ 474 | SEP \ 475 | MACRO(9, CONTEXT) 476 | 477 | #define metamacro_for_cxt11(MACRO, SEP, CONTEXT) \ 478 | metamacro_for_cxt10(MACRO, SEP, CONTEXT) \ 479 | SEP \ 480 | MACRO(10, CONTEXT) 481 | 482 | #define metamacro_for_cxt12(MACRO, SEP, CONTEXT) \ 483 | metamacro_for_cxt11(MACRO, SEP, CONTEXT) \ 484 | SEP \ 485 | MACRO(11, CONTEXT) 486 | 487 | #define metamacro_for_cxt13(MACRO, SEP, CONTEXT) \ 488 | metamacro_for_cxt12(MACRO, SEP, CONTEXT) \ 489 | SEP \ 490 | MACRO(12, CONTEXT) 491 | 492 | #define metamacro_for_cxt14(MACRO, SEP, CONTEXT) \ 493 | metamacro_for_cxt13(MACRO, SEP, CONTEXT) \ 494 | SEP \ 495 | MACRO(13, CONTEXT) 496 | 497 | #define metamacro_for_cxt15(MACRO, SEP, CONTEXT) \ 498 | metamacro_for_cxt14(MACRO, SEP, CONTEXT) \ 499 | SEP \ 500 | MACRO(14, CONTEXT) 501 | 502 | #define metamacro_for_cxt16(MACRO, SEP, CONTEXT) \ 503 | metamacro_for_cxt15(MACRO, SEP, CONTEXT) \ 504 | SEP \ 505 | MACRO(15, CONTEXT) 506 | 507 | #define metamacro_for_cxt17(MACRO, SEP, CONTEXT) \ 508 | metamacro_for_cxt16(MACRO, SEP, CONTEXT) \ 509 | SEP \ 510 | MACRO(16, CONTEXT) 511 | 512 | #define metamacro_for_cxt18(MACRO, SEP, CONTEXT) \ 513 | metamacro_for_cxt17(MACRO, SEP, CONTEXT) \ 514 | SEP \ 515 | MACRO(17, CONTEXT) 516 | 517 | #define metamacro_for_cxt19(MACRO, SEP, CONTEXT) \ 518 | metamacro_for_cxt18(MACRO, SEP, CONTEXT) \ 519 | SEP \ 520 | MACRO(18, CONTEXT) 521 | 522 | #define metamacro_for_cxt20(MACRO, SEP, CONTEXT) \ 523 | metamacro_for_cxt19(MACRO, SEP, CONTEXT) \ 524 | SEP \ 525 | MACRO(19, CONTEXT) 526 | 527 | // metamacro_if_eq expansions 528 | #define metamacro_if_eq0(VALUE) \ 529 | metamacro_concat(metamacro_if_eq0_, VALUE) 530 | 531 | #define metamacro_if_eq0_0(...) __VA_ARGS__ metamacro_consume_ 532 | #define metamacro_if_eq0_1(...) metamacro_expand_ 533 | #define metamacro_if_eq0_2(...) metamacro_expand_ 534 | #define metamacro_if_eq0_3(...) metamacro_expand_ 535 | #define metamacro_if_eq0_4(...) metamacro_expand_ 536 | #define metamacro_if_eq0_5(...) metamacro_expand_ 537 | #define metamacro_if_eq0_6(...) metamacro_expand_ 538 | #define metamacro_if_eq0_7(...) metamacro_expand_ 539 | #define metamacro_if_eq0_8(...) metamacro_expand_ 540 | #define metamacro_if_eq0_9(...) metamacro_expand_ 541 | #define metamacro_if_eq0_10(...) metamacro_expand_ 542 | #define metamacro_if_eq0_11(...) metamacro_expand_ 543 | #define metamacro_if_eq0_12(...) metamacro_expand_ 544 | #define metamacro_if_eq0_13(...) metamacro_expand_ 545 | #define metamacro_if_eq0_14(...) metamacro_expand_ 546 | #define metamacro_if_eq0_15(...) metamacro_expand_ 547 | #define metamacro_if_eq0_16(...) metamacro_expand_ 548 | #define metamacro_if_eq0_17(...) metamacro_expand_ 549 | #define metamacro_if_eq0_18(...) metamacro_expand_ 550 | #define metamacro_if_eq0_19(...) metamacro_expand_ 551 | #define metamacro_if_eq0_20(...) metamacro_expand_ 552 | 553 | #define metamacro_if_eq1(VALUE) metamacro_if_eq0(metamacro_dec(VALUE)) 554 | #define metamacro_if_eq2(VALUE) metamacro_if_eq1(metamacro_dec(VALUE)) 555 | #define metamacro_if_eq3(VALUE) metamacro_if_eq2(metamacro_dec(VALUE)) 556 | #define metamacro_if_eq4(VALUE) metamacro_if_eq3(metamacro_dec(VALUE)) 557 | #define metamacro_if_eq5(VALUE) metamacro_if_eq4(metamacro_dec(VALUE)) 558 | #define metamacro_if_eq6(VALUE) metamacro_if_eq5(metamacro_dec(VALUE)) 559 | #define metamacro_if_eq7(VALUE) metamacro_if_eq6(metamacro_dec(VALUE)) 560 | #define metamacro_if_eq8(VALUE) metamacro_if_eq7(metamacro_dec(VALUE)) 561 | #define metamacro_if_eq9(VALUE) metamacro_if_eq8(metamacro_dec(VALUE)) 562 | #define metamacro_if_eq10(VALUE) metamacro_if_eq9(metamacro_dec(VALUE)) 563 | #define metamacro_if_eq11(VALUE) metamacro_if_eq10(metamacro_dec(VALUE)) 564 | #define metamacro_if_eq12(VALUE) metamacro_if_eq11(metamacro_dec(VALUE)) 565 | #define metamacro_if_eq13(VALUE) metamacro_if_eq12(metamacro_dec(VALUE)) 566 | #define metamacro_if_eq14(VALUE) metamacro_if_eq13(metamacro_dec(VALUE)) 567 | #define metamacro_if_eq15(VALUE) metamacro_if_eq14(metamacro_dec(VALUE)) 568 | #define metamacro_if_eq16(VALUE) metamacro_if_eq15(metamacro_dec(VALUE)) 569 | #define metamacro_if_eq17(VALUE) metamacro_if_eq16(metamacro_dec(VALUE)) 570 | #define metamacro_if_eq18(VALUE) metamacro_if_eq17(metamacro_dec(VALUE)) 571 | #define metamacro_if_eq19(VALUE) metamacro_if_eq18(metamacro_dec(VALUE)) 572 | #define metamacro_if_eq20(VALUE) metamacro_if_eq19(metamacro_dec(VALUE)) 573 | 574 | // metamacro_if_eq_recursive expansions 575 | #define metamacro_if_eq_recursive0(VALUE) \ 576 | metamacro_concat(metamacro_if_eq_recursive0_, VALUE) 577 | 578 | #define metamacro_if_eq_recursive0_0(...) __VA_ARGS__ metamacro_consume_ 579 | #define metamacro_if_eq_recursive0_1(...) metamacro_expand_ 580 | #define metamacro_if_eq_recursive0_2(...) metamacro_expand_ 581 | #define metamacro_if_eq_recursive0_3(...) metamacro_expand_ 582 | #define metamacro_if_eq_recursive0_4(...) metamacro_expand_ 583 | #define metamacro_if_eq_recursive0_5(...) metamacro_expand_ 584 | #define metamacro_if_eq_recursive0_6(...) metamacro_expand_ 585 | #define metamacro_if_eq_recursive0_7(...) metamacro_expand_ 586 | #define metamacro_if_eq_recursive0_8(...) metamacro_expand_ 587 | #define metamacro_if_eq_recursive0_9(...) metamacro_expand_ 588 | #define metamacro_if_eq_recursive0_10(...) metamacro_expand_ 589 | #define metamacro_if_eq_recursive0_11(...) metamacro_expand_ 590 | #define metamacro_if_eq_recursive0_12(...) metamacro_expand_ 591 | #define metamacro_if_eq_recursive0_13(...) metamacro_expand_ 592 | #define metamacro_if_eq_recursive0_14(...) metamacro_expand_ 593 | #define metamacro_if_eq_recursive0_15(...) metamacro_expand_ 594 | #define metamacro_if_eq_recursive0_16(...) metamacro_expand_ 595 | #define metamacro_if_eq_recursive0_17(...) metamacro_expand_ 596 | #define metamacro_if_eq_recursive0_18(...) metamacro_expand_ 597 | #define metamacro_if_eq_recursive0_19(...) metamacro_expand_ 598 | #define metamacro_if_eq_recursive0_20(...) metamacro_expand_ 599 | 600 | #define metamacro_if_eq_recursive1(VALUE) metamacro_if_eq_recursive0(metamacro_dec(VALUE)) 601 | #define metamacro_if_eq_recursive2(VALUE) metamacro_if_eq_recursive1(metamacro_dec(VALUE)) 602 | #define metamacro_if_eq_recursive3(VALUE) metamacro_if_eq_recursive2(metamacro_dec(VALUE)) 603 | #define metamacro_if_eq_recursive4(VALUE) metamacro_if_eq_recursive3(metamacro_dec(VALUE)) 604 | #define metamacro_if_eq_recursive5(VALUE) metamacro_if_eq_recursive4(metamacro_dec(VALUE)) 605 | #define metamacro_if_eq_recursive6(VALUE) metamacro_if_eq_recursive5(metamacro_dec(VALUE)) 606 | #define metamacro_if_eq_recursive7(VALUE) metamacro_if_eq_recursive6(metamacro_dec(VALUE)) 607 | #define metamacro_if_eq_recursive8(VALUE) metamacro_if_eq_recursive7(metamacro_dec(VALUE)) 608 | #define metamacro_if_eq_recursive9(VALUE) metamacro_if_eq_recursive8(metamacro_dec(VALUE)) 609 | #define metamacro_if_eq_recursive10(VALUE) metamacro_if_eq_recursive9(metamacro_dec(VALUE)) 610 | #define metamacro_if_eq_recursive11(VALUE) metamacro_if_eq_recursive10(metamacro_dec(VALUE)) 611 | #define metamacro_if_eq_recursive12(VALUE) metamacro_if_eq_recursive11(metamacro_dec(VALUE)) 612 | #define metamacro_if_eq_recursive13(VALUE) metamacro_if_eq_recursive12(metamacro_dec(VALUE)) 613 | #define metamacro_if_eq_recursive14(VALUE) metamacro_if_eq_recursive13(metamacro_dec(VALUE)) 614 | #define metamacro_if_eq_recursive15(VALUE) metamacro_if_eq_recursive14(metamacro_dec(VALUE)) 615 | #define metamacro_if_eq_recursive16(VALUE) metamacro_if_eq_recursive15(metamacro_dec(VALUE)) 616 | #define metamacro_if_eq_recursive17(VALUE) metamacro_if_eq_recursive16(metamacro_dec(VALUE)) 617 | #define metamacro_if_eq_recursive18(VALUE) metamacro_if_eq_recursive17(metamacro_dec(VALUE)) 618 | #define metamacro_if_eq_recursive19(VALUE) metamacro_if_eq_recursive18(metamacro_dec(VALUE)) 619 | #define metamacro_if_eq_recursive20(VALUE) metamacro_if_eq_recursive19(metamacro_dec(VALUE)) 620 | 621 | // metamacro_take expansions 622 | #define metamacro_take0(...) 623 | #define metamacro_take1(...) metamacro_head(__VA_ARGS__) 624 | #define metamacro_take2(...) metamacro_head(__VA_ARGS__), metamacro_take1(metamacro_tail(__VA_ARGS__)) 625 | #define metamacro_take3(...) metamacro_head(__VA_ARGS__), metamacro_take2(metamacro_tail(__VA_ARGS__)) 626 | #define metamacro_take4(...) metamacro_head(__VA_ARGS__), metamacro_take3(metamacro_tail(__VA_ARGS__)) 627 | #define metamacro_take5(...) metamacro_head(__VA_ARGS__), metamacro_take4(metamacro_tail(__VA_ARGS__)) 628 | #define metamacro_take6(...) metamacro_head(__VA_ARGS__), metamacro_take5(metamacro_tail(__VA_ARGS__)) 629 | #define metamacro_take7(...) metamacro_head(__VA_ARGS__), metamacro_take6(metamacro_tail(__VA_ARGS__)) 630 | #define metamacro_take8(...) metamacro_head(__VA_ARGS__), metamacro_take7(metamacro_tail(__VA_ARGS__)) 631 | #define metamacro_take9(...) metamacro_head(__VA_ARGS__), metamacro_take8(metamacro_tail(__VA_ARGS__)) 632 | #define metamacro_take10(...) metamacro_head(__VA_ARGS__), metamacro_take9(metamacro_tail(__VA_ARGS__)) 633 | #define metamacro_take11(...) metamacro_head(__VA_ARGS__), metamacro_take10(metamacro_tail(__VA_ARGS__)) 634 | #define metamacro_take12(...) metamacro_head(__VA_ARGS__), metamacro_take11(metamacro_tail(__VA_ARGS__)) 635 | #define metamacro_take13(...) metamacro_head(__VA_ARGS__), metamacro_take12(metamacro_tail(__VA_ARGS__)) 636 | #define metamacro_take14(...) metamacro_head(__VA_ARGS__), metamacro_take13(metamacro_tail(__VA_ARGS__)) 637 | #define metamacro_take15(...) metamacro_head(__VA_ARGS__), metamacro_take14(metamacro_tail(__VA_ARGS__)) 638 | #define metamacro_take16(...) metamacro_head(__VA_ARGS__), metamacro_take15(metamacro_tail(__VA_ARGS__)) 639 | #define metamacro_take17(...) metamacro_head(__VA_ARGS__), metamacro_take16(metamacro_tail(__VA_ARGS__)) 640 | #define metamacro_take18(...) metamacro_head(__VA_ARGS__), metamacro_take17(metamacro_tail(__VA_ARGS__)) 641 | #define metamacro_take19(...) metamacro_head(__VA_ARGS__), metamacro_take18(metamacro_tail(__VA_ARGS__)) 642 | #define metamacro_take20(...) metamacro_head(__VA_ARGS__), metamacro_take19(metamacro_tail(__VA_ARGS__)) 643 | 644 | // metamacro_drop expansions 645 | #define metamacro_drop0(...) __VA_ARGS__ 646 | #define metamacro_drop1(...) metamacro_tail(__VA_ARGS__) 647 | #define metamacro_drop2(...) metamacro_drop1(metamacro_tail(__VA_ARGS__)) 648 | #define metamacro_drop3(...) metamacro_drop2(metamacro_tail(__VA_ARGS__)) 649 | #define metamacro_drop4(...) metamacro_drop3(metamacro_tail(__VA_ARGS__)) 650 | #define metamacro_drop5(...) metamacro_drop4(metamacro_tail(__VA_ARGS__)) 651 | #define metamacro_drop6(...) metamacro_drop5(metamacro_tail(__VA_ARGS__)) 652 | #define metamacro_drop7(...) metamacro_drop6(metamacro_tail(__VA_ARGS__)) 653 | #define metamacro_drop8(...) metamacro_drop7(metamacro_tail(__VA_ARGS__)) 654 | #define metamacro_drop9(...) metamacro_drop8(metamacro_tail(__VA_ARGS__)) 655 | #define metamacro_drop10(...) metamacro_drop9(metamacro_tail(__VA_ARGS__)) 656 | #define metamacro_drop11(...) metamacro_drop10(metamacro_tail(__VA_ARGS__)) 657 | #define metamacro_drop12(...) metamacro_drop11(metamacro_tail(__VA_ARGS__)) 658 | #define metamacro_drop13(...) metamacro_drop12(metamacro_tail(__VA_ARGS__)) 659 | #define metamacro_drop14(...) metamacro_drop13(metamacro_tail(__VA_ARGS__)) 660 | #define metamacro_drop15(...) metamacro_drop14(metamacro_tail(__VA_ARGS__)) 661 | #define metamacro_drop16(...) metamacro_drop15(metamacro_tail(__VA_ARGS__)) 662 | #define metamacro_drop17(...) metamacro_drop16(metamacro_tail(__VA_ARGS__)) 663 | #define metamacro_drop18(...) metamacro_drop17(metamacro_tail(__VA_ARGS__)) 664 | #define metamacro_drop19(...) metamacro_drop18(metamacro_tail(__VA_ARGS__)) 665 | #define metamacro_drop20(...) metamacro_drop19(metamacro_tail(__VA_ARGS__)) 666 | 667 | #endif 668 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Draveness 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | [![Version](http://img.shields.io/cocoapods/v/Typeset.svg?style=flat)](http://cocoadocs.org/docsets/Typeset) [![Build Status](https://travis-ci.org/Draveness/Typeset.svg?branch=1.0.0)](https://travis-ci.org/Draveness/Typeset) ![MIT License](https://img.shields.io/github/license/mashape/apistatus.svg) ![Platform](https://img.shields.io/badge/platform-%20iOS%20-lightgrey.svg) 6 | 7 | ---- 8 | 9 | Typeset makes it easy to create `NSAttributedString` 10 | 11 | ``` 12 | @"Hello typeset".typeset 13 | .match(@"Hello").fontSize(40) 14 | .match(@"type").purple 15 | .match(@"set").blue 16 | .string; 17 | ``` 18 | 19 | # Demo 20 | 21 | ![](./images/Typeset.gif) 22 | 23 | 24 | # Usage 25 | 26 | + Method chaining 27 | + All the method for typeset returns a `self` object to chaining itself. 28 | 29 | ``` 30 | @"Hello typeset".typeset 31 | .match(@"Hello").fontSize(40) 32 | .match(@"type").purple 33 | .match(@"set").blue 34 | .string; 35 | ``` 36 | 37 | > call `typeset` method first and call `string` at last returns a `NSAttributedString`. 38 | 39 | + `UILabel` and `UITextField` support 40 | + Add `typesetBlock` to UILabel or `UITextField`, and you can directly set it's text style with: 41 | 42 | ```objectivec 43 | label.typesetBlock = TSBlock(fontSize(40) 44 | .match(@"type").purple 45 | .match(@"set").blue); 46 | label.text = @"Hello typeset, hello."; 47 | 48 | // If you type in this text field, it will color all the `1` in text field to red 49 | textField.typesetBlock = TSBlock(match(@"1").red); 50 | ``` 51 | 52 | + Construct complicated `NSMutableAttributedString` 53 | 54 | ```objectivec 55 | TSAttributedString(@"Hello".red, @" ", @"World".blue); 56 | ``` 57 | 58 | + Match part of string 59 | + Typeset providing a series of method to match part of your string, you can use these method to select part of your string, and add attribute to it. 60 | 61 | ```objectivec 62 | @"Hello".typeset.from(0).to(2).red.string; 63 | @"Hello".typeset.location(0).length(2).red.string; 64 | @"Hello".typeset.range(NSMakeRange(0,2)).red.string; 65 | @"Hello".typeset.match(@"He").red.string; 66 | ``` 67 | 68 | > These lines of code all make `@"He"` of `@"Hello"` to red 69 | 70 | | Match Method | Explain | 71 | | ------------------------------------------------------ | ------------------------------------------------------ | 72 | | `from(NSUInteger)` `to(NSUInteger)` | | 73 | | `location(NSUInteger)` `length(NSUInteger)` | | 74 | | `range(NSRange)` | | 75 | | `match(NSString *)` | match the first substring | 76 | | `matchWithOptions(NSString *, NSStringCompareOptions)` | match the first substring with options | 77 | | `matchAll(NSString)` | match all the substring | 78 | | `matchAllWithOptions(NSString *, NSStringCompareOptions)`| match all the substring with options | 79 | | `all` | select all the string | 80 | 81 | + Match with pattern 82 | 83 | | Match Method | Pattern | 84 | | ------------------------------------------------------ | -------------------------- | 85 | | `matchAllWithPattern(NSString *pattern)` | | 86 | | `matchAllWithPatternAndOptions(NSString *pattern, NSRegularExpressionOptions options)` | | 87 | | `matchNumbers` | \d+ | 88 | | `matchLetters` | [a-zA-Z]+ | 89 | | `matchLanguage(NSString *language)` | \p{script=%@} | 90 | | `matchChinese` | \p{script=@"Han"} | 91 | 92 | + Convinient method 93 | + If you don't want to change some part of the string, and only want to **change the color or the font**, you call call these methods directly without calling `typeset` first 94 | 95 | ```objectivec 96 | @"Hello".red 97 | @"Hello".fontSize(20).red 98 | ``` 99 | 100 | 101 | ## References 102 | 103 | ### Attributes 104 | 105 | | Dictionary Key | `Typeset` Method | 106 | | ----------------------------------- | ------------------------------------------------------ | 107 | | `NSFontAttributeName` | `font(NSString fontName, CGFloat size)` | 108 | | | `fontSize(CGFloat size)` | 109 | | | `fontName(NSString name)` | 110 | | | `regular` `light` `italic` `thin` `bold` | 111 | | `NSForegroundColorAttributeName` | `color(UIColor color)` | 112 | | | `hexColor(CGFloat hexColor)` | 113 | | | `black` `darkGray` `lightGray` `white` `gray` `red` `green` `blue` `cyan` `yellow` `magenta` `orange` `purple` `brown` `clear` | 114 | | `NSKernAttributeName` | `kern(CGFloat kern)` | 115 | | `NSUnderlineStyleAttributeName` | `underline(NSUnderlineStyle underline)` | 116 | | `NSUnderlineColorAttributeName` | `underlineColor(UIColor *underlineColor)` | 117 | | `NSBaselineOffsetAttributeName` | `baseline(CGFloat baseline)` | 118 | | `NSStrikethroughStyleAttributeName` | `strikeThrough(NSUnderlineStyle strikeThrough)` | 119 | | `NSStrikethroughColorAttributeName` | `strikeThroughColor(UIColor *underlineColor)` | 120 | | `NSLinkAttributeName` | `link(NSString *url)` | 121 | | `NSLigatureAttributeName` | `ligature(NSUInteger ligature)` | 122 | | `NSStrokeColorAttributeName` | `strokeColor(UIColor *strokeColor)` | 123 | | `NSStrokeWidthAttributeName` | `strokeWidth(CGFloat strokeWidth)` | 124 | | `NSShadowAttributeName` | `shadow(NSShadow *shadow)` | 125 | | `NSTextEffectAttributeName` | `textEffect(NSString *textEffect)` | 126 | | `NSObliquenessAttributeName` | `obliqueness(CGFloat obliqueness)` | 127 | | `NSExpansionAttributeName` | `expansion(CGFloat expansion)` | 128 | 129 | ### NSParagraphStyle 130 | 131 | | `Typeset` Method | 132 | | ------------------------------------------------------ | 133 | | `lineBreakMode(NSLineBreakMode lineBreakMode)` | 134 | | `alignment(NSTextAlignment textAlignment)` | 135 | | `lineSpacing(CGFloat lineSpacing)` | 136 | | `paragraphSpacing(CGFloat paragraphSpacing)` | 137 | | `firstLineHeadIndent(CGFloat firstLineHeadIndent)` | 138 | | `headIndent(CGFloat headIndent)` | 139 | | `tailIndent(CGFloat tailIndent)` | 140 | | `minimumLineHeight(CGFloat minimumLineHeight)` | 141 | | `maximumLineHeight(CGFloat maximumLineHeight)` | 142 | | `lineHeightMultiple(CGFloat lineHeightMultiple)` | 143 | | `paragraphSpacingBefore(CGFloat paragraphSpacingBefore)` | 144 | | `hyphenationFactor(CGFloat hyphenationFactor)` | 145 | | `defaultTabInterval(CGFloat defaultTabInterval)` | 146 | | `baseWritingDirection(NSWritingDirection baseWritingDirection)`| 147 | | `allowsDefaultTighteningForTruncation(BOOL allowsDefaultTighteningForTruncation)`| 148 | 149 | ## Installation 150 | 151 | ### CocoaPods 152 | 153 | [CocoaPods](https://cocoapods.org/) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like Typeset in your projects. See the [Get Started section](https://cocoapods.org/#get_started) for more details. 154 | 155 | ## Podfile 156 | 157 | ``` 158 | pod "Typeset" 159 | ``` 160 | 161 | # Contribute 162 | 163 | Feel free to open an issue or pull request, if you need help or there is a bug. 164 | 165 | # Contact 166 | 167 | - Powered by [Draveness](http://github.com/draveness) 168 | 169 | # License 170 | 171 | Typeset is available under the MIT license. See the LICENSE file for more info. 172 | 173 | # Todo 174 | 175 | - Documentation 176 | - More features 177 | 178 | -------------------------------------------------------------------------------- /Typeset.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "Typeset" 3 | s.version = "3.4.1" 4 | s.summary = "An convenient and fast approach to create AttributedString" 5 | s.description = <<-DESC 6 | I create this repo, beacuse deal with NSAttributedString in ObjectiveC is so painful. And this project is inspired by ruby gem colorize. Use this to deal with string more easily. 7 | DESC 8 | 9 | s.homepage = "https://github.com/Draveness/Typeset" 10 | s.license = "MIT" 11 | s.author = { "Draveness" => "stark.draven@gmail.com" } 12 | s.platform = :ios, "6.0" 13 | 14 | s.source = { :git => "https://github.com/Draveness/Typeset.git", :tag => s.version } 15 | 16 | s.source_files = "Classes/*.{h,m}" 17 | # s.public_header_files = "Classes/Typeset.h" 18 | end 19 | -------------------------------------------------------------------------------- /Typeset.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 181B1A881B18124D00E9BEA3 /* NSValue+Range.m in Sources */ = {isa = PBXBuildFile; fileRef = 181B1A871B18124D00E9BEA3 /* NSValue+Range.m */; }; 11 | 183D50771B13F8110041B180 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 183D50761B13F8110041B180 /* main.m */; }; 12 | 183D507A1B13F8110041B180 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 183D50791B13F8110041B180 /* AppDelegate.m */; }; 13 | 183D507D1B13F8110041B180 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 183D507C1B13F8110041B180 /* ViewController.m */; }; 14 | 183D50801B13F8110041B180 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 183D507E1B13F8110041B180 /* Main.storyboard */; }; 15 | 183D50821B13F8110041B180 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 183D50811B13F8110041B180 /* Images.xcassets */; }; 16 | 183D50851B13F8110041B180 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 183D50831B13F8110041B180 /* LaunchScreen.xib */; }; 17 | 183D50911B13F8110041B180 /* TypesetTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 183D50901B13F8110041B180 /* TypesetTests.m */; }; 18 | 183D50A21B13F8200041B180 /* NSString+Typeset.m in Sources */ = {isa = PBXBuildFile; fileRef = 183D509C1B13F8200041B180 /* NSString+Typeset.m */; }; 19 | 183D50A31B13F8200041B180 /* TypesetKit+Color.m in Sources */ = {isa = PBXBuildFile; fileRef = 183D509F1B13F8200041B180 /* TypesetKit+Color.m */; }; 20 | 183D50A41B13F8200041B180 /* TypesetKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 183D50A11B13F8200041B180 /* TypesetKit.m */; }; 21 | 188212871B13FF3700322397 /* NSMutableAttributedString+Typeset.m in Sources */ = {isa = PBXBuildFile; fileRef = 188212861B13FF3700322397 /* NSMutableAttributedString+Typeset.m */; }; 22 | 7219A74B1CACCC0B00D53165 /* UILabel+Typeset.m in Sources */ = {isa = PBXBuildFile; fileRef = 7219A74A1CACCC0B00D53165 /* UILabel+Typeset.m */; }; 23 | 7219A7521CACD79F00D53165 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 7219A74F1CACD79F00D53165 /* LICENSE */; }; 24 | 7219A7531CACD79F00D53165 /* README.md in Sources */ = {isa = PBXBuildFile; fileRef = 7219A7501CACD79F00D53165 /* README.md */; }; 25 | 7219A7541CACD79F00D53165 /* Typeset.podspec in Resources */ = {isa = PBXBuildFile; fileRef = 7219A7511CACD79F00D53165 /* Typeset.podspec */; }; 26 | 7219A7571CACDAD000D53165 /* UIFont+Weight.m in Sources */ = {isa = PBXBuildFile; fileRef = 7219A7561CACDAD000D53165 /* UIFont+Weight.m */; }; 27 | 724DBF141CC14433008C2C50 /* Typeset.h in Headers */ = {isa = PBXBuildFile; fileRef = 183D509D1B13F8200041B180 /* Typeset.h */; settings = {ATTRIBUTES = (Public, ); }; }; 28 | 724DBF151CC14433008C2C50 /* TypesetKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 183D50A01B13F8200041B180 /* TypesetKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 29 | 724DBF161CC14433008C2C50 /* TypesetKit+Color.h in Headers */ = {isa = PBXBuildFile; fileRef = 183D509E1B13F8200041B180 /* TypesetKit+Color.h */; settings = {ATTRIBUTES = (Public, ); }; }; 30 | 724DBF171CC14433008C2C50 /* NSString+Typeset.h in Headers */ = {isa = PBXBuildFile; fileRef = 183D509B1B13F8200041B180 /* NSString+Typeset.h */; settings = {ATTRIBUTES = (Public, ); }; }; 31 | 724DBF181CC14433008C2C50 /* NSMutableAttributedString+Typeset.h in Headers */ = {isa = PBXBuildFile; fileRef = 188212851B13FF3700322397 /* NSMutableAttributedString+Typeset.h */; settings = {ATTRIBUTES = (Public, ); }; }; 32 | 724DBF191CC14433008C2C50 /* NSValue+Range.h in Headers */ = {isa = PBXBuildFile; fileRef = 181B1A861B18124D00E9BEA3 /* NSValue+Range.h */; }; 33 | 724DBF1A1CC14433008C2C50 /* UIFont+Weight.h in Headers */ = {isa = PBXBuildFile; fileRef = 7219A7551CACDAD000D53165 /* UIFont+Weight.h */; }; 34 | 724DBF1B1CC14433008C2C50 /* UILabel+Typeset.h in Headers */ = {isa = PBXBuildFile; fileRef = 7219A7491CACCC0B00D53165 /* UILabel+Typeset.h */; settings = {ATTRIBUTES = (Public, ); }; }; 35 | 724DBF1C1CC14433008C2C50 /* UITextField+Typeset.h in Headers */ = {isa = PBXBuildFile; fileRef = 7258DEFE1CB3618200C8762B /* UITextField+Typeset.h */; settings = {ATTRIBUTES = (Public, ); }; }; 36 | 7258DF001CB3618200C8762B /* UITextField+Typeset.m in Sources */ = {isa = PBXBuildFile; fileRef = 7258DEFF1CB3618200C8762B /* UITextField+Typeset.m */; }; 37 | 7292FC161D64AB240054F827 /* metamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 7292FC151D64AB240054F827 /* metamacros.h */; }; 38 | 729F1A601D44B9BF00111F98 /* UITextView+Typeset.h in Headers */ = {isa = PBXBuildFile; fileRef = 729F1A5E1D44B9BF00111F98 /* UITextView+Typeset.h */; }; 39 | 729F1A611D44B9BF00111F98 /* UITextView+Typeset.m in Sources */ = {isa = PBXBuildFile; fileRef = 729F1A5F1D44B9BF00111F98 /* UITextView+Typeset.m */; }; 40 | 72B0B9701CC48770000E7EDA /* TypesetKit+Match.h in Headers */ = {isa = PBXBuildFile; fileRef = 72B0B96E1CC48770000E7EDA /* TypesetKit+Match.h */; settings = {ATTRIBUTES = (Public, ); }; }; 41 | 72B0B9711CC48770000E7EDA /* TypesetKit+Match.m in Sources */ = {isa = PBXBuildFile; fileRef = 72B0B96F1CC48770000E7EDA /* TypesetKit+Match.m */; }; 42 | /* End PBXBuildFile section */ 43 | 44 | /* Begin PBXContainerItemProxy section */ 45 | 183D508B1B13F8110041B180 /* PBXContainerItemProxy */ = { 46 | isa = PBXContainerItemProxy; 47 | containerPortal = 183D50691B13F8110041B180 /* Project object */; 48 | proxyType = 1; 49 | remoteGlobalIDString = 183D50701B13F8110041B180; 50 | remoteInfo = Typeset; 51 | }; 52 | /* End PBXContainerItemProxy section */ 53 | 54 | /* Begin PBXFileReference section */ 55 | 181B1A861B18124D00E9BEA3 /* NSValue+Range.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSValue+Range.h"; sourceTree = ""; }; 56 | 181B1A871B18124D00E9BEA3 /* NSValue+Range.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSValue+Range.m"; sourceTree = ""; }; 57 | 183D50711B13F8110041B180 /* Typeset.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Typeset.app; sourceTree = BUILT_PRODUCTS_DIR; }; 58 | 183D50751B13F8110041B180 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 59 | 183D50761B13F8110041B180 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 60 | 183D50781B13F8110041B180 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 61 | 183D50791B13F8110041B180 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 62 | 183D507B1B13F8110041B180 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 63 | 183D507C1B13F8110041B180 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 64 | 183D507F1B13F8110041B180 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 65 | 183D50811B13F8110041B180 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 66 | 183D50841B13F8110041B180 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 67 | 183D508A1B13F8110041B180 /* TypesetTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TypesetTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 68 | 183D508F1B13F8110041B180 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 69 | 183D50901B13F8110041B180 /* TypesetTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TypesetTests.m; sourceTree = ""; }; 70 | 183D509B1B13F8200041B180 /* NSString+Typeset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+Typeset.h"; sourceTree = ""; }; 71 | 183D509C1B13F8200041B180 /* NSString+Typeset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+Typeset.m"; sourceTree = ""; }; 72 | 183D509D1B13F8200041B180 /* Typeset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Typeset.h; sourceTree = ""; }; 73 | 183D509E1B13F8200041B180 /* TypesetKit+Color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "TypesetKit+Color.h"; sourceTree = ""; }; 74 | 183D509F1B13F8200041B180 /* TypesetKit+Color.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "TypesetKit+Color.m"; sourceTree = ""; }; 75 | 183D50A01B13F8200041B180 /* TypesetKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypesetKit.h; sourceTree = ""; }; 76 | 183D50A11B13F8200041B180 /* TypesetKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TypesetKit.m; sourceTree = ""; }; 77 | 188212851B13FF3700322397 /* NSMutableAttributedString+Typeset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableAttributedString+Typeset.h"; sourceTree = ""; }; 78 | 188212861B13FF3700322397 /* NSMutableAttributedString+Typeset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableAttributedString+Typeset.m"; sourceTree = ""; }; 79 | 7219A7491CACCC0B00D53165 /* UILabel+Typeset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UILabel+Typeset.h"; sourceTree = ""; }; 80 | 7219A74A1CACCC0B00D53165 /* UILabel+Typeset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UILabel+Typeset.m"; sourceTree = ""; }; 81 | 7219A74F1CACD79F00D53165 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 82 | 7219A7501CACD79F00D53165 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 83 | 7219A7511CACD79F00D53165 /* Typeset.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Typeset.podspec; sourceTree = ""; }; 84 | 7219A7551CACDAD000D53165 /* UIFont+Weight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIFont+Weight.h"; sourceTree = ""; }; 85 | 7219A7561CACDAD000D53165 /* UIFont+Weight.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+Weight.m"; sourceTree = ""; }; 86 | 7258DEFE1CB3618200C8762B /* UITextField+Typeset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITextField+Typeset.h"; sourceTree = ""; }; 87 | 7258DEFF1CB3618200C8762B /* UITextField+Typeset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITextField+Typeset.m"; sourceTree = ""; }; 88 | 7292FC151D64AB240054F827 /* metamacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = metamacros.h; sourceTree = ""; }; 89 | 729F1A5E1D44B9BF00111F98 /* UITextView+Typeset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITextView+Typeset.h"; sourceTree = ""; }; 90 | 729F1A5F1D44B9BF00111F98 /* UITextView+Typeset.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITextView+Typeset.m"; sourceTree = ""; }; 91 | 72B0B96E1CC48770000E7EDA /* TypesetKit+Match.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "TypesetKit+Match.h"; sourceTree = ""; }; 92 | 72B0B96F1CC48770000E7EDA /* TypesetKit+Match.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "TypesetKit+Match.m"; sourceTree = ""; }; 93 | /* End PBXFileReference section */ 94 | 95 | /* Begin PBXFrameworksBuildPhase section */ 96 | 183D506E1B13F8110041B180 /* Frameworks */ = { 97 | isa = PBXFrameworksBuildPhase; 98 | buildActionMask = 2147483647; 99 | files = ( 100 | ); 101 | runOnlyForDeploymentPostprocessing = 0; 102 | }; 103 | 183D50871B13F8110041B180 /* Frameworks */ = { 104 | isa = PBXFrameworksBuildPhase; 105 | buildActionMask = 2147483647; 106 | files = ( 107 | ); 108 | runOnlyForDeploymentPostprocessing = 0; 109 | }; 110 | /* End PBXFrameworksBuildPhase section */ 111 | 112 | /* Begin PBXGroup section */ 113 | 183D50681B13F8110041B180 = { 114 | isa = PBXGroup; 115 | children = ( 116 | 7219A74F1CACD79F00D53165 /* LICENSE */, 117 | 7219A7501CACD79F00D53165 /* README.md */, 118 | 7219A7511CACD79F00D53165 /* Typeset.podspec */, 119 | 183D50731B13F8110041B180 /* Typeset */, 120 | 183D508D1B13F8110041B180 /* TypesetTests */, 121 | 183D50721B13F8110041B180 /* Products */, 122 | ); 123 | sourceTree = ""; 124 | }; 125 | 183D50721B13F8110041B180 /* Products */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | 183D50711B13F8110041B180 /* Typeset.app */, 129 | 183D508A1B13F8110041B180 /* TypesetTests.xctest */, 130 | ); 131 | name = Products; 132 | sourceTree = ""; 133 | }; 134 | 183D50731B13F8110041B180 /* Typeset */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 183D509A1B13F8200041B180 /* Classes */, 138 | 183D50781B13F8110041B180 /* AppDelegate.h */, 139 | 183D50791B13F8110041B180 /* AppDelegate.m */, 140 | 183D507B1B13F8110041B180 /* ViewController.h */, 141 | 183D507C1B13F8110041B180 /* ViewController.m */, 142 | 183D507E1B13F8110041B180 /* Main.storyboard */, 143 | 183D50811B13F8110041B180 /* Images.xcassets */, 144 | 183D50831B13F8110041B180 /* LaunchScreen.xib */, 145 | 183D50741B13F8110041B180 /* Supporting Files */, 146 | ); 147 | path = Typeset; 148 | sourceTree = ""; 149 | }; 150 | 183D50741B13F8110041B180 /* Supporting Files */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 183D50751B13F8110041B180 /* Info.plist */, 154 | 183D50761B13F8110041B180 /* main.m */, 155 | ); 156 | name = "Supporting Files"; 157 | sourceTree = ""; 158 | }; 159 | 183D508D1B13F8110041B180 /* TypesetTests */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | 183D50901B13F8110041B180 /* TypesetTests.m */, 163 | 183D508E1B13F8110041B180 /* Supporting Files */, 164 | ); 165 | path = TypesetTests; 166 | sourceTree = ""; 167 | }; 168 | 183D508E1B13F8110041B180 /* Supporting Files */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | 183D508F1B13F8110041B180 /* Info.plist */, 172 | ); 173 | name = "Supporting Files"; 174 | sourceTree = ""; 175 | }; 176 | 183D509A1B13F8200041B180 /* Classes */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | 183D509D1B13F8200041B180 /* Typeset.h */, 180 | 7219A74E1CACCD8400D53165 /* Core */, 181 | 7219A74D1CACCD7300D53165 /* Categoty */, 182 | 7219A74C1CACCC0F00D53165 /* UIKit */, 183 | ); 184 | path = Classes; 185 | sourceTree = SOURCE_ROOT; 186 | }; 187 | 7219A74C1CACCC0F00D53165 /* UIKit */ = { 188 | isa = PBXGroup; 189 | children = ( 190 | 7219A7491CACCC0B00D53165 /* UILabel+Typeset.h */, 191 | 7219A74A1CACCC0B00D53165 /* UILabel+Typeset.m */, 192 | 7258DEFE1CB3618200C8762B /* UITextField+Typeset.h */, 193 | 7258DEFF1CB3618200C8762B /* UITextField+Typeset.m */, 194 | 729F1A5E1D44B9BF00111F98 /* UITextView+Typeset.h */, 195 | 729F1A5F1D44B9BF00111F98 /* UITextView+Typeset.m */, 196 | ); 197 | name = UIKit; 198 | sourceTree = ""; 199 | }; 200 | 7219A74D1CACCD7300D53165 /* Categoty */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | 181B1A861B18124D00E9BEA3 /* NSValue+Range.h */, 204 | 181B1A871B18124D00E9BEA3 /* NSValue+Range.m */, 205 | 7219A7551CACDAD000D53165 /* UIFont+Weight.h */, 206 | 7219A7561CACDAD000D53165 /* UIFont+Weight.m */, 207 | ); 208 | name = Categoty; 209 | sourceTree = ""; 210 | }; 211 | 7219A74E1CACCD8400D53165 /* Core */ = { 212 | isa = PBXGroup; 213 | children = ( 214 | 183D50A01B13F8200041B180 /* TypesetKit.h */, 215 | 183D50A11B13F8200041B180 /* TypesetKit.m */, 216 | 72B0B96E1CC48770000E7EDA /* TypesetKit+Match.h */, 217 | 72B0B96F1CC48770000E7EDA /* TypesetKit+Match.m */, 218 | 183D509E1B13F8200041B180 /* TypesetKit+Color.h */, 219 | 183D509F1B13F8200041B180 /* TypesetKit+Color.m */, 220 | 183D509B1B13F8200041B180 /* NSString+Typeset.h */, 221 | 183D509C1B13F8200041B180 /* NSString+Typeset.m */, 222 | 188212851B13FF3700322397 /* NSMutableAttributedString+Typeset.h */, 223 | 188212861B13FF3700322397 /* NSMutableAttributedString+Typeset.m */, 224 | 7292FC151D64AB240054F827 /* metamacros.h */, 225 | ); 226 | name = Core; 227 | sourceTree = ""; 228 | }; 229 | /* End PBXGroup section */ 230 | 231 | /* Begin PBXHeadersBuildPhase section */ 232 | 724DBF131CC1441F008C2C50 /* Headers */ = { 233 | isa = PBXHeadersBuildPhase; 234 | buildActionMask = 2147483647; 235 | files = ( 236 | 724DBF151CC14433008C2C50 /* TypesetKit.h in Headers */, 237 | 729F1A601D44B9BF00111F98 /* UITextView+Typeset.h in Headers */, 238 | 724DBF181CC14433008C2C50 /* NSMutableAttributedString+Typeset.h in Headers */, 239 | 724DBF171CC14433008C2C50 /* NSString+Typeset.h in Headers */, 240 | 724DBF141CC14433008C2C50 /* Typeset.h in Headers */, 241 | 724DBF1B1CC14433008C2C50 /* UILabel+Typeset.h in Headers */, 242 | 7292FC161D64AB240054F827 /* metamacros.h in Headers */, 243 | 724DBF161CC14433008C2C50 /* TypesetKit+Color.h in Headers */, 244 | 72B0B9701CC48770000E7EDA /* TypesetKit+Match.h in Headers */, 245 | 724DBF1C1CC14433008C2C50 /* UITextField+Typeset.h in Headers */, 246 | 724DBF191CC14433008C2C50 /* NSValue+Range.h in Headers */, 247 | 724DBF1A1CC14433008C2C50 /* UIFont+Weight.h in Headers */, 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | }; 251 | /* End PBXHeadersBuildPhase section */ 252 | 253 | /* Begin PBXNativeTarget section */ 254 | 183D50701B13F8110041B180 /* Typeset */ = { 255 | isa = PBXNativeTarget; 256 | buildConfigurationList = 183D50941B13F8110041B180 /* Build configuration list for PBXNativeTarget "Typeset" */; 257 | buildPhases = ( 258 | 183D506D1B13F8110041B180 /* Sources */, 259 | 183D506E1B13F8110041B180 /* Frameworks */, 260 | 183D506F1B13F8110041B180 /* Resources */, 261 | 724DBF131CC1441F008C2C50 /* Headers */, 262 | ); 263 | buildRules = ( 264 | ); 265 | dependencies = ( 266 | ); 267 | name = Typeset; 268 | productName = Typeset; 269 | productReference = 183D50711B13F8110041B180 /* Typeset.app */; 270 | productType = "com.apple.product-type.application"; 271 | }; 272 | 183D50891B13F8110041B180 /* TypesetTests */ = { 273 | isa = PBXNativeTarget; 274 | buildConfigurationList = 183D50971B13F8110041B180 /* Build configuration list for PBXNativeTarget "TypesetTests" */; 275 | buildPhases = ( 276 | 183D50861B13F8110041B180 /* Sources */, 277 | 183D50871B13F8110041B180 /* Frameworks */, 278 | 183D50881B13F8110041B180 /* Resources */, 279 | ); 280 | buildRules = ( 281 | ); 282 | dependencies = ( 283 | 183D508C1B13F8110041B180 /* PBXTargetDependency */, 284 | ); 285 | name = TypesetTests; 286 | productName = TypesetTests; 287 | productReference = 183D508A1B13F8110041B180 /* TypesetTests.xctest */; 288 | productType = "com.apple.product-type.bundle.unit-test"; 289 | }; 290 | /* End PBXNativeTarget section */ 291 | 292 | /* Begin PBXProject section */ 293 | 183D50691B13F8110041B180 /* Project object */ = { 294 | isa = PBXProject; 295 | attributes = { 296 | LastUpgradeCheck = 0710; 297 | ORGANIZATIONNAME = DeltaX; 298 | TargetAttributes = { 299 | 183D50701B13F8110041B180 = { 300 | CreatedOnToolsVersion = 6.3; 301 | }; 302 | 183D50891B13F8110041B180 = { 303 | CreatedOnToolsVersion = 6.3; 304 | TestTargetID = 183D50701B13F8110041B180; 305 | }; 306 | }; 307 | }; 308 | buildConfigurationList = 183D506C1B13F8110041B180 /* Build configuration list for PBXProject "Typeset" */; 309 | compatibilityVersion = "Xcode 3.2"; 310 | developmentRegion = English; 311 | hasScannedForEncodings = 0; 312 | knownRegions = ( 313 | en, 314 | Base, 315 | ); 316 | mainGroup = 183D50681B13F8110041B180; 317 | productRefGroup = 183D50721B13F8110041B180 /* Products */; 318 | projectDirPath = ""; 319 | projectRoot = ""; 320 | targets = ( 321 | 183D50701B13F8110041B180 /* Typeset */, 322 | 183D50891B13F8110041B180 /* TypesetTests */, 323 | ); 324 | }; 325 | /* End PBXProject section */ 326 | 327 | /* Begin PBXResourcesBuildPhase section */ 328 | 183D506F1B13F8110041B180 /* Resources */ = { 329 | isa = PBXResourcesBuildPhase; 330 | buildActionMask = 2147483647; 331 | files = ( 332 | 183D50801B13F8110041B180 /* Main.storyboard in Resources */, 333 | 7219A7541CACD79F00D53165 /* Typeset.podspec in Resources */, 334 | 183D50851B13F8110041B180 /* LaunchScreen.xib in Resources */, 335 | 7219A7521CACD79F00D53165 /* LICENSE in Resources */, 336 | 183D50821B13F8110041B180 /* Images.xcassets in Resources */, 337 | ); 338 | runOnlyForDeploymentPostprocessing = 0; 339 | }; 340 | 183D50881B13F8110041B180 /* Resources */ = { 341 | isa = PBXResourcesBuildPhase; 342 | buildActionMask = 2147483647; 343 | files = ( 344 | ); 345 | runOnlyForDeploymentPostprocessing = 0; 346 | }; 347 | /* End PBXResourcesBuildPhase section */ 348 | 349 | /* Begin PBXSourcesBuildPhase section */ 350 | 183D506D1B13F8110041B180 /* Sources */ = { 351 | isa = PBXSourcesBuildPhase; 352 | buildActionMask = 2147483647; 353 | files = ( 354 | 181B1A881B18124D00E9BEA3 /* NSValue+Range.m in Sources */, 355 | 183D507D1B13F8110041B180 /* ViewController.m in Sources */, 356 | 7219A7571CACDAD000D53165 /* UIFont+Weight.m in Sources */, 357 | 7219A7531CACD79F00D53165 /* README.md in Sources */, 358 | 729F1A611D44B9BF00111F98 /* UITextView+Typeset.m in Sources */, 359 | 183D50A41B13F8200041B180 /* TypesetKit.m in Sources */, 360 | 72B0B9711CC48770000E7EDA /* TypesetKit+Match.m in Sources */, 361 | 183D507A1B13F8110041B180 /* AppDelegate.m in Sources */, 362 | 183D50A31B13F8200041B180 /* TypesetKit+Color.m in Sources */, 363 | 7219A74B1CACCC0B00D53165 /* UILabel+Typeset.m in Sources */, 364 | 7258DF001CB3618200C8762B /* UITextField+Typeset.m in Sources */, 365 | 188212871B13FF3700322397 /* NSMutableAttributedString+Typeset.m in Sources */, 366 | 183D50A21B13F8200041B180 /* NSString+Typeset.m in Sources */, 367 | 183D50771B13F8110041B180 /* main.m in Sources */, 368 | ); 369 | runOnlyForDeploymentPostprocessing = 0; 370 | }; 371 | 183D50861B13F8110041B180 /* Sources */ = { 372 | isa = PBXSourcesBuildPhase; 373 | buildActionMask = 2147483647; 374 | files = ( 375 | 183D50911B13F8110041B180 /* TypesetTests.m in Sources */, 376 | ); 377 | runOnlyForDeploymentPostprocessing = 0; 378 | }; 379 | /* End PBXSourcesBuildPhase section */ 380 | 381 | /* Begin PBXTargetDependency section */ 382 | 183D508C1B13F8110041B180 /* PBXTargetDependency */ = { 383 | isa = PBXTargetDependency; 384 | target = 183D50701B13F8110041B180 /* Typeset */; 385 | targetProxy = 183D508B1B13F8110041B180 /* PBXContainerItemProxy */; 386 | }; 387 | /* End PBXTargetDependency section */ 388 | 389 | /* Begin PBXVariantGroup section */ 390 | 183D507E1B13F8110041B180 /* Main.storyboard */ = { 391 | isa = PBXVariantGroup; 392 | children = ( 393 | 183D507F1B13F8110041B180 /* Base */, 394 | ); 395 | name = Main.storyboard; 396 | sourceTree = ""; 397 | }; 398 | 183D50831B13F8110041B180 /* LaunchScreen.xib */ = { 399 | isa = PBXVariantGroup; 400 | children = ( 401 | 183D50841B13F8110041B180 /* Base */, 402 | ); 403 | name = LaunchScreen.xib; 404 | sourceTree = ""; 405 | }; 406 | /* End PBXVariantGroup section */ 407 | 408 | /* Begin XCBuildConfiguration section */ 409 | 183D50921B13F8110041B180 /* Debug */ = { 410 | isa = XCBuildConfiguration; 411 | buildSettings = { 412 | ALWAYS_SEARCH_USER_PATHS = NO; 413 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 414 | CLANG_CXX_LIBRARY = "libc++"; 415 | CLANG_ENABLE_MODULES = YES; 416 | CLANG_ENABLE_OBJC_ARC = YES; 417 | CLANG_WARN_BOOL_CONVERSION = YES; 418 | CLANG_WARN_CONSTANT_CONVERSION = YES; 419 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 420 | CLANG_WARN_EMPTY_BODY = YES; 421 | CLANG_WARN_ENUM_CONVERSION = YES; 422 | CLANG_WARN_INT_CONVERSION = YES; 423 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 424 | CLANG_WARN_UNREACHABLE_CODE = YES; 425 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 426 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 427 | COPY_PHASE_STRIP = NO; 428 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 429 | ENABLE_STRICT_OBJC_MSGSEND = YES; 430 | ENABLE_TESTABILITY = YES; 431 | GCC_C_LANGUAGE_STANDARD = gnu99; 432 | GCC_DYNAMIC_NO_PIC = NO; 433 | GCC_NO_COMMON_BLOCKS = YES; 434 | GCC_OPTIMIZATION_LEVEL = 0; 435 | GCC_PREPROCESSOR_DEFINITIONS = ( 436 | "DEBUG=1", 437 | "$(inherited)", 438 | ); 439 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 440 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 441 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 442 | GCC_WARN_UNDECLARED_SELECTOR = YES; 443 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 444 | GCC_WARN_UNUSED_FUNCTION = YES; 445 | GCC_WARN_UNUSED_VARIABLE = YES; 446 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 447 | MTL_ENABLE_DEBUG_INFO = YES; 448 | ONLY_ACTIVE_ARCH = YES; 449 | SDKROOT = iphoneos; 450 | }; 451 | name = Debug; 452 | }; 453 | 183D50931B13F8110041B180 /* Release */ = { 454 | isa = XCBuildConfiguration; 455 | buildSettings = { 456 | ALWAYS_SEARCH_USER_PATHS = NO; 457 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 458 | CLANG_CXX_LIBRARY = "libc++"; 459 | CLANG_ENABLE_MODULES = YES; 460 | CLANG_ENABLE_OBJC_ARC = YES; 461 | CLANG_WARN_BOOL_CONVERSION = YES; 462 | CLANG_WARN_CONSTANT_CONVERSION = YES; 463 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 464 | CLANG_WARN_EMPTY_BODY = YES; 465 | CLANG_WARN_ENUM_CONVERSION = YES; 466 | CLANG_WARN_INT_CONVERSION = YES; 467 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 468 | CLANG_WARN_UNREACHABLE_CODE = YES; 469 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 470 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 471 | COPY_PHASE_STRIP = NO; 472 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 473 | ENABLE_NS_ASSERTIONS = NO; 474 | ENABLE_STRICT_OBJC_MSGSEND = YES; 475 | GCC_C_LANGUAGE_STANDARD = gnu99; 476 | GCC_NO_COMMON_BLOCKS = YES; 477 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 478 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 479 | GCC_WARN_UNDECLARED_SELECTOR = YES; 480 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 481 | GCC_WARN_UNUSED_FUNCTION = YES; 482 | GCC_WARN_UNUSED_VARIABLE = YES; 483 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 484 | MTL_ENABLE_DEBUG_INFO = NO; 485 | SDKROOT = iphoneos; 486 | VALIDATE_PRODUCT = YES; 487 | }; 488 | name = Release; 489 | }; 490 | 183D50951B13F8110041B180 /* Debug */ = { 491 | isa = XCBuildConfiguration; 492 | buildSettings = { 493 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 494 | INFOPLIST_FILE = Typeset/Info.plist; 495 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 496 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 497 | PRODUCT_BUNDLE_IDENTIFIER = "com.draveness.$(PRODUCT_NAME:rfc1034identifier)"; 498 | PRODUCT_NAME = "$(TARGET_NAME)"; 499 | }; 500 | name = Debug; 501 | }; 502 | 183D50961B13F8110041B180 /* Release */ = { 503 | isa = XCBuildConfiguration; 504 | buildSettings = { 505 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 506 | INFOPLIST_FILE = Typeset/Info.plist; 507 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 508 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 509 | PRODUCT_BUNDLE_IDENTIFIER = "com.draveness.$(PRODUCT_NAME:rfc1034identifier)"; 510 | PRODUCT_NAME = "$(TARGET_NAME)"; 511 | }; 512 | name = Release; 513 | }; 514 | 183D50981B13F8110041B180 /* Debug */ = { 515 | isa = XCBuildConfiguration; 516 | buildSettings = { 517 | BUNDLE_LOADER = "$(TEST_HOST)"; 518 | FRAMEWORK_SEARCH_PATHS = ( 519 | "$(SDKROOT)/Developer/Library/Frameworks", 520 | "$(inherited)", 521 | ); 522 | GCC_PREPROCESSOR_DEFINITIONS = ( 523 | "DEBUG=1", 524 | "$(inherited)", 525 | ); 526 | INFOPLIST_FILE = TypesetTests/Info.plist; 527 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 528 | PRODUCT_BUNDLE_IDENTIFIER = "com.draveness.$(PRODUCT_NAME:rfc1034identifier)"; 529 | PRODUCT_NAME = "$(TARGET_NAME)"; 530 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Typeset.app/Typeset"; 531 | }; 532 | name = Debug; 533 | }; 534 | 183D50991B13F8110041B180 /* Release */ = { 535 | isa = XCBuildConfiguration; 536 | buildSettings = { 537 | BUNDLE_LOADER = "$(TEST_HOST)"; 538 | FRAMEWORK_SEARCH_PATHS = ( 539 | "$(SDKROOT)/Developer/Library/Frameworks", 540 | "$(inherited)", 541 | ); 542 | INFOPLIST_FILE = TypesetTests/Info.plist; 543 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 544 | PRODUCT_BUNDLE_IDENTIFIER = "com.draveness.$(PRODUCT_NAME:rfc1034identifier)"; 545 | PRODUCT_NAME = "$(TARGET_NAME)"; 546 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Typeset.app/Typeset"; 547 | }; 548 | name = Release; 549 | }; 550 | /* End XCBuildConfiguration section */ 551 | 552 | /* Begin XCConfigurationList section */ 553 | 183D506C1B13F8110041B180 /* Build configuration list for PBXProject "Typeset" */ = { 554 | isa = XCConfigurationList; 555 | buildConfigurations = ( 556 | 183D50921B13F8110041B180 /* Debug */, 557 | 183D50931B13F8110041B180 /* Release */, 558 | ); 559 | defaultConfigurationIsVisible = 0; 560 | defaultConfigurationName = Release; 561 | }; 562 | 183D50941B13F8110041B180 /* Build configuration list for PBXNativeTarget "Typeset" */ = { 563 | isa = XCConfigurationList; 564 | buildConfigurations = ( 565 | 183D50951B13F8110041B180 /* Debug */, 566 | 183D50961B13F8110041B180 /* Release */, 567 | ); 568 | defaultConfigurationIsVisible = 0; 569 | defaultConfigurationName = Release; 570 | }; 571 | 183D50971B13F8110041B180 /* Build configuration list for PBXNativeTarget "TypesetTests" */ = { 572 | isa = XCConfigurationList; 573 | buildConfigurations = ( 574 | 183D50981B13F8110041B180 /* Debug */, 575 | 183D50991B13F8110041B180 /* Release */, 576 | ); 577 | defaultConfigurationIsVisible = 0; 578 | defaultConfigurationName = Release; 579 | }; 580 | /* End XCConfigurationList section */ 581 | }; 582 | rootObject = 183D50691B13F8110041B180 /* Project object */; 583 | } 584 | -------------------------------------------------------------------------------- /Typeset.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Typeset.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/Typeset.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /Typeset.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Typeset.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 183D50701B13F8110041B180 16 | 17 | primary 18 | 19 | 20 | 183D50891B13F8110041B180 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Typeset/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/26. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Typeset/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/26. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // 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. 25 | // 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. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // 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. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Typeset/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Typeset/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 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 | 26 | 27 | -------------------------------------------------------------------------------- /Typeset/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /Typeset/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 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 3.4.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 148 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Typeset/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/26. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Typeset/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/26. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "Typeset.h" 11 | 12 | 13 | @interface ViewController () 14 | 15 | @end 16 | 17 | @implementation ViewController { 18 | UILabel *label; 19 | UITextView *textView; 20 | } 21 | 22 | - (void)viewDidLoad { 23 | [super viewDidLoad]; 24 | label = [[UILabel alloc] initWithFrame:self.view.bounds]; 25 | 26 | textView = [[UITextView alloc] init]; 27 | textView.frame = self.view.frame; 28 | 29 | // [self setupLabel]; 30 | // [self.view addSubview:label]; 31 | 32 | [self setupTextView]; 33 | [self.view addSubview:textView]; 34 | } 35 | 36 | - (void)setupLabel { 37 | label.text = @"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n\n\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat."; 38 | 39 | label.numberOfLines = 0; 40 | label.textAlignment = NSTextAlignmentLeft; 41 | 42 | label.typesetBlock = TSBlock(fontSize(20).light.matchAll(@"in").red.matchAll(@"et").blue); 43 | 44 | } 45 | 46 | - (void)setupTextView { 47 | // textView.text = @"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.\n\n\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat."; 48 | 49 | textView.textAlignment = NSTextAlignmentLeft; 50 | 51 | textView.attributedText = TSAttributedString(@"Hello".red, @" ", @"World".blue); 52 | 53 | // textView.typesetBlock = TSBlock(fontSize(25).light.matchAll(@"in").red.matchAll(@"et").blue); 54 | } 55 | 56 | - (void)injected { 57 | // [self setupLabel]; 58 | [self setupTextView]; 59 | } 60 | 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Typeset/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Typeset 4 | // 5 | // Created by apple on 15/5/26. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | 18 | // From here to end of file added by Injection Plugin // 19 | 20 | #ifdef DEBUG 21 | static char _inMainFilePath[] = __FILE__; 22 | static const char *_inIPAddresses[] = {"10.10.10.101", "127.0.0.1", 0}; 23 | 24 | #define INJECTION_ENABLED 25 | #import "/tmp/injectionforxcode/BundleInjection.h" 26 | #endif 27 | -------------------------------------------------------------------------------- /TypesetTests/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 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 3.4.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 148 23 | 24 | 25 | -------------------------------------------------------------------------------- /TypesetTests/TypesetTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // TypesetTests.m 3 | // TypesetTests 4 | // 5 | // Created by apple on 15/5/26. 6 | // Copyright (c) 2015年 DeltaX. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "Typeset.h" 12 | @interface TypesetTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation TypesetTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | 34 | - (void)testSelfEqual { 35 | 36 | NSString *txt = @"Hello typeset"; 37 | 38 | NSMutableAttributedString *attributedTxt1 = txt.typeset.matchAll(@"o").red.string; 39 | 40 | NSMutableAttributedString *attributedTxt2 = txt.typeset.matchAll(@"l").red.string; 41 | 42 | XCTAssertFalse([attributedTxt1 isEqualToAttributedString:attributedTxt2]); 43 | 44 | NSMutableAttributedString *attributedTxt3 = txt.typeset.matchAll(@"o").red.string; 45 | 46 | XCTAssertTrue([attributedTxt1 isEqualToAttributedString:attributedTxt3]); 47 | 48 | } 49 | 50 | - (void)testEqual { 51 | 52 | NSDictionary *obj1 = @{@"abc":@"Hello typeset Hello typeset Hello typeset Hello typeset Hello typeset Hello typeset Hello typeset Hello typeset Hello typeset "}; 53 | 54 | NSDictionary *tmpObj = @{@"def":@"Hello typeset Hello typeset Hello typeset Hello typeset Hello typeset Hello typeset Hello typeset Hello typeset Hello typeset "}; 55 | NSDictionary *obj2 = [[NSDictionary alloc] initWithDictionary:tmpObj]; 56 | 57 | NSString *txt = obj1[@"abc"]; 58 | NSString *txt2 = [obj2[@"def"] copy]; // no difference, just to demonstrate the optimization of NSString done by Apple 59 | 60 | // XCTAssertFalse([txt isEqual:txt2]); 61 | 62 | //attributedString from txt1 63 | NSMutableAttributedString *attributedTxt1 = txt.typeset.matchAll(@"o").red.string; 64 | 65 | //attributedString from txt2 66 | NSMutableAttributedString *attributedTxt2_1 = txt2.typeset.matchAll(@"o").red.string; 67 | XCTAssertTrue([attributedTxt1 isEqualToAttributedString:attributedTxt2_1]); 68 | 69 | NSMutableAttributedString *attributedTxt2_2 = txt2.typeset.matchAll(@"l").red.string; 70 | XCTAssertFalse([attributedTxt1 isEqualToAttributedString:attributedTxt2_2]); 71 | 72 | NSMutableAttributedString *attributedTxt2_3 = txt2.typeset.matchAll(@"o").red.string; 73 | XCTAssertTrue([attributedTxt1 isEqualToAttributedString:attributedTxt2_3]); 74 | 75 | } 76 | 77 | - (void)testPerformanceExample { 78 | // This is an example of a performance test case. 79 | [self measureBlock:^{ 80 | // Put the code you want to measure the time of here. 81 | }]; 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | fastlane_version "1.70.0" 2 | 3 | default_platform :ios 4 | 5 | # Fastfile 6 | desc "Release new version" 7 | lane :release do |options| 8 | target_version = options[:version] 9 | raise "The version is missed." if target_version.nil? 10 | ensure_git_branch 11 | ensure_git_status_clean 12 | # scan 13 | 14 | sync_build_number_to_git 15 | increment_version_number(version_number: target_version) 16 | 17 | version_bump_podspec(path: "Typeset.podspec", 18 | version_number: target_version) 19 | git_commit_all(message: "Bump version to #{target_version}") 20 | add_git_tag tag: target_version 21 | push_to_git_remote 22 | pod_push 23 | end 24 | 25 | -------------------------------------------------------------------------------- /fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ================ 3 | # Installation 4 | ``` 5 | sudo gem install fastlane 6 | ``` 7 | # Available Actions 8 | ### release 9 | ``` 10 | fastlane release 11 | ``` 12 | Release new version 13 | 14 | ---- 15 | 16 | This README.md is auto-generated and will be re-generated every time to run [fastlane](https://fastlane.tools). 17 | More information about fastlane can be found on [https://fastlane.tools](https://fastlane.tools). 18 | The documentation of fastlane can be found on [GitHub](https://github.com/fastlane/fastlane/tree/master/fastlane). -------------------------------------------------------------------------------- /fastlane/actions/git_commit_all.rb: -------------------------------------------------------------------------------- 1 | module Fastlane 2 | module Actions 3 | class GitCommitAllAction < Action 4 | def self.run(params) 5 | Actions.sh "git commit -am \"#{params[:message]}\"" 6 | end 7 | 8 | ##################################################### 9 | # @!group Documentation 10 | ##################################################### 11 | 12 | def self.description 13 | "Commit all unsaved changes to git." 14 | end 15 | 16 | def self.available_options 17 | [ 18 | FastlaneCore::ConfigItem.new(key: :message, 19 | env_name: "FL_GIT_COMMIT_ALL", 20 | description: "The git message for the commit", 21 | is_string: true) 22 | ] 23 | end 24 | 25 | def self.is_supported?(platform) 26 | true 27 | end 28 | end 29 | end 30 | end 31 | 32 | -------------------------------------------------------------------------------- /fastlane/actions/sync_build_number_to_git.rb: -------------------------------------------------------------------------------- 1 | module Fastlane 2 | module Actions 3 | module SharedValues 4 | BUILD_NUMBER = :BUILD_NUMBER 5 | end 6 | class SyncBuildNumberToGitAction < Action 7 | def self.is_git? 8 | Actions.sh 'git rev-parse HEAD' 9 | return true 10 | rescue 11 | return false 12 | end 13 | 14 | def self.run(params) 15 | if is_git? 16 | command = 'git rev-list HEAD --count' 17 | else 18 | raise "Not in a git repository." 19 | end 20 | build_number = (Actions.sh command).strip 21 | Fastlane::Actions::IncrementBuildNumberAction.run(build_number: build_number) 22 | Actions.lane_context[SharedValues::BUILD_NUMBER] = build_number 23 | end 24 | 25 | def self.output 26 | [ 27 | ['BUILD_NUMBER', 'The new build number'] 28 | ] 29 | end 30 | end 31 | end 32 | end 33 | 34 | -------------------------------------------------------------------------------- /images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/draveness/Typeset/5df5c443fd69ad412c1005f4f7113a530c01526a/images/1.png -------------------------------------------------------------------------------- /images/Demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/draveness/Typeset/5df5c443fd69ad412c1005f4f7113a530c01526a/images/Demo.png -------------------------------------------------------------------------------- /images/Typeset.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/draveness/Typeset/5df5c443fd69ad412c1005f4f7113a530c01526a/images/Typeset.gif -------------------------------------------------------------------------------- /images/Typeset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/draveness/Typeset/5df5c443fd69ad412c1005f4f7113a530c01526a/images/Typeset.png --------------------------------------------------------------------------------