Revision: 5031
          http://skim-app.svn.sourceforge.net/skim-app/?rev=5031&view=rev
Author:   hofman
Date:     2008-12-09 14:13:59 +0000 (Tue, 09 Dec 2008)

Log Message:
-----------
Simplify template parsing. In particular remove whitespace around condition and 
collection tags after parsing is done, so we don't need to track complicated 
conditions that can change due to the parsing.

Modified Paths:
--------------
    trunk/SKTemplateParser.h
    trunk/SKTemplateParser.m
    trunk/SKTemplateTag.h
    trunk/SKTemplateTag.m

Modified: trunk/SKTemplateParser.h
===================================================================
--- trunk/SKTemplateParser.h    2008-12-08 22:35:59 UTC (rev 5030)
+++ trunk/SKTemplateParser.h    2008-12-09 14:13:59 UTC (rev 5031)
@@ -45,15 +45,15 @@
 
 @interface SKTemplateParser : NSObject
 
-+ (NSString *)stringByParsingTemplate:(NSString *)template 
usingObject:(id)object;
-+ (NSArray *)arrayByParsingTemplateString:(NSString *)template;
-+ (NSArray *)arrayByParsingTemplateString:(NSString *)template 
inlineOptions:(int)inlineOptions;
-+ (NSString *)stringFromTemplateArray:(NSArray *)template 
usingObject:(id)object atIndex:(int)anIndex;
++ (NSString *)stringByParsingTemplate:(NSString *)templateString 
usingObject:(id)object;
++ (NSArray *)arrayByParsingTemplateString:(NSString *)templateString;
++ (NSArray *)arrayByParsingTemplateString:(NSString *)templateString 
isSubtemplate:(BOOL)isSubtemplate;
++ (NSString *)stringFromTemplateArray:(NSArray *)templateArray 
usingObject:(id)object atIndex:(int)anIndex;
 
-+ (NSAttributedString *)attributedStringByParsingTemplate:(NSAttributedString 
*)template usingObject:(id)object;
-+ (NSArray *)arrayByParsingTemplateAttributedString:(NSAttributedString 
*)template;
-+ (NSArray *)arrayByParsingTemplateAttributedString:(NSAttributedString 
*)template inlineOptions:(int)inlineOptions;
-+ (NSAttributedString *)attributedStringFromTemplateArray:(NSArray *)template 
usingObject:(id)object atIndex:(int)anIndex;
++ (NSAttributedString *)attributedStringByParsingTemplate:(NSAttributedString 
*)templateAttrString usingObject:(id)object;
++ (NSArray *)arrayByParsingTemplateAttributedString:(NSAttributedString 
*)templateAttrString;
++ (NSArray *)arrayByParsingTemplateAttributedString:(NSAttributedString 
*)templateAttrString isSubtemplate:(BOOL)isSubtemplate;
++ (NSAttributedString *)attributedStringFromTemplateArray:(NSArray 
*)templateArray usingObject:(id)object atIndex:(int)anIndex;
 
 @end
 

Modified: trunk/SKTemplateParser.m
===================================================================
--- trunk/SKTemplateParser.m    2008-12-08 22:35:59 UTC (rev 5030)
+++ trunk/SKTemplateParser.m    2008-12-09 14:13:59 UTC (rev 5031)
@@ -185,30 +185,17 @@
     return altTag;
 }
 
-static inline NSRange altTemplateTagRange(NSString *template, NSString 
*altTag, NSString *endDelim, BOOL requireNL,  NSString **argString, BOOL 
*foundNL) {
+static inline NSRange altTemplateTagRange(NSString *template, NSString 
*altTag, NSString *endDelim, NSString **argString) {
     NSRange altTagRange = [template rangeOfString:altTag];
-    if (altTagRange.location != NSNotFound) {
-        // ignore whitespaces before the tag
-        NSRange wsRange = [template 
rangeOfTrailingEmptyLineRequiringNewline:requireNL range:NSMakeRange(0, 
altTagRange.location)];
-        if (wsRange.location != NSNotFound) 
-            altTagRange = NSMakeRange(wsRange.location, 
NSMaxRange(altTagRange) - wsRange.location);
-        if (nil != endDelim) {
-            // find the end tag and the argument (match string)
-            NSRange endRange = [template rangeOfString:endDelim options:0 
range:NSMakeRange(NSMaxRange(altTagRange), [template length] - 
NSMaxRange(altTagRange))];
-            if (endRange.location != NSNotFound) {
-                *argString = [template 
substringWithRange:NSMakeRange(NSMaxRange(altTagRange), endRange.location - 
NSMaxRange(altTagRange))];
-                altTagRange.length = NSMaxRange(endRange) - 
altTagRange.location;
-            } else {
-                *argString = @"";
-            }
+    if (altTagRange.location != NSNotFound && nil != endDelim) {
+        // find the end tag and the argument (match string)
+        NSRange endRange = [template rangeOfString:endDelim options:0 
range:NSMakeRange(NSMaxRange(altTagRange), [template length] - 
NSMaxRange(altTagRange))];
+        if (endRange.location != NSNotFound) {
+            *argString = [template 
substringWithRange:NSMakeRange(NSMaxRange(altTagRange), endRange.location - 
NSMaxRange(altTagRange))];
+            altTagRange.length = NSMaxRange(endRange) - altTagRange.location;
+        } else {
+            *argString = @"";
         }
-        // ignore whitespaces after the tag, including a trailing newline 
-        wsRange = [template rangeOfLeadingEmptyLineRequiringNewline:requireNL 
range:NSMakeRange(NSMaxRange(altTagRange), [template length] - 
NSMaxRange(altTagRange))];
-        if (wsRange.location != NSNotFound)
-            altTagRange.length = NSMaxRange(wsRange) - altTagRange.location;
-        if (foundNL) *foundNL = wsRange.location != NSNotFound;
-    } else {
-        if (foundNL) *foundNL = NO;
     }
     return altTagRange;
 }
@@ -220,15 +207,13 @@
 }
 
 + (NSArray *)arrayByParsingTemplateString:(NSString *)template {
-    return [self arrayByParsingTemplateString:template inlineOptions:0];
+    return [self arrayByParsingTemplateString:template isSubtemplate:NO];
 }
 
-+ (NSArray *)arrayByParsingTemplateString:(NSString *)template 
inlineOptions:(int)inlineOptions {
++ (NSArray *)arrayByParsingTemplateString:(NSString *)template 
isSubtemplate:(BOOL)isSubtemplate {
     NSScanner *scanner = [[NSScanner alloc] initWithString:template];
     NSMutableArray *result = [[NSMutableArray alloc] init];
     id currentTag = nil;
-    BOOL inlineAtEnd = (inlineOptions & SKTemplateInlineAtEnd) != 0;
-    BOOL precedingNewline = (inlineOptions & SKTemplateInlineAtStart) == 0;
 
     [scanner setCharactersToBeSkipped:nil];
     
@@ -262,59 +247,24 @@
                 [result addObject:currentTag];
                 [currentTag release];
                 
-                precedingNewline = NO;
-                
             } else if ([scanner scanString:COLLECTION_TAG_CLOSE_DELIM 
intoString:nil]) {
                 
-                SKPlaceholderTemplateTag *itemTemplate = nil, 
*separatorTemplate = nil;
-                NSString *itemTemplateString = nil;
+                NSString *itemTemplate = nil, *separatorTemplate = nil;
                 NSString *endTag;
-                NSRange sepTagRange, wsRange;
-                BOOL foundNL, nextFoundNL = NO;
+                NSRange sepTagRange;
                 
                 // collection template tag
-                // ignore whitespace before the tag. Should we also remove a 
newline?
-                if (currentTag && [(SKTemplateTag *)currentTag type] == 
SKTextTemplateTagType) {
-                    wsRange = [[(SKTextTemplateTag *)currentTag text] 
rangeOfTrailingEmptyLineRequiringNewline:precedingNewline == NO];
-                    if (wsRange.location != NSNotFound) {
-                        if (wsRange.length == [[currentTag text] length]) {
-                            [result removeLastObject];
-                            currentTag = [result lastObject];
-                        } else {
-                            [(SKTextTemplateTag *)currentTag 
setText:[[(SKTextTemplateTag *)currentTag text] 
substringToIndex:wsRange.location]];
-                        }
-                    }
-                }
-                
                 endTag = endCollectionTagWithTag(tag);
-                // ignore the rest of an empty line after the tag
-                foundNL = [scanner scanEmptyLineRequiringNewline:inlineAtEnd];
-                if ([scanner scanString:endTag intoString:nil]) {
-                    // ignore the the rest of an empty line after the 
currentTag
-                    precedingNewline = [scanner 
scanEmptyLineRequiringNewline:inlineAtEnd];
-                } else if ([scanner scanUpToString:endTag 
intoString:&itemTemplateString] && [scanner scanString:endTag intoString:nil]) {
-                    // ignore whitespace before the tag. Should we also remove 
a newline?
-                    wsRange = [itemTemplateString rangeOfTrailingEmptyLine];
-                    if (wsRange.location != NSNotFound)
-                        itemTemplateString = [itemTemplateString 
substringToIndex:wsRange.location];
-                    
-                    sepTagRange = altTemplateTagRange(itemTemplateString, 
sepCollectionTagWithTag(tag), nil, foundNL == NO, NULL, &nextFoundNL);
+                if ([scanner scanString:endTag intoString:nil] == NO && 
[scanner scanUpToString:endTag intoString:&itemTemplate] && [scanner 
scanString:endTag intoString:nil]) {
+                    sepTagRange = altTemplateTagRange(itemTemplate, 
sepCollectionTagWithTag(tag), nil, NULL);
                     if (sepTagRange.location != NSNotFound) {
-                        separatorTemplate = [[SKPlaceholderTemplateTag alloc] 
initWithString:[itemTemplateString substringFromIndex:NSMaxRange(sepTagRange)] 
atStartOfLine:nextFoundNL];
-                        itemTemplate = [[SKPlaceholderTemplateTag alloc] 
initWithString:[itemTemplateString substringToIndex:sepTagRange.location] 
atStartOfLine:foundNL];
-                    } else {
-                        itemTemplate = [[SKPlaceholderTemplateTag alloc] 
initWithString:[itemTemplateString substringToIndex:sepTagRange.location] 
atStartOfLine:foundNL];
+                        separatorTemplate = [itemTemplate 
substringFromIndex:NSMaxRange(sepTagRange)];
+                        itemTemplate = [itemTemplate 
substringToIndex:sepTagRange.location];
                     }
                     
-                    currentTag = [(SKCollectionTemplateTag 
*)[SKCollectionTemplateTag alloc] initWithKeyPath:tag itemTemplate:itemTemplate 
separatorTemplate:separatorTemplate];
+                    currentTag = [(SKCollectionTemplateTag 
*)[SKCollectionTemplateTag alloc] initWithKeyPath:tag 
itemTemplateString:itemTemplate separatorTemplateString:separatorTemplate];
                     [result addObject:currentTag];
                     [currentTag release];
-                    [itemTemplate release];
-                    [separatorTemplate release];
-                    
-                    // ignore the the rest of an empty line after the 
currentTag
-                    precedingNewline = [scanner 
scanEmptyLineRequiringNewline:inlineAtEnd];
-                    
                 }
                 
             } else {
@@ -343,65 +293,34 @@
                 if ([scanner scanString:CONDITION_TAG_CLOSE_DELIM 
intoString:nil]) {
                     
                     NSMutableArray *subTemplates, *matchStrings;
-                    SKPlaceholderTemplateTag *subTemplate = nil;
-                    NSString *subTemplateString = nil;
+                    NSString *subTemplate = nil;
                     NSString *endTag, *altTag;
-                    NSRange altTagRange, wsRange;
-                    BOOL foundNL, nextFoundNL = NO;
+                    NSRange altTagRange;
                     
                     // condition template tag
-                    // ignore whitespace before the tag. Should we also remove 
a newline?
-                    if (currentTag && [(SKTemplateTag *)currentTag type] == 
SKTextTemplateTagType) {
-                        wsRange = [[(SKTextTemplateTag *)currentTag text] 
rangeOfTrailingEmptyLineRequiringNewline:precedingNewline == NO];
-                        if (wsRange.location != NSNotFound) {
-                            if (wsRange.length == [[currentTag text] length]) {
-                                [result removeLastObject];
-                                currentTag = [result lastObject];
-                            } else {
-                                [(SKTextTemplateTag *)currentTag 
setText:[[(SKTextTemplateTag *)currentTag text] 
substringToIndex:wsRange.location]];
-                            }
-                        }
-                    }
-                    
                     endTag = endConditionTagWithTag(tag);
-                    // ignore the rest of an empty line after the tag
-                    foundNL = [scanner 
scanEmptyLineRequiringNewline:inlineAtEnd];
-                    if ([scanner scanString:endTag intoString:nil])
-                        continue;
-                    if ([scanner scanUpToString:endTag 
intoString:&subTemplateString] && [scanner scanString:endTag intoString:nil]) {
-                        // ignore whitespace before the currentTag. Should we 
also remove a newline?
-                        wsRange = [subTemplateString rangeOfTrailingEmptyLine];
-                        if (wsRange.location != NSNotFound)
-                            subTemplateString = [subTemplateString 
substringToIndex:wsRange.location];
+                    if ([scanner scanString:endTag intoString:nil] == NO && 
[scanner scanUpToString:endTag intoString:&subTemplate] && [scanner 
scanString:endTag intoString:nil]) {
                         
                         subTemplates = [[NSMutableArray alloc] init];
                         matchStrings = [[NSMutableArray alloc] 
initWithObjects:matchString ?: @"", nil];
                         
                         if (matchType != SKTemplateTagMatchOther) {
                             altTag = compareConditionTagWithTag(tag, 
matchType);
-                            altTagRange = 
altTemplateTagRange(subTemplateString, altTag, CONDITION_TAG_CLOSE_DELIM, 
foundNL == NO, &matchString, &nextFoundNL);
+                            altTagRange = altTemplateTagRange(subTemplate, 
altTag, CONDITION_TAG_CLOSE_DELIM, &matchString);
                             while (altTagRange.location != NSNotFound) {
-                                subTemplate = [[SKPlaceholderTemplateTag 
alloc] initWithString:[subTemplateString substringToIndex:altTagRange.location] 
atStartOfLine:foundNL];
-                                [subTemplates addObject:subTemplate];
-                                [subTemplate release];
+                                [subTemplates addObject:[subTemplate 
substringToIndex:altTagRange.location]];
                                 [matchStrings addObject:matchString ?: @""];
-                                subTemplateString = [subTemplateString 
substringFromIndex:NSMaxRange(altTagRange)];
-                                foundNL = nextFoundNL;
-                                altTagRange = 
altTemplateTagRange(subTemplateString, altTag, CONDITION_TAG_CLOSE_DELIM, 
foundNL == NO, &matchString, &nextFoundNL);
+                                subTemplate = [subTemplate 
substringFromIndex:NSMaxRange(altTagRange)];
+                                altTagRange = altTemplateTagRange(subTemplate, 
altTag, CONDITION_TAG_CLOSE_DELIM, &matchString);
                             }
                         }
                         
-                        altTagRange = altTemplateTagRange(subTemplateString, 
altConditionTagWithTag(tag), nil, foundNL == NO, NULL, &nextFoundNL);
+                        altTagRange = altTemplateTagRange(subTemplate, 
altConditionTagWithTag(tag), nil, NULL);
                         if (altTagRange.location != NSNotFound) {
-                            subTemplate = [[SKPlaceholderTemplateTag alloc] 
initWithString:[subTemplateString substringToIndex:altTagRange.location] 
atStartOfLine:foundNL];
-                            [subTemplates addObject:subTemplate];
-                            [subTemplate release];
-                            subTemplateString = [subTemplateString 
substringFromIndex:NSMaxRange(altTagRange)];
-                            foundNL = nextFoundNL;
+                            [subTemplates addObject:[subTemplate 
substringToIndex:altTagRange.location]];
+                            subTemplate = [subTemplate 
substringFromIndex:NSMaxRange(altTagRange)];
                         }
-                        subTemplate = [[SKPlaceholderTemplateTag alloc] 
initWithString:subTemplateString atStartOfLine:foundNL];
                         [subTemplates addObject:subTemplate];
-                        [subTemplate release];
                         
                         currentTag = [[SKConditionTemplateTag alloc] 
initWithKeyPath:tag matchType:matchType matchStrings:matchStrings 
subtemplates:subTemplates];
                         [result addObject:currentTag];
@@ -410,9 +329,6 @@
                         [subTemplates release];
                         [matchStrings release];
                         
-                        // ignore the the rest of an empty line after the 
currentTag
-                        precedingNewline = [scanner 
scanEmptyLineRequiringNewline:inlineAtEnd];
-                        
                     }
                     
                 } else {
@@ -432,6 +348,46 @@
         } // scan START_TAG_OPEN_DELIM
     } // while
     [scanner release];
+    
+    // remove whitespace before and after collection and condition tags up 
till newlines
+    int i, count = [result count];
+    
+    for (i = count - 1; i >= 0; i++) {
+        SKTemplateTag *tag = [result objectAtIndex:i];
+        
+        if ([tag type] != SKTextTemplateTagType) continue;
+        
+        SKTemplateTagType typeAfter = i < count - 1 ? [(SKTemplateTag 
*)[result objectAtIndex:i + 1] type] : isSubtemplate ? 
SKCollectionTemplateTagType : SKValueTemplateTagType;
+        SKTemplateTagType typeBefore = i > 0 ? [(SKTemplateTag *)[result 
objectAtIndex:i - 1] type] : isSubtemplate ? SKCollectionTemplateTagType : 
SKValueTemplateTagType;
+        NSString *string = [(SKTextTemplateTag *)tag text];
+        NSRange range = NSMakeRange(0, [string length]), wsRange;
+        
+        if (typeAfter == SKCollectionTemplateTagType || typeAfter == 
SKConditionTemplateTagType) {
+            // remove whitespace at the end, just before the collection or 
condition tag
+            if (isSubtemplate == NO && i == 0 && [string 
rangeOfCharacterFromSet:[NSCharacterSet nonWhitespaceCharacterSet]].length == 
0) {
+                range.length = 0;
+            } else {
+                wsRange = [string rangeOfLeadingEmptyLine];
+                if (wsRange.location != NSNotFound)
+                    range.length = wsRange.location;
+            }
+        }
+        if (typeBefore == SKCollectionTemplateTagType || typeAfter == 
SKConditionTemplateTagType) {
+            // remove whitespace and a newline at the start, just after the 
collection or condition tag
+            if (isSubtemplate == NO && i == count - 1 && [string 
rangeOfCharacterFromSet:[NSCharacterSet nonWhitespaceCharacterSet]].length == 
0) {
+                range.length = 0;
+            } else {
+                wsRange = [string rangeOfTrailingEmptyLineInRange:range];
+                if (wsRange.location != NSNotFound)
+                    range = NSMakeRange(NSMaxRange(wsRange), NSMaxRange(range) 
- NSMaxRange(wsRange));
+            }
+        }
+        if (range.length == 0)
+            [result removeObjectAtIndex:i];
+        else if (range.length != [string length])
+            [(SKTextTemplateTag *)tag setText:[string 
substringWithRange:range]];
+    }
+    
     return [result autorelease];    
 }
 
@@ -541,16 +497,14 @@
 }
 
 + (NSArray *)arrayByParsingTemplateAttributedString:(NSAttributedString 
*)template {
-    return [self arrayByParsingTemplateAttributedString:template 
inlineOptions:0];
+    return [self arrayByParsingTemplateAttributedString:template 
isSubtemplate:NO];
 }
 
-+ (NSArray *)arrayByParsingTemplateAttributedString:(NSAttributedString 
*)template inlineOptions:(int)inlineOptions {
++ (NSArray *)arrayByParsingTemplateAttributedString:(NSAttributedString 
*)template isSubtemplate:(BOOL)isSubtemplate {
     NSString *templateString = [template string];
     NSScanner *scanner = [[NSScanner alloc] initWithString:templateString];
     NSMutableArray *result = [[NSMutableArray alloc] init];
     id currentTag = nil;
-    BOOL inlineAtEnd = (inlineOptions & SKTemplateInlineAtEnd) != 0;
-    BOOL precedingNewline = (inlineOptions & SKTemplateInlineAtStart) == 0;
 
     [scanner setCharactersToBeSkipped:nil];
     
@@ -593,62 +547,32 @@
                 [result addObject:currentTag];
                 [currentTag release];
                 
-                precedingNewline = NO;
-                
             } else if ([scanner scanString:COLLECTION_TAG_CLOSE_DELIM 
intoString:nil]) {
                 
                 NSString *itemTemplateString = nil;
-                SKRichPlaceholderTemplateTag *itemTemplate = nil, 
*separatorTemplate = nil;
-                NSAttributedString *itemTemplateAttrString = nil;
+                NSAttributedString *itemTemplate = nil, *separatorTemplate = 
nil;
                 NSString *endTag;
-                NSRange sepTagRange, wsRange;
-                BOOL foundNL, nextFoundNL = NO;
+                NSRange sepTagRange;
                 
                 // collection template tag
-                // ignore whitespace before the tag. Should we also remove a 
newline?
-                if (currentTag && [(SKTemplateTag *)currentTag type] == 
SKTextTemplateTagType) {
-                    wsRange = [[[(SKRichTextTemplateTag *)currentTag 
attributedText] string] 
rangeOfTrailingEmptyLineRequiringNewline:precedingNewline == NO];
-                    if (wsRange.location != NSNotFound) {
-                        if (wsRange.length == [[(SKRichTextTemplateTag 
*)currentTag attributedText] length]) {
-                            [result removeLastObject];
-                            currentTag = [result lastObject];
-                        } else {
-                            [(SKRichTextTemplateTag *)currentTag 
setAttributedText:[[(SKRichTextTemplateTag *)currentTag attributedText] 
attributedSubstringFromRange:NSMakeRange(0, wsRange.location)]];
-                        }
-                    }
-                }
-                
                 endTag = endCollectionTagWithTag(tag);
-                // ignore the rest of an empty line after the tag
-                foundNL = [scanner scanEmptyLineRequiringNewline:inlineAtEnd];
-                if ([scanner scanString:endTag intoString:nil]) {
-                    // ignore the the rest of an empty line after the tag
-                    precedingNewline = [scanner 
scanEmptyLineRequiringNewline:inlineAtEnd];
+                if ([scanner scanString:endTag intoString:nil])
                     continue;
-                }
                 start = [scanner scanLocation];
                 if ([scanner scanUpToString:endTag 
intoString:&itemTemplateString] && [scanner scanString:endTag intoString:nil]) {
                     // ignore whitespace before the tag. Should we also remove 
a newline?
-                    wsRange = [itemTemplateString rangeOfTrailingEmptyLine];
-                    itemTemplateAttrString = [template 
attributedSubstringFromRange:NSMakeRange(start, [itemTemplateString length] - 
wsRange.length)];
+                    itemTemplate = [template 
attributedSubstringFromRange:NSMakeRange(start, [itemTemplateString length])];
                     
-                    sepTagRange = altTemplateTagRange([itemTemplateAttrString 
string], sepCollectionTagWithTag(tag), nil, foundNL == NO, NULL, &nextFoundNL);
+                    sepTagRange = altTemplateTagRange([itemTemplate string], 
sepCollectionTagWithTag(tag), nil, NULL);
                     if (sepTagRange.location != NSNotFound) {
-                        separatorTemplate = [[SKRichPlaceholderTemplateTag 
alloc] initWithAttributedString:[itemTemplateAttrString 
attributedSubstringFromRange:NSMakeRange(NSMaxRange(sepTagRange), 
[itemTemplateAttrString length] - NSMaxRange(sepTagRange))] 
atStartOfLine:nextFoundNL];
-                        itemTemplate = [[SKRichPlaceholderTemplateTag alloc] 
initWithAttributedString:[itemTemplateAttrString 
attributedSubstringFromRange:NSMakeRange(0, sepTagRange.location)] 
atStartOfLine:foundNL];
-                    } else {
-                        itemTemplate = [[SKRichPlaceholderTemplateTag alloc] 
initWithAttributedString:itemTemplateAttrString atStartOfLine:foundNL];
+                        separatorTemplate = [itemTemplate 
attributedSubstringFromRange:NSMakeRange(NSMaxRange(sepTagRange), [itemTemplate 
length] - NSMaxRange(sepTagRange))];
+                        itemTemplate = [itemTemplate 
attributedSubstringFromRange:NSMakeRange(0, sepTagRange.location)];
                     }
                     
-                    currentTag = [(SKRichCollectionTemplateTag 
*)[SKRichCollectionTemplateTag alloc] initWithKeyPath:tag 
itemTemplate:itemTemplate separatorTemplate:separatorTemplate];
+                    currentTag = [(SKRichCollectionTemplateTag 
*)[SKRichCollectionTemplateTag alloc] initWithKeyPath:tag 
itemTemplateAttributedString:itemTemplate 
separatorTemplateAttributedString:separatorTemplate];
                     [result addObject:currentTag];
                     [currentTag release];
-                    [itemTemplate release];
-                    [separatorTemplate release];
                     
-                    // ignore the the rest of an empty line after the tag
-                    precedingNewline = [scanner 
scanEmptyLineRequiringNewline:inlineAtEnd];
-                    
                 }
                 
             } else {
@@ -678,69 +602,39 @@
                     
                     NSMutableArray *subTemplates, *matchStrings;
                     NSString *subTemplateString = nil;
-                    SKRichPlaceholderTemplateTag *subTemplate = nil;
-                    NSAttributedString *subTemplateAttrString = nil;
+                    NSAttributedString *subTemplate = nil;
                     NSString *endTag, *altTag;
-                    NSRange altTagRange, wsRange;
-                    BOOL foundNL, nextFoundNL = NO;
+                    NSRange altTagRange;
                     
                     // condition template tag
-                    // ignore whitespace before the tag. Should we also remove 
a newline?
-                    if (currentTag && [(SKTemplateTag *)currentTag type] == 
SKTextTemplateTagType) {
-                        wsRange = [[[(SKRichTextTemplateTag *)currentTag 
attributedText] string] 
rangeOfTrailingEmptyLineRequiringNewline:precedingNewline == NO];
-                        if (wsRange.location != NSNotFound) {
-                            if (wsRange.length == [[(SKRichTextTemplateTag 
*)currentTag attributedText] length]) {
-                                [result removeLastObject];
-                                currentTag = [result lastObject];
-                            } else {
-                                [(SKRichTextTemplateTag *)currentTag 
setAttributedText:[[(SKRichTextTemplateTag *)currentTag attributedText] 
attributedSubstringFromRange:NSMakeRange(0, wsRange.location)]];
-                            }
-                        }
-                    }
-                    
                     endTag = endConditionTagWithTag(tag);
                     altTag = altConditionTagWithTag(tag);
-                    // ignore the rest of an empty line after the tag
-                    foundNL = [scanner 
scanEmptyLineRequiringNewline:inlineAtEnd];
-                    if ([scanner scanString:endTag intoString:nil]) {
-                        // ignore the the rest of an empty line after the tag
-                        precedingNewline = [scanner 
scanEmptyLineRequiringNewline:inlineAtEnd];
+                    if ([scanner scanString:endTag intoString:nil])
                         continue;
-                    }
                     start = [scanner scanLocation];
                     if ([scanner scanUpToString:endTag 
intoString:&subTemplateString] && [scanner scanString:endTag intoString:nil]) {
-                        // ignore whitespace before the tag. Should we also 
remove a newline?
-                        wsRange = [subTemplateString rangeOfTrailingEmptyLine];
-                        subTemplateAttrString = [template 
attributedSubstringFromRange:NSMakeRange(start, [subTemplateString length] - 
wsRange.length)];
+                        subTemplate = [template 
attributedSubstringFromRange:NSMakeRange(start, [subTemplateString length])];
                         
                         subTemplates = [[NSMutableArray alloc] init];
                         matchStrings = [[NSMutableArray alloc] 
initWithObjects:matchString ?: @"", nil];
                         
                         if (matchType != SKTemplateTagMatchOther) {
                             altTag = compareConditionTagWithTag(tag, 
matchType);
-                            altTagRange = 
altTemplateTagRange([subTemplateAttrString string], altTag, 
CONDITION_TAG_CLOSE_DELIM, foundNL == NO, &matchString, &nextFoundNL);
+                            altTagRange = altTemplateTagRange([subTemplate 
string], altTag, CONDITION_TAG_CLOSE_DELIM, &matchString);
                             while (altTagRange.location != NSNotFound) {
-                                subTemplate = [[SKRichPlaceholderTemplateTag 
alloc] initWithAttributedString:[subTemplateAttrString 
attributedSubstringFromRange:NSMakeRange(0, altTagRange.location)] 
atStartOfLine:foundNL];
-                                [subTemplates addObject:subTemplate];
-                                [subTemplate release];
+                                [subTemplates addObject:[subTemplate 
attributedSubstringFromRange:NSMakeRange(0, altTagRange.location)]];
                                 [matchStrings addObject:matchString ?: @""];
-                                subTemplateAttrString = [subTemplateAttrString 
attributedSubstringFromRange:NSMakeRange(NSMaxRange(altTagRange), 
[subTemplateAttrString length] - NSMaxRange(altTagRange))];
-                                foundNL = nextFoundNL;
-                                altTagRange = 
altTemplateTagRange([subTemplateAttrString string], altTag, 
CONDITION_TAG_CLOSE_DELIM, foundNL == NO, &matchString, &nextFoundNL);
+                                subTemplate = [subTemplate 
attributedSubstringFromRange:NSMakeRange(NSMaxRange(altTagRange), [subTemplate 
length] - NSMaxRange(altTagRange))];
+                                altTagRange = altTemplateTagRange([subTemplate 
string], altTag, CONDITION_TAG_CLOSE_DELIM, &matchString);
                             }
                         }
                         
-                        altTagRange = 
altTemplateTagRange([subTemplateAttrString string], 
altConditionTagWithTag(tag), nil, foundNL == NO, NULL, &nextFoundNL);
+                        altTagRange = altTemplateTagRange([subTemplate 
string], altConditionTagWithTag(tag), nil, NULL);
                         if (altTagRange.location != NSNotFound) {
-                            subTemplate = [[SKRichPlaceholderTemplateTag 
alloc] initWithAttributedString:[subTemplateAttrString 
attributedSubstringFromRange:NSMakeRange(0, altTagRange.location)] 
atStartOfLine:foundNL];
-                            [subTemplates addObject:subTemplate];
-                            [subTemplate release];
-                            subTemplateAttrString = [subTemplateAttrString 
attributedSubstringFromRange:NSMakeRange(NSMaxRange(altTagRange), 
[subTemplateAttrString length] - NSMaxRange(altTagRange))];
-                            foundNL = nextFoundNL;
+                            [subTemplates addObject:[subTemplate 
attributedSubstringFromRange:NSMakeRange(0, altTagRange.location)]];
+                            subTemplate = [subTemplate 
attributedSubstringFromRange:NSMakeRange(NSMaxRange(altTagRange), [subTemplate 
length] - NSMaxRange(altTagRange))];
                         }
-                        subTemplate = [[SKRichPlaceholderTemplateTag alloc] 
initWithAttributedString:subTemplateAttrString atStartOfLine:foundNL];
                         [subTemplates addObject:subTemplate];
-                        [subTemplate release];
                         
                         currentTag = [[SKRichConditionTemplateTag alloc] 
initWithKeyPath:tag matchType:matchType matchStrings:matchStrings 
subtemplates:subTemplates];
                         [result addObject:currentTag];
@@ -749,9 +643,6 @@
                         [subTemplates release];
                         [matchStrings release];
                         
-                        // ignore the the rest of an empty line after the tag
-                        precedingNewline = [scanner 
scanEmptyLineRequiringNewline:inlineAtEnd];
-                        
                     }
                     
                 } else {
@@ -777,6 +668,46 @@
     
     [scanner release];
     
+    // remove whitespace before and after collection and condition tags up 
till newlines
+    int i, count = [result count];
+    
+    for (i = count - 1; i >= 0; i++) {
+        SKTemplateTag *tag = [result objectAtIndex:i];
+        
+        if ([tag type] != SKTextTemplateTagType) continue;
+        
+        SKTemplateTagType typeAfter = i < count - 1 ? [(SKTemplateTag 
*)[result objectAtIndex:i + 1] type] : isSubtemplate ? 
SKCollectionTemplateTagType : SKValueTemplateTagType;
+        SKTemplateTagType typeBefore = i > 0 ? [(SKTemplateTag *)[result 
objectAtIndex:i - 1] type] : isSubtemplate ? SKCollectionTemplateTagType : 
SKValueTemplateTagType;
+        NSAttributedString *attrString = [(SKRichTextTemplateTag *)tag 
attributedText];
+        NSString *string = [attrString string];
+        NSRange range = NSMakeRange(0, [string length]), wsRange;
+        
+        if (typeAfter == SKCollectionTemplateTagType || typeAfter == 
SKConditionTemplateTagType) {
+            // remove whitespace at the end, just before the collection or 
condition tag
+            if (isSubtemplate == NO && i == 0 && [string 
rangeOfCharacterFromSet:[NSCharacterSet nonWhitespaceCharacterSet]].length == 
0) {
+                range.length = 0;
+            } else {
+                wsRange = [string rangeOfLeadingEmptyLine];
+                if (wsRange.location != NSNotFound)
+                    range.length = wsRange.location;
+            }
+        }
+        if (typeBefore == SKCollectionTemplateTagType || typeAfter == 
SKConditionTemplateTagType) {
+            // remove whitespace and a newline at the beginning, just after 
the collection or condition tag
+            if (isSubtemplate == NO && i == count - 1 && [string 
rangeOfCharacterFromSet:[NSCharacterSet nonWhitespaceCharacterSet]].length == 
0) {
+                range.length = 0;
+            } else {
+                wsRange = [string rangeOfTrailingEmptyLineInRange:range];
+                if (wsRange.location != NSNotFound)
+                    range = NSMakeRange(NSMaxRange(wsRange), NSMaxRange(range) 
- NSMaxRange(wsRange));
+            }
+        }
+        if (range.length == 0)
+            [result removeObjectAtIndex:i];
+        else if (range.length != [string length])
+            [(SKRichTextTemplateTag *)tag setAttributedText:[attrString 
attributedSubstringFromRange:range]];
+    }
+    
     return [result autorelease];    
 }
 

Modified: trunk/SKTemplateTag.h
===================================================================
--- trunk/SKTemplateTag.h       2008-12-08 22:35:59 UTC (rev 5030)
+++ trunk/SKTemplateTag.h       2008-12-09 14:13:59 UTC (rev 5031)
@@ -62,34 +62,6 @@
 
 #pragma mark -
 
[EMAIL PROTECTED] SKPlaceholderTemplateTag : SKTemplateTag {
-    NSString *string;
-    int inlineOptions;
-}
-
-- (id)initWithString:(NSString *)aString atStartOfLine:(BOOL)flag;
-
-- (NSString *)string;
-- (NSArray *)templateArray;
-
[EMAIL PROTECTED]
-
-#pragma mark -
-
[EMAIL PROTECTED] SKRichPlaceholderTemplateTag : SKTemplateTag {
-    NSAttributedString *attributedString;
-    int inlineOptions;
-}
-
-- (id)initWithAttributedString:(NSAttributedString *)anAttributedString 
atStartOfLine:(BOOL)flag;
-
-- (NSAttributedString *)attributedString;
-- (NSArray *)templateArray;
-
[EMAIL PROTECTED]
-
-#pragma mark -
-
 @interface SKValueTemplateTag : SKTemplateTag {
     NSString *keyPath;
 }
@@ -115,13 +87,13 @@
 #pragma mark -
 
 @interface SKCollectionTemplateTag : SKValueTemplateTag {
-    SKPlaceholderTemplateTag *itemPlaceholderTemplate;
-    SKPlaceholderTemplateTag *separatorPlaceholderTemplate;
+    NSString *itemTemplateString;
+    NSString *separatorTemplateString;
     NSArray *itemTemplate;
     NSArray *separatorTemplate;
 }
 
-- (id)initWithKeyPath:(NSString *)aKeyPath 
itemTemplate:(SKPlaceholderTemplateTag *)anItemTemplate 
separatorTemplate:(SKPlaceholderTemplateTag *)aSeparatorTemplate;
+- (id)initWithKeyPath:(NSString *)aKeyPath itemTemplateString:(NSString 
*)anItemTemplateString separatorTemplateString:(NSString 
*)aSeparatorTemplateString;
 
 - (NSArray *)itemTemplate;
 - (NSArray *)separatorTemplate;
@@ -131,13 +103,13 @@
 #pragma mark -
 
 @interface SKRichCollectionTemplateTag : SKValueTemplateTag {
-    SKRichPlaceholderTemplateTag *itemPlaceholderTemplate;
-    SKRichPlaceholderTemplateTag *separatorPlaceholderTemplate;
+    NSAttributedString *itemTemplateAttributedString;
+    NSAttributedString *separatorTemplateAttributedString;
     NSArray *itemTemplate;
     NSArray *separatorTemplate;
 }
 
-- (id)initWithKeyPath:(NSString *)aKeyPath 
itemTemplate:(SKRichPlaceholderTemplateTag *)anItemTemplate 
separatorTemplate:(SKRichPlaceholderTemplateTag *)aSeparatorTemplate;
+- (id)initWithKeyPath:(NSString *)aKeyPath 
itemTemplateAttributedString:(NSAttributedString 
*)anItemTemplateAttributedString 
separatorTemplateAttributedString:(NSAttributedString 
*)aSeparatorTemplateAttributedString;
 
 - (NSArray *)itemTemplate;
 - (NSArray *)separatorTemplate;

Modified: trunk/SKTemplateTag.m
===================================================================
--- trunk/SKTemplateTag.m       2008-12-08 22:35:59 UTC (rev 5030)
+++ trunk/SKTemplateTag.m       2008-12-09 14:13:59 UTC (rev 5031)
@@ -46,64 +46,6 @@
 
 #pragma mark -
 
[EMAIL PROTECTED] SKPlaceholderTemplateTag
-
-- (id)initWithString:(NSString *)aString atStartOfLine:(BOOL)flag {
-    if (self = [super init]) {
-        string = [aString copy];
-        inlineOptions = SKTemplateInlineAtEnd;
-        if (flag)
-            inlineOptions = SKTemplateInlineAtStart;
-    }
-    return self;
-}
-
-- (void)dealloc {
-    [string release];
-    [super dealloc];
-}
-
-- (NSString *)string {
-    return string;
-}
-
-- (NSArray *)templateArray {
-    return [SKTemplateParser arrayByParsingTemplateString:string 
inlineOptions:inlineOptions];
-}
-
[EMAIL PROTECTED]
-
-#pragma mark -
-
[EMAIL PROTECTED] SKRichPlaceholderTemplateTag
-
-- (id)initWithAttributedString:(NSAttributedString *)anAttributedString 
atStartOfLine:(BOOL)flag {
-    if (self = [super init]) {
-        attributedString = [anAttributedString copy];
-        inlineOptions = SKTemplateInlineAtEnd;
-        if (flag)
-            inlineOptions = SKTemplateInlineAtStart;
-    }
-    return self;
-}
-
-- (void)dealloc {
-    [attributedString release];
-    [super dealloc];
-}
-
-- (NSAttributedString *)attributedString {
-    return attributedString;
-}
-
-- (NSArray *)templateArray {
-    return [SKTemplateParser 
arrayByParsingTemplateAttributedString:attributedString 
inlineOptions:inlineOptions];
-}
-
[EMAIL PROTECTED]
-
-#pragma mark -
-
 @implementation SKValueTemplateTag
 
 - (id)initWithKeyPath:(NSString *)aKeyPath {
@@ -152,10 +94,10 @@
 
 @implementation SKCollectionTemplateTag
 
-- (id)initWithKeyPath:(NSString *)aKeyPath 
itemTemplate:(SKPlaceholderTemplateTag *)anItemTemplate 
separatorTemplate:(SKPlaceholderTemplateTag *)aSeparatorTemplate {
+- (id)initWithKeyPath:(NSString *)aKeyPath itemTemplateString:(NSString 
*)anItemTemplateString separatorTemplateString:(NSString 
*)aSeparatorTemplateString {
     if (self = [super initWithKeyPath:aKeyPath]) {
-        itemPlaceholderTemplate = [anItemTemplate retain];
-        separatorPlaceholderTemplate = [aSeparatorTemplate retain];
+        itemTemplateString = [anItemTemplateString retain];
+        separatorTemplateString = [aSeparatorTemplateString retain];
         itemTemplate = nil;
         separatorTemplate = nil;
     }
@@ -163,8 +105,8 @@
 }
 
 - (void)dealloc {
-    [itemPlaceholderTemplate release];
-    [separatorPlaceholderTemplate release];
+    [itemTemplateString release];
+    [separatorTemplateString release];
     [itemTemplate release];
     [separatorTemplate release];
     [super dealloc];
@@ -173,14 +115,14 @@
 - (SKTemplateTagType)type { return SKCollectionTemplateTagType; }
 
 - (NSArray *)itemTemplate {
-    if (itemTemplate == nil && itemPlaceholderTemplate)
-        itemTemplate = [[itemPlaceholderTemplate templateArray] retain];
+    if (itemTemplate == nil && itemTemplateString)
+        itemTemplate = [[SKTemplateParser 
arrayByParsingTemplateString:itemTemplateString isSubtemplate:YES] retain];
     return itemTemplate;
 }
 
 - (NSArray *)separatorTemplate {
-    if (separatorTemplate == nil && separatorPlaceholderTemplate)
-        separatorTemplate = [[separatorPlaceholderTemplate templateArray] 
retain];
+    if (separatorTemplate == nil && separatorTemplateString)
+        separatorTemplate = [[SKTemplateParser 
arrayByParsingTemplateString:separatorTemplateString isSubtemplate:YES] retain];
     return separatorTemplate;
 }
 
@@ -190,10 +132,10 @@
 
 @implementation SKRichCollectionTemplateTag
 
-- (id)initWithKeyPath:(NSString *)aKeyPath 
itemTemplate:(SKRichPlaceholderTemplateTag *)anItemTemplate 
separatorTemplate:(SKRichPlaceholderTemplateTag *)aSeparatorTemplate {
+- (id)initWithKeyPath:(NSString *)aKeyPath 
itemTemplateAttributedString:(NSAttributedString 
*)anItemTemplateAttributedString 
separatorTemplateAttributedString:(NSAttributedString 
*)aSeparatorTemplateAttributedString {
     if (self = [super initWithKeyPath:aKeyPath]) {
-        itemPlaceholderTemplate = [anItemTemplate retain];
-        separatorPlaceholderTemplate = [aSeparatorTemplate retain];
+        itemTemplateAttributedString = [anItemTemplateAttributedString retain];
+        separatorTemplateAttributedString = 
[aSeparatorTemplateAttributedString retain];
         itemTemplate = nil;
         separatorTemplate = nil;
     }
@@ -201,8 +143,8 @@
 }
 
 - (void)dealloc {
-    [itemPlaceholderTemplate release];
-    [separatorPlaceholderTemplate release];
+    [itemTemplateAttributedString release];
+    [separatorTemplateAttributedString release];
     [itemTemplate release];
     [separatorTemplate release];
     [super dealloc];
@@ -211,14 +153,14 @@
 - (SKTemplateTagType)type { return SKCollectionTemplateTagType; }
 
 - (NSArray *)itemTemplate {
-    if (itemTemplate == nil && itemPlaceholderTemplate)
-        itemTemplate = [[itemPlaceholderTemplate templateArray] retain];
+    if (itemTemplate == nil && itemTemplateAttributedString)
+        itemTemplate = [[SKTemplateParser 
arrayByParsingTemplateAttributedString:itemTemplateAttributedString 
isSubtemplate:YES] retain];
     return itemTemplate;
 }
 
 - (NSArray *)separatorTemplate {
-    if (separatorTemplate == nil && separatorPlaceholderTemplate)
-        separatorTemplate = [[separatorPlaceholderTemplate templateArray] 
retain];
+    if (separatorTemplate == nil && separatorTemplateAttributedString)
+        separatorTemplate = [[SKTemplateParser 
arrayByParsingTemplateAttributedString:separatorTemplateAttributedString 
isSubtemplate:YES] retain];
     return separatorTemplate;
 }
 
@@ -260,7 +202,7 @@
 - (NSArray *)subtemplateAtIndex:(unsigned)anIndex {
     id subtemplate = [subtemplates objectAtIndex:anIndex];
     if ([subtemplate isKindOfClass:[NSArray class]] == NO) {
-         subtemplate = [subtemplate templateArray];
+        subtemplate = [SKTemplateParser 
arrayByParsingTemplateString:subtemplate isSubtemplate:YES];
         [subtemplates replaceObjectAtIndex:anIndex withObject:subtemplate];
     }
     return subtemplate;
@@ -275,7 +217,7 @@
 - (NSArray *)subtemplateAtIndex:(unsigned)anIndex {
     id subtemplate = [subtemplates objectAtIndex:anIndex];
     if ([subtemplate isKindOfClass:[NSArray class]] == NO) {
-        subtemplate = [subtemplate templateArray];
+        subtemplate = [SKTemplateParser 
arrayByParsingTemplateAttributedString:subtemplate isSubtemplate:YES];
         [subtemplates replaceObjectAtIndex:anIndex withObject:subtemplate];
     }
     return subtemplate;


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you.  Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
_______________________________________________
Skim-app-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/skim-app-commit

Reply via email to