-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathSCKSyntaxHighlighter.m
100 lines (94 loc) · 3.38 KB
/
SCKSyntaxHighlighter.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
#import "SCKSyntaxHighlighter.h"
#import <Cocoa/Cocoa.h>
#import <EtoileFoundation/EtoileFoundation.h>
#import "SCKTextTypes.h"
#include <time.h>
static NSDictionary *noAttributes;
@implementation SCKSyntaxHighlighter
@synthesize tokenAttributes, semanticAttributes;
+ (void)initialize
{
noAttributes = [NSDictionary dictionary];
}
- (id)init
{
SUPERINIT;
NSDictionary *comment = D([NSColor grayColor], NSForegroundColorAttributeName);
NSDictionary *keyword = D([NSColor redColor], NSForegroundColorAttributeName);
NSDictionary *literal = D([NSColor redColor], NSForegroundColorAttributeName);
tokenAttributes = [D(
comment, SCKTextTokenTypeComment,
noAttributes, SCKTextTokenTypePunctuation,
keyword, SCKTextTokenTypeKeyword,
literal, SCKTextTokenTypeLiteral)
mutableCopy];
semanticAttributes = [D(
D([NSColor blueColor], NSForegroundColorAttributeName), SCKTextTypeDeclRef,
D([NSColor brownColor], NSForegroundColorAttributeName), SCKTextTypeMessageSend,
//D([NSColor greenColor], NSForegroundColorAttributeName), SCKTextTypeDeclaration,
D([NSColor magentaColor], NSForegroundColorAttributeName), SCKTextTypeMacroInstantiation,
D([NSColor magentaColor], NSForegroundColorAttributeName), SCKTextTypeMacroDefinition,
D([NSColor orangeColor], NSForegroundColorAttributeName), SCKTextTypePreprocessorDirective,
D([NSColor purpleColor], NSForegroundColorAttributeName), SCKTextTypeReference)
mutableCopy];
return self;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused"
- (void)transformString: (NSMutableAttributedString*)source;
{
clock_t c1 = clock();
NSUInteger end = [source length];
NSUInteger i = 0;
NSRange r;
do
{
NSDictionary *attrs = [source attributesAtIndex: i
longestEffectiveRange: &r
inRange: NSMakeRange(i, end-i)];
i = r.location + r.length;
NSString *token = [attrs objectForKey: kSCKTextTokenType];
NSString *semantic = [attrs objectForKey: kSCKTextSemanticType];
NSDictionary *diagnostic = [attrs objectForKey: kSCKDiagnostic];
// Skip ranges that have attributes other than semantic markup
if ((nil == semantic) && (nil == token)) continue;
if (semantic == SCKTextTypePreprocessorDirective)
{
attrs = [semanticAttributes objectForKey: semantic];
}
else if (token == nil || token != SCKTextTokenTypeIdentifier)
{
attrs = [tokenAttributes objectForKey: token];
}
else
{
NSString *semantic = [attrs objectForKey: kSCKTextSemanticType];
attrs = [semanticAttributes objectForKey: semantic];
//NSLog(@"Applying semantic attributes: %@", semantic);
}
if (nil == attrs)
{
attrs = noAttributes;
}
[source setAttributes: attrs
range: r];
// Re-apply the diagnostic
if (nil != diagnostic)
{
[source addAttribute: NSToolTipAttributeName
value: [diagnostic objectForKey: kSCKDiagnosticText]
range: r];
[source addAttribute: NSUnderlineStyleAttributeName
value: [NSNumber numberWithInt: NSSingleUnderlineStyle]
range: r];
[source addAttribute: NSUnderlineColorAttributeName
value: [NSColor redColor]
range: r];
}
} while (i < end);
clock_t c2 = clock();
//NSLog(@"Generating presentation markup took %f seconds. .",
// ((double)c2 - (double)c1) / (double)CLOCKS_PER_SEC);
}
#pragma clang diagnostic pop
@end