private static ICssValue ParseRepeat(this StringSource source, Func <StringSource, ICssValue> parseCount, Func <StringSource, ICssValue> parseValue)
        {
            var pos   = source.Index;
            var ident = source.ParseIdent();

            if (ident.Isi(FunctionNames.Repeat) && source.Current == Symbols.RoundBracketOpen)
            {
                var c     = source.SkipCurrentAndSpaces();
                var count = parseCount(source);
                c = source.SkipSpaces();

                if (count != null && c == Symbols.Comma)
                {
                    source.SkipCurrentAndSpaces();
                    var value = parseValue(source);
                    c = source.SkipSpacesAndComments();

                    if (value != null && c == Symbols.RoundBracketClose)
                    {
                        source.Next();
                        return(new Repeat(count, value));
                    }
                }
            }

            source.BackTo(pos);
            return(null);
        }
        public static ICssValue ParseAutoTrackList(this StringSource source)
        {
            var values = new List <ICssValue>();
            var pos    = source.Index;
            var head   = source.ParseRepeatValue(s => s.ParseFixedSize() ?? s.ParseFixedRepeat(), true);

            if (head != null)
            {
                values.Add(head);
            }

            source.SkipSpacesAndComments();
            var repeat = source.ParseAutoRepeat();

            if (repeat == null)
            {
                source.BackTo(pos);
                return(null);
            }

            values.Add(repeat);
            source.SkipSpacesAndComments();
            var tail = source.ParseRepeatValue(s => s.ParseFixedSize() ?? s.ParseFixedRepeat(), true);

            source.SkipSpacesAndComments();

            if (tail != null)
            {
                values.Add(tail);
            }

            return(new CssTupleValue(values.ToArray()));
        }
        public static LineNames ParseLineNames(this StringSource source)
        {
            var pos = source.Index;

            if (source.Current == Symbols.SquareBracketOpen)
            {
                source.SkipCurrentAndSpaces();
                var names = new List <String>();

                while (!source.IsDone)
                {
                    var name = source.ParseIdent();

                    if (name == null)
                    {
                        break;
                    }

                    names.Add(name);
                    var current = source.SkipSpacesAndComments();

                    if (current == Symbols.SquareBracketClose)
                    {
                        source.Next();
                        return(new LineNames(names));
                    }
                }
            }

            source.BackTo(pos);
            return(null);
        }
        public static ICssValue ParseFixedSize(this StringSource source)
        {
            var length = source.ParseDistanceOrCalc();

            if (length == null)
            {
                var pos   = source.Index;
                var ident = source.ParseIdent();

                if (ident.Isi(FunctionNames.Minmax) && source.Current == Symbols.RoundBracketOpen)
                {
                    var c   = source.SkipCurrentAndSpaces();
                    var min = source.ParseTrackBreadth(false);
                    c = source.SkipSpaces();

                    if (min != null && c == Symbols.Comma)
                    {
                        source.SkipCurrentAndSpaces();
                        var max = source.ParseTrackBreadth();
                        c = source.SkipSpacesAndComments();

                        if (max != null && c == Symbols.RoundBracketClose && (min is Length? || max is Length?))
                        {
                            source.Next();
                            return(new Minmax(min, max));
                        }
                    }
                }

                source.BackTo(pos);
                return(null);
            }

            return(length);
        }
Beispiel #5
0
        private static IConditionFunction ConjunctionOrDisjunction(StringSource source)
        {
            var condition = Group(source);

            source.SkipSpacesAndComments();
            var pos   = source.Index;
            var ident = source.ParseIdent();

            if (ident != null)
            {
                var isAnd = ident.Is(CssKeywords.And);
                var isOr  = ident.Is(CssKeywords.Or);

                if (isAnd || isOr)
                {
                    var conditions = Scan(source, ident, condition);

                    if (isAnd)
                    {
                        return(new AndCondition(conditions));
                    }
                    else if (isOr)
                    {
                        return(new OrCondition(conditions));
                    }
                }
            }

            source.BackTo(pos);
            return(condition);
        }
        /// <summary>
        /// Parses a linear gradient.
        /// https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient
        /// </summary>
        private static IGradient ParseLinearGradient(StringSource source, Boolean repeating)
        {
            var start = source.Index;
            var angle = ParseLinearAngle(source);

            if (angle != null)
            {
                var current = source.SkipSpacesAndComments();

                if (current != Symbols.Comma)
                {
                    return(null);
                }

                source.SkipCurrentAndSpaces();
            }
            else
            {
                source.BackTo(start);
            }

            var stops = ParseGradientStops(source);

            if (stops != null && source.Current == Symbols.RoundBracketClose)
            {
                source.SkipCurrentAndSpaces();
                return(new LinearGradient(angle, stops, repeating));
            }

            return(null);
        }
Beispiel #7
0
        public static ICssTimingFunctionValue ParseTimingFunction(this StringSource source)
        {
            var pos    = source.Index;
            var result = default(ICssTimingFunctionValue);
            var ident  = source.ParseIdent();

            if (ident != null)
            {
                if (source.Current == Symbols.RoundBracketOpen)
                {
                    var function = default(Func <StringSource, ICssTimingFunctionValue>);

                    if (TimingFunctions.TryGetValue(ident, out function))
                    {
                        source.SkipCurrentAndSpaces();
                        result = function.Invoke(source);
                    }
                }
                else
                {
                    Map.TimingFunctions.TryGetValue(ident, out result);
                }
            }

            if (result == null)
            {
                source.BackTo(pos);
            }

            return(result);
        }
        private static ICssValue ParseRepeatValue(this StringSource source, Func <StringSource, ICssValue> parseTrack, Boolean hasSize = false)
        {
            var values = new List <ICssValue>();
            var pos    = source.Index;

            while (!source.IsDone)
            {
                var names = source.ParseLineNames();
                source.SkipSpacesAndComments();

                if (names != null)
                {
                    values.Add(names);
                }

                var size = parseTrack(source);
                source.SkipSpacesAndComments();

                if (size == null)
                {
                    break;
                }

                hasSize = true;
                values.Add(size);
            }

            if (hasSize)
            {
                return(new CssTupleValue(values.ToArray()));
            }

            source.BackTo(pos);
            return(null);
        }
        public static IEnumerable <IDocumentFunction> ParseDocumentFunctions(this StringSource source, IDocumentFunctionFactory factory)
        {
            var functions = new List <IDocumentFunction>();

            while (!source.IsDone)
            {
                var current = source.SkipSpacesAndComments();

                if (functions.Count > 0)
                {
                    if (current != Symbols.Comma)
                    {
                        return(null);
                    }

                    source.SkipCurrentAndSpaces();
                }

                var position = source.Index;
                var uri      = source.ParseUri();
                var name     = FunctionNames.Url;
                var data     = uri?.Path;

                if (uri == null)
                {
                    source.BackTo(position);
                    name = source.ParseIdent();
                    var start = source.Current;

                    if (name == null || start != Symbols.RoundBracketOpen)
                    {
                        return(null);
                    }

                    source.SkipCurrentAndSpaces();
                    data = source.ParseString();
                    var end = source.SkipSpacesAndComments();

                    if (end != Symbols.RoundBracketClose)
                    {
                        return(null);
                    }

                    source.SkipCurrentAndSpaces();
                }

                var function = factory.Create(name, data);

                if (function == null)
                {
                    return(null);
                }

                functions.Add(function);
            }

            return(functions);
        }
Beispiel #10
0
        public static String TakeUntilClosed(this StringSource source)
        {
            var start             = source.Index;
            var open              = 1;
            var current           = source.Current;
            var lastNonWhitespace = start;

            while (!source.IsDone)
            {
                if (current == Symbols.RoundBracketOpen)
                {
                    open++;
                }
                else if (current == Symbols.RoundBracketClose && --open == 0)
                {
                    break;
                }
                else if (current == Symbols.Solidus && source.Peek() == Symbols.Asterisk)
                {
                    source.Next();
                    current = source.SkipCssComment();
                    continue;
                }
                else if (current.IsOneOf(Symbols.SingleQuote, Symbols.DoubleQuote))
                {
                    source.ParseString();
                    current           = source.Current;
                    lastNonWhitespace = source.Index;
                    continue;
                }
                else if (current == Symbols.ReverseSolidus && source.IsValidEscape())
                {
                    source.ConsumeEscape();
                    current           = source.Current;
                    lastNonWhitespace = source.Index;
                    continue;
                }
                else if (current.IsSpaceCharacter())
                {
                    current = source.SkipSpacesAndComments();
                    continue;
                }

                current           = source.Next();
                lastNonWhitespace = source.Index;
            }

            var end = source.Index;

            source.BackTo(lastNonWhitespace);
            var content = source.Substring(start);

            source.NextTo(end);
            return(content);
        }
Beispiel #11
0
        public static Unit ParseUnit(this StringSource source)
        {
            var pos    = source.Index;
            var result = UnitStart(source);

            if (result == null)
            {
                source.BackTo(pos);
            }

            return(result);
        }
Beispiel #12
0
        public static Color?ParseColor(this StringSource source)
        {
            var pos    = source.Index;
            var result = Start(source);

            if (result == null)
            {
                source.BackTo(pos);
            }

            return(result);
        }
Beispiel #13
0
        public static Length?ParseDistance(this StringSource source)
        {
            var pos    = source.Index;
            var test   = source.ParseUnit();
            var length = GetLength(test);

            if (!length.HasValue)
            {
                source.BackTo(pos);
            }

            return(length);
        }
Beispiel #14
0
        public static Boolean IsIdentifier(this StringSource source, String identifier)
        {
            var pos  = source.Index;
            var test = source.ParseIdent();

            if (test != null && test.Isi(identifier))
            {
                return(true);
            }

            source.BackTo(pos);
            return(false);
        }
Beispiel #15
0
        public static Int32?ParseNaturalInteger(this StringSource source)
        {
            var pos     = source.Index;
            var element = source.ParseInteger();

            if (element.HasValue && element.Value >= 0)
            {
                return(element);
            }

            source.BackTo(pos);
            return(null);
        }
Beispiel #16
0
        public static Int32?ParseWeightInteger(this StringSource source)
        {
            var pos     = source.Index;
            var element = source.ParsePositiveInteger();

            if (element.HasValue && IsWeight(element.Value))
            {
                return(element);
            }

            source.BackTo(pos);
            return(null);
        }
Beispiel #17
0
        public static Int32?ParseBinary(this StringSource source)
        {
            var pos     = source.Index;
            var element = source.ParseInteger();

            if (element.HasValue && (element.Value == 0 || element.Value == 1))
            {
                return(element);
            }

            source.BackTo(pos);
            return(null);
        }
Beispiel #18
0
        public static Double?ParseGreaterOrEqualOneNumber(this StringSource source)
        {
            var pos     = source.Index;
            var element = source.ParseNumber();

            if (element.HasValue && element.Value >= 1f)
            {
                return(element);
            }

            source.BackTo(pos);
            return(null);
        }
Beispiel #19
0
        public static Double?ParsePercent(this StringSource source)
        {
            var pos  = source.Index;
            var test = source.ParseUnit();

            if (test?.Dimension == "%" &&
                Double.TryParse(test.Value, NumberStyles.Float, CultureInfo.InvariantCulture, out var value))
            {
                return(value * 0.01);
            }

            source.BackTo(pos);
            return(null);
        }
        private static RadialGradient.SizeMode?ToSizeMode(StringSource source)
        {
            var pos    = source.Index;
            var ident  = source.ParseIdent();
            var result = RadialGradient.SizeMode.None;

            if (ident != null && Map.RadialGradientSizeModes.TryGetValue(ident, out result))
            {
                return(result);
            }

            source.BackTo(pos);
            return(null);
        }
        public static ICssGradientFunctionValue ParseGradient(this StringSource source)
        {
            var pos   = source.Index;
            var ident = source.ParseIdent();

            if (ident != null && source.Current == Symbols.RoundBracketOpen && GradientFunctions.TryGetValue(ident, out var function))
            {
                source.SkipCurrentAndSpaces();
                return(function.Invoke(source));
            }

            source.BackTo(pos);
            return(null);
        }
Beispiel #22
0
        public static Double?ParsePercent(this StringSource source)
        {
            var pos  = source.Index;
            var test = source.ParseUnit();

            if (test != null && test.Dimension == "%")
            {
                var value = Double.Parse(test.Value, CultureInfo.InvariantCulture);
                return(value * 0.01);
            }

            source.BackTo(pos);
            return(null);
        }
Beispiel #23
0
        public static Length?ParseLength(this StringSource source)
        {
            var pos    = source.Index;
            var test   = source.ParseUnit();
            var length = GetLength(test);

            if (!length.HasValue || length.Value.Type == Length.Unit.Percent)
            {
                source.BackTo(pos);
                return(null);
            }

            return(length);
        }
Beispiel #24
0
        public static ICssValue ParseConstant <T>(this StringSource source, IDictionary <String, T> values)
            where T : struct
        {
            var pos   = source.Index;
            var ident = source.ParseIdent();

            if (ident != null && values.TryGetValue(ident, out T mode))
            {
                return(mode as ICssValue ?? new Constant <T>(ident.ToLowerInvariant(), mode));
            }

            source.BackTo(pos);
            return(null);
        }
Beispiel #25
0
        public static String ParseAnimatableIdent(this StringSource source)
        {
            var pos  = source.Index;
            var test = source.ParseNormalizedIdent();

            //TODO Replace Animatables with call to DeclarationFactory - get from flags
            if (test != null && (test.Isi(CssKeywords.All) || Animatables.Contains(test)))
            {
                return(test);
            }

            source.BackTo(pos);
            return(null);
        }
        public ICssValue Convert(StringSource source)
        {
            var pos   = source.Index;
            var ident = source.ParseIdent();
            var mode  = default(T);

            if (ident != null && _values.TryGetValue(ident, out mode))
            {
                return(new Constant <T>(ident.ToLowerInvariant(), mode));
            }

            source.BackTo(pos);
            return(null);
        }
Beispiel #27
0
        public static Double?ParseRatio(this StringSource source)
        {
            var pos    = source.Index;
            var top    = source.ParseNumber();
            var c      = source.SkipGetSkip();
            var bottom = source.ParseNumber();

            if (top.HasValue && bottom.HasValue && c == Symbols.Solidus)
            {
                return(top.Value / bottom.Value);
            }

            source.BackTo(pos);
            return(null);
        }
Beispiel #28
0
        public static IKeyframeSelector ParseKeyframeSelector(this StringSource source)
        {
            var stops   = new List <Double>();
            var current = source.SkipSpacesAndComments();

            while (current != Symbols.EndOfFile)
            {
                var start = source.Index;
                var id    = source.ParseIdent();

                if (id == null)
                {
                    source.BackTo(start);
                    var test = source.ParsePercent();

                    if (!test.HasValue)
                    {
                        return(null);
                    }

                    stops.Add(test.Value);
                }
                else if (id.Is(CssKeywords.From))
                {
                    stops.Add(0f);
                }
                else if (id.Is(CssKeywords.To))
                {
                    stops.Add(1f);
                }
                else
                {
                    return(null);
                }

                current = source.SkipSpacesAndComments();

                if (current != Symbols.Comma)
                {
                    break;
                }

                current = source.SkipCurrentAndSpaces();
            }

            return(new KeyframeSelector(stops));
        }
Beispiel #29
0
        public static CssCalcValue ParseCalc(this StringSource source)
        {
            var pos = source.Index;

            if (source.IsFunction(FunctionNames.Calc))
            {
                var expression = source.ParseExpression();

                if (expression != null)
                {
                    return(new CssCalcValue(expression));
                }
            }

            source.BackTo(pos);
            return(null);
        }
Beispiel #30
0
        public static Boolean IsFunction(this StringSource source, String name)
        {
            var rest = source.Content.Length - source.Index;

            if (rest >= name.Length + 2)
            {
                var length  = 0;
                var current = source.Current;
                var pos     = source.Index;

                while (length < name.Length)
                {
                    if (current == Symbols.ReverseSolidus && source.IsValidEscape())
                    {
                        var next = source.ConsumeEscape();

                        if (next.Length != 1)
                        {
                            break;
                        }

                        current = next[0];
                    }

                    if (Char.ToLowerInvariant(current) != Char.ToLowerInvariant(name[length]))
                    {
                        break;
                    }

                    length++;
                    current = source.Next();
                }

                if (length == name.Length && current == Symbols.RoundBracketOpen)
                {
                    source.SkipCurrentAndSpaces();
                    return(true);
                }

                source.BackTo(pos);
            }

            return(false);
        }