internal static MediaBlock ParseMediaDirective(ParserStream stream) { var start = stream.Position; var media = new StringBuilder(); stream.ScanUntil(media, '{'); var mediaStr = media.ToString().Trim(); if (mediaStr.IsNullOrEmpty()) { Current.RecordError(ErrorType.Parser, Position.Create(start, stream.Position, Current.CurrentFilePath), "Expected media list"); throw new StoppedParsingException(); } var mediaQuery = MediaQueryParser.Parse(mediaStr, Position.Create(start, stream.Position, Current.CurrentFilePath)); var contained = new List <Block>(); char c; while ((c = stream.Peek()) != '}') { if (char.IsWhiteSpace(c)) { stream.AdvancePastWhiteSpace(); continue; } // More directive (probably) if (c == '@') { contained.Add(ParseDirective(stream)); continue; } // Selector + block time! contained.Add(ParseSelectorAndBlock(stream)); } var notAllowed = contained.Where(x => !(x is SelectorAndBlock || x is MoreVariable)); foreach (var illegal in notAllowed) { Current.RecordError(ErrorType.Parser, illegal, "@media can only contain blocks and variable declarations"); } if (notAllowed.Count() != 0) { throw new StoppedParsingException(); } // Skip past } stream.Advance(); return(new MediaBlock(mediaQuery, contained, start, stream.Position, Current.CurrentFilePath)); }
internal static List <Property> ParseCssRules(Selector selector, ParserStream stream) { var ret = new List <Property>(); while (stream.HasMore() && stream.Peek() != '}') { var c = stream.Peek(); if (char.IsWhiteSpace(c)) { stream.AdvancePastWhiteSpace(); } else { ret.Add(ParseRule(stream)); } } stream.AdvancePast("}"); return(ret); }
public List <Block> Parse(string filePath, TextReader reader) { try { using (var stream = new ParserStream(reader)) { Current.SwitchToFile(filePath); var ret = new List <Block>(); while (stream.HasMore()) { char c = stream.Peek(); //Ignore white space if (char.IsWhiteSpace(c)) { stream.AdvancePastWhiteSpace(); continue; } // More directive (probably) if (c == '@') { ret.Add(ParseDirective(stream)); continue; } // Selector + block time! ret.Add(ParseSelectorAndBlock(stream)); } return(ret); } } catch (StoppedParsingException) { return(null); } }
public List<Block> Parse(string filePath, TextReader reader) { try { using (var stream = new ParserStream(reader)) { Current.SwitchToFile(filePath); var ret = new List<Block>(); while (stream.HasMore()) { char c = stream.Peek(); //Ignore white space if (char.IsWhiteSpace(c)) { stream.AdvancePastWhiteSpace(); continue; } // More directive (probably) if (c == '@') { ret.Add(ParseDirective(stream)); continue; } // Selector + block time! ret.Add(ParseSelectorAndBlock(stream)); } return ret; } } catch (StoppedParsingException) { return null; } }
internal static List <SpriteRule> ParseSpriteRules(ParserStream stream) { var ret = new List <SpriteRule>(); stream.AdvancePast("{"); while (stream.HasMore() && stream.Peek() != '}') { var c = stream.Peek(); if (char.IsWhiteSpace(c)) { stream.AdvancePastWhiteSpace(); } else { ret.Add(ParseSpriteRule(stream)); } } stream.AdvancePast("}"); return(ret); }
internal static ResetBlock ParseResetDirective(ParserStream stream, int start) { var ignored = new StringBuilder(); stream.ScanUntil(ignored, '{'); var contained = new List <Block>(); char c; while ((c = stream.Peek()) != '}') { if (char.IsWhiteSpace(c)) { stream.AdvancePastWhiteSpace(); continue; } // More directive (probably) if (c == '@') { contained.Add(ParseDirective(stream)); continue; } // Selector + block time! contained.Add(ParseSelectorAndBlock(stream)); } var notAllowed = contained.Where(x => !(x is SelectorAndBlock || x is MoreVariable)); foreach (var illegal in notAllowed) { Current.RecordError(ErrorType.Parser, illegal, "@reset can only contain blocks and variable declarations"); } if (notAllowed.Count() != 0) { throw new StoppedParsingException(); } // The whole @reset{} block disappears pretty quickly, but the actual // blocks need to know what they were "near" for variable resolution. var variables = contained.OfType <MoreVariable>(); var bound = new List <Block>(); foreach (var x in contained) { var asBlock = x as SelectorAndBlock; if (asBlock != null) { bound.Add(asBlock.InReset(variables)); } else { bound.Add(x); } } // Skip past } stream.Advance(); return(new ResetBlock(bound, start, stream.Position, Current.CurrentFilePath)); }
internal static KeyFramesBlock ParseKeyFramesDirective(string prefix, ParserStream stream, int start) { var buffer = new StringBuilder(); stream.ScanUntil(buffer, '{'); var name = buffer.ToString().Trim(); if (name.Length == 0) { Current.RecordError(ErrorType.Parser, Position.Create(start, stream.Position, Current.CurrentFilePath), "Expected a name for the keyframe animation"); throw new StoppedParsingException(); } if ((name[0] != '-' && char.IsDigit(name[0])) || (name[0] == '-' && name.Length > 1 && char.IsDigit(name[1])) || name.Any(a => a != '-' && !char.IsLetterOrDigit(a))) { Current.RecordError(ErrorType.Parser, Position.Create(start, stream.Position, Current.CurrentFilePath), "Animation name `" + name + "` is not a valid identifier"); throw new StoppedParsingException(); } var frames = new List <KeyFrame>(); var rules = new List <VariableProperty>(); while (stream.HasMore()) { var c = stream.Peek(); if (char.IsWhiteSpace(c)) { stream.AdvancePastWhiteSpace(); continue; } if (c == '}') { break; } if (c == '@') { var rule = ParseMixinOrVariableRule(stream); if (!(rule is VariableProperty)) { Current.RecordError(ErrorType.Parser, rule, "Expected variable declaration"); throw new StoppedParsingException(); } rules.Add((VariableProperty)rule); continue; } frames.Add(ParseKeyFrame(stream)); } if (stream.Peek() != '}') { Current.RecordError(ErrorType.Parser, Position.Create(start, stream.Position, Current.CurrentFilePath), "Expected '}'"); throw new StoppedParsingException(); } stream.Advance(); // Skip } return(new KeyFramesBlock(prefix, name, frames, rules, start, stream.Position, Current.CurrentFilePath)); }
internal static ResetBlock ParseResetDirective(ParserStream stream, int start) { var ignored = new StringBuilder(); stream.ScanUntil(ignored, '{'); var contained = new List<Block>(); char c; while ((c = stream.Peek()) != '}') { if (char.IsWhiteSpace(c)) { stream.AdvancePastWhiteSpace(); continue; } // More directive (probably) if (c == '@') { contained.Add(ParseDirective(stream)); continue; } // Selector + block time! contained.Add(ParseSelectorAndBlock(stream)); } var notAllowed = contained.Where(x => !(x is SelectorAndBlock || x is MoreVariable)); foreach (var illegal in notAllowed) { Current.RecordError(ErrorType.Parser, illegal, "@reset can only contain blocks and variable declarations"); } if (notAllowed.Count() != 0) { throw new StoppedParsingException(); } // The whole @reset{} block disappears pretty quickly, but the actual // blocks need to know what they were "near" for variable resolution. var variables = contained.OfType<MoreVariable>(); var bound = new List<Block>(); foreach (var x in contained) { var asBlock = x as SelectorAndBlock; if (asBlock != null) { bound.Add(asBlock.InReset(variables)); } else { bound.Add(x); } } // Skip past } stream.Advance(); return new ResetBlock(bound, start, stream.Position, Current.CurrentFilePath); }
internal static MediaBlock ParseMediaDirective(ParserStream stream) { var start = stream.Position; var media = new StringBuilder(); stream.ScanUntil(media, '{'); var mediaStr = media.ToString().Trim(); if (mediaStr.IsNullOrEmpty()) { Current.RecordError(ErrorType.Parser, Position.Create(start, stream.Position, Current.CurrentFilePath), "Expected media list"); throw new StoppedParsingException(); } var mediaQuery = MediaQueryParser.Parse(mediaStr, Position.Create(start, stream.Position, Current.CurrentFilePath)); var contained = new List<Block>(); char c; while ((c = stream.Peek()) != '}') { if (char.IsWhiteSpace(c)) { stream.AdvancePastWhiteSpace(); continue; } // More directive (probably) if (c == '@') { contained.Add(ParseDirective(stream)); continue; } // Selector + block time! contained.Add(ParseSelectorAndBlock(stream)); } var notAllowed = contained.Where(x => !(x is SelectorAndBlock || x is MoreVariable)); foreach (var illegal in notAllowed) { Current.RecordError(ErrorType.Parser, illegal, "@media can only contain blocks and variable declarations"); } if (notAllowed.Count() != 0) { throw new StoppedParsingException(); } // Skip past } stream.Advance(); return new MediaBlock(mediaQuery, contained, start, stream.Position, Current.CurrentFilePath); }
internal static KeyFramesBlock ParseKeyFramesDirective(string prefix, ParserStream stream, int start) { var buffer = new StringBuilder(); stream.ScanUntil(buffer, '{'); var name = buffer.ToString().Trim(); if (name.Length == 0) { Current.RecordError(ErrorType.Parser, Position.Create(start, stream.Position, Current.CurrentFilePath), "Expected a name for the keyframe animation"); throw new StoppedParsingException(); } if((name[0] != '-' && char.IsDigit(name[0])) || (name[0] == '-' && name.Length > 1 && char.IsDigit(name[1])) || name.Any(a => a != '-' && !char.IsLetterOrDigit(a))) { Current.RecordError(ErrorType.Parser, Position.Create(start, stream.Position, Current.CurrentFilePath), "Animation name `"+name+"` is not a valid identifier"); throw new StoppedParsingException(); } var frames = new List<KeyFrame>(); var rules = new List<VariableProperty>(); while (stream.HasMore()) { var c = stream.Peek(); if (char.IsWhiteSpace(c)) { stream.AdvancePastWhiteSpace(); continue; } if (c == '}') { break; } if (c == '@') { var rule = ParseMixinOrVariableRule(stream); if (!(rule is VariableProperty)) { Current.RecordError(ErrorType.Parser, rule, "Expected variable declaration"); throw new StoppedParsingException(); } rules.Add((VariableProperty)rule); continue; } frames.Add(ParseKeyFrame(stream)); } if (stream.Peek() != '}') { Current.RecordError(ErrorType.Parser, Position.Create(start, stream.Position, Current.CurrentFilePath), "Expected '}'"); throw new StoppedParsingException(); } stream.Advance(); // Skip } return new KeyFramesBlock(prefix, name, frames, rules, start, stream.Position, Current.CurrentFilePath); }
internal static List<Property> ParseCssRules(Selector selector, ParserStream stream) { var ret = new List<Property>(); while (stream.HasMore() && stream.Peek() != '}') { var c = stream.Peek(); if (char.IsWhiteSpace(c)) { stream.AdvancePastWhiteSpace(); } else { ret.Add(ParseRule(stream)); } } stream.AdvancePast("}"); return ret; }
internal static List<SpriteRule> ParseSpriteRules(ParserStream stream) { var ret = new List<SpriteRule>(); stream.AdvancePast("{"); while (stream.HasMore() && stream.Peek() != '}') { var c = stream.Peek(); if (char.IsWhiteSpace(c)) { stream.AdvancePastWhiteSpace(); } else { ret.Add(ParseSpriteRule(stream)); } } stream.AdvancePast("}"); return ret; }
internal static Value ParseImpl(ParserStream stream, IPosition forPosition, bool allowSelectorIncludes) { Value ret = null; while (stream.HasMore()) { var c = stream.Peek(); if (char.IsWhiteSpace(c)) { stream.AdvancePastWhiteSpace(); continue; } if (ret != null) { if (c.In('+', '-', '*', '/', '%')) { ret = ParseMathValue(c, ret, stream, forPosition); continue; } if (c == '?') { stream.Advance(); // skip ? if (stream.HasMore() && stream.Peek() == '?') { if (ret == null) { Current.RecordError(ErrorType.Parser, forPosition, "Expected value, found '??'"); throw new StoppedParsingException(); } stream.Advance(); // skip second ? var rhs = ParseImpl(stream, forPosition, allowSelectorIncludes); ret = new MathValue(ret, Operator.Take_Exists, rhs); continue; } ret = new LeftExistsValue(ret); continue; } } if (char.IsDigit(c) || c == '.' || c == '-') { ret = Combine(ret, ParseNumber(stream, forPosition)); continue; } if (c == '(') { ret = Combine(ret, ParseGroup(stream, forPosition)); continue; } if (c.In('\'', '"')) { ret = Combine(ret, ParseQuotedString(c, stream, forPosition)); continue; } if (c == '#') { ret = Combine(ret, ParseHashColor(stream, forPosition)); continue; } if (c == '@') { ret = Combine(ret, ParseFuncValue(stream, forPosition, allowSelectorIncludes)); continue; } ret = Combine(ret, ParseString(stream, forPosition)); } return ret; }
internal static Value ParseImpl(ParserStream stream, IPosition forPosition, bool allowSelectorIncludes) { Value ret = null; while (stream.HasMore()) { var c = stream.Peek(); if (char.IsWhiteSpace(c)) { stream.AdvancePastWhiteSpace(); continue; } if (ret != null) { if (c.In('+', '-', '*', '/', '%')) { ret = ParseMathValue(c, ret, stream, forPosition); continue; } if (c == '?') { stream.Advance(); // skip ? if (stream.HasMore() && stream.Peek() == '?') { if (ret == null) { Current.RecordError(ErrorType.Parser, forPosition, "Expected value, found '??'"); throw new StoppedParsingException(); } stream.Advance(); // skip second ? var rhs = ParseImpl(stream, forPosition, allowSelectorIncludes); ret = new MathValue(ret, Operator.Take_Exists, rhs); continue; } ret = new LeftExistsValue(ret); continue; } } if (char.IsDigit(c) || c == '.' || c == '-') { ret = Combine(ret, ParseNumber(stream, forPosition)); continue; } if (c == '(') { ret = Combine(ret, ParseGroup(stream, forPosition)); continue; } if (c.In('\'', '"')) { ret = Combine(ret, ParseQuotedString(c, stream, forPosition)); continue; } if (c == '#') { ret = Combine(ret, ParseHashColor(stream, forPosition)); continue; } if (c == '@') { ret = Combine(ret, ParseFuncValue(stream, forPosition, allowSelectorIncludes)); continue; } ret = Combine(ret, ParseString(stream, forPosition)); } return(ret); }