⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htmlparser.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:

bool wxSimpleHtmlParser::IsAlpha(int ch)
{
    return (wxIsalpha((wxChar) ch) != 0);
}

bool wxSimpleHtmlParser::IsWordChar(int ch)
{
    return (wxIsalpha((wxChar) ch) != 0 || ch == wxT('-') || ch == wxT('_') || IsNumeric(ch));
}

bool wxSimpleHtmlParser::IsNumeric(int ch)
{
    return (wxIsdigit((wxChar) ch) != 0 || ch == wxT('-') || ch == wxT('.')) ;
}

bool wxSimpleHtmlParser::IsCloseTagNeeded(const wxString &name)
{
    if (name.IsSameAs(wxT("P"), false)) // e.g <P>
        return false;

    // ToDo add more items here.

    return true;
}

// Encode/Decode Special Characters.
// See here for the used table: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsql/ac_xml1_1nqk.asp
/* static */ void wxSimpleHtmlParser::DecodeSpecialChars(wxString &value)
{
    // XML translation
    value.Replace(wxT("&gt;"),   wxT(">"),  true);
    value.Replace(wxT("&lt;"),   wxT("<"),  true);
    value.Replace(wxT("&quot;"), wxT("\""), true);
    value.Replace(wxT("&apos;"), wxT("'"),  true);
    value.Replace(wxT("&amp;"),  wxT("&"),  true);    // Note: do this as last to prevent replace problems.
}

/* static */ wxString wxSimpleHtmlParser::EncodeSpecialChars(const wxString &value)
{
    wxString newvalue = value;

    // XML translation
    newvalue.Replace(wxT("&"), wxT("&amp;"),  true);    // Note: do this as first to prevent replace problems.
    newvalue.Replace(wxT(">"), wxT("&gt;"),   true);
    newvalue.Replace(wxT("<"), wxT("&lt;"),   true);
    newvalue.Replace(wxT("\""),wxT("&quot;"), true);
    newvalue.Replace(wxT("'"), wxT("&apos;"), true);

    return newvalue;
}

// Matches this string (case insensitive)
bool wxSimpleHtmlParser::Matches(const wxString& tok, bool eatIt)
{
    wxString text(m_text.Mid(m_pos, tok.Length()));
    bool success = (text.CmpNoCase(tok) == 0) ;
    if (success && eatIt)
    {
        m_pos += tok.Length();
    }
    return success;
}

// Safe way of getting a character
int wxSimpleHtmlParser::GetChar(size_t i) const
{
    if (i >= (size_t) m_length)
        return -1;
    return m_text[i];
}

void wxSimpleHtmlParser::Clear()
{
    if (m_topLevel)
        delete m_topLevel;
    m_topLevel = NULL;
    m_text = wxEmptyString;
    m_pos = 0;
    m_length = 0;
}

// Write this file
void wxSimpleHtmlParser::Write(wxOutputStream& stream)
{
    if (m_topLevel)
        m_topLevel->Write(stream);
}

bool wxSimpleHtmlParser::WriteFile(wxString& filename)
{
    wxFileOutputStream fstream(filename);
    if (fstream.Ok())
    {
        Write(fstream);
        return true;
    }
    else
        return false;
}

/*
 * wxSimpleHtmlTag
 * Representation of a tag or chunk of text
 */

wxSimpleHtmlTag::wxSimpleHtmlTag(const wxString& tagName, int tagType)
{
    m_name = tagName;
    m_type = tagType;
    m_attributes = NULL;
    m_children = NULL;
    m_parent = NULL;
    m_next = NULL;
}

wxSimpleHtmlTag::~wxSimpleHtmlTag()
{
    ClearAttributes();
    ClearChildren();
}

//// Operations
void wxSimpleHtmlTag::ClearAttributes()
{
    if (m_attributes)
    {
        wxSimpleHtmlAttribute* attr = m_attributes;
        while (attr)
        {
            wxSimpleHtmlAttribute* next = attr->m_next;

            attr->m_next = NULL;
            delete attr;
            attr = next;
        }
        m_attributes = NULL;
    }
}

wxSimpleHtmlAttribute* wxSimpleHtmlTag::FindAttribute(const wxString& name) const
{
    wxSimpleHtmlAttribute* attr = m_attributes;
    while (attr)
    {
        if (attr->GetName().CmpNoCase(name) == 0)
        {
            return attr;
        }
        attr = attr->m_next;
    }
    return NULL;
}

void wxSimpleHtmlTag::AppendAttribute(const wxString& name, const wxString& value)
{
    wxSimpleHtmlAttribute* attr = new wxSimpleHtmlAttribute(name, value);
    if (m_attributes)
    {
        // Find tail
        wxSimpleHtmlAttribute* last = m_attributes;
        while (last->m_next)
            last = last->m_next;

        last->m_next = attr;
    }
    else
        m_attributes = attr;
}

void wxSimpleHtmlTag::ClearChildren()
{
    if (m_children)
    {
        wxSimpleHtmlTag* child = m_children;
        while (child)
        {
            wxSimpleHtmlTag* next = child->m_next;

            child->m_next = NULL;
            delete child;
            child = next;
        }
        m_children = NULL;
    }
}

void wxSimpleHtmlTag::RemoveChild(wxSimpleHtmlTag *remove)
{
    if (m_children)
    {
        wxSimpleHtmlTag* child = m_children;
        wxSimpleHtmlTag* prev = NULL;
        while (child)
        {
            wxSimpleHtmlTag* next = child->m_next;

            if (child == remove)
            {
                child->m_next = NULL;
                delete child;

                if (prev != NULL)
                    prev->m_next = next;
                else
                    m_children = next;

                return;
            }
            prev = child;
            child = next;
        }
    }
}

void wxSimpleHtmlTag::AppendTag(wxSimpleHtmlTag* tag)
{
    if (!tag)
        return;

    if (m_children)
    {
        // Find tail
        wxSimpleHtmlTag* last = m_children;
        while (last->m_next)
            last = last->m_next;

        last->m_next = tag;
    }
    else
    {
        m_children = tag;
    }

    tag->m_parent = this;
}

void wxSimpleHtmlTag::AppendTagAfterUs(wxSimpleHtmlTag* tag)
{
    if (!tag)
        return;

    tag->m_parent = m_parent;
    tag->m_next = m_next;
    m_next = tag;
}

// Gets the text from this tag and its descendants
wxString wxSimpleHtmlTag::GetTagText()
{
    wxString text;
    if (m_children)
    {
        wxSimpleHtmlTag* tag = m_children;
        while (tag)
        {
            text += tag->GetTagText();
            tag = tag->m_next;
        }
        return text;
    }
    else if (GetType() == wxSimpleHtmlTag_Text)
        return GetText();
    else
        return wxEmptyString;
}

int wxSimpleHtmlTag::GetAttributeCount() const
{
    int count = 0;
    wxSimpleHtmlAttribute* attr = m_attributes;
    while (attr)
    {
        count ++;
        attr = attr->m_next;
    }
    return count;
}

wxSimpleHtmlAttribute* wxSimpleHtmlTag::GetAttribute(int i) const
{
    int count = 0;
    wxSimpleHtmlAttribute* attr = m_attributes;
    while (attr)
    {
        if (count == i)
            return attr;
        count ++;
        attr = attr->m_next;
    }
    return NULL;
}

int wxSimpleHtmlTag::GetChildCount() const
{
    int count = 0;
    wxSimpleHtmlTag* tag = m_children;
    while (tag)
    {
        count ++;
        tag = tag->m_next;
    }
    return count;
}

bool wxSimpleHtmlTag::HasAttribute(const wxString& name, const wxString& value) const
{
    wxSimpleHtmlAttribute* attr = FindAttribute(name);

    return (attr && (attr->GetValue().CmpNoCase(value) == 0)) ;
}

bool wxSimpleHtmlTag::HasAttribute(const wxString& name) const
{
    return FindAttribute(name) != NULL ;
}

bool wxSimpleHtmlTag::GetAttributeValue(wxString& value, const wxString& attrName)
{
    wxSimpleHtmlAttribute* attr = FindAttribute(attrName);
    if (attr)
    {
        value = attr->GetValue();
        return true;
    }
    else
        return false;
}

// Search forward from this tag until we find a tag with this name & attribute
wxSimpleHtmlTag* wxSimpleHtmlTag::FindTag(const wxString& tagName, const wxString& attrName)
{
    wxSimpleHtmlTag* tag = m_next;
    while (tag)
    {
        if (tag->NameIs(tagName) && (attrName.IsEmpty() || tag->FindAttribute(attrName)))
            return tag;

        tag = tag->m_next;
    }
    return NULL;
}

bool wxSimpleHtmlTag::FindTextUntilTagClose(wxString& text, const wxString& tagName)
{
    wxSimpleHtmlTag* tag = this;
    while (tag)
    {
        if (tag->GetType() == wxSimpleHtmlTag_Close && tag->NameIs(tagName))
            return true;

        if (tag->GetType() == wxSimpleHtmlTag_Text)
            text += tag->GetText();

        tag = tag->m_next;
    }
    return true;
}


wxSimpleHtmlTag* wxSimpleHtmlTag::GetChild(int i) const
{
    int count = 0;
    wxSimpleHtmlTag* tag = m_children;
    while (tag)
    {
        if (count == i)
            return tag;

        count ++;
        tag = tag->m_next;
    }
    return NULL;
}

void wxSimpleHtmlTag::Write(wxOutputStream& stream)
{
    // Some helpers to layout the open and close tags.
    static bool sbUseTab = true;
    static size_t snTabLevel = 0;

#if 0 // Enable if no tabs should be used to align the tags.
    snTabLevel = 0;
#endif

    // Handle the different types of tags we can write.
    switch (GetType())
    {
    case wxSimpleHtmlTag_Text:
        {
            stream << wxSimpleHtmlParser::EncodeSpecialChars(m_text);
            break;
        }
    case wxSimpleHtmlTag_Open:
        {
            size_t tab;
            for(tab = 0; tab < snTabLevel; tab++)
                stream << wxT("\t");
            stream << wxT("<") << wxSimpleHtmlParser::EncodeSpecialChars(m_name);
            if (GetAttributeCount() > 0)
                stream << wxT(" ");
            int i;
            for (i = 0; i < GetAttributeCount(); i++)
            {
                wxSimpleHtmlAttribute* attr = GetAttribute(i);
                attr->Write(stream);
                if (i < GetAttributeCount() - 1)
                    stream << wxT(" ");
            }
            if(!m_children)
            {
                sbUseTab = false;   // We're putting the open a close tag on the same line,
                                    // so we don't wan't any tabs
                stream << wxT(">");
            }
            else
            {
                // sbUseTab = true;
                stream << wxT(">\n");
            }
            snTabLevel++;
            break;
        }
    case wxSimpleHtmlTag_Directive:
        {
            stream << wxT("<!") << wxSimpleHtmlParser::EncodeSpecialChars(m_name) << wxT(" ");
            int i;
            for (i = 0; i < GetAttributeCount(); i++)
            {
                wxSimpleHtmlAttribute* attr = GetAttribute(i);
                attr->Write(stream);
                if (i < GetAttributeCount() - 1)
                    stream << wxT(" ");
            }
            stream << wxT(">\n");
            break;
        }
    case wxSimpleHtmlTag_XMLDeclaration:
        {
            stream << wxT("<?") << wxSimpleHtmlParser::EncodeSpecialChars(m_name) << wxT(" ");
            int i;
            for (i = 0; i < GetAttributeCount(); i++)
            {
                wxSimpleHtmlAttribute* attr = GetAttribute(i);
                attr->Write(stream);
                if (i < GetAttributeCount() - 1)
                    stream << wxT(" ");
            }
            stream << wxT(">\n\n");
            break;
        }
    case wxSimpleHtmlTag_Close:
        {
            if (snTabLevel)     // Safety to prevent going around...
                snTabLevel--;   // Reduce the tab level
            if (sbUseTab)   // Do we write the open tag and close tag on a other line?
            {
                size_t tab;
                for(tab = 0; tab < snTabLevel; tab++)
                    stream << wxT("\t");
            }
            stream << wxT("</") << wxSimpleHtmlParser::EncodeSpecialChars(m_name) << wxT(">\n");
            sbUseTab = true;
            break;
        }
    default:
        {
            break;
        }
    }
    wxSimpleHtmlTag* tag = m_children;
    while (tag)
    {
        tag->Write(stream);
        tag = tag->m_next;
    }

}

void wxSimpleHtmlAttribute::Write(wxOutputStream& stream)
{
    if (m_value.IsEmpty())
        stream << wxSimpleHtmlParser::EncodeSpecialChars(m_name);
    else
    {
        stream << wxSimpleHtmlParser::EncodeSpecialChars(m_name);
        stream << wxT("=\"");
        stream << wxSimpleHtmlParser::EncodeSpecialChars(m_value);
        stream << wxT("\"");
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -