The new code didn't changed much, also I added support for URL and tables so use this code as base and then start from there:

void Markdown::WriteText(wxRichTextCtrl* richTextChatBox, const wxString& message, const wxTextAttr& style)
{
    wxString formattedMessage = Markdown::FormatMessage(message);
    wxString::size_type pos = 0;

    std::map<wxString, wxString> markers = {
        { BOLD_ITALIC_MARKER, BOLD_ITALIC_MARKER },
        { BOLD_MARKER, BOLD_MARKER },
        { ITALIC_MARKER, ITALIC_MARKER },
        { UNDERLINE_MARKER, UNDERLINE_MARKER },
        { CODE_MARKER, CODE_MARKER },
        { STRIKETHROUGH_MARKER, STRIKETHROUGH_MARKER },
        { START_LINK_TEXT_MARKER, END_LINK_URL_MARKER },
        { BLOCKQUOTE_MARKER, "\n" },
        { START_LIST_MARKER, "\n" },
        { HEADING_MARKERS[0], "\n" },
        { HEADING_MARKERS[1], "\n" },
        { HEADING_MARKERS[2], "\n" },
        { HEADING_MARKERS[3], "\n" },
        { HEADING_MARKERS[4], "\n" },
        { HEADING_MARKERS[5], "\n" },
        { TABLE_MARKER, TABLE_MARKER }
    };

    while (pos < formattedMessage.Length() && pos != wxString::npos)
    {
        bool foundMarker = false;
        bool foundURL = false;
        auto [markerPos, startMarker, endMarkerPos] = FindEarliestMarker(formattedMessage, markers, pos);

        if (markerPos != wxString::npos)
        {
            wxString endMarker = markers[startMarker];

            if (endMarkerPos != wxString::npos)
            {
                if (startMarker == TABLE_MARKER)
                {
                    wxString::size_type tableEnd = formattedMessage.find(TABLE_MARKER, markerPos + TABLE_MARKER.Length());
                    if (tableEnd != wxString::npos)
                    {
                        wxString tableData = formattedMessage.substr(markerPos + TABLE_MARKER.Length(), tableEnd - (markerPos + TABLE_MARKER.Length()));
                        CreateAndInsertTable(richTextChatBox, tableData, style);
                        pos = tableEnd + TABLE_MARKER.Length();
                        continue;
                    }
                    else
                    {
                        richTextChatBox->WriteText(formattedMessage.Mid(pos));
                        pos = wxString::npos;
                        continue;
                    }
                }

                foundMarker = true;
                wxString beforeMarker = formattedMessage.Mid(pos, markerPos - pos);
                wxString styledText = formattedMessage.Mid(markerPos, endMarkerPos + endMarker.Length() - markerPos);

                richTextChatBox->BeginStyle(style);
                richTextChatBox->WriteText(beforeMarker);
                richTextChatBox->EndStyle();

                if (std::find(std::begin(HEADING_MARKERS), std::end(HEADING_MARKERS), startMarker) != std::end(HEADING_MARKERS))
                {
                    richTextChatBox->WriteText("\n");
                }

                wxRichTextAttr textAttr = wxRichTextAttr(style);
                textAttr.SetFont(richTextChatBox->GetFont());
                textAttr = Markdown::FormatMarkdownStyle(styledText, textAttr);
                richTextChatBox->BeginStyle(textAttr);

                wxString cleanText;

                if (startMarker == START_LINK_TEXT_MARKER)
                {
                    wxString::size_type endLinkText = formattedMessage.find(END_LINK_TEXT_MARKER, markerPos + 1);
                    wxString::size_type startLinkUrl = formattedMessage.find(START_LINK_URL_MARKER, endLinkText);
                    wxString::size_type endLinkUrl = formattedMessage.find(END_LINK_URL_MARKER, startLinkUrl);

                    if (endLinkText != wxString::npos && startLinkUrl != wxString::npos && endLinkUrl != wxString::npos)
                    {
                        wxString linkText = formattedMessage.Mid(markerPos + 1, endLinkText - markerPos - 1);
                        wxString linkUrl = formattedMessage.Mid(startLinkUrl + 1, endLinkUrl - startLinkUrl - 1);

                        if (linkUrl.StartsWith("http://") || linkUrl.StartsWith("https://"))
                        {
                            foundURL = true;
                            richTextChatBox->BeginURL(linkUrl);
                            cleanText = linkText;
                        }
                        else
                        {
                            cleanText = beforeMarker + formattedMessage.substr(markerPos, endLinkUrl - markerPos + 1);
                        }
                    }
                    else
                    {
                        cleanText = beforeMarker + formattedMessage.substr(markerPos, endLinkUrl - markerPos + 1);
                    }
                }
                else
                {
                    cleanText = styledText.Mid(startMarker.Length(), styledText.Length() - startMarker.Length() - endMarker.Length());
                }

                richTextChatBox->WriteText(cleanText);

                if (foundURL)
                {
                    richTextChatBox->EndURL();
                }

                richTextChatBox->EndStyle();

                if (startMarker == BLOCKQUOTE_MARKER || std::find(std::begin(HEADING_MARKERS), std::end(HEADING_MARKERS), startMarker) != std::end(HEADING_MARKERS))
                {
                    richTextChatBox->WriteText("\n");
                }

                pos = endMarkerPos + endMarker.Length();
            }
        }

        if (!foundMarker)
        {
            richTextChatBox->BeginStyle(style);
            richTextChatBox->WriteText(formattedMessage.Mid(pos));
            pos = wxString::npos;
            richTextChatBox->EndStyle();
        }
    }
}