Skip to content

Commit

Permalink
Fix original attribute string display. Fix issue #37, #38 and #35.
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Chen committed Nov 17, 2015
1 parent 04c1cc1 commit 5b44cfe
Show file tree
Hide file tree
Showing 8 changed files with 273 additions and 229 deletions.
8 changes: 8 additions & 0 deletions MCLog.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
8CBAF63C198B88C70067171A /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8CBAF63B198B88C70067171A /* CoreFoundation.framework */; };
8CBAF642198B88C70067171A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8CBAF640198B88C70067171A /* InfoPlist.strings */; };
8CBAF64B198B88DD0067171A /* MCLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CBAF64A198B88DD0067171A /* MCLog.m */; };
8CEB067E1BFADD0F00ED4438 /* MCDVTTextStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 8CEB067D1BFADD0F00ED4438 /* MCDVTTextStorage.m */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -20,6 +21,9 @@
8CBAF643198B88C70067171A /* MCLog-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "MCLog-Prefix.pch"; sourceTree = "<group>"; };
8CBAF649198B88DD0067171A /* MCLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCLog.h; sourceTree = "<group>"; };
8CBAF64A198B88DD0067171A /* MCLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MCLog.m; sourceTree = "<group>"; };
8CEB067B1BFADA1700ED4438 /* MCXcodeHeaders.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCXcodeHeaders.h; sourceTree = "<group>"; };
8CEB067C1BFADD0F00ED4438 /* MCDVTTextStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCDVTTextStorage.h; sourceTree = "<group>"; };
8CEB067D1BFADD0F00ED4438 /* MCDVTTextStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MCDVTTextStorage.m; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -65,6 +69,9 @@
8CBAF63E198B88C70067171A /* Supporting Files */,
8CBAF649198B88DD0067171A /* MCLog.h */,
8CBAF64A198B88DD0067171A /* MCLog.m */,
8CEB067C1BFADD0F00ED4438 /* MCDVTTextStorage.h */,
8CEB067D1BFADD0F00ED4438 /* MCDVTTextStorage.m */,
8CEB067B1BFADA1700ED4438 /* MCXcodeHeaders.h */,
);
path = MCLog;
sourceTree = "<group>";
Expand Down Expand Up @@ -142,6 +149,7 @@
buildActionMask = 2147483647;
files = (
8CBAF64B198B88DD0067171A /* MCLog.m in Sources */,
8CEB067E1BFADD0F00ED4438 /* MCDVTTextStorage.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,27 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugXPCServices = "NO"
allowLocationSimulation = "YES">
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
viewDebuggingEnabled = "No">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
Expand All @@ -53,10 +57,10 @@
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
Expand Down
21 changes: 21 additions & 0 deletions MCLog/MCDVTTextStorage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// MCDVTTextStorage.h
// MCLog
//
// Created by Michael Chen on 2015/11/17.
// Copyright © 2015年 Yuhua Chen. All rights reserved.
//

#import "MCXcodeHeaders.h"

@interface NSTextStorage (MCDVTTextStorage)

- (void)mc_fixAttributesInRange:(NSRange)range;
- (void)updateAttributes:(NSMutableDictionary *)attrs withANSIESCString:(NSString *)ansiEscString;

- (void)setLastAttribute:(NSDictionary *)attribute;
- (NSDictionary *)lastAttribute;
- (void)setConsoleStorage:(BOOL)consoleStorage;
- (BOOL)consoleStorage;

@end
187 changes: 187 additions & 0 deletions MCLog/MCDVTTextStorage.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
//
// MCDVTTextStorage.m
// MCLog
//
// Created by Michael Chen on 2015/11/17.
// Copyright © 2015年 Yuhua Chen. All rights reserved.
//

#import "MCDVTTextStorage.h"
#import <objc/runtime.h>

#define NSColorWithHexRGB(rgb) [NSColor colorWithCalibratedRed:((rgb) >> 16 & 0xFF) / 255.f green:((rgb) >> 8 & 0xFF) / 255.f blue:((rgb) & 0xFF) / 255.f alpha:1.f]

NSRegularExpression * escCharPattern();

@implementation NSTextStorage (MCDVTTextStorage)

- (void)mc_fixAttributesInRange:(NSRange)range
{
[self mc_fixAttributesInRange:range];

if (!self.consoleStorage) {
return;
}

__block NSRange lastRange = NSMakeRange(range.location, 0);
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
if (self.lastAttribute.count > 0) {
[attrs setValuesForKeysWithDictionary:self.lastAttribute];
}

[escCharPattern() enumerateMatchesInString:self.string options:0 range:range usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
if (attrs.count > 0) {
NSRange attrRange = NSMakeRange(lastRange.location, result.range.location - lastRange.location);
[self addAttributes:attrs range:attrRange];
//MCLogger(@"apply attributes:%@\nin range:[%zd, %zd], affected string:%@", attrs, attrRange.location, attrRange.length, [self.string substringWithRange:attrRange]);
}

NSString *attrsDesc = [self.string substringWithRange:[result rangeAtIndex:1]];
if (attrsDesc.length == 0) {
[self addAttributes:@{
NSFontAttributeName: [NSFont systemFontOfSize:0.000001f],
NSForegroundColorAttributeName: [NSColor clearColor]
}
range:result.range];
lastRange = result.range;
return;
}
[self updateAttributes:attrs withANSIESCString:attrsDesc];
[self addAttributes:@{
NSFontAttributeName: [NSFont systemFontOfSize:0.000001f],
NSForegroundColorAttributeName: [NSColor clearColor]
}
range:result.range];
lastRange = result.range;
}];
self.lastAttribute = attrs;
}

- (void)updateAttributes:(NSMutableDictionary *)attrs withANSIESCString:(NSString *)ansiEscString
{
NSArray *attrComponents = [ansiEscString componentsSeparatedByString:@";"];
for (NSString *attrName in attrComponents) {
NSUInteger attrCode = [attrName integerValue];
switch (attrCode) {
case 0:
[attrs removeAllObjects];
break;

case 1:
[attrs setObject:[NSFont boldSystemFontOfSize:11.f] forKey:NSFontAttributeName];
break;

case 4:
[attrs setObject:@( NSUnderlineStyleSingle ) forKey:NSUnderlineStyleAttributeName];
break;

case 24:
[attrs setObject:@(NSUnderlineStyleNone ) forKey:NSUnderlineStyleAttributeName];
break;
//foreground color
case 30: //black
[attrs setObject:[NSColor blackColor] forKey:NSForegroundColorAttributeName];
break;

case 31: // Red
[attrs setObject:NSColorWithHexRGB(0xd70000) forKey:NSForegroundColorAttributeName];
break;

case 32: // Green
[attrs setObject:NSColorWithHexRGB(0x00ff00) forKey:NSForegroundColorAttributeName];
break;

case 33: // Yellow
[attrs setObject:NSColorWithHexRGB(0xffff00) forKey:NSForegroundColorAttributeName];
break;

case 34: // Blue
[attrs setObject:NSColorWithHexRGB(0x005fff) forKey:NSForegroundColorAttributeName];
break;

case 35: // purple
[attrs setObject:NSColorWithHexRGB(0xff00ff) forKey:NSForegroundColorAttributeName];
break;

case 36: // cyan
[attrs setObject:NSColorWithHexRGB(0x00ffff) forKey:NSForegroundColorAttributeName];
break;

case 37: // gray
[attrs setObject:NSColorWithHexRGB(0x808080) forKey:NSForegroundColorAttributeName];
break;
//background color
case 40: //black
[attrs setObject:[NSColor blackColor] forKey:NSBackgroundColorAttributeName];
break;

case 41: // Red
[attrs setObject:NSColorWithHexRGB(0xd70000) forKey:NSBackgroundColorAttributeName];
break;

case 42: // Green
[attrs setObject:NSColorWithHexRGB(0x00ff00) forKey:NSBackgroundColorAttributeName];
break;

case 43: // Yellow
[attrs setObject:NSColorWithHexRGB(0xffff00) forKey:NSBackgroundColorAttributeName];
break;

case 44: // Blue
[attrs setObject:NSColorWithHexRGB(0x005fff) forKey:NSBackgroundColorAttributeName];
break;

case 45: // purple
[attrs setObject:NSColorWithHexRGB(0xff00ff) forKey:NSBackgroundColorAttributeName];
break;

case 46: // cyan
[attrs setObject:NSColorWithHexRGB(0x00ffff) forKey:NSBackgroundColorAttributeName];
break;

case 47: // gray
[attrs setObject:NSColorWithHexRGB(0x808080) forKey:NSBackgroundColorAttributeName];
break;

default:
break;
}
}
}

- (void)setLastAttribute:(NSDictionary *)attribute
{
objc_setAssociatedObject(self, @selector(lastAttribute), attribute, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSDictionary *)lastAttribute
{
return objc_getAssociatedObject(self, @selector(lastAttribute));
}

- (void)setConsoleStorage:(BOOL)consoleStorage
{
objc_setAssociatedObject(self, @selector(consoleStorage), @(consoleStorage), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (BOOL)consoleStorage
{
return [objc_getAssociatedObject(self, @selector(consoleStorage)) boolValue];
}

@end

#pragma mark - Utilities

NSRegularExpression * escCharPattern()
{
static NSRegularExpression *pattern = nil;
if (pattern == nil) {
NSError *error = nil;
pattern = [NSRegularExpression regularExpressionWithPattern:(LC_ESC @"\\[([\\d;]*\\d+)m") options:0 error:&error];
if (!pattern) {
MCLogger(@"%@", error);
}
}
return pattern;
}
16 changes: 16 additions & 0 deletions MCLog/MCLog-Prefix.pch
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,19 @@
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif

#if TARGET_OS_IPHONE
#define LC_ESC @"\xC2\xA0"
#else
#define LC_ESC @"\033"
#endif

// Reset colors
#define LC_RESET LC_ESC @"[0m"

// Defaults

#define MCLOG_FLAG "MCLOG_FLAG"
#define kTagSearchField 99

#define MCLogger(fmt, ...) NSLog((@"[MCLog] %s(Line:%d) " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
13 changes: 1 addition & 12 deletions MCLog/MCLog.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,7 @@
// Copyright (c) 2014年 Yuhua Chen. All rights reserved.
//

#import <Foundation/Foundation.h>

#if TARGET_OS_IPHONE
#define LC_ESC @"\xC2\xA0"
#else
#define LC_ESC @"\033"
#endif



// Reset colors
#define LC_RESET LC_ESC @"[0m"
@import Foundation;

@interface MCLog : NSObject
+ (void)pluginDidLoad:(NSBundle *)bundle;
Expand Down
Loading

0 comments on commit 5b44cfe

Please sign in to comment.