/// <summary> /// Parses the CSS rule. /// </summary> /// <param name="curStyle">Current style.</param> /// <param name="rule">Rule.</param> internal static void ParseCSSRule(ref TextStyleParameters curStyle, CssParserRule rule) { foreach (var declaration in rule.Declarations) { if (_textStyleProperties.ContainsKey(declaration.Property)) { var cleanedValue = declaration.Value.Replace("\"", ""); cleanedValue = cleanedValue.Trim(); var prop = _textStyleProperties [declaration.Property]; switch (prop.PropertyType.Name) { case "String": curStyle.SetValue(prop.Name, cleanedValue); break; case "Int32": int numInt; if (int.TryParse(cleanedValue, out numInt)) { curStyle.SetValue(prop.Name, numInt); } break; case "Single": cleanedValue = cleanedValue.Replace("px", ""); float numFloat; if (float.TryParse(cleanedValue, out numFloat)) { curStyle.SetValue(prop.Name, numFloat); } else { throw new Exception("Failed to Parse Single value " + cleanedValue); } break; case "Single[]": var parts = cleanedValue.Split(new char [] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries); var parsedValues = new float [parts.Length]; for (int i = 0; i < parts.Length; i++) { float numArrayFloat; if (float.TryParse(parts [i], out numArrayFloat)) { parsedValues [i] = numArrayFloat; } } curStyle.SetValue(prop.Name, parsedValues); break; case "TextStyleAlign": curStyle.TextAlign = EnumUtils.FromDescription <TextStyleAlign> (cleanedValue); break; case "TextStyleDecoration": curStyle.TextDecoration = EnumUtils.FromDescription <TextStyleDecoration> (cleanedValue); break; case "TextStyleTextTransform": curStyle.TextTransform = EnumUtils.FromDescription <TextStyleTextTransform> (cleanedValue); break; case "TextStyleTextOverflow": curStyle.TextOverflow = EnumUtils.FromDescription <TextStyleTextOverflow> (cleanedValue); break; case "TextStyleFontStyle": curStyle.FontStyle = EnumUtils.FromDescription <TextStyleFontStyle> (cleanedValue); break; case "TextStyleFontWeight": curStyle.FontWeight = EnumUtils.FromDescription <TextStyleFontWeight> (cleanedValue); break; default: throw new InvalidCastException("Could not find the appropriate type " + prop.PropertyType.Name); } } } }
public IEnumerable <CssParserRule> ParseAll(string css) { int start; Reset(css); StripAllComments(); List <CssParserRule> rules = new List <CssParserRule> (); while (!EndOfText) { MovePastWhitespace(); if (Peek() == '@') { // Process "at-rule" string atRule = ExtractSkippedText(MoveToWhiteSpace).ToLower(); if (atRule == "@media") { start = Position; MoveTo('{'); string newMedia = Extract(start, Position).Trim(); // Parse contents of media block string innerBlock = ExtractSkippedText(() => SkipOverBlock('{', '}')); // Trim curly braces if (innerBlock.StartsWith("{")) { innerBlock = innerBlock.Remove(0, 1); } if (innerBlock.EndsWith("}")) { innerBlock = innerBlock.Substring(0, innerBlock.Length - 1); } // Parse CSS in block CssParser parser = new CssParser(newMedia); rules.AddRange(parser.ParseAll(innerBlock)); continue; } else { throw new NotSupportedException(String.Format("{0} rule is unsupported", atRule)); } } // Find start of next declaration block start = Position; MoveTo('{'); if (EndOfText) // Done if no more { break; } // Parse selectors string selectors = Extract(start, Position); CssParserRule rule = new CssParserRule(_media); rule.Selectors = from s in selectors.Split(',') let s2 = s.Trim() where s2.Length > 0 select s2; // Parse declarations MoveAhead(); start = Position; MoveTo('}'); string properties = Extract(start, Position); rule.Declarations = from s in properties.Split(';') let s2 = s.Trim() where s2.Length > 0 let x = s2.IndexOf(':') select new CssParserDeclaration { Property = s2.Substring(0, (x < 0) ? 0 : x).TrimEnd(), Value = s2.Substring((x < 0) ? 0 : x + 1).TrimStart() }; // Skip over closing curly brace MoveAhead(); // Add rule to results rules.Add(rule); } // Return rules to caller return(rules); }