-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBCCiteKey.m
221 lines (148 loc) · 7.35 KB
/
BCCiteKey.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
//
// BCCiteKey.m
// Xynk
//
// Created by Tom Houpt on 15/2/23.
//
//
#import "BCCiteKey.h"
#import "BCStringExtensions.h"
NSInteger globalAnonCitationCount = 0;
@implementation BCCiteKey
@synthesize doi;
@synthesize firstAuthor;
@synthesize title;
@synthesize publicationYear;
@synthesize oldCiteKey;
@synthesize hasBeenDeleted;
-(id)init; {
return [self initWithAuthor:@"Anonymous" title:@"Untitled" year:-1 doi:nil];
}
-(id)initWithAuthor:(NSString *)a title:(NSString *)t year:(NSInteger)y doi:(NSString *)d; {
self = [super init];
if (self) {
if (nil != a) { self.firstAuthor = a; }
else { self.firstAuthor = [NSString stringWithFormat:@"Anonymous%ld",globalAnonCitationCount];
globalAnonCitationCount++;
}
if (nil != t) { self.title = t; }
else { self.title = @"Untitled"; }
if (nil != d) { self.doi = d; }
else { self.doi = [NSString string]; }
if (y != -1) {
publicationYear = y;
}
else {
publicationYear = [[[NSCalendar currentCalendar]
components:NSCalendarUnitYear fromDate:[NSDate date]]
year];
}
}
return self;
}
-(NSString *)citeKeyBase; {
// if no author name provided, use "Anonymous"
// otherwise, use canonical form of author name, and replace white space with dashes
// 2015-9-9 actually, the spec is wrong:
// need to delete white space, and dashes, and apostrophes (and all non-letter characters?)
// but preserve capitalization
// examples:
// Figueroa-Guzman-> FigueroaGuzman ; delete hyphen
// Hurd-Karrer -> HurdKarrer ; delete hyphen
// O'Reilly -> OReilly ; delete apostrophe
// Le Van -> LeVan ; delete space
// van Eersel-> vanEersel:
// van der Kooy-> vanderKooy ; delete multiple spaces
// Verboeket-van de Venne -> VerboeketvandeVenne ; delete hyphen and multiple spaces
NSString *author_name;
if (nil == firstAuthor || 0 == [firstAuthor length]) {
author_name = @"Anonymous";
}
else {
// // replace multiple whitespace with single whitespace, then with a dash
// NSString *authorWithWhiteSpaceCompressed = [firstAuthor stringByReplacingOccurrencesOfString:@"\\s+"
// withString:@" "
// options:NSRegularExpressionSearch
// range:NSMakeRange(0, firstAuthor.length)];
//
// NSString *trimmedAuthor = [authorWithWhiteSpaceCompressed stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// author_name = [[trimmedAuthor decomposedStringWithCanonicalMapping] stringWithDashesForWhiteSpace];
#define excluded_author_characters_set @" ‘’‛“”‟\"\'-—–-—"
NSCharacterSet *excludeCharactersSet = [NSCharacterSet characterSetWithCharactersInString:excluded_author_characters_set ];
NSString *excludedString = [[firstAuthor componentsSeparatedByCharactersInSet:excludeCharactersSet] componentsJoinedByString:@""];
author_name = [excludedString decomposedStringWithCanonicalMapping];
}
NSString *citeKeyBase = [NSString stringWithFormat:@"%@:%ld",author_name,(long)publicationYear];
return citeKeyBase;
}
-(NSString *)doiCiteKey; {
NSString * ucDoi;
if (nil == doi || 0 == [doi length]) {
// nil string if no doi provided
ucDoi = nil;
}
else {
NSString *doiHash = [self doiHash:doi];
ucDoi = [NSString stringWithFormat:@"%@%@",[self citeKeyBase],doiHash];
}
return ucDoi;
}
-(NSString *)doiHash:(NSString *)theDoi; {
// need to confirm that crc32 uses same table as Papers citekey
UInt32 crcDoi = [theDoi crc32];
char doiHash1 = 'b' + (char)floor((crcDoi % (10 * 26))/26);
char doiHash2 = 'a' + (char)(crcDoi % 26);
return [NSString stringWithFormat:@"%c%c",doiHash1,doiHash2];
}
-(NSString *)titleCiteKey; {
NSString * ucTitle;
if (nil == title || 0 == [title length]) {
// nil string if no doi provided
ucTitle = nil;
}
else {
NSString *titleHash = [self titleHash:title];
ucTitle = [NSString stringWithFormat:@"%@%@",[self citeKeyBase],titleHash];
}
return ucTitle;
}
-(NSString *)titleHash:(NSString *)theTitle; {
// remove excluded characters
// var excluded_characters = "±˙˜´‘’‛“”‟·•!¿¡#∞£¥$%‰&˝¨ˆ¯˘¸˛^~√∫*§◊¬¶†‡≤≥÷:ªº\"\'©®™";
// replace characters with a space
// var replaced_characetrs = "°˚+-–—_…,.;ı(){}‹›<>«=≈?|/\\";
// replace multiple whitespace with single whitespace
// convert strings to "canonical form"
// see http://unicode.org/reports/tr15/
// see http://www.objc.io/issue-9/unicode.html
// I think Papers citekey uses equivalent of [NSString decomposedStringWithCanonicalMapping]
// and not precomposedStringWithCanonicalMapping
#define excluded_characters_set @"±˙˜´‘’‛“”‟·•!¿¡#∞£¥$%‰&˝¨ˆ¯˘¸˛^~√∫*§◊¬¶†‡≤≥÷:ªº\"\'©®™"
#define replaced_characters_set @"°˚+-–—_…,.;ı(){}‹›<>«=≈?|/\\"
NSCharacterSet *excludeCharactersSet = [NSCharacterSet characterSetWithCharactersInString:excluded_characters_set ];
NSCharacterSet *replaceCharactersSet = [NSCharacterSet characterSetWithCharactersInString:replaced_characters_set ];
NSString *excludedString = [[theTitle componentsSeparatedByCharactersInSet:excludeCharactersSet] componentsJoinedByString:@""];
NSString *replacedString = [[excludedString componentsSeparatedByCharactersInSet:replaceCharactersSet] componentsJoinedByString:@" "];
NSString *titleWithWhiteSpaceCompressed = [replacedString stringByReplacingOccurrencesOfString:@"\\s+"
withString:@" "
options:NSRegularExpressionSearch
range:NSMakeRange(0, replacedString.length)];
NSString *trimmedTitle = [titleWithWhiteSpaceCompressed stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// get canonical version
NSString *canonicalTitle = [[trimmedTitle lowercaseString] decomposedStringWithCanonicalMapping];
UInt32 crcTitle = [canonicalTitle crc32];
char titleHash1 = 't' + (char)floor((crcTitle % (4 * 26))/26);
char titleHash2 = 'a' + (char)(crcTitle % 26);
return [NSString stringWithFormat:@"%c%c",titleHash1,titleHash2];
}
-(NSString *)citeKey; {
NSString *citeKey = [self doiCiteKey];
if (nil == citeKey) {
citeKey = [self titleCiteKey];
}
return citeKey;
}
-(NSString *)citeKeyInBrackets; {
return [NSString stringWithFormat:@"{%@}",self.citeKey];
}
@end