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

Reply via email to