August, 2009

  • Eric White's Blog

    Update to CommentMerger.MergeComments Method

    • 0 Comments

    Word 2007 has a feature where you can lock a document, preventing any changes to content, yet allowing the user to add comments.  CommentMerger is a small method (~400 lines of code) that merges comments from two documents into a single document, provided the two contain the same content.  This code is part of the PowerTools for Open XML project.  In the future, I'm going to write a cmdlet that will use this code to merge comments.

    This blog is inactive.
    New blog: EricWhite.com/blog

    Blog TOC
    I’ve updated the CommentMerger class (actually completely rewritten it).  The new code (again, written in a functional style) is much more robust.  It now merges comments on math formulas.  The code (and example program to use it) is available in the ‘downloads’ tab at codeplex.com/powertools.

    There have been two good side effects of this effort – I’ve learned more about the Open XML formats, and I’ve refined my approach for doing recursive pure functional transforms.

    One of the biggest differences in the code is the approach that I took to selecting elements for transform.  Previously, I was looking for paragraph nodes, then recursively processing the descendants.  But this became more complicated in certain scenarios – paragraphs can contain runs which contain other content which can contain paragraphs.  In the new version, I simply select the elements for transform based on their contents.  For example, the following code selects a node for transform based on if the node contains any child w:commentRangeStart, w:commentRangeEnd, or runs (w:r) that contain w:commentReference elements:

    // If fromElement contains comments, then do special clone that merges comments.
    if (fromElement
        .Elements()
        .Where(e => e.Name == W.commentRangeStart ||
            e.Name == W.commentRangeEnd ||
            ((e.Name == W.r || e.Name == M.r) &&
                e.Elements(W.commentReference).Any()
                ))
        .Any())
    {
        // Get new, cloned element with merged comments.
        XElement newToElement = CloneElementWithComments(toElement, fromElement,
            commentIdTransformDictionary);
        return newToElement;
    }
     

    I used this approach throughout the transform.  I had a question about whether this approach would perform well enough.  I believe it does for two reasons – first, the Any extension method ‘short-circuits’ any positive matches, reducing the work to be done.  Second, I think that CPU caching may be effective in these situations.  In any case, the code seems to be more than fast enough.

Page 3 of 3 (3 items) 123
Page 1 of 1 (3 items)