/// <summary> /// Creates an eval expression given template replacement info /// </summary> /// <param name="replacementKeyToken">The replacement key token which in this case is the evaluation expression</param> /// <param name="parameters">Optional parameters for foreground and background colors. The values should be valid ConsoleColor values.</param> /// <param name="body">Should be empty. Eval expressions don't support bodies.</param> /// <returns></returns> public IDocumentExpression CreateExpression(DocumentToken replacementKeyToken, List <DocumentToken> parameters, List <DocumentToken> body) { if (body.Count > 0) { throw new DocumentRenderException("eval tags can't have a body", replacementKeyToken); } TokenReader <DocumentToken> reader = new TokenReader <DocumentToken>(parameters); DocumentToken fgToken, bgToken; var ret = new EvalExpression(replacementKeyToken); if (reader.TryAdvance(out fgToken, skipWhitespace: true) == false) { return(ret); } else { ret.ForegroundColorToken = fgToken; } if (reader.TryAdvance(out bgToken, skipWhitespace: true) == false) { return(ret); } else { ret.BackgroundColorToken = bgToken; } return(ret); }
/// <summary> /// Removes a local variable. This will throw if there is no variable with the given name /// </summary> /// <param name="variableToken">The token containing the identifier of the variable to remove</param> public void Remove(DocumentToken variableToken) { if (localVariables.Remove(variableToken.Value) == false) { throw new ArgumentException("There is no variable to remove called '" + variableToken.Value + "' at " + variableToken.Position); } }
/// <summary> /// Creates a new table expression given a collection evaluation expression and a list of column tokens /// </summary> /// <param name="evalToken">A token containing an expression that should evaluate to an IEnumerable</param> /// <param name="columns">A list of tokens containing the names of columns to display in the table</param> public TableExpression(DocumentToken evalToken, List <DocumentToken> columns) { this.EvalToken = evalToken; this.Columns = columns; this.ShowDefaultValuesForArguments = true; this.ShowPossibleValuesForArguments = true; }
/// <summary> /// Creates a variable expression given replacement info /// </summary> /// <param name="replacementKeyToken">The replacement key token that should have a value of 'var'</param> /// <param name="parameters">There should be 2 parameters. The name of the variable and the initial value.</param> /// <param name="body">There should be no body</param> /// <returns>A variable expression</returns> public IDocumentExpression CreateExpression(DocumentToken replacementKeyToken, List <DocumentToken> parameters, List <DocumentToken> body) { if (body.Count > 0) { throw new DocumentRenderException("var tags can't have a body", body.First()); } TokenReader <DocumentToken> reader = new TokenReader <DocumentToken>(parameters); DocumentToken variableName; if (reader.TryAdvance(out variableName, skipWhitespace: true) == false) { throw new DocumentRenderException("Expected variable name after var tag", replacementKeyToken); } DocumentToken variableValue; if (reader.TryAdvance(out variableValue, skipWhitespace: true) == false) { throw new DocumentRenderException("Expected variable value expression", variableName); } return(new VarExpression(variableName, variableValue)); }
private static void AssignTokenTypes(DocumentToken token, List <DocumentToken> tokens) { DocumentTokenType?previousNonWhitespaceTokenType = null; var myIndex = tokens.IndexOf(token); for (var i = myIndex - 1; i >= 0; i--) { var current = tokens[i]; if (string.IsNullOrWhiteSpace(current.Value) == false) { previousNonWhitespaceTokenType = current.TokenType; break; } } DocumentTokenType constantValueType; if (TryParseDocumentTokenType(token.Value, out constantValueType)) { token.TokenType = constantValueType; } else if (previousNonWhitespaceTokenType.HasValue && (previousNonWhitespaceTokenType.Value == DocumentTokenType.BeginReplacementSegment || previousNonWhitespaceTokenType.Value == DocumentTokenType.BeginTerminateReplacementSegment)) { token.TokenType = DocumentTokenType.ReplacementKey; } else if (previousNonWhitespaceTokenType.HasValue && (previousNonWhitespaceTokenType.Value == DocumentTokenType.ReplacementKey || previousNonWhitespaceTokenType.Value == DocumentTokenType.ReplacementParameter)) { token.TokenType = DocumentTokenType.ReplacementParameter; } else { token.TokenType = DocumentTokenType.PlainText; } }
/// <summary> /// Creates a template expression given a replacement token and parameters. /// </summary> /// <param name="replacementKeyToken">The token whose value should be 'template'</param> /// <param name="parameters">There should be 2 parameters. One representing the name of the template to render and one representing the data to bind to the template.</param> /// <param name="body">Should be empty. Template expressions do not support a body.</param> /// <returns>a template expression</returns> public IDocumentExpression CreateExpression(DocumentToken replacementKeyToken, List <DocumentToken> parameters, List <DocumentToken> body) { if (body.Count > 0) { throw new DocumentRenderException("template tags can't have a body", replacementKeyToken); } TokenReader <DocumentToken> reader = new TokenReader <DocumentToken>(parameters); DocumentToken idToken; if (reader.TryAdvance(out idToken, skipWhitespace: true) == false) { throw new DocumentRenderException("missing template Id", replacementKeyToken); } DocumentToken evalToken; if (reader.TryAdvance(out evalToken, skipWhitespace: true) == false) { throw new DocumentRenderException("missing eval token", idToken); } var ret = new TemplateExpression(idToken, evalToken); return(ret); }
private static bool IsReplacementToken(DocumentToken token) { return(token.TokenType == DocumentTokenType.BeginReplacementSegment || token.TokenType == DocumentTokenType.BeginTerminateReplacementSegment || token.TokenType == DocumentTokenType.EndReplacementSegment || token.TokenType == DocumentTokenType.QuickTerminateReplacementSegment || token.TokenType == DocumentTokenType.ReplacementKey || token.TokenType == DocumentTokenType.ReplacementParameter); }
internal DocumentTemplateInfo GetTemplate(DocumentToken nameToken) { DocumentTemplateInfo ret; if (namedTemplates.TryGetValue(nameToken.Value, out ret) == false) { throw new DocumentRenderException("There is no templated named '" + nameToken.Value + "'", nameToken); } return ret; }
/// <summary> /// Creates a new table expression given a collection evaluation expression and a list of column tokens /// </summary> /// <param name="evalToken">A token containing an expression that should evaluate to an IEnumerable</param> /// <param name="columns">A list of tokens containing the names of columns to display in the table</param> /// <param name="context">Context that is used to determine the indentation of the table within the document</param> public TableExpression(DocumentToken evalToken, List <DocumentToken> columns, DocumentExpressionContext context) { this.EvalToken = evalToken; this.Columns = columns; this.ShowDefaultValuesForArguments = true; this.ShowPossibleValuesForArguments = true; this.indent = context.OpenToken.Column - 1; }
/// <summary> /// Creates a new table expression given a collection evaluation expression and a list of column tokens /// </summary> /// <param name="evalToken">A token containing an expression that should evaluate to an IEnumerable</param> /// <param name="columns">A list of tokens containing the names of columns to display in the table</param> /// <param name="context">Context that is used to determine the indentation of the table within the document</param> public TableExpression(DocumentToken evalToken, List<DocumentToken> columns, DocumentExpressionContext context) { this.EvalToken = evalToken; this.Columns = columns; this.ShowDefaultValuesForArguments = true; this.ShowPossibleValuesForArguments = true; this.indent = context.OpenToken.Column - 1; }
private void ParseReplacement(TokenReader <DocumentToken> reader, List <IDocumentExpression> ret) { var openToken = AdvanceAndExpectConstantType(reader, DocumentTokenType.BeginReplacementSegment); var replacementKeyToken = AdvanceAndExpect(reader, DocumentTokenType.ReplacementKey, "replacement key", skipWhitespace: true); List <DocumentToken> parameters = new List <DocumentToken>(); List <DocumentToken> body = new List <DocumentToken>(); while (reader.CanAdvance(skipWhitespace: true) && reader.Peek(skipWhitespace: true).TokenType == DocumentTokenType.ReplacementParameter) { var paramToken = reader.Advance(skipWhitespace: true); parameters.Add(paramToken); } DocumentToken closeReplacementToken; if (reader.TryAdvance(out closeReplacementToken, skipWhitespace: true) == false) { throw Unexpected(string.Format("'{0}' or '{1}'", DocumentToken.GetTokenTypeValue(DocumentTokenType.EndReplacementSegment), DocumentToken.GetTokenTypeValue(DocumentTokenType.QuickTerminateReplacementSegment))); } if (closeReplacementToken.TokenType == DocumentTokenType.EndReplacementSegment) { body.AddRange(ReadReplacementBody(reader, replacementKeyToken)); } else if (closeReplacementToken.TokenType == DocumentTokenType.QuickTerminateReplacementSegment) { // do nothing, there is no body when the quick termination replacement segment is used } else { throw Unexpected(string.Format("'{0}' or '{1}'", DocumentToken.GetTokenTypeValue(DocumentTokenType.EndReplacementSegment), DocumentToken.GetTokenTypeValue(DocumentTokenType.QuickTerminateReplacementSegment)), closeReplacementToken); } IDocumentExpressionProvider provider; if (this.expressionProviders.TryGetValue(replacementKeyToken.Value, out provider) == false) { provider = new EvalExpressionProvider(); } var context = new DocumentExpressionContext { OpenToken = openToken, CloseToken = closeReplacementToken, Parameters = parameters.AsReadOnly(), Body = body.AsReadOnly(), ReplacementKeyToken = replacementKeyToken, }; var expression = provider.CreateExpression(context); ret.Add(expression); }
/// <summary> /// Adds a new local variable. This will throw if there's already a variable defined with the given identifier /// </summary> /// <param name="variableToken">The token containing the identifier of the variable name</param> /// <param name="value">The initial value of the local variable</param> public void Add(DocumentToken variableToken, object value) { if (localVariables.ContainsKey(variableToken.Value)) { throw new ArgumentException("There is already a variable called '" + variableToken.Value + "' at " + variableToken.Position); } else { localVariables.Add(variableToken.Value, value); } }
private DocumentRenderException Unexpected(string expected, DocumentToken actual = null) { if (actual != null) { return(new DocumentRenderException(string.Format("Expected '{0}', got '{1}'", expected, actual.Value), actual)); } else { var format = "Expected '{0}'"; var msg = string.Format(format, expected); return(new DocumentRenderException(msg, DocumentRenderException.NoTokenReason.EndOfString)); } }
/// <summary> /// Creates a table expression from the given document info. /// </summary> /// <param name="replacementKeyToken">The token that should contain a value of 'table'</param> /// <param name="parameters">Replacement parameters that should be column names and optional properties</param> /// <param name="body">Should be empty. Table expressions don't support bodies</param> /// <returns>The created document expression</returns> public IDocumentExpression CreateExpression(DocumentToken replacementKeyToken, List <DocumentToken> parameters, List <DocumentToken> body) { if (body.Count > 0) { throw new DocumentRenderException("table tags can't have a body", replacementKeyToken); } TokenReader <DocumentToken> reader = new TokenReader <DocumentToken>(parameters); DocumentToken variableExpressionToken; if (reader.TryAdvance(out variableExpressionToken, skipWhitespace: true) == false) { throw new DocumentRenderException("missing collection expression after table tag", replacementKeyToken); } List <DocumentToken> columns = new List <DocumentToken>(); bool showDefaults = true; bool showPossibilities = true; while (reader.CanAdvance(skipWhitespace: true)) { var nextToken = reader.Advance(skipWhitespace: true); if (nextToken.Value == "-HideDefaults") { showDefaults = false; } else if (nextToken.Value == "-HideEnumValues") { showPossibilities = false; } else { columns.Add(nextToken); } } if (columns.Count == 0) { throw new DocumentRenderException("table elements need to have at least one column parameter", replacementKeyToken); } return(new TableExpression(variableExpressionToken, columns) { ShowDefaultValuesForArguments = showDefaults, ShowPossibleValuesForArguments = showPossibilities }); }
private DocumentToken AdvanceAndExpectConstantType(TokenReader <DocumentToken> reader, DocumentTokenType expectedType) { DocumentToken read; if (reader.TryAdvance(out read, skipWhitespace: true) == false) { throw Unexpected(DocumentToken.GetTokenTypeValue(expectedType)); } if (read.TokenType != expectedType) { throw Unexpected(DocumentToken.GetTokenTypeValue(expectedType), read); } return(read); }
private static List <DocumentToken> RemoveLinesThatOnlyContainReplacements(List <DocumentToken> tokens) { var currentLine = 1; int numContentTokensOnCurrentLine = 0; int numReplacementTokensOnCurrentLine = 0; List <DocumentToken> filtered = new List <DocumentToken>(); DocumentToken lastToken = null; foreach (var token in tokens) { lastToken = token; if (token.Line != currentLine) { currentLine = token.Line; FilterOutNewlinesIfNeeded(numContentTokensOnCurrentLine, numReplacementTokensOnCurrentLine, filtered); numReplacementTokensOnCurrentLine = 0; numContentTokensOnCurrentLine = 0; } if (string.IsNullOrWhiteSpace(token.Value)) { // do nothing } else if (IsReplacementToken(token)) { numReplacementTokensOnCurrentLine++; } else { numContentTokensOnCurrentLine++; } filtered.Add(token); } if (lastToken != null) { currentLine = lastToken.Line; FilterOutNewlinesIfNeeded(numContentTokensOnCurrentLine, numReplacementTokensOnCurrentLine, filtered); numReplacementTokensOnCurrentLine = 0; numContentTokensOnCurrentLine = 0; } return(filtered); }
/// <summary> /// Creates either an if or an ifnot expression, based on its configuration, using the given document info. /// </summary> /// <param name="replacementKeyToken">The replacement key token whose value is either 'if' or 'ifnot'</param> /// <param name="parameters">There should be no parameters to an if or ifnot expression</param> /// <param name="body">The body which will be conditionally rendered.</param> /// <returns>The expression, either an if or an ifnot expression</returns> public IDocumentExpression CreateExpression(DocumentToken replacementKeyToken, List <DocumentToken> parameters, List <DocumentToken> body) { TokenReader <DocumentToken> reader = new TokenReader <DocumentToken>(parameters); DocumentToken ifExpressionToken; if (reader.TryAdvance(out ifExpressionToken, skipWhitespace: true) == false) { throw new DocumentRenderException("missing if expression", replacementKeyToken); } if (reader.CanAdvance(skipWhitespace: true)) { throw new DocumentRenderException("unexpected parameters after if expression", reader.Advance(skipWhitespace: true)); } return(not ? new IfNotExpression(ifExpressionToken, body) : new IfExpression(ifExpressionToken, body)); }
/// <summary> /// Takes in document replacement info and converts it into a document expression that represents an each loop. /// </summary> /// <param name="replacementKeyToken">The token that is expected to have a value of 'each'</param> /// <param name="parameters">The parameters which should follow the format ITERATION_VARIABLE_NAME in COLLECTION_EXPRESSION</param> /// <param name="body">The body of the each loop</param> /// <returns>The parsed each expression</returns> public IDocumentExpression CreateExpression(DocumentToken replacementKeyToken, List <DocumentToken> parameters, List <DocumentToken> body) { if (body.Count == 0) { throw new DocumentRenderException("Each tag has no body", replacementKeyToken); } TokenReader <DocumentToken> reader = new TokenReader <DocumentToken>(parameters); DocumentToken variableName; if (reader.TryAdvance(out variableName, skipWhitespace: true) == false) { throw new DocumentRenderException("missing variable name in each tag", replacementKeyToken); } DocumentToken inToken; if (reader.TryAdvance(out inToken, skipWhitespace: true) == false) { throw new DocumentRenderException("Expected 'in' after iteration variable", variableName); } if (inToken.Value != "in") { throw new DocumentRenderException("Expected 'in', got '" + inToken.Value + "'", inToken); } DocumentToken collectionExpressionToken; if (reader.TryAdvance(out collectionExpressionToken, skipWhitespace: true) == false) { throw new DocumentRenderException("Expected collection expression after 'in' ", inToken); } DocumentToken unexpected; if (reader.TryAdvance(out unexpected, skipWhitespace: true)) { throw new DocumentRenderException("Unexpected parameter '" + unexpected.Value + "' after collection", unexpected); } return(new EachExpression(variableName, collectionExpressionToken, body)); }
private DocumentRenderException Unexpected(DocumentToken t) { return(new DocumentRenderException(string.Format("Unexpected token '{0}'", t.Value), t)); }
/// <summary> /// Adds a new local variable. This will throw if there's already a variable defined with the given identifier /// </summary> /// <param name="variableToken">The token containing the identifier of the variable name</param> /// <param name="value">The initial value of the local variable</param> public void Add(DocumentToken variableToken, object value) { if(localVariables.ContainsKey(variableToken.Value)) { throw new ArgumentException("There is already a variable called '" + variableToken.Value + "' at " + variableToken.Position); } else { localVariables.Add(variableToken.Value, value); } }
private List<DocumentToken> ReadReplacementBody(TokenReader<DocumentToken> reader, DocumentToken replacementKeyToken) { List<DocumentToken> replacementContents = new List<DocumentToken>(); int numOpenReplacements = 1; while (reader.CanAdvance()) { if (reader.Peek().TokenType == DocumentTokenType.BeginReplacementSegment) { numOpenReplacements++; } else if (reader.Peek().TokenType == DocumentTokenType.QuickTerminateReplacementSegment) { numOpenReplacements--; if(numOpenReplacements == 0) { throw Unexpected(reader.Peek()); } } else if (reader.Peek().TokenType == DocumentTokenType.BeginTerminateReplacementSegment) { numOpenReplacements--; if(numOpenReplacements == 0) { AdvanceAndExpectConstantType(reader, DocumentTokenType.BeginTerminateReplacementSegment); AdvanceAndExpect(reader, DocumentTokenType.ReplacementKey, replacementKeyToken.Value, skipWhitespace: true); AdvanceAndExpectConstantType(reader, DocumentTokenType.EndReplacementSegment); break; } } replacementContents.Add(reader.Advance()); } if(numOpenReplacements != 0) { throw Unexpected("end of '" + replacementKeyToken.Value + "' replacement"); } return replacementContents; }
/// <summary> /// Creates a new ifnot expression given a conditional token and a body /// </summary> /// <param name="ifExpressionToken">The token containing the conditional expression</param> /// <param name="body">The body of the document to render only if the condition evaluates to false</param> public IfNotExpression(DocumentToken ifExpressionToken, IEnumerable <DocumentToken> body) : base(ifExpressionToken, body) { }
/// <summary> /// Creates a new each expression given an iteration variable name, a collection expression, and a body. /// </summary> /// <param name="iterationVariable">The name to assign to ther variable representing the current element in the template</param> /// <param name="collectionExpression">The expression used to determine the collection to enumerate</param> /// <param name="body">The body of the each loop</param> public EachExpression(DocumentToken iterationVariable, DocumentToken collectionExpression, List <DocumentToken> body) { this.IterationVariableNameToken = iterationVariable; this.CollectionVariableExpressionToken = collectionExpression; this.Body = body; }
private DocumentRenderException Unexpected(DocumentToken t) { return new DocumentRenderException(string.Format("Unexpected token '{0}'", t.Value), t); }
private static bool IsReplacementToken(DocumentToken token) { return token.TokenType == DocumentTokenType.BeginReplacementSegment || token.TokenType == DocumentTokenType.BeginTerminateReplacementSegment || token.TokenType == DocumentTokenType.EndReplacementSegment || token.TokenType == DocumentTokenType.QuickTerminateReplacementSegment || token.TokenType == DocumentTokenType.ReplacementKey || token.TokenType == DocumentTokenType.ReplacementParameter; }
/// <summary> /// Creates a new if expression given a conditional token and a body /// </summary> /// <param name="ifExpressionToken">The token containing the conditional expression</param> /// <param name="body">The body of the document to render only if the condition evaluates to true</param> public IfExpression(DocumentToken ifExpressionToken, List <DocumentToken> body) { this.IfExpressionToken = ifExpressionToken; this.Body = body; }
/// <summary> /// Creates an exception given a message and the offending token /// </summary> /// <param name="msg">The exception message</param> /// <param name="offendingToken">The offending token</param> public DocumentRenderException(string msg, DocumentToken offendingToken) : base(msg + ": " + offendingToken.Position) { }
/// <summary> /// Creates an eval expression given a token that represents the expression to evaluate /// </summary> /// <param name="evalToken">The token containing the expression to evaluate</param> public EvalExpression(DocumentToken evalToken) { this.EvalToken = evalToken; }
/// <summary> /// Creates a new clear variable expression given a variable name /// </summary> /// <param name="name">A token containing the name of the variable whose scope is ending</param> public ClearVarExpression(DocumentToken name) { this.NameToken = name; }
/// <summary> /// Creates a new each expression given an iteration variable name, a collection expression, and a body. /// </summary> /// <param name="iterationVariable">The name to assign to ther variable representing the current element in the template</param> /// <param name="collectionExpression">The expression used to determine the collection to enumerate</param> /// <param name="body">The body of the each loop</param> public EachExpression(DocumentToken iterationVariable, DocumentToken collectionExpression, IEnumerable<DocumentToken> body) { this.IterationVariableNameToken = iterationVariable; this.CollectionVariableExpressionToken = collectionExpression; this.Body = body; }
/// <summary> /// Dynamically renders the given template. /// </summary> /// <param name="dynamicTemplate">The template to render</param> /// <param name="nestedToken">The token in the original document that resulted in dynamic rendering</param> /// <returns>The rendered content</returns> public ConsoleString RenderDynamicContent(string dynamicTemplate, DocumentToken nestedToken) { return(this.DocumentRenderer.Render(dynamicTemplate, this, "dynamic evaluation sourced from '" + nestedToken.Position + "'")); }
/// <summary> /// Creates a new template expression given an id token and a data evaluation token. /// </summary> /// <param name="idToken">A token containing the id of the template to render</param> /// <param name="evalToken">A token containing an expression to be evaluated. The result of the evaluation will be /// used as the root data object to be bound to the named template.</param> public TemplateExpression(DocumentToken idToken, DocumentToken evalToken) { this.IdToken = idToken; this.EvalToken = evalToken; }
/// <summary> /// Creates a plain text document expression given a single plain text token /// </summary> /// <param name="singleToken">A single plain text token to render without any special handling</param> public PlainTextDocumentExpression(DocumentToken singleToken) : this(new List <DocumentToken> { singleToken }) { }
/// <summary> /// Creates a new ifnot expression given a conditional token and a body /// </summary> /// <param name="ifExpressionToken">The token containing the conditional expression</param> /// <param name="body">The body of the document to render only if the condition evaluates to false</param> public IfNotExpression(DocumentToken ifExpressionToken, List <DocumentToken> body) : base(ifExpressionToken, body) { }
/// <summary> /// Creates a new ifnot expression given a conditional token and a body /// </summary> /// <param name="ifExpressionToken">The token containing the conditional expression</param> /// <param name="body">The body of the document to render only if the condition evaluates to false</param> public IfNotExpression(DocumentToken ifExpressionToken, IEnumerable<DocumentToken> body) : base(ifExpressionToken, body) { }
private DocumentRenderException Unexpected(string expected, DocumentToken actual = null) { if (actual != null) { return new DocumentRenderException(string.Format("Expected '{0}', got '{1}'", expected, actual.Value), actual); } else { var format = "Expected '{0}'"; var msg = string.Format(format, expected); return new DocumentRenderException(msg, DocumentRenderException.NoTokenReason.EndOfString); } }
/// <summary> /// Creates a new if expression given a conditional token and a body /// </summary> /// <param name="ifExpressionToken">The token containing the conditional expression</param> /// <param name="body">The body of the document to render only if the condition evaluates to true</param> public IfExpression(DocumentToken ifExpressionToken, IEnumerable <DocumentToken> body) { this.IfExpressionToken = ifExpressionToken; this.Body = body; }
private List <DocumentToken> ReadReplacementBody(TokenReader <DocumentToken> reader, DocumentToken replacementKeyToken) { List <DocumentToken> replacementContents = new List <DocumentToken>(); int numOpenReplacements = 1; while (reader.CanAdvance()) { if (reader.Peek().TokenType == DocumentTokenType.BeginReplacementSegment) { numOpenReplacements++; } else if (reader.Peek().TokenType == DocumentTokenType.QuickTerminateReplacementSegment) { numOpenReplacements--; if (numOpenReplacements == 0) { throw Unexpected(reader.Peek()); } } else if (reader.Peek().TokenType == DocumentTokenType.BeginTerminateReplacementSegment) { numOpenReplacements--; if (numOpenReplacements == 0) { AdvanceAndExpectConstantType(reader, DocumentTokenType.BeginTerminateReplacementSegment); AdvanceAndExpect(reader, DocumentTokenType.ReplacementKey, replacementKeyToken.Value, skipWhitespace: true); AdvanceAndExpectConstantType(reader, DocumentTokenType.EndReplacementSegment); break; } } replacementContents.Add(reader.Advance()); } if (numOpenReplacements != 0) { throw Unexpected("end of '" + replacementKeyToken.Value + "' replacement"); } return(replacementContents); }
/// <summary> /// Creates a new if expression given a conditional token and a body /// </summary> /// <param name="ifExpressionToken">The token containing the conditional expression</param> /// <param name="body">The body of the document to render only if the condition evaluates to true</param> public IfExpression(DocumentToken ifExpressionToken, IEnumerable<DocumentToken> body) { this.IfExpressionToken = ifExpressionToken; this.Body = body; }
/// <summary> /// Dynamically renders the given template. /// </summary> /// <param name="dynamicTemplate">The template to render</param> /// <param name="nestedToken">The token in the original document that resulted in dynamic rendering</param> /// <returns>The rendered content</returns> public ConsoleString RenderDynamicContent(string dynamicTemplate, DocumentToken nestedToken) { return this.DocumentRenderer.Render(dynamicTemplate, this, "dynamic evaluation sourced from '" + nestedToken.Position + "'"); }
internal ConsoleString Render(string template, DocumentRendererContext context, string sourceFileLocation = null) { List <DocumentToken> tokens = DocumentToken.Tokenize(template, sourceFileLocation); return(Render(tokens, context)); }
/// <summary> /// Creates a new variable expression given a name and value expression /// </summary> /// <param name="name">A token containing the name of the local variable to initialize</param> /// <param name="value">A token containing an expression that should resolve to the initial value of the variable</param> public VarExpression(DocumentToken name, DocumentToken value) { this.NameToken = name; this.ValueToken = value; }