private bool ParseDollar(ProjectItem projectItem, string sourcePath, Stream stream, object context, ref string output) { if (stream.Current == '$') { var identifier = stream.PeekWord(1); object value; if (TryGetIdentifier(projectItem, sourcePath, identifier, context, out value)) { stream.Advance(identifier.Length); var collection = value as IEnumerable <Item>; if (collection != null) { var filter = ParseBlock(stream, '(', ')'); var block = ParseBlock(stream, '[', ']'); var separator = ParseBlock(stream, '[', ']'); if (filter == null && block == null && separator == null) { var stringValue = value.ToString(); if (stringValue != value.GetType().FullName) { output += stringValue; } else { output += "$" + identifier; } } else { IEnumerable <Item> items; if (filter != null && filter.StartsWith("$")) { var predicate = filter.Remove(0, 1); if (extensions != null) { // Lambda filters are always defined in the first extension type var c = extensions.FirstOrDefault()?.GetMethod(predicate); if (c != null) { try { items = collection.Where(x => (bool)c.Invoke(null, new object[] { x })).ToList(); matchFound = matchFound || items.Any(); } catch (Exception e) { items = new Item[0]; hasError = true; var message = $"Error rendering template. Cannot apply filter to identifier '{identifier}'."; LogException(e, message, projectItem, sourcePath); } } else { items = new Item[0]; } } else { items = new Item[0]; } } else { items = ItemFilter.Apply(collection, filter, ref matchFound); } output += string.Join(ParseTemplate(projectItem, sourcePath, separator, context), items.Select(item => ParseTemplate(projectItem, sourcePath, block, item))); } } else if (value is bool) { var trueBlock = ParseBlock(stream, '[', ']'); var falseBlock = ParseBlock(stream, '[', ']'); output += ParseTemplate(projectItem, sourcePath, (bool)value ? trueBlock : falseBlock, context); } else { var block = ParseBlock(stream, '[', ']'); if (value != null) { if (block != null) { output += ParseTemplate(projectItem, sourcePath, block, value); } else { output += value.ToString(); } } } return(true); } } return(false); }
private bool ParseDollar(Stream stream, object context, ref string output) { if (stream.Current == '$') { var identifier = stream.PeekWord(1); object value; if (TryGetIdentifier(identifier, context, out value)) { stream.Advance(identifier.Length); var collection = value as IEnumerable <CodeItem>; if (collection != null) { var filter = ParseBlock(stream, '(', ')'); var block = ParseBlock(stream, '[', ']'); var separator = ParseBlock(stream, '[', ']'); if (filter == null && block == null && separator == null) { var stringValue = value.ToString(); if (stringValue != value.GetType().FullName) { output += stringValue; } else { output += "$" + identifier; } } else { IEnumerable <CodeItem> items; if (filter != null && filter.StartsWith("$")) { var predicate = filter.Remove(0, 1); if (customExtensions != null) { var c = customExtensions.GetMethod(predicate); if (c != null) { items = collection.Where(x => (bool)c.Invoke(null, new object[] { x })).ToList(); matchFound = matchFound || items.Any(); } else { items = new CodeItem[0]; } } else { items = new CodeItem[0]; } } else { items = ItemFilter.Apply(collection, filter, ref matchFound); } output += string.Join(ParseTemplate(separator, context), items.Select(item => ParseTemplate(block, item))); } } else if (value is bool) { var trueBlock = ParseBlock(stream, '[', ']'); var falseBlock = ParseBlock(stream, '[', ']'); output += ParseTemplate((bool)value ? trueBlock : falseBlock, context); } else { var block = ParseBlock(stream, '[', ']'); if (value != null) { if (block != null) { output += ParseTemplate(block, value); } else { //var extension = standardExtensions.GetMethod(identifier, new[] { value.GetType() }); //if (extension != null && extension.ReturnType == typeof (string)) //{ // value = extension.Invoke(null, new[] { value }); //} output += value.ToString(); } } } return(true); } } return(false); }