/// <summary>
 ///     Initializes a new instance of the <see cref="FormatterRequest" /> class.
 /// </summary>
 /// <param name="sourceLiteral">
 ///     The source literal.
 /// </param>
 /// <param name="variable">
 ///     The variable.
 /// </param>
 /// <param name="formatterName">
 ///     Name of the formatter.
 /// </param>
 /// <param name="formatterArguments">
 ///     The formatter arguments.
 /// </param>
 public FormatterRequest(Literal sourceLiteral, string variable, string formatterName, string formatterArguments)
 {
     this.SourceLiteral = sourceLiteral;
     this.Variable = variable;
     this.FormatterName = formatterName;
     this.FormatterArguments = formatterArguments;
 }
 public void ReadLiteralSection(string source, string expected, int expectedLastIndex)
 {
     var literal = new Literal(10, 10, 1, 1, new StringBuilder(source));
     int lastIndex;
     Assert.Equal(expected, PatternParser.ReadLiteralSection(literal, 0, false, out lastIndex));
     Assert.Equal(expectedLastIndex, lastIndex);
 }
        public void ShiftIndices()
        {
            var subject = new Literal(20, 29, 1, 1, new StringBuilder(new string('a', 10)));
            var other = new Literal(5, 10, 1, 1, new StringBuilder(new string('a', 6)));

            subject.ShiftIndices(2, other);

            // I honestly have no explanation for this, but it works with the formatter. Magic?
            Assert.Equal(18, subject.StartIndex);
            Assert.Equal(27, subject.EndIndex);
        }
 public void ReadLiteralSection_throws_with_invalid_characters(
     Literal literal, 
     int expectedLine, 
     int expectedColumn)
 {
     int lastIndex;
     var ex =
         Assert.Throws<MalformedLiteralException>(
             () => PatternParser.ReadLiteralSection(literal, 0, false, out lastIndex));
     Assert.Equal(expectedLine, ex.LineNumber);
     Assert.Equal(expectedColumn, ex.ColumnNumber);
     this.outputHelper.WriteLine(ex.Message);
 }
 public void ReadLiteralSection_with_offset(string source, string expected, int offset)
 {
     var literal = new Literal(10, 10, 1, 1, new StringBuilder(source));
     int lastIndex;
     Assert.Equal(expected, PatternParser.ReadLiteralSection(literal, offset, true, out lastIndex));
 }
        /// <summary>
        ///     Gets the key from the literal.
        /// </summary>
        /// <param name="literal">
        ///     The literal.
        /// </param>
        /// <param name="offset">
        ///     The offset.
        /// </param>
        /// <param name="allowEmptyResult">
        ///     if set to <c>true</c>, allows an empty result, in which case the return value is
        ///     <c>null</c>
        /// </param>
        /// <param name="lastIndex">
        ///     The last index.
        /// </param>
        /// <returns>
        ///     The <see cref="string" />.
        /// </returns>
        /// <exception cref="MalformedLiteralException">
        ///     Parsing the variable key yielded an empty string.
        /// </exception>
        internal static string ReadLiteralSection(Literal literal, int offset, bool allowEmptyResult, out int lastIndex)
        {
            const char Comma = ',';
            var sb = new StringBuilder();
            var innerText = literal.InnerText;
            var column = literal.SourceColumnNumber;
            var foundWhitespace = false;
            lastIndex = 0;
            for (var i = offset; i < innerText.Length; i++)
            {
                var c = innerText[i];
                column++;
                lastIndex = i;
                if (c == Comma)
                {
                    break;
                }

                // Disregard whitespace.
                var whitespace = c == ' ' || c == '\r' || c == '\n' || c == '\t';
                if (!whitespace)
                {
                    if (c.IsAlphaNumeric() == false)
                    {
                        var msg = string.Format("Invalid literal character '{0}'.", c);

                        // Line number can't have changed.
                        throw new MalformedLiteralException(msg, literal.SourceLineNumber, column, innerText.ToString());
                    }
                }
                else
                {
                    foundWhitespace = true;
                }

                sb.Append(c);
            }

            if (sb.Length != 0)
            {
                // Trim whitespace from beginning and end of the string, if necessary.
                if (!foundWhitespace)
                {
                    return sb.ToString();
                }

                StringBuilder trimmed = sb.TrimWhitespace();
                if (trimmed.Length == 0)
                {
                    return null;
                }

                if (trimmed.ContainsWhitespace())
                {
                    throw new MalformedLiteralException(
                        "Parsed literal must not contain whitespace.", 
                        0, 
                        0, 
                        trimmed.ToString());
                }

                return sb.ToString();
            }

            if (allowEmptyResult)
            {
                return null;
            }

            throw new MalformedLiteralException(
                "Parsing the literal yielded an empty string.", 
                literal.SourceLineNumber, 
                column);
        }
 /// <summary>
 ///     Updates the start and end index.
 /// </summary>
 /// <param name="resultLength">
 ///     Length of the result.
 /// </param>
 /// <param name="literal">
 ///     The literal that was just formatted.
 /// </param>
 public void ShiftIndices(int resultLength, Literal literal)
 {
     int offset = (literal.EndIndex - literal.StartIndex) - 1;
     this.StartIndex = (this.StartIndex - offset) + resultLength;
     this.EndIndex = (this.EndIndex - offset) + resultLength;
 }