xoofx / markdig

A fast, powerful, CommonMark compliant, extensible Markdown processor for .NET
BSD 2-Clause "Simplified" License
4.21k stars 444 forks source link

Comparing MarkdownDocuments when one has been appended to #793

Open jphorv-bdo opened 2 months ago

jphorv-bdo commented 2 months ago

I have a problem for which I don't see an obvious solution. I have a markdown string that is continuously appended to. After each append it is parsed to a MarkdownDocument. I want to determine what blocks are different between the previous MarkdownDocument and the latest one.

My naive approach was to iterate over each document's top-level Blocks and compare their Span properties, something like:

        int maxIndex = Math.Max(oldDoc.Count, newDoc.Count);

        for (int index = 0; index < maxIndex; index++)
        {
            var oldBlock = index < oldDoc.Count ? oldDoc[index] : null;
            var newBlock = index < newDoc.Count ? newDoc[index] : null;
            if (oldBlock is null && newBlock is null)
                // do nothing, shouldn't ever happen
            else if (oldBlock is null)
                // New block that wasn't here before
            else if (newBlock is null)
                // Old block is no longer here (not even sure if this can happen)
            else if (oldBlock.Span != newBlock.Span)
                // This block is different, do something...
        }

But that doesn't work. One scenario where I found it doesn't (and surely there are more) is when the document ends in the middle of a fenced code block, the block's Span property doesn't encompass the remainder of the markdown string, and it isn't until the fenced block's delimiter arrives that that Span accurately reflects the whole length of the fenced block. I assume this is expected behavior.

My question is, for 2 non-null Block objects, what can I compare on them to determine equality?