public static Style Parse(CssReader reader, char stopChar = '\0') { Style style = new Style(); string propertyName = null, propertyValue = null; int p; reader.SkipWhiteSpaces(); bool readingName = true; while ((p = reader.Peek()) > 0) { switch (unchecked ((char)p)) { case ':': reader.Read(); readingName = false; reader.SkipWhiteSpaces(); break; case ';': reader.Read(); if (!string.IsNullOrEmpty(propertyName) && !string.IsNullOrEmpty(propertyValue)) { style.Declarations.Add(propertyName, propertyValue); } propertyName = propertyValue = null; readingName = true; reader.SkipWhiteSpaces(); break; default: if ((char)p == stopChar) { return(style); } if (readingName) { propertyName = reader.ReadIdent(); if (propertyName == null) { throw new Exception(); } } else { propertyValue = reader.ReadUntil(stopChar, ';', ':'); } break; } } return(style); }
public static Selector Parse(CssReader reader, char stopChar = '\0') { Selector root = All, workingRoot = All; Operator workingRootParent = null; Action <Operator, Selector> setCurrentSelector = (op, sel) => SetCurrentSelector(ref root, ref workingRoot, ref workingRootParent, op, sel); int p; reader.SkipWhiteSpaces(); while ((p = reader.Peek()) > 0) { switch (unchecked ((char)p)) { case '*': setCurrentSelector(new And(), All); reader.Read(); break; case '.': reader.Read(); var className = reader.ReadIdent(); if (className == null) { return(Invalid); } setCurrentSelector(new And(), new Class(className)); break; case '#': reader.Read(); var id = reader.ReadName(); if (id == null) { return(Invalid); } setCurrentSelector(new And(), new Id(id)); break; case '[': throw new NotImplementedException("Attributes not implemented"); case ',': reader.Read(); setCurrentSelector(new Or(), All); reader.SkipWhiteSpaces(); break; case '+': reader.Read(); setCurrentSelector(new Adjacent(), All); reader.SkipWhiteSpaces(); break; case '~': reader.Read(); setCurrentSelector(new Sibling(), All); reader.SkipWhiteSpaces(); break; case '>': reader.Read(); setCurrentSelector(new Child(), All); reader.SkipWhiteSpaces(); break; case '^': //not in CSS spec reader.Read(); var element = reader.ReadIdent(); if (element == null) { return(Invalid); } setCurrentSelector(new And(), new Base(element)); break; case ' ': case '\t': case '\n': case '\r': case '\f': reader.Read(); bool processWs = false; while ((p = reader.Peek()) > 0) { var c = unchecked ((char)p); if (char.IsWhiteSpace(c)) { reader.Read(); continue; } processWs = (c != '+' && c != '>' && c != ',' && c != '~' && c != '^' && c != stopChar); break; } if (!processWs) { break; } setCurrentSelector(new Descendent(), All); reader.SkipWhiteSpaces(); break; default: if (unchecked ((char)p) == stopChar) { return(root); } var elementName = reader.ReadIdent(); if (elementName == null) { return(Invalid); } setCurrentSelector(new And(), new Element(elementName)); break; } } return(root); }