Revision: 3309
http://skim-app.svn.sourceforge.net/skim-app/?rev=3309&view=rev
Author: hofman
Date: 2007-12-04 07:01:39 -0800 (Tue, 04 Dec 2007)
Log Message:
-----------
Add support for counter in collections in templates.
Modified Paths:
--------------
trunk/SKTemplateParser.h
trunk/SKTemplateParser.m
Modified: trunk/SKTemplateParser.h
===================================================================
--- trunk/SKTemplateParser.h 2007-12-03 20:53:46 UTC (rev 3308)
+++ trunk/SKTemplateParser.h 2007-12-04 15:01:39 UTC (rev 3309)
@@ -43,11 +43,11 @@
+ (NSString *)stringByParsingTemplate:(NSString *)template
usingObject:(id)object;
+ (NSArray *)arrayByParsingTemplateString:(NSString *)template;
-+ (NSString *)stringFromTemplateArray:(NSArray *)template
usingObject:(id)object;
++ (NSString *)stringFromTemplateArray:(NSArray *)template
usingObject:(id)object atIndex:(int)anIndex;
+ (NSAttributedString *)attributedStringByParsingTemplate:(NSAttributedString
*)template usingObject:(id)object;
+ (NSArray *)arrayByParsingTemplateAttributedString:(NSAttributedString
*)template;
-+ (NSAttributedString *)attributedStringFromTemplateArray:(NSArray *)template
usingObject:(id)object;
++ (NSAttributedString *)attributedStringFromTemplateArray:(NSArray *)template
usingObject:(id)object atIndex:(int)anIndex;
@end
@@ -70,11 +70,20 @@
- (NSData *)RTFRepresentation;
@end
+
@interface NSString (SKTemplateParser)
- (NSString *)xmlString;
@end
[EMAIL PROTECTED] NSNumber (SKTemplateParser)
+- (NSNumber *)numberByAddingOne;
+- (NSString *)romanNumeralValue;
+- (NSString *)alphaCounterValue;
+- (NSString *)greekCounterValue;
[EMAIL PROTECTED]
+
+
@interface NSData (SKTemplateParser)
- (NSString *)xmlString;
@end
Modified: trunk/SKTemplateParser.m
===================================================================
--- trunk/SKTemplateParser.m 2007-12-03 20:53:46 UTC (rev 3308)
+++ trunk/SKTemplateParser.m 2007-12-04 15:01:39 UTC (rev 3309)
@@ -87,7 +87,7 @@
OBINITIALIZE;
NSMutableCharacterSet *tmpSet = [[NSCharacterSet alphanumericCharacterSet]
mutableCopy];
- [tmpSet addCharactersInString:@".-:;@"];
+ [tmpSet addCharactersInString:@".-:;@#"];
keyCharacterSet = [tmpSet copy];
[tmpSet release];
@@ -221,7 +221,7 @@
#pragma mark Parsing string templates
+ (NSString *)stringByParsingTemplate:(NSString *)template
usingObject:(id)object {
- return [self stringFromTemplateArray:[self
arrayByParsingTemplateString:template] usingObject:object];
+ return [self stringFromTemplateArray:[self
arrayByParsingTemplateString:template] usingObject:object atIndex:1];
}
+ (NSArray *)arrayByParsingTemplateString:(NSString *)template {
@@ -414,87 +414,100 @@
return [result autorelease];
}
-+ (NSString *)stringFromTemplateArray:(NSArray *)template
usingObject:(id)object {
++ (NSString *)stringFromTemplateArray:(NSArray *)template
usingObject:(id)object atIndex:(int)anIndex {
NSEnumerator *tagEnum = [template objectEnumerator];
id tag;
NSMutableString *result = [[NSMutableString alloc] init];
while (tag = [tagEnum nextObject]) {
int type = [(SKTag *)tag type];
- id keyValue = nil;
if (type == SKTextTagType) {
[result appendString:[tag text]];
- } else if (type == SKValueTagType) {
+ } else {
- if (keyValue = [object safeValueForKeyPath:[tag keyPath]])
- [result appendString:[keyValue stringDescription]];
+ NSString *keyPath = [tag keyPath];
+ id keyValue = nil;
- } else if (type == SKCollectionTagType) {
-
- keyValue = [object safeValueForKeyPath:[tag keyPath]];
- if ([keyValue respondsToSelector:@selector(objectEnumerator)]) {
- NSEnumerator *itemE = [keyValue objectEnumerator];
- id nextItem, item = [itemE nextObject];
- NSArray *itemTemplate = [[tag itemTemplate]
arrayByAddingObjectsFromArray:[tag separatorTemplate]];
- while (item) {
- nextItem = [itemE nextObject];
- if (nextItem == nil)
- itemTemplate = [tag itemTemplate];
- keyValue = [self stringFromTemplateArray:itemTemplate
usingObject:item];
- if (keyValue != nil)
- [result appendString:keyValue];
- item = nextItem;
- }
+ if ([keyPath hasPrefix:@"#"]) {
+ keyValue = [NSNumber numberWithInt:anIndex];
+ if ([keyPath hasPrefix:@"#."] && [keyPath length] > 2)
+ keyValue = [keyValue safeValueForKeyPath:[keyPath
substringFromIndex:2]];
+ } else {
+ keyValue = [object safeValueForKeyPath:keyPath];
}
- } else {
-
- NSString *matchString = nil;
- BOOL isMatch;
- NSArray *matchStrings = [tag matchStrings];
- unsigned int i, count = [matchStrings count];
- NSArray *subtemplate = nil;
-
- keyValue = [object safeValueForKeyPath:[tag keyPath]];
- for (i = 0; i < count; i++) {
- matchString = [matchStrings objectAtIndex:i];
- if ([matchString hasPrefix:@"$"]) {
- matchString = [[object safeValueForKeyPath:[matchString
substringFromIndex:1]] stringDescription];
- if (matchString == nil)
- matchString = @"";
+ if (type == SKValueTagType) {
+
+ if (keyValue)
+ [result appendString:[keyValue stringDescription]];
+
+ } else if (type == SKCollectionTagType) {
+
+ if ([keyValue respondsToSelector:@selector(objectEnumerator)])
{
+ NSEnumerator *itemE = [keyValue objectEnumerator];
+ id nextItem, item = [itemE nextObject];
+ NSArray *itemTemplate = [[tag itemTemplate]
arrayByAddingObjectsFromArray:[tag separatorTemplate]];
+ int idx = 0;
+ while (item) {
+ nextItem = [itemE nextObject];
+ if (nextItem == nil)
+ itemTemplate = [tag itemTemplate];
+ keyValue = [self stringFromTemplateArray:itemTemplate
usingObject:item atIndex:++idx];
+ if (keyValue != nil)
+ [result appendString:keyValue];
+ item = nextItem;
+ }
}
- switch ([tag matchType]) {
- case SKConditionTagMatchEqual:
- isMatch = [matchString isEqualToString:@""] ? NO ==
[keyValue isNotEmpty] : [[keyValue stringDescription]
caseInsensitiveCompare:matchString] == NSOrderedSame;
+
+ } else {
+
+ NSString *matchString = nil;
+ BOOL isMatch;
+ NSArray *matchStrings = [tag matchStrings];
+ unsigned int i, count = [matchStrings count];
+ NSArray *subtemplate = nil;
+
+ for (i = 0; i < count; i++) {
+ matchString = [matchStrings objectAtIndex:i];
+ if ([matchString hasPrefix:@"$"]) {
+ matchString = [[object
safeValueForKeyPath:[matchString substringFromIndex:1]] stringDescription];
+ if (matchString == nil)
+ matchString = @"";
+ }
+ switch ([tag matchType]) {
+ case SKConditionTagMatchEqual:
+ isMatch = [matchString isEqualToString:@""] ? NO
== [keyValue isNotEmpty] : [[keyValue stringDescription]
caseInsensitiveCompare:matchString] == NSOrderedSame;
+ break;
+ case SKConditionTagMatchContain:
+ isMatch = [matchString isEqualToString:@""] ? NO
== [keyValue isNotEmpty] : [[keyValue stringDescription]
rangeOfString:matchString options:NSCaseInsensitiveSearch].location !=
NSNotFound;
+ break;
+ case SKConditionTagMatchSmaller:
+ isMatch = [matchString isEqualToString:@""] ? NO
== [keyValue isNotEmpty] : [[keyValue stringDescription]
localizedCaseInsensitiveNumericCompare:matchString] == NSOrderedAscending;
+ break;
+ case SKConditionTagMatchSmallerOrEqual:
+ isMatch = [matchString isEqualToString:@""] ? NO
== [keyValue isNotEmpty] : [[keyValue stringDescription]
localizedCaseInsensitiveNumericCompare:matchString] != NSOrderedDescending;
+ break;
+ default:
+ isMatch = [keyValue isNotEmpty];
+ break;
+ }
+ if (isMatch) {
+ subtemplate = [tag subtemplateAtIndex:i];
break;
- case SKConditionTagMatchContain:
- isMatch = [matchString isEqualToString:@""] ? NO ==
[keyValue isNotEmpty] : [[keyValue stringDescription] rangeOfString:matchString
options:NSCaseInsensitiveSearch].location != NSNotFound;
- break;
- case SKConditionTagMatchSmaller:
- isMatch = [matchString isEqualToString:@""] ? NO ==
[keyValue isNotEmpty] : [[keyValue stringDescription]
localizedCaseInsensitiveNumericCompare:matchString] == NSOrderedAscending;
- break;
- case SKConditionTagMatchSmallerOrEqual:
- isMatch = [matchString isEqualToString:@""] ? NO ==
[keyValue isNotEmpty] : [[keyValue stringDescription]
localizedCaseInsensitiveNumericCompare:matchString] != NSOrderedDescending;
- break;
- default:
- isMatch = [keyValue isNotEmpty];
- break;
+ }
}
- if (isMatch) {
- subtemplate = [tag subtemplateAtIndex:i];
- break;
+ if (subtemplate == nil && [[tag subtemplates] count] > count) {
+ subtemplate = [tag subtemplateAtIndex:count];
}
+ if (subtemplate != nil) {
+ keyValue = [self stringFromTemplateArray:subtemplate
usingObject:object atIndex:anIndex];
+ [result appendString:keyValue];
+ }
+
}
- if (subtemplate == nil && [[tag subtemplates] count] > count) {
- subtemplate = [tag subtemplateAtIndex:count];
- }
- if (subtemplate != nil) {
- keyValue = [self stringFromTemplateArray:subtemplate
usingObject:object];
- [result appendString:keyValue];
- }
}
} // while
@@ -505,7 +518,7 @@
#pragma mark Parsing attributed string templates
+ (NSAttributedString *)attributedStringByParsingTemplate:(NSAttributedString
*)template usingObject:(id)object {
- return [self attributedStringFromTemplateArray:[self
arrayByParsingTemplateAttributedString:template] usingObject:object];
+ return [self attributedStringFromTemplateArray:[self
arrayByParsingTemplateAttributedString:template] usingObject:object atIndex:1];
}
+ (NSArray *)arrayByParsingTemplateAttributedString:(NSAttributedString
*)template {
@@ -717,97 +730,110 @@
return [result autorelease];
}
-+ (NSAttributedString *)attributedStringFromTemplateArray:(NSArray *)template
usingObject:(id)object {
++ (NSAttributedString *)attributedStringFromTemplateArray:(NSArray *)template
usingObject:(id)object atIndex:(int)anIndex {
NSEnumerator *tagEnum = [template objectEnumerator];
id tag;
NSMutableAttributedString *result = [[NSMutableAttributedString alloc]
init];
while (tag = [tagEnum nextObject]) {
int type = [(SKTag *)tag type];
- id keyValue = nil;
NSAttributedString *tmpAttrStr = nil;
if (type == SKTextTagType) {
[result appendAttributedString:[tag attributedText]];
- } else if (type == SKValueTagType) {
+ } else {
- if (keyValue = [object safeValueForKeyPath:[tag keyPath]]) {
- if ([keyValue isKindOfClass:[NSAttributedString class]]) {
- tmpAttrStr = [[NSAttributedString alloc]
initWithAttributedString:keyValue attributes:[(SKRichValueTag *)tag
attributes]];
- } else {
- tmpAttrStr = [[NSAttributedString alloc]
initWithString:[keyValue stringDescription] attributes:[(SKRichValueTag *)tag
attributes]];
- }
- [result appendAttributedString:tmpAttrStr];
- [tmpAttrStr release];
- }
+ NSString *keyPath = [tag keyPath];
+ id keyValue = nil;
- } else if (type == SKCollectionTagType) {
-
- keyValue = [object safeValueForKeyPath:[tag keyPath]];
- if ([keyValue respondsToSelector:@selector(objectEnumerator)]) {
- NSEnumerator *itemE = [keyValue objectEnumerator];
- id nextItem, item = [itemE nextObject];
- NSArray *itemTemplate = [[tag itemTemplate]
arrayByAddingObjectsFromArray:[tag separatorTemplate]];
- while (item) {
- nextItem = [itemE nextObject];
- if (nextItem == nil)
- itemTemplate = [tag itemTemplate];
- tmpAttrStr = [self
attributedStringFromTemplateArray:itemTemplate usingObject:item];
- if (tmpAttrStr != nil)
- [result appendAttributedString:tmpAttrStr];
- item = nextItem;
- }
+ if ([keyPath hasPrefix:@"#"]) {
+ keyValue = [NSNumber numberWithInt:anIndex];
+ if ([keyPath hasPrefix:@"#."] && [keyPath length] > 2)
+ keyValue = [keyValue safeValueForKeyPath:[keyPath
substringFromIndex:2]];
+ } else {
+ keyValue = [object safeValueForKeyPath:keyPath];
}
- } else {
-
- NSString *matchString = nil;
- BOOL isMatch;
- NSArray *matchStrings = [tag matchStrings];
- unsigned int i, count = [matchStrings count];
- NSArray *subtemplate = nil;
-
- keyValue = [object safeValueForKeyPath:[tag keyPath]];
- count = [matchStrings count];
- subtemplate = nil;
- for (i = 0; i < count; i++) {
- matchString = [matchStrings objectAtIndex:i];
- if ([matchString hasPrefix:@"$"]) {
- matchString = [[object safeValueForKeyPath:[matchString
substringFromIndex:1]] stringDescription];
- if (matchString == nil)
- matchString = @"";
+ if (type == SKValueTagType) {
+
+ if (keyValue) {
+ if ([keyValue isKindOfClass:[NSAttributedString class]]) {
+ tmpAttrStr = [[NSAttributedString alloc]
initWithAttributedString:keyValue attributes:[(SKRichValueTag *)tag
attributes]];
+ } else {
+ tmpAttrStr = [[NSAttributedString alloc]
initWithString:[keyValue stringDescription] attributes:[(SKRichValueTag *)tag
attributes]];
+ }
+ [result appendAttributedString:tmpAttrStr];
+ [tmpAttrStr release];
}
- switch ([tag matchType]) {
- case SKConditionTagMatchEqual:
- isMatch = [matchString isEqualToString:@""] ? NO ==
[keyValue isNotEmpty] : [[keyValue stringDescription]
caseInsensitiveCompare:matchString] == NSOrderedSame;
+
+ } else if (type == SKCollectionTagType) {
+
+ if ([keyValue respondsToSelector:@selector(objectEnumerator)])
{
+ NSEnumerator *itemE = [keyValue objectEnumerator];
+ id nextItem, item = [itemE nextObject];
+ NSArray *itemTemplate = [[tag itemTemplate]
arrayByAddingObjectsFromArray:[tag separatorTemplate]];
+ int idx = 0;
+ while (item) {
+ nextItem = [itemE nextObject];
+ if (nextItem == nil)
+ itemTemplate = [tag itemTemplate];
+ tmpAttrStr = [self
attributedStringFromTemplateArray:itemTemplate usingObject:item atIndex:++idx];
+ if (tmpAttrStr != nil)
+ [result appendAttributedString:tmpAttrStr];
+ item = nextItem;
+ }
+ }
+
+ } else {
+
+ NSString *matchString = nil;
+ BOOL isMatch;
+ NSArray *matchStrings = [tag matchStrings];
+ unsigned int i, count = [matchStrings count];
+ NSArray *subtemplate = nil;
+
+ count = [matchStrings count];
+ subtemplate = nil;
+ for (i = 0; i < count; i++) {
+ matchString = [matchStrings objectAtIndex:i];
+ if ([matchString hasPrefix:@"$"]) {
+ matchString = [[object
safeValueForKeyPath:[matchString substringFromIndex:1]] stringDescription];
+ if (matchString == nil)
+ matchString = @"";
+ }
+ switch ([tag matchType]) {
+ case SKConditionTagMatchEqual:
+ isMatch = [matchString isEqualToString:@""] ? NO
== [keyValue isNotEmpty] : [[keyValue stringDescription]
caseInsensitiveCompare:matchString] == NSOrderedSame;
+ break;
+ case SKConditionTagMatchContain:
+ isMatch = [matchString isEqualToString:@""] ? NO
== [keyValue isNotEmpty] : [[keyValue stringDescription]
rangeOfString:matchString options:NSCaseInsensitiveSearch].location !=
NSNotFound;
+ break;
+ case SKConditionTagMatchSmaller:
+ isMatch = [matchString isEqualToString:@""] ? NO
== [keyValue isNotEmpty] : [[keyValue stringDescription]
localizedCaseInsensitiveNumericCompare:matchString] == NSOrderedAscending;
+ break;
+ case SKConditionTagMatchSmallerOrEqual:
+ isMatch = [matchString isEqualToString:@""] ? NO
== [keyValue isNotEmpty] : [[keyValue stringDescription]
localizedCaseInsensitiveNumericCompare:matchString] != NSOrderedDescending;
+ break;
+ default:
+ isMatch = [keyValue isNotEmpty];
+ break;
+ }
+ if (isMatch) {
+ subtemplate = [tag subtemplateAtIndex:i];
break;
- case SKConditionTagMatchContain:
- isMatch = [matchString isEqualToString:@""] ? NO ==
[keyValue isNotEmpty] : [[keyValue stringDescription] rangeOfString:matchString
options:NSCaseInsensitiveSearch].location != NSNotFound;
- break;
- case SKConditionTagMatchSmaller:
- isMatch = [matchString isEqualToString:@""] ? NO ==
[keyValue isNotEmpty] : [[keyValue stringDescription]
localizedCaseInsensitiveNumericCompare:matchString] == NSOrderedAscending;
- break;
- case SKConditionTagMatchSmallerOrEqual:
- isMatch = [matchString isEqualToString:@""] ? NO ==
[keyValue isNotEmpty] : [[keyValue stringDescription]
localizedCaseInsensitiveNumericCompare:matchString] != NSOrderedDescending;
- break;
- default:
- isMatch = [keyValue isNotEmpty];
- break;
+ }
}
- if (isMatch) {
- subtemplate = [tag subtemplateAtIndex:i];
- break;
+ if (subtemplate == nil && [[tag subtemplates] count] > count) {
+ subtemplate = [tag subtemplateAtIndex:count];
}
+ if (subtemplate != nil) {
+ tmpAttrStr = [self
attributedStringFromTemplateArray:subtemplate usingObject:object
atIndex:anIndex];
+ [result appendAttributedString:tmpAttrStr];
+ }
+
}
- if (subtemplate == nil && [[tag subtemplates] count] > count) {
- subtemplate = [tag subtemplateAtIndex:count];
- }
- if (subtemplate != nil) {
- tmpAttrStr = [self
attributedStringFromTemplateArray:subtemplate usingObject:object];
- [result appendAttributedString:tmpAttrStr];
- }
}
} // while
@@ -978,6 +1004,62 @@
return [self isEqualToNumber:[NSNumber numberWithBool:NO]] == NO;
}
+inline static NSString *romanNumeralForDigit(unsigned digit, NSString *i,
NSString *v, NSString *x){
+ switch (digit) {
+ case 1: return i;
+ case 2: return [NSString stringWithFormat:@"[EMAIL PROTECTED]@", i, i];
+ case 3: return [NSString stringWithFormat:@"[EMAIL PROTECTED]@%@", i,
i, i];
+ case 4: return [NSString stringWithFormat:@"[EMAIL PROTECTED]@", i, v];
+ case 5: return v;
+ case 6: return [NSString stringWithFormat:@"[EMAIL PROTECTED]@", v, i];
+ case 7: return [NSString stringWithFormat:@"[EMAIL PROTECTED]@%@", v,
i, i];
+ case 8: return [NSString stringWithFormat:@"[EMAIL PROTECTED]@[EMAIL
PROTECTED]@", v, i, i, i];
+ case 9: return [NSString stringWithFormat:@"[EMAIL PROTECTED]@", i, x];
+ default: return @"";
+ }
+}
+
+- (NSString *)romanNumeralValue{
+ static NSString *symbols[9] = {@"i", @"v", @"x", @"l", @"c", @"d", @"m",
@"mmm", @""};
+
+ NSMutableString *string = [NSMutableString string];
+ unsigned digit, offset, number = [self unsignedIntValue];
+
+ if (number >= 5000)
+ [NSException raise:@"Roman Numeral Exception" format:@"The number %i
is too big to represent as a roman numeral.", number];
+
+ for (offset = 0; number > 0 && offset < 7; offset += 2) {
+ digit = number % 10;
+ number /= 10;
+ [string insertString:romanNumeralForDigit(digit, symbols[offset],
symbols[offset + 1], symbols[offset + 2]) atIndex:0];
+ }
+ return string;
+}
+
+- (NSString *)alphaCounterValue{
+ NSMutableString *string = [NSMutableString string];
+ unsigned letter, number = [self unsignedIntValue];
+
+ while (number > 0) {
+ letter = number % 26;
+ number /= 26;
+ [string insertString:[NSString stringWithFormat:@"%C", 'a' + letter -
1] atIndex:0];
+ }
+ return string;
+}
+
+- (NSString *)greekCounterValue{
+ NSMutableString *string = [NSMutableString string];
+ unsigned letter, number = [self unsignedIntValue];
+
+ while (number > 0) {
+ letter = number % 24;
+ number /= 24;
+ [string insertString:[NSString stringWithFormat:@"%C", 0x03b1 + letter
- 1] atIndex:0];
+ }
+ return string;
+}
+
@end
#pragma mark -
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper
from Novell. From the desktop to the data center, Linux is going
mainstream. Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit