/************************************************************************
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, typename V, typename W> class xhtml_element;
template<typename T, typename U, typename V, typename W> class xhtml_end_tag;
template<typename T, typename U, typename V, typename W> class xhtml_formatter;
}
namespace XportPro
{
template<typename T, typename U> class xp_markup;
}
template<typename DT, typename CT, typename MBT, typename SBT>
class Xport::xhtml_element : public MBT
{
// construction/destruction
protected:
xhtml_element();
explicit xhtml_element(const std::basic_string<CT>& start_tag, const xhtml_parser<DT, CT, MBT, SBT>& prsr);
public:
typedef typename MBT::size_type size_type;
typedef typename MBT::iterator base_iterator_type; // vc6 compatibility
typedef typename MBT::const_iterator const_base_iterator_type; // vc6 compatibility
typedef typename MBT::element_type element_type; // vc6 compatibility
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, MBT, SBT>(tg);
if (!elem_id.empty()) {
this->attribute(attribute::id, elem_id);
}
if (!cls.empty()) {
this->attribute(attribute::class_attribute, cls);
}
}
virtual ~xhtml_element();
xhtml_element(const element_type& src);
xhtml_element& operator=(const element_type& rhs);
// 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 Xport::xhtml_formatter<DT, CT, MBT, SBT>& 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 base_iterator_type insert(const MBT& markup);
virtual typename MBT::iterator insert(const std::basic_string<CT>& pcdat) { return insert(MBT::end(), pcdat); }
virtual base_iterator_type insert(const const_base_iterator_type& pos, const MBT& markup);
virtual base_iterator_type insert(const const_base_iterator_type& pos, const std::basic_string<CT>& pcdat);
virtual void insert(const const_base_iterator_type& pos, size_type num, const MBT& markup);
virtual void insert(const const_base_iterator_type& pos, const const_base_iterator_type& it_beg, const const_base_iterator_type& it_end);
virtual MBT& operator << (const std::basic_string<CT>& pcdat);
virtual MBT& operator << (const MBT& markup);
virtual typename MBT::iterator push_back(const MBT& mkup) { return insert(mkup); }
virtual typename MBT::iterator push_back(const std::basic_string<CT>& pcdat) { return insert(pcdat); }
virtual typename MBT::iterator push_front(const MBT& markup) { return insert(MBT::begin(), markup); }
virtual typename MBT::iterator push_front(const std::basic_string<CT>& pcdat) { return insert(MBT::begin(), pcdat); }
protected:
// implementation
virtual bool allow_pcdata() const { return pTag->allow_pcdata(); }
virtual xhtml_nesting_type allowed_nested_type() const { return pTag->allowed_nested_type(); }
virtual MBT* clone() const { return new xhtml_element(*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, MBT, SBT>* get_tag() const { return pTag; }
virtual base_iterator_type insert(MBT* pMarkup);
virtual xhtml_nesting_type nesting_type() const { return pTag->nesting_type(); }
bool valid_parsed_end_tag(const MBT* parsed_markup, const xhtml_parser<DT, CT, MBT, SBT>& prsr);
bool check_for_duplicate_element(xhtml_tag_enum tag_enum);
bool verify_head_body_order(xhtml_tag_enum tag_enum, const const_base_iterator_type& pos);
virtual bool validate_nesting(const MBT& _markup) const;
//data
Xport::tag<DT, CT, MBT, SBT>* 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, MBT, SBT>;
friend class xhtml_formatter<DT, CT, MBT, SBT>;
friend class xhtml_parser<DT, CT, MBT, SBT>;
#else
template<typename T, typename U, typename V, typename W> friend class xhtml_doc;
template<typename T, typename U, typename V, typename W> friend class xhtml_formatter;
template<typename T, typename U, typename V, typename W> friend class xhtml_parser;
#endif
};
/************************************************************************/
/* xhtml_end_tag (for parsing purposes only) */
/************************************************************************/
template<typename DT, typename CT, typename MBT, typename SBT>
class Xport::xhtml_end_tag : MBT
{
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, MBT, SBT> 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, MBT, SBT>;
friend class xhtml_parser<DT, CT, MBT, SBT>;
#else
template<typename T, typename U, typename V, typename W> friend class xhtml_element;
template<typename T, typename U, typename V, typename W> friend class xhtml_parser;
#endif
};
#include "xhtml_element.inl"