public (StringBuilder, StringReader) Execute( string currentLine, StringReader templateReader, StringBuilder output, IDictionary <string, object> model = null) { if (currentLine == null) { throw new ArgumentNullException(nameof(currentLine)); } var forEachDetails = Regex.Match(currentLine, @"@foreach\s*\((?'criteria'.*)\)"); if (!forEachDetails.Success) { throw new MalformedException($"Malformed foreach statement: `{ currentLine }`."); } var loopCriteria = forEachDetails.Groups["criteria"].Value.Trim(); if (!loopCriteria.StartsWith("var")) { throw new MalformedException("Missing keyword `var`"); } var variableRefs = Regex.Match(loopCriteria, @"var\s*(?'varName'[\w]+)\s*in\s*(?'collection'[\w.]+)"); if (!variableRefs.Success) { throw new MalformedException(loopCriteria); } var varName = variableRefs.Groups["varName"].Value; var collectionNavProps = variableRefs.Groups["collection"].Value; // resolve collection if (!(model.GetReference(collectionNavProps) is ICollection collection)) { throw new Exception($"`{ collectionNavProps }` isn't a valid collection"); } // look for the loop statements. var forBlock = BlockReader.ReadBlock(templateReader).ReadToEnd(); var engine = new RazorAlikeEngine(); foreach (var item in collection) { var iteratorModel = model.Clone(); iteratorModel.DefineVariable(varName, item); var iterationOutput = engine.Run(forBlock, iteratorModel); output.Append(iterationOutput.ToString()); } return(output, templateReader); }
public void MultipleBlockPositiveTests() { var reader = new StringReader(@" { { BLOCK } }!"); var blockReader = BlockReader.ReadBlock(reader); Assert.AreEqual("{ BLOCK }", blockReader.ReadToEnd().Trim()); Assert.AreEqual('!', reader.Read()); }
public (StringBuilder, StringReader) Execute( string currentLine, StringReader templateReader, StringBuilder output, IDictionary <string, object> model = null) { var blockBody = BlockReader.ReadBlock(new StringReader(currentLine)); var engine = new RazorAlikeEngine(); var resolved = engine.Run(blockBody.ReadToEnd(), model); output.AppendLine(resolved); return(output, templateReader); }