public static ReadOnlyMemory<char> ChopNewLine(this ReadOnlyMemory<char> literal) { var lastChar = literal.SafeGetChar(literal.Length - 1); if (lastChar == '\r' || lastChar == '\n') { return literal.Span.SafeCharEquals(literal.Length - 2, '\r') ? literal.Slice(0, literal.Length - 2) : literal.Slice(0, literal.Length - 1); } return literal; }
// {{#name}} {{else if a=b}} {{else}} {{/name}} // ^ // returns ^ ^ static ReadOnlyMemory <char> ParseStatementBody(this ReadOnlyMemory <char> literal, ReadOnlyMemory <char> blockName, out List <PageFragment> body) { var inStatements = 0; var pos = 0; while (true) { pos = literal.IndexOf("{{", pos); if (pos == -1) { throw new SyntaxErrorException($"End block for '{blockName}' not found."); } var c = literal.SafeGetChar(pos + 2); if (c == '#') { inStatements++; pos = literal.IndexOf("}}", pos) + 2; //end of expression continue; } if (c == '/') { if (inStatements == 0) { literal.Slice(pos + 2 + 1).ParseVarName(out var name); if (name.EqualsOrdinal(blockName)) { body = ParseTemplatePage(literal.Slice(0, pos).TrimFirstNewLine()); return(literal.Slice(pos)); } } inStatements--; } else if (literal.Slice(pos + 2).StartsWith("else")) { if (inStatements == 0) { body = ParseTemplatePage(literal.Slice(0, pos).TrimFirstNewLine()); return(literal.Slice(pos)); } } pos += 2; } }
// {{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; } }