forked from tomaz/appledoc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNSString+GBString.m
144 lines (112 loc) · 4.65 KB
/
NSString+GBString.m
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//
// NSString+GBString.m
// appledoc
//
// Created by Tomaz Kragelj on 31.7.10.
// Copyright (C) 2010, Gentle Bytes. All rights reserved.
//
#import "RegexKitLite.h"
#import "NSString+GBString.h"
@interface NSString (GBPrivateAPI)
- (unichar)lastCharacter;
- (NSArray *)arrayOfWords;
@end
#pragma mark -
@implementation NSString (GBString)
#pragma mark Simplifying string
- (NSString *)stringByTrimmingCharactersInSetFromEnd:(NSCharacterSet *)set {
NSParameterAssert(set != nil);
NSMutableString *result = [self mutableCopy];
while ([result length] > 0 && [set characterIsMember:[result lastCharacter]]) {
[result deleteCharactersInRange:NSMakeRange([result length] - 1, 1)];
}
return result;
}
- (NSString *)stringByWordifyingWithSpaces {
if ([self length] == 0) return self;
NSMutableString *result = [NSMutableString stringWithCapacity:[self length]];
NSArray *words = [self arrayOfWords];
[words enumerateObjectsUsingBlock:^(NSString *word, NSUInteger idx, BOOL *stop) {
if ([word length] == 0) return;
if ([result length] > 0) [result appendString:@" "];
[result appendString:word];
}];
return result;
}
- (NSString *)stringByTrimmingWhitespace {
return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}
- (NSString *)stringByTrimmingWhitespaceAndNewLine {
return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
#pragma mark Preparing nice descriptions
- (NSString *)normalizedDescription {
return [self normalizedDescriptionWithMaxLength:[[self class] defaultNormalizedDescriptionLength]];
}
- (NSString *)normalizedDescriptionWithMaxLength:(NSUInteger)length {
NSString *extract = [self stringByReplacingOccurrencesOfRegex:@"\\s+" withString:@" "];
if ([extract length] <= length) return [extract stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSArray *words = [extract arrayOfWords];
length /= 2;
NSMutableString *prefix = [NSMutableString stringWithCapacity:[extract length] / 2];
[words enumerateObjectsUsingBlock:^(NSString *word, NSUInteger idx, BOOL *stop) {
if ([prefix length] > 0) [prefix appendString:@" "];
[prefix appendString:word];
if ([prefix length] >= length) *stop = YES;
}];
NSMutableString *suffix = [NSMutableString stringWithCapacity:[prefix length]];
[words enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSString *word, NSUInteger idx, BOOL *stop) {
if ([suffix length] > 0) [suffix insertString:@" " atIndex:0];
[suffix insertString:word atIndex:0];
if ([suffix length] >= length) *stop = YES;
}];
// Make sure we strip long words; note that we're casting to NSMutableString to prevent compiler warnings; although not good coding practice, it's safe in this case...
if ([prefix length] > length) prefix = (NSMutableString *)[prefix substringToIndex:length];
if ([suffix length] > length) suffix = (NSMutableString *)[suffix substringToIndex:length];
return [NSString stringWithFormat:@"%@…%@", prefix, suffix];
}
+ (NSUInteger)defaultNormalizedDescriptionLength {
return 35;
}
#pragma mark Getting information
+ (NSString *)stringByCombiningLines:(NSArray *)lines delimitWith:(NSString *)delimiter {
NSMutableString *result = [NSMutableString string];
if (!delimiter) delimiter = @"";
[lines enumerateObjectsUsingBlock:^(NSString *line, NSUInteger idx, BOOL *stop) {
if ([result length] > 0) [result appendString:delimiter];
[result appendString:line];
}];
return result;
}
- (NSArray *)arrayOfLines {
// Although we could use regex here, this gives us nicer results (strips all newlines for example), taken straight from Apple String Programming Guide.
NSMutableArray *result = [NSMutableArray array];
NSUInteger length = [self length];
NSUInteger paraStart = 0, paraEnd = 0, contentsEnd = 0;
NSRange currentRange;
while (paraEnd < length) {
[self getParagraphStart:¶Start end:¶End contentsEnd:&contentsEnd forRange:NSMakeRange(paraEnd, 0)];
currentRange = NSMakeRange(paraStart, contentsEnd - paraStart);
[result addObject:[self substringWithRange:currentRange]];
}
return result;
}
- (NSUInteger)numberOfLines {
if ([self length] == 0) return 0;
return [self numberOfLinesInRange:NSMakeRange(0, [self length])];
}
- (NSUInteger)numberOfLinesInRange:(NSRange)range {
NSString *substring = [self substringWithRange:range];
NSArray *lines = [substring componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
return [lines count];
}
@end
#pragma mark -
@implementation NSString (GBPrivateAPI)
- (unichar)lastCharacter {
return [self characterAtIndex:[self length] - 1];
}
- (NSArray *)arrayOfWords {
return [self componentsSeparatedByRegex:@"\\s+"];
}
@end