Source

Murky / Source / SourceHighlighting.m

Full commit
//
//  SourceHighlighting.m
//  Murky
//
//  Created by Jens Alfke on 9/2/09.
//  Copyright 2009 Jens Alfke. All rights reserved.
//

#import "SourceHighlighting.h"


NSMutableAttributedString* AttributedStringForSourceCode (NSString *code) {
    if (!code) return nil;
    NSFont *font = [NSFont fontWithName: @"Courier" size: 10.0f];
    NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init];
    paraStyle.lineBreakMode = NSLineBreakByClipping;
    NSDictionary *attrs = $dict({NSFontAttributeName, font},
                                {NSParagraphStyleAttributeName, paraStyle});
    return [[NSMutableAttributedString alloc] initWithString: code
                                                  attributes: attrs];
}


void HighlightDiffs (NSMutableAttributedString* text) {
    static NSDictionary *added, *deleted, *section;
    if (!added)
        added = $dict({NSForegroundColorAttributeName, 
            [NSColor colorWithCalibratedHue: 150/360.0f saturation: 1.0f
                                 brightness: 0.5f alpha: 1.0f]},
                      {NSBackgroundColorAttributeName, 
                          [NSColor colorWithCalibratedHue: 150/360.0f saturation: 0.05f
                                               brightness: 1.0f alpha: 1.0f]} );
    if (!deleted)
        deleted = $dict({NSForegroundColorAttributeName, 
            [NSColor colorWithCalibratedHue: 0.0f saturation: 0.6f
                                 brightness: 0.8f alpha: 1.0f]},
                        {NSBackgroundColorAttributeName, 
                            [NSColor colorWithCalibratedHue: 0.0f saturation: 0.05f
                                                 brightness: 1.0f alpha: 1.0f]} );
    if (!section)
        section = $dict({NSForegroundColorAttributeName, [NSColor whiteColor]},
                        {NSBackgroundColorAttributeName, [NSColor darkGrayColor]} );
    
    [text addAttribute: NSForegroundColorAttributeName
                 value: [NSColor grayColor] 
                 range: NSMakeRange(0,text.length)];
    NSUInteger nextStart, firstLineStart=0;
    for (NSUInteger start = 0,lineNo = 0; start < text.length; start=nextStart,lineNo++) {
        NSUInteger end;
        [text.string getLineStart: &start end: &nextStart contentsEnd: &end 
                         forRange: NSMakeRange(start,1)];
        NSDictionary *attrs;
        switch ([text.string characterAtIndex: start]) {
            case '+':   attrs = added; break;
            case '-':   attrs = deleted; break;
            case '@':
                attrs = section; 
                if (firstLineStart == 0)
                    firstLineStart = start;
                break;
            default:
                attrs = nil; break;
        }
        if (attrs)
            [text addAttributes: attrs range: NSMakeRange(start,nextStart-start)];
    }
    [text deleteCharactersInRange: NSMakeRange(0,firstLineStart)];
}