Exemplo n.º 1
0
        public static void VisitTextNodes(SyntaxTreeNode node, Action <string> visitText, Func <TagNode, bool> tagFilter)
        {
            node.ThrowIfNull(nameof(node));
            visitText.ThrowIfNull(nameof(visitText));

            if (node is TextNode)
            {
                visitText(((TextNode)node).Text);
            }
            else
            {
                //skip filtered tags
                if (node is TagNode && (tagFilter != null && !tagFilter((TagNode)node)))
                {
                    return;
                }

                foreach (var subNode in node.SubNodes)
                {
                    VisitTextNodes(subNode, visitText, tagFilter);
                }
            }
        }
Exemplo n.º 2
0
        public static SyntaxTreeNode ReplaceTextSpans(SyntaxTreeNode node, Func <string, IList <TextSpanReplaceInfo> > getTextSpansToReplace, Func <TagNode, bool> tagFilter)
        {
            node.ThrowIfNull(nameof(node));
            getTextSpansToReplace.ThrowIfNull(nameof(getTextSpansToReplace));

            if (node is TextNode)
            {
                var text = ((TextNode)node).Text;

                var replacements = getTextSpansToReplace(text);

                if (replacements is null || replacements.Count == 0)
                {
                    return(node);
                }

                var replacementNodes = new List <SyntaxTreeNode>(replacements.Count * 2 + 1);
                var lastPos          = 0;

                foreach (var r in replacements)
                {
                    if (r.Index < lastPos)
                    {
                        throw new ArgumentException("the replacement text spans must be ordered by index and non-overlapping");
                    }

                    if (r.Index > text.Length - r.Length)
                    {
                        throw new ArgumentException("every replacement text span must reference a range within the text node");
                    }

                    if (r.Index != lastPos)
                    {
                        replacementNodes.Add(new TextNode(text.Substring(lastPos, r.Index - lastPos)));
                    }

                    if (r.Replacement != null)
                    {
                        replacementNodes.Add(r.Replacement);
                    }

                    lastPos = r.Index + r.Length;
                }

                if (lastPos != text.Length)
                {
                    replacementNodes.Add(new TextNode(text.Substring(lastPos)));
                }

                return(new SequenceNode(replacementNodes));
            }
            else
            {
                var fixedSubNodes = node.SubNodes.Select(n => {
                    //skip filtered tags
                    if (n is TagNode && (tagFilter != null && !tagFilter((TagNode)n)))
                    {
                        return(n);
                    }

                    var repl = ReplaceTextSpans(n, getTextSpansToReplace, tagFilter);

                    Debug.Assert(repl != null);

                    return(repl);
                }).ToList();

                if (fixedSubNodes.SequenceEqual(node.SubNodes, ReferenceEqualityComparer <SyntaxTreeNode> .Instance))
                {
                    return(node);
                }

                return(node.SetSubNodes(fixedSubNodes));
            }
        }