/************************************************************************
Xport: XHTML Parsing & Objective Reporting Toolkit
Copyright (C) 2007 Mitchel Haas
This file is part of Xport.
Xport is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Xport is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Xport. If not, see <http://www.gnu.org/licenses/>.
For complete documentation on this library and alternative
licensing options, visit http://www.xportpro.com
Email questions, comments or suggestions to mitchel.haas@xportpro.com
************************************************************************/
#pragma once
#include "tag.h"
#include "xhtml_pcdata.h"
#include "xhtml_parser.h"
#include "xhtml_markup.h"
#include "xhtml_formatter.h"
#include <list>
#include <map>
#include <string>
#include <sstream>
namespace Xport
{
template<typename T, typename U> class xhtml_element;
template<typename T, typename U> class xhtml_end_tag;
template<typename T, typename U> class xhtml_formatter;
}
template<typename DT, typename CT>
class Xport::xhtml_element : public xhtml_markup<DT, CT>
{
// construction/destruction
xhtml_element();
explicit xhtml_element(const std::basic_string<CT>& start_tag, const xhtml_parser<DT, CT>& prsr);
public:
explicit xhtml_element(xhtml_tag_enum tg, const std::basic_string<CT>& elem_id = std::basic_string<CT>(), const std::basic_string<CT>& cls = std::basic_string<CT>()) : pTag(0)
{
pTag = new Xport::tag<DT, CT>(tg);
if (!elem_id.empty()) {
this->attribute(attribute::id, elem_id);
}
if (!cls.empty()) {
this->attribute(attribute::class_attribute, cls);
}
}
xhtml_element(const xhtml_element& src);
~xhtml_element();
xhtml_element& operator=(const xhtml_element& rhs);
using xhtml_markup<DT, CT>::size_type;
// public interface
virtual std::basic_string<CT> attribute(attribute::xhtml_attribute attrib ) const;
virtual bool attribute(attribute::xhtml_attribute attrib, const std::basic_string<CT>& value );
virtual const std::map<attribute::xhtml_attribute, std::basic_string<CT> >* attributes() const { return &attribute_map; }
virtual std::map<attribute::xhtml_attribute, std::basic_string<CT> >* attributes() { return &attribute_map; }
virtual void write(const xhtml_formatter<DT, CT>& fmtr) const { fmtr.get_element_xhtml(this, attribute_map, style_map); fmtr.output->flush(); }
virtual xhtml_markup_type markup_type() const { return mt_element; }
virtual std::basic_string<CT> style(css::css_property prop ) const;
virtual bool style(css::css_property prop, const std::basic_string<CT>& value );
virtual const std::map<css::css_property, std::basic_string<CT> >* styles() const { return &style_map; }
virtual std::map<css::css_property, std::basic_string<CT> >* styles() { return &style_map; }
virtual std::basic_string<CT> tag_name() const { return pTag->tag_name(); }
virtual xhtml_tag_enum tag() const { return pTag->tag_enumeration(); }
virtual typename xhtml_markup<DT, CT>::iterator insert(const xhtml_markup<DT, CT>& markup);
virtual typename xhtml_markup<DT, CT>::iterator insert(const std::basic_string<CT>& pcdat);
virtual typename xhtml_markup<DT, CT>::iterator insert(const typename xhtml_markup<DT, CT>::const_iterator& pos, const xhtml_markup<DT, CT>& markup);
virtual typename xhtml_markup<DT, CT>::iterator insert(const typename xhtml_markup<DT, CT>::const_iterator& pos, const std::basic_string<CT>& pcdat);
virtual void insert(const typename xhtml_markup<DT, CT>::const_iterator& pos, typename xhtml_markup<DT, CT>::size_type num, const xhtml_markup<DT, CT>& markup);
virtual void insert(const typename xhtml_markup<DT, CT>::const_iterator& pos, const typename xhtml_markup<DT, CT>::const_iterator& it_beg, const typename xhtml_markup<DT, CT>::const_iterator& it_end);
virtual xhtml_markup<DT, CT>& operator << (const std::basic_string<CT>& pcdat);
virtual xhtml_markup<DT, CT>& operator << (const xhtml_markup<DT, CT>& markup);
virtual typename xhtml_markup<DT, CT>::iterator push_back(const xhtml_markup<DT, CT>& mkup) { return insert(mkup); }
virtual typename xhtml_markup<DT, CT>::iterator push_back(const std::basic_string<CT>& pcdat) { return insert(pcdat); }
virtual typename xhtml_markup<DT, CT>::iterator push_front(const xhtml_markup<DT, CT>& markup) { return insert(xhtml_markup<DT, CT>::begin(), markup); }
virtual typename xhtml_markup<DT, CT>::iterator push_front(const std::basic_string<CT>& pcdat) { return insert(xhtml_markup<DT, CT>::begin(), pcdat); }
private:
// implementation
virtual bool allow_pcdata() const { return pTag->allow_pcdata(); }
virtual xhtml_nesting_type allowed_nested_type() const { return pTag->allowed_nested_type(); }
virtual xhtml_markup<DT, CT>* clone() const { return new xhtml_element<DT, CT>(*this); }
virtual bool empty_tag() const { return pTag->empty_tag(); }
virtual std::basic_string<CT> end_tag() const { return pTag->end_tag(); }
void extract_attributes(const std::basic_string<CT>& attribs);
void extract_styles(const std::basic_string<CT>& _styles);
virtual const Xport::tag<DT, CT>* get_tag() const { return pTag; }
virtual typename xhtml_markup<DT, CT>::iterator insert(xhtml_markup<DT, CT>* pMarkup);
virtual xhtml_nesting_type nesting_type() const { return pTag->nesting_type(); }
bool valid_parsed_end_tag(const xhtml_markup<DT, CT>* parsed_markup, const xhtml_parser<DT, CT>& prsr);
bool check_for_duplicate_element(xhtml_tag_enum tag_enum);
bool verify_head_body_order(xhtml_tag_enum tag_enum, const typename xhtml_markup<DT, CT>::const_iterator& pos);
virtual bool validate_nesting(const xhtml_markup<DT, CT>& _markup) const;
//data
Xport::tag<DT, CT>* pTag;
std::map<css::css_property, std::basic_string<CT> > style_map;
std::map<attribute::xhtml_attribute, std::basic_string<CT> > attribute_map;
// friends
#if defined(_MSC_VER) && _MSC_VER < 1300
friend class xhtml_doc<DT, CT>;
friend class xhtml_formatter<DT, CT>;
friend class xhtml_parser<DT, CT>;
#else
template<typename T, typename U> friend class xhtml_doc;
template<typename T, typename U> friend class xhtml_formatter;
template<typename T, typename U> friend class xhtml_parser;
#endif
};
/************************************************************************/
/* xhtml_end_tag (for parsing purposes only) */
/************************************************************************/
template<typename DT, typename CT>
class Xport::xhtml_end_tag : public xhtml_markup<DT, CT>
{
public:
// construction
explicit xhtml_end_tag(const std::basic_string<CT>& end_tag_str);
private:
explicit xhtml_end_tag(xhtml_tag_enum tt) : end_tag_type(tt)
{
Xport::tag<DT, CT> tg(tt);
data = tg.end_tag();
}
public:
// interface
virtual xhtml_tag_enum tag() const { return end_tag_type; }
virtual std::basic_string<CT> tag_name() const { return data; }
private:
// private interface
virtual bool is_end_tag() const { return true; }
// data
xhtml_tag_enum end_tag_type;
std::basic_string<CT> data;
// friends
#if defined(_MSC_VER) && _MSC_VER < 1300
friend class xhtml_element<DT, CT>;
friend class xhtml_parser<DT, CT>;
#else
template<typename T, typename U> friend class xhtml_element;
template<typename T, typename U> friend class xhtml_parser;
#endif
};
#include "xhtml_element.inl"