/*************************************************************************** * Copyright (C) 2003 by Sylvain Joyeux * * sylvain.joyeux@m4x.org * * * * This program 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 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #ifndef TQHtmlStream_H #define TQHtmlStream_H #include #include class TQHtmlStream; class TQHtmlStreamManip; /** @author Sylvain Joyeux */ class TQHtmlStreamManip { protected: virtual void apply(TQHtmlStream& stream) const = 0; public: virtual ~TQHtmlStreamManip() {}; void operator () (TQHtmlStream& stream) const { apply(stream); } }; class TQHtmlStream { TQTextOStream m_stream; enum States { NORMAL_FLOW, TAG, BLOCK, PARAM }; int m_state, m_enclosing_state; bool m_newline; TQString m_indent; TQStringList m_blockstack; void finalize_open() { if (m_state == PARAM) m_state = m_enclosing_state; if (m_state == BLOCK) m_stream << ">"; else if (m_state == TAG) m_stream << " />"; m_state = NORMAL_FLOW; } void indent() { if (m_newline) { m_stream << m_indent; m_newline = false; } } template TQHtmlStream& output(const T& o) { indent(); if (m_state == PARAM) { m_stream << "=\"" << o << "\""; m_state = m_enclosing_state; return *this; } if (m_state == BLOCK) { m_stream << ">"; m_state = NORMAL_FLOW; } else if (m_state == TAG) { m_stream << "/>"; m_state = NORMAL_FLOW; } m_stream << o; return *this; } public: TQHtmlStream(TQString* buffer) : m_stream(buffer), m_state(NORMAL_FLOW), m_newline(true) {} ~TQHtmlStream() {} void tag(const TQString& name, const TQString& cl, const TQString& id) { finalize_open(); indent(); m_stream << '<' << name; m_state = TAG; if (!cl.isEmpty()) m_stream << " class=\"" << cl << "\""; if (!id.isEmpty()) m_stream << " id=\"" << id << "\""; } void block(const TQString& name, const TQString& cl, const TQString& id) { finalize_open(); indent(); m_stream << '<' << name; m_indent += '\t'; m_blockstack.push_front(name); m_state = BLOCK; if (!cl.isEmpty()) m_stream << " class=\"" << cl << "\""; if (!id.isEmpty()) m_stream << " id=\"" << id << "\""; } void parameter(const TQString& param_name) { if (m_state == NORMAL_FLOW) return; m_stream << " " << param_name; m_enclosing_state = m_state; m_state = PARAM; } void close() { finalize_open(); m_indent.truncate(m_indent.length() - 1); indent(); m_stream << ""; m_blockstack.pop_front(); } void close_all(bool indent) { while( ! m_blockstack.empty() ) { if (indent) (*this) << endl; close(); } } void data() { finalize_open(); } TQHtmlStream & operator<< ( TQChar c ) { return output(c); } TQHtmlStream & operator<< ( char c ) { return output(c); } TQHtmlStream & operator<< ( signed short i ) { return output(i); } TQHtmlStream & operator<< ( unsigned short i ) { return output(i); } TQHtmlStream & operator<< ( signed int i ) { return output(i); } TQHtmlStream & operator<< ( unsigned int i ) { return output(i); } TQHtmlStream & operator<< ( signed long i ) { return output(i); } TQHtmlStream & operator<< ( unsigned long i ) { return output(i); } TQHtmlStream & operator<< ( float f ) { return output(f); } TQHtmlStream & operator<< ( double f ) { return output(f); } TQHtmlStream & operator<< ( const char * s ) { return output(s); } TQHtmlStream & operator<< ( const TQString & s ) { return output(s); } TQHtmlStream & operator<< ( const TQCString & s ) { return output(s); } TQHtmlStream & operator<< ( const TQHtmlStreamManip& op ) { op(*this); return *this; } TQHtmlStream & operator<< (TQTSManip m) { finalize_open(); m_stream << m; return (*this); } TQHtmlStream & operator<< (TQTSFUNC f) { finalize_open(); int old_flags = m_stream.flags(); m_stream << f; if (old_flags == m_stream.flags()) m_newline = true; return (*this); } }; /*************************************************************************************** * Stream manipulators */ class TQHtmlStreamManip0 : public TQHtmlStreamManip { public: typedef void (TQHtmlStream::*Method)(); private: Method m_method; void apply (TQHtmlStream& stream) const { (stream.*m_method)(); } public: TQHtmlStreamManip0(Method m) : m_method(m) {} }; class TQHtmlStreamManip1 : public TQHtmlStreamManip { public: typedef void (TQHtmlStream::*Method)(const TQString& param); private: Method m_method; TQString m_param; void apply(TQHtmlStream& stream) const { (stream.*m_method)(m_param); } public: TQHtmlStreamManip1(Method m, const TQString& param) : m_method(m), m_param(param) {} }; class TQHtmlStreamManip3 : public TQHtmlStreamManip { public: typedef void (TQHtmlStream::*Method)(const TQString& param0, const TQString& param1, const TQString& param2); private: Method m_method; TQString m_param0, m_param1, m_param2; void apply(TQHtmlStream& stream) const { (stream.*m_method)(m_param0, m_param1, m_param2); } public: TQHtmlStreamManip3(Method m, const TQString& param0, const TQString& param1, const TQString& param2) : m_method(m), m_param0(param0), m_param1(param1), m_param2(param2) {} }; class CloseAll : public TQHtmlStreamManip { private: bool m_indent; void apply(TQHtmlStream& stream) const { stream.close_all(m_indent); } public: CloseAll(bool indent) : m_indent(indent) {} }; inline TQHtmlStreamManip3 tag(const TQString& name, const TQString& cl = TQString(), const TQString& id = TQString()) { return TQHtmlStreamManip3(&TQHtmlStream::tag, name, cl, id); } inline TQHtmlStreamManip3 block(const TQString& name, const TQString& cl = TQString(), const TQString& id = TQString()) { return TQHtmlStreamManip3(&TQHtmlStream::block, name, cl, id); } inline TQHtmlStreamManip1 param(const TQString& name) { return TQHtmlStreamManip1(&TQHtmlStream::parameter, name); } inline TQHtmlStreamManip0 close() { return TQHtmlStreamManip0(&TQHtmlStream::close); } inline TQHtmlStreamManip0 data() { return TQHtmlStreamManip0(&TQHtmlStream::data); } inline CloseAll close_all(bool indent = true) { return CloseAll(indent); } #endif