// {{else if a=b}} {{else}} {{/name}} // ^ // returns ^ ^ static ReadOnlyMemory <char> ParseElseStatement(this ReadOnlyMemory <char> literal, string blockName, out PageElseBlock statement) { var inStatements = 0; var pos = 0; statement = null; var statementPos = -1; var elseExpr = default(ReadOnlyMemory <char>); while (true) { pos = literal.IndexOf("{{", pos); if (pos == -1) { throw new SyntaxErrorException($"End block for 'else' not found."); } var c = literal.SafeGetChar(pos + 2); if (c == '#') { inStatements++; pos = literal.IndexOf("}}", pos) + 2; //end of expression } else if (c == '/') { if (inStatements == 0) { literal.Slice(pos + 2 + 1).ParseVarName(out var name); if (name.EqualsOrdinal(blockName)) { var body = ParseTemplatePage(literal.Slice(statementPos, pos - statementPos).TrimFirstNewLine()); statement = new PageElseBlock(elseExpr, body); return(literal.Slice(pos)); } } inStatements--; } else if (literal.Slice(pos + 2).StartsWith("else")) { if (inStatements == 0) { if (statementPos >= 0) { var bodyText = literal.Slice(statementPos, pos - statementPos).TrimFirstNewLine(); var body = ParseTemplatePage(bodyText); statement = new PageElseBlock(elseExpr, body); return(literal.Slice(pos)); } var endExprPos = literal.IndexOf("}}", pos); if (endExprPos == -1) { throw new SyntaxErrorException($"End expression for 'else' not found."); } var exprStartPos = pos + 2 + 4; //= {{else... elseExpr = literal.Slice(exprStartPos, endExprPos - exprStartPos).Trim(); statementPos = endExprPos + 2; } } pos += 2; } }
/// <summary> /// Gets the else call trace. /// </summary> /// <param name="fragment">The fragment.</param> /// <returns>System.String.</returns> protected virtual string GetElseCallTrace(PageElseBlock fragment) => "Block: " + Name + " > Else" + (fragment.Argument.IsNullOrEmpty() ? "" : " (" + fragment.Argument + ")");
protected bool Equals(PageElseBlock other) { return(Argument.Span.SequenceEqual(other.Argument.Span) && Body.EquivalentTo(other.Body) && Equals(BodyStatement, other.BodyStatement)); }
/// <summary> /// Write else as an asynchronous operation. /// </summary> /// <param name="scope">The scope.</param> /// <param name="fragment">The fragment.</param> /// <param name="token">The cancellation token that can be used by other objects or threads to receive notice of cancellation.</param> /// <returns>A Task representing the asynchronous operation.</returns> protected virtual async Task WriteElseAsync(ScriptScopeContext scope, PageElseBlock fragment, CancellationToken token) { await WriteAsync(scope, fragment.Body, GetElseCallTrace(fragment), token).ConfigAwait(); }