/************************************************************************
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 "common.h"
#include <iosfwd>
#include <vector>
namespace Xport
{
// forward declarations
template<typename T, typename U, typename V, typename W> class xhtml_formatter;
template<typename T, typename U, typename V, typename W> class xhtml_element;
template<typename T, typename U, typename V, typename W> class xhtml_comment;
template<typename T, typename U, typename V, typename W> class xhtml_doctype_declaration;
template<typename T, typename U, typename V, typename W> class xhtml_processing_instruction;
template<typename T, typename U, typename V, typename W> class xhtml_pcdata;
// inline_layout 00000
// newline_before_start_tag 00001
// newline_after_start_tag 00010
// block_level_start_tag 00011
// newline_before_end_tag 00100
// newline_after_end_tag 01000
// block_level_end_tag 01100
// block_level_layout 01111
// pre_layout 10000
enum formatter_integer_option {max_line_length, nesting_indent};
enum formatter_boolean_option { attributes_double_quoted, attributes_spaced};
enum formatter_string_option {};
}
namespace XportPro
{
template<typename T, typename U> class xp_document;
}
template<typename DT, typename CT, typename MBT, typename SBT>
class Xport::xhtml_formatter
{
public:
explicit xhtml_formatter(const std::basic_string<char>& filename);
explicit xhtml_formatter(std::basic_ostream<CT>& out);
~xhtml_formatter();
private:
xhtml_formatter(const xhtml_formatter<DT, CT, MBT, SBT>& src);
public:
// public interface
bool operator !() const { return output->fail(); }
xhtml_formatter<DT, CT, MBT, SBT>& operator << (const xhtml_doc<DT, CT, MBT, SBT>& doc) { doc.write(*this); return *this; }
xhtml_formatter<DT, CT, MBT, SBT>& operator << (const MBT& mkup) { mkup.write(*this); return *this; }
void layout_style(xhtml_tag_enum tg, tag_layout_style tls) { tag_layout_styles[tg] = tls; }
tag_layout_style layout_style(xhtml_tag_enum tg) const { return tag_layout_styles[tg]; }
// get option
int option(formatter_integer_option opt) const;
bool option(formatter_boolean_option opt) const;
std::basic_string<CT> option(formatter_string_option opt) const;
encoding option(formatter_encoding_option opt) const;
// set option
bool option(formatter_integer_option opt, int value);
bool option(formatter_boolean_option opt, bool value);
bool option(formatter_string_option opt, const std::basic_string<CT>& value);
bool option(formatter_encoding_option opt, encoding enc);
private:
// implementation
enum output_type { file, stream };
bool empty_tag(const xhtml_element<DT, CT, MBT, SBT>* pElem) const { return pElem->empty_tag(); }
std::basic_string<CT> end_tag(const xhtml_element<DT, CT, MBT, SBT>* pElem) const { return pElem->end_tag(); }
void get_comment_xhtml(const std::basic_string<CT>& data) const;
void get_doctype_decl_xhtml(const xhtml_doctype_declaration<DT, CT, MBT, SBT>* _decl) const;
std::basic_string<CT> get_element_attributes(const xhtml_element<DT, CT, MBT, SBT>* _pElement, const std::map<attribute::xhtml_attribute, std::basic_string<CT> >& attributes) const;
std::basic_string<CT> get_element_styles(const xhtml_element<DT, CT, MBT, SBT>* _pElement, const std::map<css::css_property, std::basic_string<CT> >& styles) const;
void get_element_xhtml(const xhtml_element<DT, CT, MBT, SBT>* _element, const std::map<attribute::xhtml_attribute, std::basic_string<CT> >& attributes, const std::map<css::css_property, std::basic_string<CT> >& styles) const;
void get_pcdata_xhtml(const xhtml_pcdata<DT, CT, MBT, SBT>* _pcdata, const std::basic_string<CT>& data) const;
void get_proc_instr_xhtml(const std::basic_string<CT>& data) const;
std::basic_string<CT> get_tag_xhtml(const xhtml_element<DT, CT, MBT, SBT>* _pElement) const;
tag_layout_style layout_style(const MBT& mkup) const;
void reset_line_length() const { cur_line_len = 0; }
void process_bom(MBT* pRoot) const;
// data
output_type out_type;
int nesting_ind;
mutable short indent_lvl;
size_t max_line_len;
mutable size_t cur_line_len;
std::vector<tag_layout_style> tag_layout_styles;
mutable std::basic_ostream<CT>* output;
bool attrib_double_quoted;
bool attrib_spaced;
encoding file_encoding;
std::basic_string<char> filepath;
// friends
#if defined(_MSC_VER) && _MSC_VER < 1300
friend class xhtml_element<DT, CT, MBT, SBT>;
friend class xhtml_pcdata<DT, CT, MBT, SBT>;
friend class xhtml_comment<DT, CT, MBT, SBT>;
friend class xhtml_processing_instruction<DT, CT, MBT, SBT>;
friend class xhtml_doctype_declaration<DT, CT, MBT, SBT>;
friend class xhtml_doc<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_pcdata;
template<typename T, typename U, typename V, typename W> friend class xhtml_comment;
template<typename T, typename U, typename V, typename W> friend class xhtml_processing_instruction;
template<typename T, typename U, typename V, typename W> friend class xhtml_doctype_declaration;
template<typename T, typename U, typename V, typename W> friend class xhtml_doc;
#endif
friend class XportPro::xp_document<DT, CT>;
};
#include "xhtml_formatter.inl"