/* * Copyright (c) 2004, Nate Nielsen * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the * above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or * other materials provided with the distribution. * * The names of contributors to this software may not be * used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * * CONTRIBUTORS * Nate Nielsen * */ #ifndef __RTFPARSER_H__ #define __RTFPARSER_H__ #include "levelhandler.h" struct RtfParserOptions { RtfParserOptions() { memset(this, 0, sizeof(*this)); } bool doColors; }; class RtfParser : public LevelHandler { public: RtfParser(const RtfParserOptions& options); virtual ~RtfParser(); virtual void startDocument(RtfReader* reader); virtual void endDocument(); virtual void controlWord(const string& cw, int flags, int param); virtual void groupStart(); virtual void groupEnd(); virtual void charData(wstring data); // Element management functions DOM::Element createElement(const string& name); void pushElement(const DOM::Element& element); void replaceElement(const DOM::Element& element); DOM::Element popElement(); void setAttribute(const string& name, const wstring& value, DOM::Element el = DOM::Element()); void setAttribute(const string& name, int value, DOM::Element el = DOM::Element()); // Changing the current parser functions void setAnalyser(AnalyserPtr analy); void setDestination(DestinationPtr dest); DestinationPtr replaceDestination(DestinationPtr dest); // The types of auto counters enum { AUTOCOUNT_FOOTNOTE, AUTOCOUNT_MAX }; // Functions for auto numbering int getAutoCount(int type); void incrementAutoCount(int type); // Current status functions RtfFormatting& getTextFormatting(); AnalyserPtr getAnalyser(); DestinationPtr getDestination(); DOM::Document getDocument() { return m_document; } const RtfParserOptions& getOptions() { return m_options; } static wstring formatInt(int num); protected: virtual void clear(); // Data protected: DOM::DOMImplementation m_impl; // For creating the document DOM::Document m_document; // The current document RtfParserOptions m_options; // Configurable options for parsing int m_autocount[AUTOCOUNT_MAX]; // Auto counters for the document // Sub classes protected: #define DESTINATION(cls) class cls : public Destination { public: #define END_DESTINATION }; #define ANALYSER(cls) class cls : public ParseAnalyser { public: #define END_ANALYSER }; #define DATA_PORTION protected: #define INITIALIZE virtual void initialize(); #define CHARDATA virtual void charData(wstring data); #define CONTROLWORD virtual void controlWord(const string& cw, int flags, int param); #define GROUPSTART virtual void groupStart(); #define GROUPEND virtual void groupEnd(); #define DONE virtual void done(); DESTINATION(Content) INITIALIZE CHARDATA DATA_PORTION bool created; DOM::Element parent; END_DESTINATION DESTINATION(Null) END_DESTINATION DESTINATION(Raw) CHARDATA END_DESTINATION DESTINATION(Attribute) Attribute(const string& nm) : name(nm) {} INITIALIZE CHARDATA DATA_PORTION string name; DOM::Element element; END_DESTINATION class ParseAnalyser : public Analyser { public: virtual void controlWord(const string& cw, int flags, int param) { processDefault(cw, flags, param); } protected: // Some helper functions bool processDefault(const string& cw, int flags, int param); bool processTextFormatting(const string& cw, int flags, int param, RtfFormatting& format); bool processTextContent(const string& cw, int flags, int param); bool processTextFormatting(const string& cw, int flags, int param); bool processTextAutoContent(const string& cw, int flags, int param); DOM::Element getCurrentBlock(); void applyParaFormatting(RtfFormatting* format, DOM::Element& el); }; ANALYSER(Skip) INITIALIZE GROUPSTART END_ANALYSER ANALYSER(Upr) Upr(AnalyserPtr prv); GROUPSTART GROUPEND DATA_PORTION AnalyserPtr prev; END_ANALYSER ANALYSER(Stylesheet) INITIALIZE GROUPSTART END_ANALYSER ANALYSER(Style) INITIALIZE CONTROLWORD GROUPSTART GROUPEND DATA_PORTION bool haveStyle; END_ANALYSER ANALYSER(ListTable) INITIALIZE GROUPSTART END_ANALYSER ANALYSER(List) INITIALIZE CONTROLWORD GROUPSTART DATA_PORTION int levelsSeen; END_ANALYSER ANALYSER(ListOverrideTable) INITIALIZE CONTROLWORD GROUPSTART GROUPEND DATA_PORTION DOM::NodeList lists; int lsId; DOM::Element curList; END_ANALYSER ANALYSER(Info) INITIALIZE CONTROLWORD END_ANALYSER ANALYSER(Root) INITIALIZE CONTROLWORD END_ANALYSER ANALYSER(FootNote) INITIALIZE CONTROLWORD GROUPSTART GROUPEND DONE END_ANALYSER }; #endif // __RTFPARSER_H__