Exemplo n.º 1
0
        public static SyntaxTreeNode ReplaceTextSpans(SyntaxTreeNode node, Func <String, IList <TextSpanReplaceInfo> > getTextSpansToReplace, Func <TagNode, bool> tagFilter)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }
            if (getTextSpansToReplace == null)
            {
                throw new ArgumentNullException("getTextSpansToReplace");
            }

            TextNode Node = node as TextNode;

            if (Node != null)
            {
                String text = Node.Text;

                IList <TextSpanReplaceInfo> replacements = getTextSpansToReplace(text);
                if (replacements == null || replacements.Count == 0)
                {
                    return(node);
                }

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

                foreach (TextSpanReplaceInfo 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));
            }
            List <SyntaxTreeNode> fixedSubNodes = node.SubNodes.Select(n => {
                if (n is TagNode && (tagFilter != null && !tagFilter((TagNode)n)))
                {
                    return(n);                                                                               //skip filtered tags
                }
                SyntaxTreeNode repl = ReplaceTextSpans(n, getTextSpansToReplace, tagFilter);
                Debug.Assert(repl != null);
                return(repl);
            }).ToList();

            return(fixedSubNodes.SequenceEqual(node.SubNodes, ReferenceEqualityComparer <SyntaxTreeNode> .Instance)
                                ? node
                                : node.SetSubNodes(fixedSubNodes));
        }