private static void MatchNormal(string data, ref int pos, int end) { for (; pos < end; pos++) { switch (data[pos]) { case '\'': return; case '\"': return; case '/': if (end > pos + 1) { switch (data[pos + 1]) { case '/': case '*': return; } } break; case '<': if (ParseMethods.SubstringMatch(data, pos, end, "<!--")) { return; } break; case '-': if (ParseMethods.SubstringMatch(data, pos, end, "-->")) { return; } break; case 'u': case 'U': if (ParseMethods.SubstringMatchIgnoreCase(data, pos, end, "url(")) { return; } break; case '@': if (ParseMethods.SubstringMatchIgnoreCase(data, pos, end, "@import")) { return; } break; } } }
private static void MatchImport(string data, ref int pos, int end, out int literalPos, out int literalEnd, out char quotChar) { literalPos = pos; literalEnd = pos; quotChar = (char)0; // skip (illegal) leading whitespace, e.g. url( http://www.microsoft.com) MatchWhitespace(data, ref pos, end); if (pos >= end) { return; } if (ParseMethods.SubstringMatchIgnoreCase(data, pos, end, "url(")) { pos += 4; MatchUrl(data, ref pos, end, out literalPos, out literalEnd, out quotChar); ParseMethods.MatchUntilChar(';', true, data, ref pos, end); return; } switch (data[pos++]) { case '\'': quotChar = '\''; literalPos = pos; ParseMethods.MatchSingleQuotedLiteral(data, ref pos, end, out literalEnd); MatchWhitespace(data, ref pos, end); ParseMethods.MatchUntilChar(';', true, data, ref pos, end); break; case '"': quotChar = '"'; literalPos = pos; ParseMethods.MatchDoubleQuotedLiteral(data, ref pos, end, out literalEnd); MatchWhitespace(data, ref pos, end); ParseMethods.MatchUntilChar(';', true, data, ref pos, end); break; default: quotChar = (char)0; literalPos = --pos; ParseMethods.MatchUntilChar(';', true, data, ref pos, end); literalEnd = Math.Max(literalPos, pos - 1); TrimWhitespace(data, ref literalPos, ref literalEnd); break; } }
public StyleElement Next() { if (pos >= end) { return(null); } int start = pos; switch (data[pos++]) { case '"': { int literalPos = pos; int literalEnd; ParseMethods.MatchDoubleQuotedLiteral(data, ref pos, end, out literalEnd); return(new StyleLiteral(data, start, pos - start, literalPos, literalEnd - literalPos, '"')); } case '\'': { int literalPos = pos; int literalEnd; ParseMethods.MatchSingleQuotedLiteral(data, ref pos, end, out literalEnd); return(new StyleLiteral(data, start, pos - start, literalPos, literalEnd - literalPos, '\'')); } case '/': if (ParseMethods.SubstringMatch(data, pos - 1, end, "//")) { pos++; ParseMethods.MatchSingleLineComment(data, ref pos, end); return(new StyleComment(data, start, pos - start)); } else if (ParseMethods.SubstringMatch(data, pos - 1, end, "/*")) { pos++; ParseMethods.MatchMultiLineComment(data, ref pos, end); return(new StyleComment(data, start, pos - start)); } goto default; case '<': if (ParseMethods.SubstringMatch(data, pos - 1, end, "<!--")) { pos += 3; ParseMethods.MatchSingleLineComment(data, ref pos, end); return(new StyleComment(data, start, pos - start)); } goto default; case '-': if (ParseMethods.SubstringMatch(data, pos - 1, end, "-->")) { pos += 2; ParseMethods.MatchSingleLineComment(data, ref pos, end); return(new StyleComment(data, start, pos - start)); } goto default; case 'u': case 'U': { if (ParseMethods.SubstringMatchIgnoreCase(data, pos - 1, end, "url(")) { int literalPos; int literalEnd; char quotChar; pos += 3; MatchUrl(data, ref pos, end, out literalPos, out literalEnd, out quotChar); return(new StyleUrl(data, start, pos - start, literalPos, literalEnd - literalPos, quotChar)); } goto default; } case '@': { const string IMPORT = "@import"; if (ParseMethods.SubstringMatchIgnoreCase(data, pos - 1, end, IMPORT)) { // We play a little fast and loose with CSS here. Technically // it's possible for "@import" to be immediately followed by // something besides a whitespace char and still be valid, but // we will not recognize those cases as @import statements, // except when the following char is a quote. int nextCharIndex = pos - 1 + IMPORT.Length; if (data.Length > nextCharIndex) { char nextChar = data[nextCharIndex]; if (IsWhitespace(nextChar)) { pos += IMPORT.Length; } else if (nextChar == '\'' || nextChar == '"') { pos += IMPORT.Length - 1; } else { goto default; // per note above, treat as normal text } int literalPos; int literalEnd; char quotChar; MatchImport(data, ref pos, end, out literalPos, out literalEnd, out quotChar); return(new StyleImport(data, start, pos - start, literalPos, literalEnd - literalPos, quotChar)); } } goto default; } default: MatchNormal(data, ref pos, end); return(new StyleText(data, start, pos - start)); } }