// {{#if ...}} // ^ public static ReadOnlyMemory <char> ParseTemplateScriptBlock(this ReadOnlyMemory <char> literal, ScriptContext context, out PageBlockFragment blockFragment) { literal = literal.ParseVarName(out var blockNameSpan); PageBlockFragment statement; var blockName = blockNameSpan.ToString(); var endBlock = "{{/" + blockName + "}}"; var endExprPos = literal.IndexOf("}}"); if (endExprPos == -1) { throw new SyntaxErrorException($"Unterminated '{blockName}' block expression, near '{literal.DebugLiteral()}'"); } var argument = literal.Slice(0, endExprPos).Trim(); literal = literal.Advance(endExprPos + 2); var language = context.ParseAsLanguage.TryGetValue(blockName, out var lang) ? lang : ScriptTemplate.Language; if (language.Name == ScriptVerbatim.Language.Name) { var endBlockPos = literal.IndexOf(endBlock); if (endBlockPos == -1) { throw new SyntaxErrorException($"Unterminated end block '{endBlock}'"); } var body = literal.Slice(0, endBlockPos); literal = literal.Advance(endBlockPos + endBlock.Length).TrimFirstNewLine(); blockFragment = language.ParseVerbatimBlock(blockName, argument, body); return(literal); } literal = literal.ParseTemplateBody(blockNameSpan, out var bodyText); var bodyFragments = language.Parse(context, bodyText); var elseBlocks = new List <PageElseBlock>(); while (literal.StartsWith("{{else")) { literal = literal.ParseTemplateElseBlock(blockName, out var elseArgument, out var elseBody); var elseBlock = new PageElseBlock(elseArgument, language.Parse(context, elseBody)); elseBlocks.Add(elseBlock); } literal = literal.Advance(2 + 1 + blockName.Length + 2); //remove new line after partial block end tag literal = literal.TrimFirstNewLine(); blockFragment = new PageBlockFragment(blockName, argument, bodyFragments, elseBlocks); return(literal); }
protected virtual async Task WriteElseAsync(ScriptScopeContext scope, PageElseBlock fragment, CancellationToken token) { if (fragment.Body != null) { await WriteAsync(scope, fragment.Body, GetElseCallTrace(fragment), token); } else if (fragment.BodyStatement?.Statements != null) { await WriteAsync(scope, fragment.BodyStatement.Statements, GetElseCallTrace(fragment), token); } }
// #if ... // ^ public static ReadOnlyMemory <char> ParseCodeScriptBlock(this ReadOnlyMemory <char> literal, ScriptContext context, out PageBlockFragment blockFragment) { literal = literal.ParseVarName(out var blockNameSpan); var endArgumentPos = literal.IndexOf('\n'); var argument = literal.Slice(0, endArgumentPos).Trim(); literal = literal.Slice(endArgumentPos + 1); var blockName = blockNameSpan.ToString(); var language = context.ParseAsLanguage.TryGetValue(blockName, out var lang) ? lang : ScriptCode.Language; if (language.Name == ScriptVerbatim.Language.Name) { literal = literal.ParseCodeBody(blockNameSpan, out var body); body = body.ChopNewLine(); blockFragment = language.ParseVerbatimBlock(blockName, argument, body); return(literal); } literal = literal.ParseCodeBody(blockNameSpan, out var bodyText); var bodyFragments = language.Parse(context, bodyText); var elseBlocks = new List <PageElseBlock>(); literal = literal.AdvancePastWhitespace(); while (literal.StartsWith("else")) { literal = literal.ParseCodeElseBlock(blockNameSpan, out var elseArgument, out var elseBody); var elseBlock = new PageElseBlock(elseArgument, language.Parse(context, elseBody)); elseBlocks.Add(elseBlock); literal = literal.AdvancePastWhitespace(); } blockFragment = new PageBlockFragment(blockName, argument, bodyFragments, elseBlocks); return(literal); }
protected virtual async Task WriteElseAsync(ScriptScopeContext scope, PageElseBlock fragment, CancellationToken token) { await WriteAsync(scope, fragment.Body, GetElseCallTrace(fragment), token); }
protected virtual string GetElseCallTrace(PageElseBlock fragment) => "Block: " + Name + " > Else" + (fragment.Argument.IsNullOrEmpty() ? "" : " (" + fragment.Argument + ")");