Refactor my C++ custom wxWidgets code into separate methods and make it more clearer and improve it:

class wxMarkdownTextCtrl : public wxRichTextCtrl
{
    public:
        wxMarkdownTextCtrl(wxWindow* parent, wxWindowID id=-1, const wxString& value=wxEmptyString, const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize, long style=wxRE_MULTILINE, const wxValidator& validator=wxDefaultValidator, const wxString& name=wxTextCtrlNameStr);
        ~wxMarkdownTextCtrl() = default;
        void WriteText(const wxString& text) override;

    private:
        void ReplaceTags(wxString& text);
        void ProcessMarker(const wxString& text, wxString::size_type& pos);
        void ProcessLink(const wxString& text, wxString::size_type& pos, wxString::size_type startLinkText);
};

#include "wxMarkdownTextCtrl.h"

wxMarkdownTextCtrl::wxMarkdownTextCtrl(wxWindow* parent, wxWindowID id, const wxString& value, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator, const wxString& name) : wxRichTextCtrl(parent, id, value, pos, size, style, validator, name)
{
}

void wxMarkdownTextCtrl::WriteText(const wxString& text)
{
    wxString formattedText = text;

    ReplaceTags(formattedText);

    wxString::size_type pos = 0;
    while (pos < formattedText.Length() && pos != wxString::npos)
    {
        ProcessMarker(formattedText, pos);
    }
}

void wxMarkdownTextCtrl::ReplaceTags(wxString& text)
{
    text.Replace("<br>", "\n");
    text.Replace("<strong>", "**");
    text.Replace("</strong>", "**");
    text.Replace("<em>", "*");
    text.Replace("</em>", "*");
    text.Replace("\n- ", wxString::FromUTF8("\n● "));
    text.Replace("\n* ", wxString::FromUTF8("\n● "));
}

void wxMarkdownTextCtrl::ProcessMarker(const wxString& text, wxString::size_type& pos)
{
    while (pos < text.Length() && pos != wxString::npos)
    {
        wxString::size_type startBoldItalic = text.find("***", pos);
        wxString::size_type startBold = text.find("**", pos);
        wxString::size_type startItalic = text.find("*", pos);
        wxString::size_type startUnderline = text.find("__", pos);
        wxString::size_type startLinkText = text.find("[", pos);
        wxString::size_type startCode = text.find("`", pos);

        wxString::size_type startHeading1 = text.find("\n# ", pos);
        wxString::size_type startHeading2 = text.find("\n## ", pos);
        wxString::size_type startHeading3 = text.find("\n### ", pos);
        wxString::size_type startHeading4 = text.find("\n#### ", pos);
        wxString::size_type startHeading5 = text.find("\n##### ", pos);
        wxString::size_type startHeading6 = text.find("\n###### ", pos);
        wxString::size_type startBlockquote = text.find("\n> ", pos);

        if (pos == 0)
        {
            startHeading1 = text.find("# ", pos);
            startHeading2 = text.find("## ", pos);
            startHeading3 = text.find("### ", pos);
            startHeading4 = text.find("#### ", pos);
            startHeading5 = text.find("##### ", pos);
            startHeading6 = text.find("###### ", pos);
            startBlockquote = text.find("> ", pos);
        }

        std::vector<std::pair<wxString::size_type, int>> markers = {
            { startBoldItalic, 3 },
            { startBold, 2 },
            { startItalic, 1 },
            { startUnderline, 2 },
            { startCode, 1 },
            { startHeading6, 7 },
            { startHeading5, 6 },
            { startHeading4, 5 },
            { startHeading3, 4 },
            { startHeading2, 3 },
            { startHeading1, 2 },
            { startBlockquote, 2 },
            { startLinkText, -1 }
        };

        // Find the earliest marker
        auto earliestIt = std::min_element(markers.begin(), markers.end(), [](const auto& lhs, const auto& rhs){
            return (lhs.first != wxString::npos && (rhs.first == wxString::npos || lhs.first < rhs.first));
        });

        if (earliestIt->first != wxString::npos)
        {
            wxString::size_type markerPos = earliestIt->first;
            int markerLength = earliestIt->second;

            wxString::size_type endMarker;

            if (startBoldItalic == markerPos)
            {
                endMarker = text.find("***", markerPos + markerLength);
            }
            else if (startBold == markerPos)
            {
                endMarker = text.find("**", markerPos + markerLength);
            }
            else if (startUnderline == markerPos)
            {
                endMarker = text.find("__", markerPos + markerLength);
            }
            else if (startItalic == markerPos)
            {
                endMarker = text.find("*", markerPos + markerLength);
            }
            else if (startCode == markerPos)
            {
                endMarker = text.find("`", markerPos + markerLength);
            }
            else if (startHeading1 == markerPos || startHeading2 == markerPos || startHeading3 == markerPos || startHeading4 == markerPos || startHeading5 == markerPos || startHeading6 == markerPos || startBlockquote == markerPos)
            {
                endMarker = text.find("\n", markerPos + markerLength);
            }
            else if (startLinkText == markerPos)
            {
                ProcessLink(text, pos, startLinkText);
            }

            if (endMarker != wxString::npos)
            {
                wxString beforeMarker = text.substr(pos, markerPos - pos);
                wxRichTextCtrl::WriteText(beforeMarker);
                wxString styledText = text.substr(markerPos + markerLength, endMarker - markerPos - markerLength);

                if (startBoldItalic == markerPos || startBold == markerPos || startUnderline == markerPos) // Bold and/or Underline
                {
                    if (startBoldItalic == markerPos)
                    {
                        wxRichTextCtrl::BeginBold();
                        wxRichTextCtrl::BeginUnderline();
                    }
                    else if (startBold == markerPos)
                    {
                        wxRichTextCtrl::BeginBold();
                    }
                    else if (startUnderline == markerPos)
                    {
                        wxRichTextCtrl::BeginUnderline();
                    }

                    wxRichTextCtrl::WriteText(styledText);

                    if (startBoldItalic == markerPos)
                    {
                        wxRichTextCtrl::EndBold();
                        wxRichTextCtrl::EndUnderline();
                    }
                    else if (startBold == markerPos)
                    {
                        wxRichTextCtrl::EndBold();
                    }
                    else if (startUnderline == markerPos)
                    {
                        wxRichTextCtrl::EndUnderline();
                    }
                }
                else if (markerLength == 1 && startItalic == markerPos) // Italic
                {
                    wxRichTextCtrl::BeginItalic();
                    wxRichTextCtrl::WriteText(styledText);
                    wxRichTextCtrl::EndItalic();
                }
                else if (markerLength == 1 && startCode == markerPos) // Inline code
                {
                    wxTextAttr style;
                    wxRichTextCtrl::GetStyle(pos, style);

                    wxTextAttr codeAttr;
                    codeAttr.SetFontWeight(wxFONTWEIGHT_MEDIUM);
                    codeAttr.SetBackgroundColour(style.GetBackgroundColour().ChangeLightness(60));
                    codeAttr.SetTextColour(style.GetTextColour().ChangeLightness(140));

                    wxRichTextCtrl::BeginStyle(codeAttr);
                    wxRichTextCtrl::WriteText(styledText);
                    wxRichTextCtrl::EndStyle();
                }
                else if (markerLength == 2 && startBlockquote == markerPos) // Blockquote
                {
                    wxTextAttr style;
                    wxRichTextCtrl::GetStyle(pos, style);

                    wxTextAttr blockquoteAttr;
                    blockquoteAttr.SetBackgroundColour(style.GetBackgroundColour().ChangeLightness(50));
                    blockquoteAttr.SetTextColour(wxColour(220, 220, 220));

                    wxRichTextCtrl::BeginStyle(blockquoteAttr);
                    wxRichTextCtrl::WriteText(styledText);
                    wxRichTextCtrl::EndStyle();

                    if (endMarker < text.Length() && text[endMarker] == '\n')
                    {
                        wxRichTextCtrl::WriteText("\n");
                    }
                }
                else if (markerLength >= 2 && markerLength <= 7 && (startHeading1 == markerPos || startHeading2 == markerPos || startHeading3 == markerPos || startHeading4 == markerPos || startHeading5 == markerPos || startHeading6 == markerPos)) // Headings
                {
                    wxFont font = wxRichTextCtrl::GetFont();
                    int pointSize = font.GetPointSize();

                    if (startHeading1 == markerPos)
                    {
                        pointSize *= 2;
                    }
                    else if (startHeading2 == markerPos)
                    {
                        pointSize *= 1.7;
                    }
                    else if (startHeading3 == markerPos)
                    {
                        pointSize *= 1.5;
                    }
                    else if (startHeading4 == markerPos)
                    {
                        pointSize *= 1.3;
                    }
                    else if (startHeading5 == markerPos)
                    {
                        pointSize *= 1.2;
                    }
                    else if (startHeading6 == markerPos)
                    {
                        pointSize *= 1.1;
                    }

                    wxRichTextCtrl::WriteText("\n");
                    wxRichTextCtrl::BeginFontSize(pointSize);
                    wxRichTextCtrl::WriteText(styledText);
                    wxRichTextCtrl::EndFontSize();
                    wxRichTextCtrl::WriteText("\n");
                }

                if (startHeading1 == markerPos || startHeading2 == markerPos || startHeading3 == markerPos || startHeading4 == markerPos || startHeading5 == markerPos || startHeading6 == markerPos)
                {
                    pos = endMarker + 1;
                }
                else
                {
                    pos = endMarker + markerLength;
                }
            }
            else
            {
                wxRichTextCtrl::WriteText(text.substr(pos));
                pos = wxString::npos;
            }
        }
        else
        {
            wxRichTextCtrl::WriteText(text.substr(pos));
            pos = wxString::npos;
        }
    }
}

void wxMarkdownTextCtrl::ProcessLink(const wxString& text, wxString::size_type& pos, wxString::size_type startLinkText)
{
    wxString::size_type endLinkText = text.find("]", startLinkText);
    wxString::size_type startLinkUrl = text.find("(", endLinkText);
    wxString::size_type endLinkUrl = text.find(")", startLinkUrl);

    if (endLinkText != wxString::npos && startLinkUrl != wxString::npos && endLinkUrl != wxString::npos)
    {
        wxString beforeMarker = text.substr(pos, startLinkText - pos);
        wxString linkText = text.substr(startLinkText + 1, endLinkText - startLinkText - 1);
        wxString linkUrl = text.substr(startLinkUrl + 1, endLinkUrl - startLinkUrl - 1);

        if (linkUrl.StartsWith("http://") || linkUrl.StartsWith("https://"))
        {
            wxRichTextCtrl::WriteText(beforeMarker);

            wxRichTextAttr urlStyle;
            urlStyle.SetTextColour(*wxBLUE);
            urlStyle.SetFontUnderlined(true);

            wxRichTextCtrl::BeginStyle(urlStyle);
            wxRichTextCtrl::BeginURL(linkUrl);
            wxRichTextCtrl::WriteText(linkText);
            wxRichTextCtrl::EndURL();
            wxRichTextCtrl::EndStyle();

            pos = endLinkUrl + 1;
        }
        else
        {
            wxString invalidLinkText = text.substr(startLinkText, endLinkUrl - startLinkText + 1);
            wxRichTextCtrl::WriteText(beforeMarker + invalidLinkText);
            pos = endLinkUrl + 1;
        }
    }
    else
    {
        wxRichTextCtrl::WriteText(text.substr(pos));
        pos = wxString::npos;
    }
}