aboutsummaryrefslogtreecommitdiff
path: root/QSThingsPlugin/Helpers/TextParsingHelper.m
blob: 3fbbd3d2fc677ac10f68d55941ab3299843e2bf8 (plain)
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
#import "TextParsingHelper.h"

NS_ASSUME_NONNULL_BEGIN

@implementation TextParsingHelper

+ (NSMutableDictionary *)parseText:(NSString *)text {
    if (!text || [text length] == 0) {
        return nil;
    }
    
    NSArray *lines = [text componentsSeparatedByString:@"\n"];
    if ([lines count] == 0) {
        return nil;
    }
    
    NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
    NSMutableString *notes = nil;
    BOOL processingNotes = NO;
    
    for (NSInteger i = 0; i < [lines count]; i++) {
        NSString *line = [lines objectAtIndex:i];
        
        // The first line is always interpreted as the title. No matter what. Notes start with >>
        if (i == 0) {
            NSRange rangeOfSeparator = [line rangeOfString:@">>"];
            if (rangeOfSeparator.location != NSNotFound) {
                NSString *title = [line substringToIndex:rangeOfSeparator.location];
                NSString *notesPart = [line substringFromIndex:rangeOfSeparator.location + 2];
                
                if ([title length] > 0) {
                    [result setObject:title forKey:@"title"];
                }
                
                if ([notesPart length] > 0) {
                    notes = [[NSMutableString alloc] initWithString:notesPart];
                    processingNotes = YES;
                }
            } else {
                if ([line length] > 0) {
                    [result setObject:line forKey:@"title"];
                }
            }
        } else {
            if ([line length] > 0) {
                unichar firstChar = [line characterAtIndex:0];
                
              // Once we encounter a special line, we stop parsing notes.
              if (firstChar == '#' || firstChar == '@' || firstChar == '!') {
                    processingNotes = NO;
                    
                    NSString *content = nil;
                    if ([line length] > 1) {
                        content = [line substringFromIndex:1];
                    }
                    
                    if (content && [content length] > 0) {
                        switch (firstChar) {
                            case '#':
                                if (![result objectForKey:@"tags"]) {
                                    [result setObject:content forKey:@"tags"];
                                }
                                break;
                            case '@':
                                if (![result objectForKey:@"when"]) {
                                    [result setObject:content forKey:@"when"];
                                }
                                break;
                            case '!':
                                if (![result objectForKey:@"deadline"]) {
                                    [result setObject:content forKey:@"deadline"];
                                }
                                break;
                        }
                    }
                } else if (processingNotes) {
                    if (notes) {
                        [notes appendString:@"\n"];
                        [notes appendString:line];
                    } else {
                        notes = [[NSMutableString alloc] initWithString:line];
                    }
                }
            } else if (processingNotes) {
              // This is an empty notes line
              if (notes) {
                    [notes appendString:@"\n"];
                }
            }
        }
    }
    
    if (notes && [notes length] > 0) {
        [result setObject:[NSString stringWithString:notes] forKey:@"notes"];
    }
    
    if (notes) {
        [notes release];
    }
    
    if ([result count] == 0) {
        [result release];
        return nil;
    }
    
    return [result autorelease];
}

@end

NS_ASSUME_NONNULL_END