PushBack() public method

Puts these characters back into the stream
public PushBack ( IEnumerable pushBack ) : void
pushBack IEnumerable
return void
Example #1
0
        internal static Block ParseDirective(ParserStream stream)
        {
            const string import       = "import";
            const string @using       = "using";
            const string sprite       = "sprite";
            const string charset      = "charset";
            const string media        = "media";
            const string keyframes    = "keyframes";
            const string mozKeyframes = "-moz-keyframes";
            const string webKeyframes = "-webkit-keyframes";
            const string fontFace     = "font-face";
            const string reset        = "reset";

            stream.Advance(); // Advance past @

            var bufferStart = stream.Position;
            var buffer      = new StringBuilder();
            var next        = stream.WhichNextInsensitive(buffer, @using, sprite, import, charset, media, keyframes, mozKeyframes, webKeyframes, fontFace, reset);

            if (next == @using)
            {
                return(ParseUsingDirective(stream));
            }

            if (next == sprite)
            {
                return(ParseSpriteDeclaration(stream));
            }

            if (next == import)
            {
                return(ParseImportDirective(stream));
            }

            if (next == charset)
            {
                return(ParseCharsetDirective(stream));
            }

            if (next == media)
            {
                return(ParseMediaDirective(stream));
            }

            if (next.In(keyframes, mozKeyframes, webKeyframes))
            {
                string prefix = "";
                if (next == mozKeyframes)
                {
                    prefix = "-moz-";
                }
                if (next == webKeyframes)
                {
                    prefix = "-webkit-";
                }

                return(ParseKeyFramesDirective(prefix, stream, bufferStart));
            }

            if (next == fontFace)
            {
                return(ParseFontFace(stream, bufferStart));
            }

            if (next == reset)
            {
                return(ParseResetDirective(stream, bufferStart));
            }

            stream.PushBack(buffer.ToString());

            var leader = new StringBuilder();

            var eqOrPara = stream.ScanUntil(leader, '=', '(');

            if (eqOrPara == '=')
            {
                return(ParseMoreVariable(leader.ToString(), stream, bufferStart));
            }

            return(ParseMixinDeclaration(leader.ToString(), stream));
        }
Example #2
0
        public void StreamPushBack()
        {
            using (var stream = new ParserStream(new StringReader("")))
            {
                var buffer = new StringBuilder();

                stream.PushBack("hello world!");
                stream.ScanUntil(buffer, '!');
                Assert.AreEqual("hello world", buffer.ToString());
                Assert.IsFalse(stream.HasMore());

                buffer.Clear();

                stream.PushBack("world!");
                stream.PushBack("hello ");
                stream.ScanUntil(buffer, '!');
                Assert.AreEqual("hello world", buffer.ToString());
                Assert.IsFalse(stream.HasMore());
            }
        }
Example #3
0
        internal static Property ParseRule(ParserStream stream)
        {
            var start = stream.Position;

            if (stream.Peek() == '@')
            {
                return(ParseMixinOrVariableRule(stream));
            }

            var ruleName = new StringBuilder();
            var found    = stream.ScanUntil(ruleName, ';', '{', '}');

            // Final semi-colon in a block is optional, so inject a ';' if we encounter a '}' in this case
            if (found == '}')
            {
                found = ';';
                // trailing semi-colon may be optional
                if (ruleName[ruleName.Length - 1] == ';')
                {
                    ruleName = ruleName.Remove(ruleName.Length - 1, 1);
                }
                stream.PushBack(new[] { '}' });
            }

            if (found == '{')
            {
                var nestedBlock = ParseSelectorAndBlock(stream, ruleName.ToString().Trim());

                return(new NestedBlockProperty(nestedBlock, start, stream.Position));
            }

            if (found == null)
            {
                Current.RecordError(ErrorType.Parser, Position.Create(start, stream.Position, Current.CurrentFilePath), "Expected ';', '{', or '}'");
                throw new StoppedParsingException();
            }

            var colon = ruleName.ToString().IndexOf(':');

            if (colon == -1)
            {
                Current.RecordError(ErrorType.Parser, Position.Create(start, stream.Position, Current.CurrentFilePath), "Expected ':'");
                throw new StoppedParsingException();
            }

            var name   = ruleName.ToString().Substring(0, colon).Trim();
            var valStr = ruleName.ToString().Substring(colon + 1).Trim() + ";";

            if (valStr == ";")
            {
                Current.RecordError(ErrorType.Parser, Position.Create(start, stream.Position, Current.CurrentFilePath), "Expected value");
                throw new StoppedParsingException();
            }

            stream.PushBack(valStr);

            Value value;

            if (name.Equals("font", StringComparison.InvariantCultureIgnoreCase))
            {
                // font has a goofy shorthand, needs special treatment
                value = ParseFontLikeValue(stream);
            }
            else
            {
                if (name.Equals("background-position"))
                {
                    // likewise, background-position can often look like a math statement
                    value = ParseBackgroundPositionValue(stream);
                }
                else
                {
                    if (name.Equals("border-radius"))
                    {
                        value = ParseFontLikeValue(stream);
                    }
                    else
                    {
                        value = ParseMoreValue(stream);
                    }
                }
            }

            return(new NameValueProperty(name, value, start, stream.Position, Current.CurrentFilePath));
        }
Example #4
0
        internal static Property ParseRule(ParserStream stream)
        {
            var start = stream.Position;

            if (stream.Peek() == '@')
            {
                return ParseMixinOrVariableRule(stream);
            }

            var ruleName = new StringBuilder();
            var found = stream.ScanUntil(ruleName, ';', '{', '}');

            // Final semi-colon in a block is optional, so inject a ';' if we encounter a '}' in this case
            if (found == '}')
            {
                found = ';';
                // trailing semi-colon may be optional
                if (ruleName[ruleName.Length - 1] == ';')
                {
                    ruleName = ruleName.Remove(ruleName.Length - 1, 1);
                }
                stream.PushBack(new[] { '}' });
            }

            if (found == '{')
            {
                var nestedBlock = ParseSelectorAndBlock(stream, ruleName.ToString().Trim());

                return new NestedBlockProperty(nestedBlock, start, stream.Position);
            }

            if (found == null)
            {
                Current.RecordError(ErrorType.Parser, Position.Create(start, stream.Position, Current.CurrentFilePath), "Expected ';', '{', or '}'");
                throw new StoppedParsingException();
            }

            var colon = ruleName.ToString().IndexOf(':');

            if (colon == -1)
            {
                Current.RecordError(ErrorType.Parser, Position.Create(start, stream.Position, Current.CurrentFilePath), "Expected ':'");
                throw new StoppedParsingException();
            }

            var name = ruleName.ToString().Substring(0, colon).Trim();
            var valStr = ruleName.ToString().Substring(colon + 1).Trim() + ";";

            if (valStr == ";")
            {
                Current.RecordError(ErrorType.Parser, Position.Create(start, stream.Position, Current.CurrentFilePath), "Expected value");
                throw new StoppedParsingException();
            }

            stream.PushBack(valStr);

            Value value;

            if (name.Equals("font", StringComparison.InvariantCultureIgnoreCase))
            {
                // font has a goofy shorthand, needs special treatment
                value = ParseFontLikeValue(stream);
            }
            else
            {
                if (name.Equals("background-position"))
                {
                    // likewise, background-position can often look like a math statement
                    value = ParseBackgroundPositionValue(stream);
                }
                else
                {
                    if (name.Equals("border-radius"))
                    {
                        value = ParseFontLikeValue(stream);
                    }
                    else
                    {
                        value = ParseMoreValue(stream);
                    }
                }
            }

            return new NameValueProperty(name, value, start, stream.Position, Current.CurrentFilePath);
        }
Example #5
0
        internal static Block ParseDirective(ParserStream stream)
        {
            const string import = "import";
            const string @using = "using";
            const string sprite = "sprite";
            const string charset = "charset";
            const string media = "media";
            const string keyframes = "keyframes";
            const string mozKeyframes = "-moz-keyframes";
            const string webKeyframes = "-webkit-keyframes";
            const string fontFace = "font-face";
            const string reset = "reset";

            stream.Advance(); // Advance past @

            var bufferStart = stream.Position;
            var buffer = new StringBuilder();
            var next = stream.WhichNextInsensitive(buffer, @using, sprite, import, charset, media, keyframes, mozKeyframes, webKeyframes, fontFace, reset);

            if (next == @using)
            {
                return ParseUsingDirective(stream);
            }

            if (next == sprite)
            {
                return ParseSpriteDeclaration(stream);
            }

            if (next == import)
            {
                return ParseImportDirective(stream);
            }

            if (next == charset)
            {
                return ParseCharsetDirective(stream);
            }

            if (next == media)
            {
                return ParseMediaDirective(stream);
            }

            if (next.In(keyframes, mozKeyframes, webKeyframes))
            {
                string prefix = "";
                if (next == mozKeyframes) prefix = "-moz-";
                if (next == webKeyframes) prefix = "-webkit-";

                return ParseKeyFramesDirective(prefix, stream, bufferStart);
            }

            if (next == fontFace)
            {
                return ParseFontFace(stream, bufferStart);
            }

            if (next == reset)
            {
                return ParseResetDirective(stream, bufferStart);
            }

            stream.PushBack(buffer.ToString());

            var leader = new StringBuilder();

            var eqOrPara = stream.ScanUntil(leader, '=', '(');

            if (eqOrPara == '=')
            {
                return ParseMoreVariable(leader.ToString(), stream, bufferStart);
            }

            return ParseMixinDeclaration(leader.ToString(), stream);
        }
Example #6
0
        private static Value ParseNumber(ParserStream stream, IPosition forPosition)
        {
            var pushbackBuffer = new StringBuilder();

            var buffer = new StringBuilder();

            bool negate = false;

            if (stream.Peek() == '-')
            {
                negate = true;
                stream.Advance();
                pushbackBuffer.Append('-');
            }

            bool decimalPassed = false;

            while (stream.HasMore() && (char.IsDigit(stream.Peek()) || (stream.Peek() == '.' && !decimalPassed)))
            {
                var c = stream.Read();
                buffer.Append(c);
                pushbackBuffer.Append(c);

                if (c == '.') decimalPassed = true;
            }

            Unit? unit = null;
            decimal digit;
            if (!decimal.TryParse(buffer.ToString(), out digit))
            {
                // Looked like a number, but wasn't!
                stream.PushBack(pushbackBuffer.ToString());
                return ParseString(stream, forPosition);
            }

            if (negate) digit *= -1m;

            buffer.Clear();
            while (stream.HasMore() && char.IsWhiteSpace(stream.Peek()))
            {
                buffer.Append(stream.Read());
            }

            var nextFour = new StringBuilder();
            for (int i = 0; i < 4; i++)
            {
                if (stream.HasMore())
                {
                    nextFour.Append(stream.Read());
                }
            }

            var possibleUnit = nextFour.ToString();
            List<char> pushBack;

            unit = ParsePossibleUnit(possibleUnit, out pushBack);

            if (unit == null)
            {
                stream.PushBack(nextFour.ToString());
                stream.PushBack(buffer.ToString());
            }
            else
            {
                stream.PushBack(pushBack);
                return new NumberWithUnitValue(digit, unit.Value);
            }

            return new NumberValue(digit);
        }
Example #7
0
        private static Value ParseNumber(ParserStream stream, IPosition forPosition)
        {
            var pushbackBuffer = new StringBuilder();

            var buffer = new StringBuilder();

            bool negate = false;

            if (stream.Peek() == '-')
            {
                negate = true;
                stream.Advance();
                pushbackBuffer.Append('-');
            }

            bool decimalPassed = false;

            while (stream.HasMore() && (char.IsDigit(stream.Peek()) || (stream.Peek() == '.' && !decimalPassed)))
            {
                var c = stream.Read();
                buffer.Append(c);
                pushbackBuffer.Append(c);

                if (c == '.')
                {
                    decimalPassed = true;
                }
            }

            Unit?   unit = null;
            decimal digit;

            if (!decimal.TryParse(buffer.ToString(), out digit))
            {
                // Looked like a number, but wasn't!
                stream.PushBack(pushbackBuffer.ToString());
                return(ParseString(stream, forPosition));
            }

            if (negate)
            {
                digit *= -1m;
            }

            buffer.Clear();
            while (stream.HasMore() && char.IsWhiteSpace(stream.Peek()))
            {
                buffer.Append(stream.Read());
            }

            var nextFour = new StringBuilder();

            for (int i = 0; i < 4; i++)
            {
                if (stream.HasMore())
                {
                    nextFour.Append(stream.Read());
                }
            }

            var         possibleUnit = nextFour.ToString();
            List <char> pushBack;

            unit = ParsePossibleUnit(possibleUnit, out pushBack);

            if (unit == null)
            {
                stream.PushBack(nextFour.ToString());
                stream.PushBack(buffer.ToString());
            }
            else
            {
                stream.PushBack(pushBack);
                return(new NumberWithUnitValue(digit, unit.Value));
            }

            return(new NumberValue(digit));
        }