public EmbeddedWebFont(string fontFileName, string alias, string cssFileName, Assembly assembly) : base(fontFileName, alias) { _glyphs = new Dictionary <string, string>(); _cssParser = new CssParser(); _cssParser.ReadCSSFile(GetResourceStream(cssFileName, assembly)); }
private static bool ContainsClass(this ICssParser parser, string className, out string content) { content = null; IDictionary <string, string> styles; className = className.Split(new[] { ' ' }).Last(); var altClassName = AltClassName(className); if (parser.Classes.ContainsKey(className)) { styles = parser.Classes[className]; } else if (parser.Classes.ContainsKey(altClassName)) { styles = parser.Classes[altClassName]; } else { return(false); } if (styles.ContainsKey("content")) { var asciiValue = Convert.ToInt32(styles["content"].Trim(new[] { '"', '\\' }), 16); content = $"{Convert.ToChar(asciiValue)}"; return(true); } else { return(false); } }
private void Initialize(string targetFileName, string mapFileName, IContentType contentType) { _contentType = contentType; _parser = CssParserLocator.FindComponent(_contentType).CreateParser(); _directory = Path.GetDirectoryName(mapFileName); PopulateMap(targetFileName, mapFileName); // Begin two-steps initialization. }
private void Initialize(string targetFileContents, string mapFileContents, string directory, IContentType contentType) { _contentType = contentType; _parser = CssParserLocator.FindComponent(_contentType).CreateParser(); _directory = directory; PopulateMap(targetFileContents, mapFileContents); // Begin two-steps initialization. }
/// <summary> /// Reads the CSS file. /// </summary> /// <param name="Path">The path.</param> public static void ReadCSSFile(this ICssParser parser, string filePath) { using (var stream = new FileStream(filePath, FileMode.Open)) { parser.ReadCSSFile(stream); } }
/// <summary> /// Reads the CSS file. /// </summary> /// <param name="stream">The file stream.</param> public static void ReadCSSFile(this ICssParser parser, Stream stream) { using (var reader = new StreamReader(stream)) { parser.ReadCSSFile(reader); } }
public string SortScss(string scss) { ICssParser parser = CssParserLocator.FindComponent(ContentTypeManager.GetContentType(ScssContentTypeDefinition.ScssContentType)).CreateParser(); StyleSheet stylesheet = parser.Parse(scss.Trim(), true); return(PreprocessorSorting(stylesheet)); }
private string FindFile(IEnumerable <string> extensions, out int position) { ICssParser parser = CssParserLocator.FindComponent(Mef.GetContentType(LessContentTypeDefinition.LessContentType)).CreateParser(); string root = ProjectHelpers.GetProjectFolder(TextView.TextBuffer.GetFileName()); position = -1; string result = null; foreach (string ext in extensions) { foreach (string file in Directory.GetFiles(root, "*" + ext, SearchOption.AllDirectories)) { if (file.EndsWith(".min" + ext, StringComparison.OrdinalIgnoreCase)) { continue; } string text = File.ReadAllText(file); int index = text.IndexOf("." + _className, StringComparison.Ordinal); if (index > -1) { var css = parser.Parse(text, true); var visitor = new CssItemCollector <ClassSelector>(false); css.Accept(visitor); var selectors = visitor.Items.Where(c => c.ClassName.Text == _className); var high = selectors.FirstOrDefault(c => c.FindType <AtDirective>() == null && (c.Parent.NextSibling == null || c.Parent.NextSibling.Text == ",")); if (high != null) { position = high.Start; return(file); } var medium = selectors.FirstOrDefault(c => c.Parent.NextSibling == null || c.Parent.NextSibling.Text == ","); if (medium != null) { position = medium.Start; result = file; continue; } var low = selectors.FirstOrDefault(); if (low != null) { position = low.Start; result = file; continue; } } } } return(result); }
public static string GetFontIcon(this ICssParser parser, string className) { if (parser.ContainsClass(className, out var content)) { return(content); } return(null); }
private void VerifyTreeAfterIncrementalParse(ITextProvider newText, TokenList newTokens, StyleSheet newStyleSheet) { ICssParser parser = _parserFactory.CreateParser(); StyleSheet validStyleSheet = parser.Parse(newText, newTokens, insertComments: true); // By the way, this is the slowest and most lame way to compare two trees DebugWriter writer = new DebugWriter(); string validTreeText = writer.Serialize(newText, validStyleSheet); string newTreeText = writer.Serialize(newText, newStyleSheet); Debug.Assert(validTreeText == newTreeText, "Bad tree after incremental parsing"); }
/// <summary> /// Reads a css file from a given assembly /// </summary> /// <param name="parser">The <see cref="ICssParser"/> instance</param> /// <param name="resourceName">The CSS file name 'sample.css' or 'sample.min.css'</param> /// <param name="assembly">The <see cref="Assembly"/> the file is embedded in</param> public static void ReadCSSFile(this ICssParser parser, string resourceName, Assembly assembly) { var resourceId = assembly.GetManifestResourceNames() .FirstOrDefault(x => x.Equals(resourceName, StringComparison.InvariantCultureIgnoreCase) || x.EndsWith(resourceName, StringComparison.InvariantCultureIgnoreCase)); if (string.IsNullOrEmpty(resourceId)) { throw new FileNotFoundException($"The css file {resourceName} could not be found in the assembly {assembly.FullName}"); } using var stream = assembly.GetManifestResourceStream(resourceId); parser.ReadCSSFile(stream); }
public static StyleSheet GetOrCreateStyleSheet(GraphNode node, IFileExtensionRegistryService fileService) { StyleSheet stylesheet = node.Id.GetNestedValueByName <StyleSheet>(CssGraphSchema.CssStyleSheet); if (stylesheet == null) { Uri url = node.Id.GetNestedValueByName <Uri>(CodeGraphNodeIdName.File); IContentType contentType = fileService.GetContentTypeForExtension(Path.GetExtension(url.LocalPath)); string contentTypeName = (contentType != null) ? contentType.TypeName : CssContentTypeDefinition.CssContentType; ICssParser parser = contentTypeName == LessContentTypeDefinition.LessContentType ? new LessParser() : new CssParser(); stylesheet = parser.Parse(File.ReadAllText(url.LocalPath), false); } return(stylesheet); }
/// <summary> /// Internal function to parse a new StyleSheet object /// </summary> private void ParseNewStyleSheet(ITextProvider textProvider, TokenList tokens) { ICssParser parser = _parserFactory.CreateParser(); if (tokens == null) { ICssTokenizer tokenizer = parser.TokenizerFactory.CreateTokenizer(); tokens = tokenizer.Tokenize(textProvider, 0, textProvider.Length, keepWhiteSpace: false); } using (CreateWriteLock()) { Tokens = tokens; StyleSheet = parser.Parse(textProvider, tokens, insertComments: true); } TreeUpdated?.Invoke(this, new CssTreeUpdateEventArgs(this)); }
private string FindRuleSetInFile(IEnumerable <string> extensions, string id, out RuleSet rule) { string root = ProjectHelpers.GetProjectFolder(peekableItem._textbuffer.GetFileName()); string result = null; bool isLow = false, isMedium = false; rule = null; foreach (string ext in extensions) { ICssParser parser = CssParserLocator.FindComponent(Mef.GetContentType(ext.Trim('.'))).CreateParser(); foreach (string file in Directory.EnumerateFiles(root, "*" + ext, SearchOption.AllDirectories)) { if (file.EndsWith(".min" + ext, StringComparison.OrdinalIgnoreCase) || file.Contains("node_modules") || file.Contains("bower_components")) { continue; } string text = FileHelpers.ReadAllTextRetry(file).ConfigureAwait(false).GetAwaiter().GetResult(); int index = text.IndexOf("#" + id, StringComparison.Ordinal); if (index == -1) { continue; } var css = parser.Parse(text, true); var visitor = new CssItemCollector <IdSelector>(false); css.Accept(visitor); var selectors = visitor.Items.Where(c => c.HashName.Text == "#" + id); var high = selectors.FirstOrDefault(c => c.FindType <AtDirective>() == null && (c.Parent.NextSibling == null || c.Parent.NextSibling.Text == ",")); if (high != null) { rule = high.FindType <RuleSet>(); return(file); } var medium = selectors.FirstOrDefault(c => c.Parent.NextSibling == null || c.Parent.NextSibling.Text == ","); if (medium != null && !isMedium) { rule = medium.FindType <RuleSet>(); result = file; isMedium = true; continue; } var low = selectors.FirstOrDefault(); if (low != null && !isMedium && !isLow) { rule = low.FindType <RuleSet>(); result = file; isLow = true; continue; } } } return(result); }
/// <summary> /// Parses a CSS stylesheet from a string asynchronously. /// </summary> /// <param name="parser">The parser to extend.</param> /// <param name="content">The string content to parse.</param> /// <returns>The task yielding the created stylesheet.</returns> public static Task <ICssStyleSheet> ParseStyleSheetAsync(this ICssParser parser, String content) => parser.ParseStyleSheetAsync(content, CancellationToken.None);
/// <summary> /// Parses a CSS stylesheet from a string asynchronously. /// </summary> /// <param name="parser">The parser to extend.</param> /// <param name="content">The stream content to parse asynchronously.</param> /// <returns>The task yielding the created stylesheet.</returns> public static Task <ICssStyleSheet> ParseStyleSheetAsync(this ICssParser parser, Stream content) { return(parser.ParseStyleSheetAsync(content, CancellationToken.None)); }
/// <summary> /// Parses a CSS stylesheet from hosting stylesheet asynchronously. /// </summary> /// <param name="parser">The parser to extend.</param> /// <param name="sheet">The stylesheet containg the URL reference.</param> /// <returns>The task yielding the finished stylesheet.</returns> public static Task <ICssStyleSheet> ParseStyleSheetAsync(this ICssParser parser, ICssStyleSheet sheet) { return(parser.ParseStyleSheetAsync(sheet, CancellationToken.None)); }
public void OnTextChange(ITextProvider fullNewText, int changeStart, int deletedLength, int insertedLength) { Debug.Assert(IsOwnerThread, "CssTree.OnTextChange must be called on the main thread"); if (StyleSheet == null || !IsOwnerThread) { return; } #if DEBUG_INCREMENTAL_PARSE DateTime startTime = DateTime.UtcNow; #endif // Figure out which tokens changed ICssParser parser = _parserFactory.CreateParser(); IncrementalTokenizer.Result tokenResult = IncrementalTokenizer.TokenizeChange( parser.TokenizerFactory, Tokens, TextProvider, fullNewText, changeStart, deletedLength, insertedLength); // Adjust the input to match what was actually tokenized changeStart = tokenResult.TokenizationStart; deletedLength = tokenResult.TextDeletedLength; insertedLength = tokenResult.TextInsertedLength; // Figure out where to start incrementally parsing IIncrementalParseItem parentItem = GetIncrementalParseParent(changeStart, deletedLength); ComplexItem parentComplexItem = (ComplexItem)parentItem; int firstReparseChild = FindFirstChildToReparse(parentComplexItem, tokenResult.OldTokenStart); int firstCleanChild = FindFirstCleanChild(parentComplexItem, tokenResult.OldTokenStart + tokenResult.OldTokenCount); int firstCleanTokenAfterParent = FindFirstCleanTokenAfterParent(parentComplexItem); using (CreateWriteLock()) { // Update the tokens and text IncrementalTokenizer.ApplyResult(tokenResult); firstCleanTokenAfterParent += tokenResult.NewTokens.Count - tokenResult.OldTokenCount; // Init the token stream for parsing TokenStream tokenStream = new TokenStream(Tokens); int streamPositionStart = FindTokenToStartParsing(parentComplexItem, firstReparseChild); tokenStream.Position = streamPositionStart; Debug.Assert(tokenStream.Position <= tokenResult.OldTokenStart); // Init parsing ItemFactory itemFactory = new ItemFactory(parser.ExternalItemFactory, fullNewText, tokenStream); tokenStream.SkipComments = true; // must be set after extracting comments // Init the old and new child lists ParseItemList oldChildren = parentComplexItem.Children; ParseItemList newChildren = new ParseItemList(); ParseItemList deletedChildren = new ParseItemList(); ParseItemList errorsChangedItems = new ParseItemList(); int deleteChildCount = oldChildren.Count - firstReparseChild; // CreateNextChild needs to know the previous child for context ParseItem prevChild = (firstReparseChild > 0) ? oldChildren[firstReparseChild - 1] : null; while (true) { ParseItem newChild = parentItem.CreateNextChild(prevChild, itemFactory, fullNewText, tokenStream); if (newChild != null) { // Are we done parsing yet? if (newChild.Start >= changeStart + insertedLength) { // See if this new child exactly matches an old child int oldChildIndex = oldChildren.FindInsertIndex(newChild.Start, beforeExisting: true); ParseItem oldChild = (oldChildIndex < oldChildren.Count) ? oldChildren[oldChildIndex] : null; if (oldChild != null && oldChildIndex >= firstCleanChild && oldChild.Start == newChild.Start && oldChild.Length == newChild.Length && oldChild.GetType() == newChild.GetType()) { // Found a match, stop parsing deleteChildCount = oldChildIndex - firstReparseChild; break; } } newChildren.Add(newChild); prevChild = newChild; } else if (tokenStream.Position != firstCleanTokenAfterParent) { // When the parse doesn't stop exactly on the first clean token after the parent, // then the tree structure changed too much. Just fall back to a full parse: ParseNewStyleSheet(fullNewText, Tokens); //Debug.WriteLine("CSS: Full parse:{0}ms", (DateTime.UtcNow - startTime).TotalMilliseconds); return; } else { break; } } // Replace items in the parent (saving the deleted items for later) oldChildren.RemoveRange(firstReparseChild, deleteChildCount, deletedChildren); oldChildren.AddRange(newChildren); if (oldChildren.Count == 0) { // The parent was deleted, currently can't deal with that as an incremental change ParseNewStyleSheet(fullNewText, Tokens); return; } // Collect comments over the parsed region tokenStream.SkipComments = false; int tokenCount = tokenStream.Position - streamPositionStart; tokenStream.Position = streamPositionStart; IList <Comment> comments = parser.ExtractComments(fullNewText, Tokens, tokenStream.Position, tokenCount); // All done parsing and updating the tree, so now update caches and fire the "on changed" event StyleSheet.TextProvider = fullNewText; parentItem.UpdateCachedChildren(); if (parentItem.UpdateParseErrors()) { errorsChangedItems.Add(parentComplexItem); } InsertComments(comments, newChildren); #if DEBUG_INCREMENTAL_PARSE Debug.WriteLine("CSS: Inc parse:{0}ms. Deleted:{1}, Inserted:{2}", (DateTime.UtcNow - startTime).TotalMilliseconds, deletedChildren.Count, newChildren.Count); VerifyTokensAfterIncrementalChange(parser.TokenizerFactory, fullNewText, Tokens); VerifyTreeAfterIncrementalParse(fullNewText, Tokens, StyleSheet); #endif FireOnItemsChanged(deletedChildren, newChildren, errorsChangedItems); // Clean up the deleted items (must be after the event is fired) foreach (ParseItem deletedItem in deletedChildren) { deletedItem.Parent = null; } } }
private string FindFile(IEnumerable <string> extensions, out int position) { string root = ProjectHelpers.GetProjectFolder(TextView.TextBuffer.GetFileName()); position = -1; bool isLow = false, isMedium = false; string result = null; foreach (string ext in extensions) { ICssParser parser = CssParserLocator.FindComponent(ProjectHelpers.GetContentType(ext.Trim('.'))).CreateParser(); foreach (string file in Directory.EnumerateFiles(root, "*" + ext, SearchOption.AllDirectories)) { if (file.EndsWith(".min" + ext, StringComparison.OrdinalIgnoreCase) || file.Contains("node_modules") || file.Contains("bower_components")) { continue; } string text = File.ReadAllText(file); int index = text.IndexOf("." + _className, StringComparison.Ordinal); if (index == -1) { continue; } Microsoft.WebTools.Languages.Css.TreeItems.StyleSheet css = parser.Parse(text, true); var visitor = new CssItemCollector <ClassSelector>(false); css.Accept(visitor); IEnumerable <ClassSelector> selectors = visitor.Items.Where(c => c.ClassName.Text == _className); ClassSelector high = selectors.FirstOrDefault(c => c.FindType <AtDirective>() == null && (c.Parent.NextSibling == null || c.Parent.NextSibling.Text == ",")); if (high != null) { position = high.Start; return(file); } ClassSelector medium = selectors.FirstOrDefault(c => c.Parent.NextSibling == null || c.Parent.NextSibling.Text == ","); if (medium != null && !isMedium) { position = medium.Start; result = file; isMedium = true; continue; } ClassSelector low = selectors.FirstOrDefault(); if (low != null && !isMedium && !isLow) { position = low.Start; result = file; isLow = true; continue; } } } return(result); }
public static void ReadCSSFile(this ICssParser parser, string resourceName, Type resolvingType) => parser.ReadCSSFile(resourceName, resolvingType.Assembly);