예제 #1
0
        /// <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);
        }
예제 #2
0
 /// <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);
     }
 }
예제 #3
0
 /// <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;
 }
예제 #4
0
        /// <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));
        }
예제 #5
0
        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;
            }
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
 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;
 }
예제 #9
0
        /// <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;
        }
예제 #10
0
        /// <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);
        }
예제 #12
0
 /// <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));
     }
 }
예제 #14
0
        /// <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);
        }
예제 #16
0
        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);
        }
예제 #17
0
        /// <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));
        }
예제 #18
0
        /// <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));
 }
예제 #20
0
 /// <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;
        }
예제 #22
0
 /// <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)
 {
 }
예제 #23
0
 /// <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);
 }
예제 #25
0
 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;
 }
예제 #26
0
 /// <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;
 }
예제 #27
0
 /// <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)
 {
 }
예제 #28
0
 /// <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;
 }
예제 #29
0
 /// <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;
 }
예제 #30
0
 /// <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 + "'"));
 }
예제 #32
0
 /// <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);
     }
 }
예제 #33
0
 /// <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;
 }
예제 #34
0
 /// <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 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
 })
 {
 }
예제 #36
0
 /// <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)
 {
 }
예제 #37
0
 /// <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)
 {
 }
예제 #38
0
 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;
 }
 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);
     }
 }
예제 #40
0
 /// <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);
        }
예제 #42
0
 /// <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;
 }
예제 #43
0
 /// <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;
 }
예제 #44
0
 /// <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 + "'");
 }
예제 #45
0
        internal ConsoleString Render(string template, DocumentRendererContext context, string sourceFileLocation = null)
        {
            List <DocumentToken> tokens = DocumentToken.Tokenize(template, sourceFileLocation);

            return(Render(tokens, context));
        }
예제 #46
0
 /// <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;
 }
예제 #47
0
 /// <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;
 }