public void Visit(Block block) { parts.Add(context.GetInnerExpressions(block.Name, value => { context.Push(block, value); if (typeof(Lambda<string>).BaseType.IsAssignableFrom(value.Type)) { return Expression.Call( Expression.Call(value, value.Type.GetMethod("Invoke"), Expression.Constant(block.InnerSource())), typeof(object).GetMethod("ToString")); } var visitor = new CompilePartVisitor(context); visitor.Visit((Section)block); var expression = CompoundExpression.NullCheck(value, nullValue: "", returnIfNotNull: visitor.Result()); context.Pop(); return expression; })); }
public IEnumerable<Part> Scan(string template) { var regex = MakeRegex(StartDelimiter, EndDelimiter); var i = 0; var lineEnded = false; while (true) { Match m; if ((m = regex.Match(template, i)).Success) { var previousLiteral = template.Substring(i, m.Index - i); var leadingWhiteSpace = m.Groups[1]; var leadingLineEnd = m.Groups[2]; var leadingWhiteSpaceOnly = m.Groups[3]; var marker = m.Groups[4].Value.Trim(); var trailingWhiteSpace = m.Groups[5]; var trailingLineEnd = m.Groups[6]; var isStandalone = (leadingLineEnd.Success || (lineEnded && m.Index == i)) && trailingLineEnd.Success; Part part = null; if (marker[0] == '=') { var delimiters = DelimitersRegex.Match(marker); if (delimiters.Success) { var start = delimiters.Groups[1].Value; var end = delimiters.Groups[2].Value; this.StartDelimiter = start; this.EndDelimiter = end; regex = MakeRegex(start, end); } } else if (marker[0] == '#') { part = new Block(marker.Substring(1).Trim()); } else if (marker[0] == '^') { part = new InvertedBlock(marker.Substring(1).Trim()); } else if (marker[0] == '<') { part = new TemplateDefinition(marker.Substring(1).Trim()); } else if (marker[0] == '/') { part = new EndSection(marker.Substring(1).Trim()); } else if (marker[0] == '>') { part = new TemplateInclude(marker.Substring(1).Trim(), lineEnded || i == 0 ? leadingWhiteSpaceOnly.Value : null); } else if (marker[0] != '!') { if (marker == "else") { part = new Block(marker); } else { part = new VariableReference(marker); isStandalone = false; } } if (!isStandalone) { previousLiteral += leadingWhiteSpace; } else { previousLiteral += leadingLineEnd; if (part is TemplateInclude) { previousLiteral += leadingWhiteSpaceOnly; } } if (previousLiteral != "") { yield return new LiteralText(previousLiteral); } if (part != null) { yield return part; } i = m.Index + m.Length; if (!isStandalone) { i -= trailingWhiteSpace.Length; } lineEnded = trailingLineEnd.Success; } else { break; } } if (i < template.Length) { var remainingLiteral = template.Substring(i); yield return new LiteralText(remainingLiteral); } }