Permalink
Browse files

Parse incoming values better

  • Loading branch information...
1 parent 2cfbc21 commit 370713e6ce58a0ceaa391b4f4b4615ef0dfc231e @hiddenmemory committed Apr 5, 2012
View
@@ -1,9 +1,13 @@
-{{# def page title author }}
+{{# template page title_test client_test }}
<html>
<head>
- <title>{{ title }}</title>
+ <title>{{ title_test }}</title>
<meta name="author" value="{{ author }}">
- </head>
- <body>{{ this }}</body>
+ </head>
+ <body>{{ client_test }}</body>
</html>
-{{/ def }}
+{{/ def }}
+
+{{ global title "This is a title" }}
+{{ global client "This is a client" }}
+{{ page title client }}
View
@@ -13,6 +13,7 @@ Platform: iPhone, iPod touch
Testimonial:
"Creating your first iOS app is pretty daunting but hiddenMemory made it a great experience - helping us understanding all the aspects of development process, going over and above to ensure everything went smoothly and we ended up with a great polished finished app. We made the right choice going with hiddenMemory!"
+
Rob Claisse, Owner & CEO, Progression Sports Ltd
Technologies:
View
@@ -1,21 +1,38 @@
+{{#template case_study title_cs client_cs description_cs platform_cs testimonial_cs Technologies_cs}}
<html>
<head>
- <title>{{ title }}</title>
+ <title>{{ title_cs }}</title>
<meta name="author" value="{{ author }}">
</head>
<body>
- <h1>{{title}}</h1>
- <h2>Client: {{client}}</h2>
+ <h1>{{title_cs}}</h1>
+ <h2>Client: {{client_cs}}</h2>
- {{description}}
+ {{description_cs}}
<h3>Platform</h3>
- <blockquote>{{platform}}</blockquote>
+ <blockquote>{{platform_cs}}</blockquote>
<h3>Testimonial</h3>
- {{Testimonial}}
+ {{Testimonial_cs}}
<h4>Technologies</h4>
- {{Technologies}}
+ {{Technologies_cs}}
+
+ {{testvalue}}
</body>
</html>
+{{/def}}
+
+{{#include /Users/chris/Repositories/git/hiddenMemory/Tipi/Tests/Test01.txt}}
+ {{#case_study title client description platform Testimonial Technologies}}
+ {{# bind testvalue }}
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+ {{/ bind }}
+ {{/case_study}}
+{{/include}}
+
+
+{{ foo }}
+
+{{ // This is a comment }}
View
@@ -0,0 +1 @@
+{{ a long item to get "right out of the" box 'of magic' "fun \"and\" games" }}
@@ -109,6 +109,7 @@
838CA727152DC02D0013C064 /* TPTemplateNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPTemplateNode.h; sourceTree = "<group>"; };
838CA728152DC02D0013C064 /* TPTemplateNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPTemplateNode.m; sourceTree = "<group>"; };
83C656BC152DD61500454E32 /* Test02.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = Test02.html; sourceTree = "<group>"; };
+ 83C656BE152DFFA200454E32 /* Test03.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = Test03.html; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -185,6 +186,7 @@
838CA683152DB39F0013C064 /* Test01.txt */,
838CA723152DBE250013C064 /* Test01.html */,
83C656BC152DD61500454E32 /* Test02.html */,
+ 83C656BE152DFFA200454E32 /* Test03.html */,
);
path = Tests;
sourceTree = SOURCE_ROOT;
@@ -277,13 +277,17 @@ - (NSString*)stringByTrimmingWhitespace {
- (NSString*)removePrefix:(NSString*)prefix suffix:(NSString*)suffix {
NSString *str = self;
- if( [str hasPrefix:prefix] ) {
+ NSLog(@"Before: %@, P: %@, S: %@", str, prefix, suffix);
+
+ if( prefix && [str hasPrefix:prefix] ) {
str = [str stringByReplacingCharactersInRange:NSMakeRange(0, [prefix length]) withString:@""];
}
- if( [str hasSuffix:suffix] ) {
+ if( suffix && [str hasSuffix:suffix] ) {
str = [str stringByReplacingCharactersInRange:NSMakeRange([str length] - [suffix length], [suffix length]) withString:@""];
}
+
+ NSLog(@"After: %@", str);
return str;
}
@@ -23,5 +23,6 @@ typedef enum {
@property (readonly) NSMutableArray *childNodes;
+ (TPTemplateNode*)node;
-- (NSString*)expansionUsingValues:(NSDictionary*)values;
+- (NSString*)expansionUsingValues:(NSDictionary*)values
+ global:(NSMutableDictionary*)global;
@end
View
@@ -50,23 +50,55 @@ - (NSString*)descriptionWithDepth:(int)depth {
- (NSString*)description {
return [self descriptionWithDepth:0];
}
-- (NSString*)expansionUsingValues:(NSDictionary*)_values {
+- (NSString*)expansionUsingValues:(NSDictionary *)_values
+ global:(NSMutableDictionary*)global
+{
NSMutableString *expansion = [NSMutableString string];
if( self.type == TPNodeText ) {
[expansion appendString:self.originalValue];
}
else {
NSString *key = [self.name lowercaseString];
- if( [_values objectForKey:key] ) {
+
+ NSLog(@"Looking for value: %@", key);
+
+ if( [global objectForKey:key] ) {
+ NSLog(@" -> Found global value: %@", key);
+
+ NSString *(^expansionBlock)( TPTemplateNode *node, NSDictionary *values, NSMutableDictionary *global, NSArray *parameters ) = [global objectForKey:key];
+
+ NSMutableArray *parameters = [NSMutableArray array];
+ for( NSString *_valueName in self.values ) {
+ NSString *valueName = [_valueName lowercaseString];
+
+ NSLog(@" ---> Looking up parameter value %@ (%@)", valueName, _valueName);
+
+ NSString *(^valueExpansionBlock)( TPTemplateNode *node, NSDictionary *values, NSMutableDictionary *global, NSArray *parameters ) = [global objectForKey:valueName];
+ if( valueExpansionBlock ) {
+ [parameters addObject:valueExpansionBlock(self, _values, global, nil)];
+ }
+ else if( [_values objectForKey:valueName] ) {
+ [parameters addObject:[_values objectForKey:valueName]];
+ }
+ }
+
+ [expansion appendString:expansionBlock(self, _values, global, parameters)];
+ }
+ else if( [_values objectForKey:key] ) {
+ NSLog(@" -> Found local value: %@", key);
+
[expansion appendString:[_values objectForKey:key]];
}
+ else {
+ NSLog(@" -> Unable to find value");
+
+ for( TPTemplateNode *node in childNodes ) {
+ [expansion appendString:[node expansionUsingValues:_values global:global]];
+ }
+ }
}
-
- for( TPTemplateNode *node in childNodes ) {
- [expansion appendString:[node expansionUsingValues:_values]];
- }
-
+
return expansion;
}
@@ -9,6 +9,7 @@
#import "TPTemplateParser.h"
#import "TPTemplateNode.h"
#import "NSString+HiddenMemory.h"
+#import "TPMarkdownDataParser.h"
@interface TPTemplateParser () {
TPTemplateNode *root;
@@ -18,7 +19,7 @@ @interface TPTemplateParser () {
}
- (id)initWithFileAtPath:(NSString*)path;
- (void)parseContent:(NSMutableString*)content parent:(TPTemplateNode*)parent;
-- (void)parseTag:(NSMutableString*)content parent:(TPTemplateNode*)parent;
+- (BOOL)parseTag:(NSMutableString*)content parent:(TPTemplateNode*)parent;
@end
@implementation TPTemplateParser
@@ -46,7 +47,67 @@ - (id)initWithFileAtPath:(NSString*)path {
return self;
}
- (NSString*)expansionUsingValues:(NSDictionary*)values {
- return [root expansionUsingValues:values];
+ NSMutableDictionary *globals = [NSMutableDictionary dictionary];
+
+ [globals setObject:[^NSString*( TPTemplateNode *node, NSDictionary *values, NSMutableDictionary *global, NSArray *parameters ) {
+ [global setObject:[^NSString*( TPTemplateNode *_, NSDictionary *values, NSMutableDictionary *global, NSArray *parameters ) {
+ NSMutableString *expansion = [NSMutableString string];
+ NSMutableDictionary *environment = [NSMutableDictionary dictionary];
+
+ [[node.values subarrayWithRange:NSMakeRange(1, [node.values count] - 1)] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
+ [environment setObject:[parameters objectAtIndex:idx] forKey:[obj lowercaseString]];
+ }];
+
+ for( TPTemplateNode *childNode in _.childNodes ) {
+ if( [childNode.name isEqualToString:@"bind"] ) {
+ [environment setObject:[childNode expansionUsingValues:[NSDictionary dictionary] global:global]
+ forKey:[[childNode.values objectAtIndex:0] lowercaseString]];
+ }
+ }
+
+ NSLog(@"Environment: %@", environment);
+
+ for( TPTemplateNode *childNode in node.childNodes ) {
+ [expansion appendString:[childNode expansionUsingValues:environment global:global]];
+ }
+
+ return expansion;
+ } copy]
+ forKey:[[node.values objectAtIndex:0] lowercaseString]];
+
+ return @"";
+ } copy]
+ forKey:@"template"];
+
+ [globals setObject:[^NSString*( TPTemplateNode *node, NSDictionary *values, NSMutableDictionary *global, NSArray *parameters ) {
+ [global setObject:[^NSString*( TPTemplateNode *_, NSDictionary *values, NSMutableDictionary *global, NSArray *parameters ) {
+ return [node.values objectAtIndex:1];
+ } copy]
+ forKey:[[node.values objectAtIndex:0] lowercaseString]];
+
+ NSLog(@"Globals: %@", global);
+
+ return @"";
+ } copy]
+ forKey:@"global"];
+
+ [globals setObject:[^NSString*( TPTemplateNode *node, NSDictionary *values, NSMutableDictionary *global, NSArray *parameters ) {
+ NSMutableString *expansion = [NSMutableString string];
+ TPMarkdownDataParser *parser = [TPMarkdownDataParser parserForFile:[node.values objectAtIndex:0]];
+ NSDictionary *environment = parser.values;
+
+ NSLog(@"Environment: %@", environment);
+
+ for( TPTemplateNode *childNode in node.childNodes ) {
+ [expansion appendString:[childNode expansionUsingValues:environment global:global]];
+ }
+
+ return expansion;
+ } copy]
+ forKey:@"include"];
+
+ return [root expansionUsingValues:values
+ global:globals];
}
- (void)parseContent:(NSMutableString*)content parent:(TPTemplateNode*)parent {
while( [content length] ) {
@@ -70,39 +131,89 @@ - (void)parseContent:(NSMutableString*)content parent:(TPTemplateNode*)parent {
[content deleteCharactersInRange:NSMakeRange(0, range.location)];
if( shouldParseTag ) {
- [self parseTag:content parent:parent];
+ if( [self parseTag:content parent:parent] ) {
+ return;
+ }
}
}
}
-- (void)parseTag:(NSMutableString*)content parent:(TPTemplateNode*)parent {
+- (BOOL)parseTag:(NSMutableString*)content parent:(TPTemplateNode*)parent {
if( [content hasPrefix:tagStart] ) {
NSRange tagContentRange = [content rangeOfString:tagEnd];
if( tagContentRange.location != NSNotFound ) {
TPTemplateNode *node = [TPTemplateNode node];
node.originalValue = [content substringToIndex:tagContentRange.location + tagEnd.length];
- NSMutableArray *parts = [NSMutableArray arrayWithArray:[[[node.originalValue removePrefix:tagStart suffix:tagEnd] stringByTrimmingWhitespace] componentsSeparatedByString:@" "]];
- [content deleteCharactersInRange:NSMakeRange(0, node.originalValue.length)];
+ NSMutableArray *parts = [NSMutableArray array];
+ NSString *stringToParse = [node.originalValue removePrefix:tagStart suffix:tagEnd];
- [parent.childNodes addObject:node];
+ while( [stringToParse length] ) {
+ stringToParse = [stringToParse stringByTrimmingWhitespace];
+
+ NSLog(@"String to parse: %@ (%@)", stringToParse, parts);
+
+
+ if( [stringToParse hasPrefix:@"\""] ) {
+ NSUInteger i = 0;
+ for( i = 1; i < [stringToParse length]; i++ ) {
+ unichar c = [stringToParse characterAtIndex:i];
+ if( c == '"' && [stringToParse characterAtIndex:i - 1] != '\\' ) {
+ [parts addObject:[stringToParse substringWithRange:NSMakeRange(1, i - 1)]];
+ stringToParse = [stringToParse substringFromIndex:i + 1];
+ break;
+ }
+ }
+ }
+ else if( [stringToParse hasPrefix:@"'"] ) {
+ NSUInteger i = 0;
+ for( i = 1; i < [stringToParse length]; i++ ) {
+ unichar c = [stringToParse characterAtIndex:i];
+ if( c == '\'' && [stringToParse characterAtIndex:i - 1] != '\\' ) {
+ [parts addObject:[stringToParse substringWithRange:NSMakeRange(1, i - 1)]];
+ stringToParse = [stringToParse substringFromIndex:i + 1];
+ break;
+ }
+ }
+ }
+ else {
+ NSRange range = [stringToParse rangeOfString:@" "];
+ NSString *nextToken = (range.location == NSNotFound ? stringToParse : [stringToParse substringToIndex:range.location]);
+
+ [parts addObject:nextToken];
+
+ if( range.location != NSNotFound ) {
+ stringToParse = [stringToParse substringFromIndex:[nextToken length]];
+ }
+ else {
+ break;
+ }
+ }
+ }
+
+ NSLog(@"Parts: %@", parts);
+
+ [content deleteCharactersInRange:NSMakeRange(0, node.originalValue.length)];
if( [[parts objectAtIndex:0] hasPrefix:tagBlockOpen] ) {
if( [[parts objectAtIndex:0] isEqualToString:tagBlockOpen] ) {
[parts removeObjectAtIndex:0];
}
else {
- [parts replaceObjectAtIndex:0 withObject:[[parts objectAtIndex:0] removePrefix:tagStart suffix:nil]];
+ [parts replaceObjectAtIndex:0 withObject:[[parts objectAtIndex:0] removePrefix:tagBlockOpen suffix:nil]];
}
+ NSLog(@"Parts: %@", parts);
+
node.type = TPNodeDefinition;
node.name = [parts objectAtIndex:0];
if( [parts count] > 1 ) {
[node.values addObjectsFromArray:[parts subarrayWithRange:NSMakeRange(1, [parts count] - 1)]];
}
+ [parent.childNodes addObject:node];
[self parseContent:content parent:node];
}
else if( [[parts objectAtIndex:0] hasPrefix:tagBlockClose] ) {
@@ -112,18 +223,23 @@ - (void)parseTag:(NSMutableString*)content parent:(TPTemplateNode*)parent {
else {
[parts replaceObjectAtIndex:0 withObject:[[parts objectAtIndex:0] removePrefix:tagBlockClose suffix:nil]];
}
+
+ return YES;
}
else {
node.type = TPNodeApplication;
node.name = [parts objectAtIndex:0];
if( [parts count] > 1 ) {
[node.values addObjectsFromArray:[parts subarrayWithRange:NSMakeRange(1, [parts count] - 1)]];
}
+
+ [parent.childNodes addObject:node];
}
}
else {
[NSException raise:@"TagParseError" format:@"Error parsing tag"];
}
}
+ return NO;
}
@end
@@ -9,5 +9,5 @@
#import "TPDataParser.h"
@interface TPTextDataParser : TPDataParser
-+ (TPTextDataParser*)parserForFile:(NSString*)path;
++ (id)parserForFile:(NSString*)path;
@end
Oops, something went wrong. Retry.

0 comments on commit 370713e

Please sign in to comment.