Associate a comment to a specific word when inserting HTML string

Hello,
I am inserting html content to a document and wanted to insert a comment to a specific word within the html content. I am not able to associate a comment with a specific place in word export.
Example
<p> This is an Html Text. <span>And</span> I wanted to add comment to it.</p>

I wanted to insert a comment to the word “And” when I export the html to word. I couldn’t find a documentation to implement this for insertHtml().

@tesfayemissy,

You can use the following code to insert a comment in Word document via InsertHtml method:

Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

builder.InsertHtml("<div><p><span>This is an Html Text. </span><a name=\"_cmntref1\"><span>And</span></a><a href=\"#_cmnt1\"><span>[a1]</span></a><span> I wanted to add comment to it.</span></p></div><hr /><div id=\"_cmnt1\" style=\"-aw-comment-author:'awaishafeez'; -aw-comment-datetime:'2018-11-15T07:07:00'; -aw-comment-initial:'a'\"><p><a href=\"#_cmntref1\"><span>[a1]</span></a><span>Comment Text</span></p></div>");

doc.Save("D:\\temp\\18.11.docx"); 

Hope, this helps.

@awais.hafeez

Thank you for your quick response. The code you provided resolves my issue. Is there an attribute for comment reply or do I just append it as a regular comment?

@tesfayemissy,

Please ZIP and attach your expected DOCX document showing the correct output here for our reference. You can create expected document by using MS Word. We will then provide you HTML to achieve the same by using Aspose.Words.

@awais.hafeez

I uploaded the output i’m expecting . Associating multiple comments to one text and also associating the replies to the same text the parent comment refers to when implementing insertHtml().

Associating comments to a text.png (8.3 KB)

@tesfayemissy,

Please see these HTML and DOCX files (reply-comment.zip (7.6 KB)) and try running the following code:

Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

builder.InsertHtml(File.ReadAllText("D:\\Temp\\reply-comment.html"));

doc.Save("D:\\temp\\18.11.docx");

Hope, this helps.

@awais.hafeez

That really helps. Thanks you for your quick response. One last question, can we find a word in an exiting word document and add comment to it ? For example if we take “18.11.docx” , if I wanted to add a comment to the word “Comment” in the generated word document, can we do that with Aspose?

@tesfayemissy,

Please see these input and output sample documents: add comment to text.zip (19.1 KB)

You can find text in Word document and add a comment to it by using the following code:

Document doc = new Document("D:\\temp\\input.docx");

FindReplaceOptions opts = new FindReplaceOptions();
opts.Direction = FindReplaceDirection.Backward;
opts.ReplacingCallback = new ReplaceEvaluator();

doc.Range.Replace(new Regex("Process me"), "", opts);

doc.Save("D:\\temp\\18.11-commented.docx");
//////////////////////////////////////////////
private class ReplaceEvaluator : IReplacingCallback
{
    ReplaceAction IReplacingCallback.Replacing(ReplacingArgs e)
    {
        // This is a Run node that contains either the beginning or the complete match.
        Node currentNode = e.MatchNode;

        // The first (and may be the only) run can contain text before the match,
        // in this case it is necessary to split the run.
        if (e.MatchOffset > 0)
            currentNode = SplitRun((Run)currentNode, e.MatchOffset);

        // This array is used to store all nodes of the match for further removing.
        ArrayList runs = new ArrayList();

        // Find all runs that contain parts of the match string.
        int remainingLength = e.Match.Value.Length;
        while (
            (remainingLength > 0) &&
            (currentNode != null) &&
            (currentNode.GetText().Length <= remainingLength))
        {
            runs.Add(currentNode);
            remainingLength = remainingLength - currentNode.GetText().Length;

            // Select the next Run node.
            // Have to loop because there could be other nodes such as BookmarkStart etc.
            do
            {
                currentNode = currentNode.NextSibling;
            }
            while ((currentNode != null) && (currentNode.NodeType != NodeType.Run));
        }

        // Split the last run that contains the match if there is any text left.
        if ((currentNode != null) && (remainingLength > 0))
        {
            SplitRun((Run)currentNode, remainingLength);
            runs.Add(currentNode);
        }


        Comment comment = new Comment(e.MatchNode.Document, "Awais Hafeez", "AH", DateTime.Today);
        comment.Paragraphs.Add(new Paragraph(e.MatchNode.Document));
        comment.FirstParagraph.Runs.Add(new Run(e.MatchNode.Document, "Comment text."));

        CommentRangeStart commentRangeStart = new CommentRangeStart(e.MatchNode.Document, comment.Id);
        CommentRangeEnd commentRangeEnd = new CommentRangeEnd(e.MatchNode.Document, comment.Id);

        Run runStart = (Run)runs[0];
        Run runEnd = (Run)runs[runs.Count - 1];

        runStart.ParentNode.InsertBefore(commentRangeStart, runStart);
        runEnd.ParentNode.InsertAfter(commentRangeEnd, runEnd);
        commentRangeEnd.ParentNode.InsertAfter(comment, commentRangeEnd);

        return ReplaceAction.Skip;
    }
}

Hope, this helps.

@awais.hafeez

Thank you for your quick response again. This should definitely help.

Hi @awais.hafeez can you please elaborate how do we add replies against of comment using builder.InsertHtml() method.

Thank you.

@cpai.sachin If you need to add comment reply content using DocumentBuider.InsertHtml() method, then you can simply move DocumentBuider cursor inside the comment reply and insert HTML. For example see the following code:

Document doc = new Document(@"C:\Temp\in.docx");
DocumentBuilder builder = new DocumentBuilder(doc);

Comment comment = (Comment)doc.GetChild(NodeType.Comment, 0, true);

//Add a reply to comment
Comment reply = comment.AddReply("John Doe", "JD", new DateTime(2017, 9, 25, 12, 15, 0), "");
// Move document builder inside the reply and insert some HTML.
builder.MoveTo(reply.FirstParagraph);
builder.InsertHtml("<b>Bold content </b><i>Italic content</i>");

// Save the document to disk.
doc.Save(@"C:\Temp\out.docx");

Also, please see our documentation to learn more about working with comments:
https://docs.aspose.com/words/net/working-with-comments/

1 Like

Thanks @alexey.noskov.

Hi @alexey.noskov thanks for your reply.
Its work for me but Its adding empty line before the comment.
Can you suggest me the solution for it.

@cpai.sachin This depends on the HTML snippet. Could you please provide your HTML string here for testing? We will check the issue and provide you more information.

Hi @alexey.noskov, yes its because of my comment reply has p tag in its text. So that it adding one more line right?

Hi @alexey.noskov can you suggest how do I use
builder.InsertHtml("Test Comment");
instead of Comment.SetText("Test Comment");

Thank you!

@cpai.sachin Yes, when <P> tag is used in HTML, it is interpreted as a separate paragraph. You can specify HtmlInsertOptions.RemoveLastEmptyParagraph to remove empty paragraph after the inserted content:

builder.InsertHtml("<p><b>Bold content </b><i>Italic content</i></p>", HtmlInsertOptions.RemoveLastEmptyParagraph);
1 Like

Hi @alexey.noskov we have Aspose.Words, Version=21.6.0.0
As I checked HtmlInsertOptions.RemoveLastEmptyParagraph not available with this version.
can you tell in which version it is available.
Thank you.

Hi @alexey.noskov any updates on this please.

@cpai.sachin This option is available starting from 21.7 version of Aspose.Words. I would suggest you to update to the latest 23.5 version of Aspose.Words to get most recent API and features.

1 Like