public void OptimizeSpan(Span span) { Require.NotNull(span, nameof(span)); var builder = new SpanBuilder(span); builder.ClearSymbols(); var prevType = HtmlSymbolType.Unknown; foreach (ISymbol item in span.Symbols) { var sym = item as HtmlSymbol; if (sym == null) { // On ne touche pas les éléments qui ne sont pas de type HtmlSymbol. builder.Accept(item); continue; } // FIXME: On perd toute information contextuelle. Peut-être pour remédier à ce problème // on pourrait ré-utiliser un HtmlSymbol. builder.Accept(new Symbol_ { Content = OptimizeContent(sym, prevType) }); prevType = sym.Type; } span.ReplaceWith(builder); }
//public override void VisitBlock(Block block) //{ // BlockBuilder parent = null; // if (_blocks.Count > 0) // { // parent = _blocks.Peek(); // } // BlockBuilder newBlock = new BlockBuilder(block); // newBlock.Children.Clear(); // _blocks.Push(newBlock); // if (block.Type == BlockType.Expression && parent != null) // { // VisitExpressionBlock(block, parent); // } // else // { // base.VisitBlock(block); // } // if (_blocks.Count > 1) // { // parent.Children.Add(_blocks.Pop().Build()); // } //} //public override void VisitSpan(Span span) //{ // Debug.Assert(_blocks.Count > 0); // _blocks.Peek().Children.Add(span); //} protected override SyntaxTreeNode RewriteBlock(BlockBuilder parent, Block block) { BlockBuilder newBlock = new BlockBuilder(block); newBlock.Children.Clear(); Span ws = block.Children.FirstOrDefault() as Span; IEnumerable <SyntaxTreeNode> newNodes = block.Children; if (ws.Content.All(Char.IsWhiteSpace)) { // Add this node to the parent SpanBuilder builder = new SpanBuilder(ws); builder.ClearSymbols(); FillSpan(builder, ws.Start, ws.Content); parent.Children.Add(builder.Build()); // Remove the old whitespace node newNodes = block.Children.Skip(1); } foreach (SyntaxTreeNode node in newNodes) { newBlock.Children.Add(node); } return(newBlock.Build()); }
private void VisitMarkupSpan(Span currentMarkupSpan) { var builder = new SpanBuilder(currentMarkupSpan); builder.ClearSymbols(); var previousMarkupSpan = currentMarkupSpan.Previous?.Kind == SpanKind.Markup ? currentMarkupSpan.Previous : null; var previousSymbol = previousMarkupSpan?.Symbols.LastOrDefault(); foreach (var currentSymbol in currentMarkupSpan.Symbols) { VisitSymbol(currentSymbol, previousSymbol, builder); previousSymbol = currentSymbol; } currentMarkupSpan.ReplaceWith(builder); }
protected virtual SpanBuilder UpdateSpan(Span target, TextChange normalizedChange) { var newContent = normalizedChange.ApplyChange(target); var newSpan = new SpanBuilder(target); newSpan.ClearSymbols(); foreach (ISymbol sym in Tokenizer(newContent)) { sym.OffsetStart(target.Start); newSpan.Accept(sym); } if (target.Next != null) { var newEnd = SourceLocationTracker.CalculateNewLocation(target.Start, newContent); target.Next.ChangeStart(newEnd); } return(newSpan); }
public void OptimizeBlock(BlockBuilder block) { Require.NotNull(block, nameof(block)); for (int i = 0; i < block.Children.Count; i++) { var span = block.Children[i] as Span; if (!IsMarkup(span)) { // On ne touche pas les éléments qui ne sont pas de type Markup. continue; } // Si on est déjà arrivé à la dernière position, on récupère le contenu directement. string content = i == block.Children.Count - 1 ? span.Content : RemoveMarkupAndMergeContentAfter(block, span.Content, ref i); if (String.IsNullOrWhiteSpace(content)) { // Le contenu n'est constitué que d'espaces blancs. block.Children.RemoveAt(i); continue; } // On optimise le contenu et on recrée l'élément. var builder = new SpanBuilder(span); builder.ClearSymbols(); // FIXME: On perd toute information contextuelle. builder.Accept(new Symbol_ { Content = BustWhiteSpaces(content) }); span.ReplaceWith(builder); } }
protected override SyntaxTreeNode RewriteBlock(BlockBuilder parent, Block block) { var newBlock = new BlockBuilder(block); newBlock.Children.Clear(); var ws = block.Children.FirstOrDefault() as Span; IEnumerable<SyntaxTreeNode> newNodes = block.Children; if (ws.Content.All(Char.IsWhiteSpace)) { // Add this node to the parent var builder = new SpanBuilder(ws); builder.ClearSymbols(); FillSpan(builder, ws.Start, ws.Content); parent.Children.Add(builder.Build()); // Remove the old whitespace node newNodes = block.Children.Skip(1); } foreach (SyntaxTreeNode node in newNodes) { newBlock.Children.Add(node); } return newBlock.Build(); }
protected virtual SpanBuilder UpdateSpan(Span target, TextChange normalizedChange) { var newContent = normalizedChange.ApplyChange(target); var newSpan = new SpanBuilder(target); newSpan.ClearSymbols(); foreach (ISymbol sym in Tokenizer(newContent)) { sym.OffsetStart(target.Start); newSpan.Accept(sym); } if (target.Next != null) { var newEnd = SourceLocationTracker.CalculateNewLocation(target.Start, newContent); target.Next.ChangeStart(newEnd); } return newSpan; }