From 6e217760d3d737a4d291f21764a227b3abea8060 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Sun, 11 Jul 2004 21:19:53 +0000 Subject: - Footnote support - Support for super and sub script --- src/rtfformatting.h | 18 +++++- src/tags.h | 5 ++ src/xmlcomposehelpers.cpp | 4 +- src/xmlcomposehelpers.h | 2 +- src/xmlcomposer.cpp | 156 +++++++++++++++++++++++++++++++++++----------- src/xmlcomposer.h | 38 +++++++---- 6 files changed, 168 insertions(+), 55 deletions(-) diff --git a/src/rtfformatting.h b/src/rtfformatting.h index c98881b..6fbcf57 100644 --- a/src/rtfformatting.h +++ b/src/rtfformatting.h @@ -60,7 +60,8 @@ public: m_strike == format.m_italic && m_hidden == format.m_hidden && m_underline == format.m_underline && - m_color == format.m_color; + m_color == format.m_color && + m_suscript == format.m_suscript; } bool paraEquals(RtfFormatting& format) const @@ -78,6 +79,7 @@ public: m_hidden = format.m_hidden; m_underline = format.m_underline; m_color = format.m_color; + m_suscript = format.m_suscript; m_style = format.m_style; m_list = format.m_list; @@ -89,6 +91,7 @@ public: m_bold = m_italic = m_strike = m_underline = m_hidden = false; m_color = -1; + m_suscript = 0; } void resetPara() @@ -109,6 +112,8 @@ public: { return m_hidden; } int textColor() const { return m_color; } + int textSuScript() const + { return m_suscript; } int paraStyle() const { return m_style; } int paraList() const @@ -128,6 +133,8 @@ public: { m_hidden = hidden; } void textSetColor(int color) { m_color = color; } + void textSetSuScript(int suscript) + { m_suscript = suscript; } void paraSetStyle(int style) { m_style = style; } void paraSetList(int list) @@ -135,17 +142,26 @@ public: void paraSetTable(bool inTable) { m_inTbl = inTable; } + enum + { + SUPERSCRIPT = 1, + SUBSCRIPT + }; + protected: bool m_bold; bool m_italic; bool m_strike; bool m_underline; bool m_hidden; + int m_suscript; int m_color; int m_style; int m_list; bool m_inTbl; + + // TODO: Character styles }; diff --git a/src/tags.h b/src/tags.h index d0382cc..33676f7 100644 --- a/src/tags.h +++ b/src/tags.h @@ -65,9 +65,13 @@ static const char* kElI = "i"; static const char* kElStrike = "strike"; static const char* kElU = "u"; static const char* kElColor = "color"; +static const char* kElSuper = "super"; +static const char* kElSub = "sub"; static const char* kElCell = "cell"; static const char* kElRow = "row"; static const char* kElTable = "table"; +static const char* kElFootNote = "footnote"; +static const char* kElRef = "ref"; static const char* kAtList = "list"; static const char* kAtName = "name"; @@ -82,6 +86,7 @@ static const char* kAtOrdered = "ordered"; static const char* kAtStart = "start"; static const char* kAtId = "id"; static const char* kAtIndex = "id"; +static const char* kAtFootNote = "footnote"; static const wchar_t* kValDisc = L"disc"; static const wchar_t* kValLowerAlpha = L"lower-alpha"; diff --git a/src/xmlcomposehelpers.cpp b/src/xmlcomposehelpers.cpp index 1bea55f..a1bc73f 100644 --- a/src/xmlcomposehelpers.cpp +++ b/src/xmlcomposehelpers.cpp @@ -92,11 +92,11 @@ void Level::setElement(DOM::Element element, bool deep) m_element = element; } -AnalyserPtr Level::getAnalyser() +AnalyserPtr Level::getAnalyser(bool deep) { if(m_analyser) return m_analyser; - else if(m_previous) + else if(deep && m_previous) return m_previous->getAnalyser(); else return NULL; diff --git a/src/xmlcomposehelpers.h b/src/xmlcomposehelpers.h index b901039..8d7e515 100644 --- a/src/xmlcomposehelpers.h +++ b/src/xmlcomposehelpers.h @@ -101,7 +101,7 @@ public: DOM::Element getElement(); void setElement(DOM::Element element, bool deep = false); - AnalyserPtr getAnalyser(); + AnalyserPtr getAnalyser(bool deep = true); void setAnalyser(AnalyserPtr analyser, bool deep = false); DestinationPtr getDestination(); void setDestination(DestinationPtr destination, bool deep = false); diff --git a/src/xmlcomposer.cpp b/src/xmlcomposer.cpp index 9be1eeb..11ed2a0 100644 --- a/src/xmlcomposer.cpp +++ b/src/xmlcomposer.cpp @@ -50,6 +50,9 @@ RtfParser::RtfParser(const RtfParserOptions& options) { m_document = NULL; memcpy(&m_options, &options, sizeof(options)); + + for(int i = 0; i < AUTOCOUNT_MAX; i++) + m_autocount[i] = 1; } RtfParser::~RtfParser() @@ -165,6 +168,14 @@ void RtfParser::setAttribute(const string& name, const wstring& value, DOM::Elem el.setAttribute(name, value); } +void RtfParser::setAttribute(const string& name, int value, DOM::Element el) +{ + ASSERT(name.length() > 0); + if(el == NULL) + el = getElement(); + el.setAttribute(name, formatInt(value)); +} + void RtfParser::setDestination(DestinationPtr dest) { ASSERT(m_curLevel); @@ -215,6 +226,17 @@ RtfFormatting& RtfParser::getTextFormatting() return m_curLevel->getFormatting(); } +int RtfParser::getAutoCount(int type) +{ + ASSERT(type < AUTOCOUNT_MAX); + return m_autocount[type]; +} + +void RtfParser::incrementAutoCount(int type) +{ + ASSERT(type < AUTOCOUNT_MAX); + m_autocount[type]++; +} // --------------------------------------------------------------------------------- // Pass this stuff on through to the appropriate analysers etc... @@ -256,8 +278,21 @@ void RtfParser::groupStart() void RtfParser::groupEnd() { ASSERT(m_curLevel != NULL); - AnalyserPtr analyser = m_curLevel->getAnalyser(); - if(analyser) + bool done = true; + + // First see if this level has an ananlyser + AnalyserPtr analyser = m_curLevel->getAnalyser(false); + if(!analyser) + { + // If not then the analyser is going to live and we + // get one from a previous level + done = false; + analyser = m_curLevel->getAnalyser(); + } + + if(done) + analyser->done(); + else analyser->groupEnd(); LevelHandler::groupEnd(); @@ -416,7 +451,7 @@ bool RtfParser::ParseAnalyser::processTextContent(const string& cw, int flags, i if(el != NULL) { // This ensures that our content destination is open and ready - DestinationPtr dest = m_parser->getDestination(); + DestinationPtr dest = m_parser->getDestination(); ASSERT(dest != NULL); dest->charData(kValNull); @@ -453,6 +488,10 @@ bool RtfParser::ParseAnalyser::processTextFormatting(const string& cw, int flags format.textSetUnderline(on); else if(cw == "cf" && HAS_PARAM) format.textSetColor(param); + else if(cw == "super") + format.textSetSuScript(RtfFormatting::SUPERSCRIPT); + else if(cw == "sub") + format.textSetSuScript(RtfFormatting::SUBSCRIPT); else return false; @@ -464,6 +503,26 @@ bool RtfParser::ParseAnalyser::processTextFormatting(const string& cw, int flags return processTextFormatting(cw, flags, param, m_parser->getTextFormatting()); } +bool RtfParser::ParseAnalyser::processTextAutoContent(const string& cw, int flags, int param) +{ + DestinationPtr dest = m_parser->getDestination(); + ASSERT(dest != NULL); + dest->charData(kValNull); + + // Auto generated content + if(cw == "chftn") + { + int ac = m_parser->getAutoCount(AUTOCOUNT_FOOTNOTE); + + AN_ELEMENT(kElRef); + AN_ATTRIBUTE(kAtFootNote, ac); + dest->charData(formatInt(ac)); + AN_POP_ELEMENT(); + return true; + } + + return false; +} ON_INITIALIZE(Skip) { AN_DESTINATION(Null); } @@ -770,6 +829,8 @@ ON_CONTROLWORD(Root) AN_ANALYSER(Skip); else if(cw == "colortbl") AN_ANALYSER(Skip); + else if(cw == "footnote") + AN_ANALYSER(FootNote); else if(cw == "pict") { AN_ANALYSER(Skip); @@ -779,6 +840,8 @@ ON_CONTROLWORD(Root) AN_ANALYSER(Skip); else if(processTextContent(cw, flags, param)) DUMMY; + else if(processTextAutoContent(cw, flags, param)) + DUMMY; else if(processTextFormatting(cw, flags, param)) DUMMY; else @@ -845,6 +908,16 @@ ON_CHARDATA(Content) AN_ATTRIBUTE(kAtIndex, NUM_ATTR(format.textColor())); elements++; } + if(format.textSuScript() == RtfFormatting::SUPERSCRIPT) + { + AN_ELEMENT(kElSuper); + elements++; + } + if(format.textSuScript() == RtfFormatting::SUBSCRIPT) + { + AN_ELEMENT(kElSub); + elements++; + } // Write the data to the element m_parser->getElement().appendChild( @@ -855,47 +928,54 @@ ON_CHARDATA(Content) AN_POP_ELEMENT(); } -#if 0 -ON_INITIALIZE(Table) -{ - stack = 0; - level = m_parser->getLevel(); - AN_ELEMENT(kElTable); - AN_DESTINATION(Content); -} -ON_CONTROLWORD(Table) +ON_INITIALIZE(FootNote) { - ASSERT(stack >= 0); - ASSERT(level != NULL); - - if(cw == "trowd") - { - stack++; - } - else if(cw == "row") - { - stack--; - if(stack <= 0) - m_parser->rewindLevel(level); - } - - else if(processTextContent(cw, flags, param)) - DUMMY; - else if(processTextFormatting(cw, flags, param)) - DUMMY; - else - DEFAULT_CONTROLWORD; - - if(!m_parser->getTextFormatting().paraInTable()) - { - m_parser->rewindLevel(level); - } + int ac = m_parser->getAutoCount(AUTOCOUNT_FOOTNOTE); + AN_ELEMENT(kElFootNote); + AN_ATTRIBUTE(kAtId, ac); + AN_DESTINATION(Content); +} +ON_CONTROLWORD(FootNote) +{ + // Inside foot notes there's no link to the foot note + if(cw == "chftn") + { + DestinationPtr dest = m_parser->getDestination(); + ASSERT(dest != NULL); + int ac = m_parser->getAutoCount(AUTOCOUNT_FOOTNOTE); + dest->charData(formatInt(ac)); + return; + } + + // Process text content in the foot note + else if(processTextContent(cw, flags, param)) + DUMMY; + else if(processTextAutoContent(cw, flags, param)) + DUMMY; + else if(processTextFormatting(cw, flags, param)) + DUMMY; + else + DEFAULT_CONTROLWORD; +} +ON_DONE(FootNote) +{ + m_parser->incrementAutoCount(AUTOCOUNT_FOOTNOTE); } -#endif +// TODO: Remove these (for debugging) +ON_GROUPSTART(FootNote) +{ + int ac = m_parser->getAutoCount(AUTOCOUNT_FOOTNOTE); + fprintf(stderr, "%d start\n", ac); +} +ON_GROUPEND(FootNote) +{ + int ac = m_parser->getAutoCount(AUTOCOUNT_FOOTNOTE); + fprintf(stderr, "%d end\n", ac); +} ON_CHARDATA(Raw) diff --git a/src/xmlcomposer.h b/src/xmlcomposer.h index fd9fd7a..fc40496 100644 --- a/src/xmlcomposer.h +++ b/src/xmlcomposer.h @@ -68,12 +68,24 @@ public: 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(); @@ -92,9 +104,11 @@ protected: // Data protected: - DOM::DOMImplementation m_impl; - DOM::Document m_document; - RtfParserOptions m_options; + 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 @@ -149,6 +163,7 @@ protected: 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); @@ -160,16 +175,6 @@ protected: GROUPSTART END_ANALYSER -#if 0 - ANALYSER(Table) - INITIALIZE - CONTROLWORD - DATA_PORTION - int stack; - LevelPtr level; - END_ANALYSER -#endif - ANALYSER(Upr) Upr(AnalyserPtr prv); GROUPSTART @@ -226,6 +231,13 @@ protected: CONTROLWORD END_ANALYSER + ANALYSER(FootNote) + INITIALIZE + CONTROLWORD + GROUPSTART + GROUPEND + DONE + END_ANALYSER }; #endif // __RTFPARSER_H__ -- cgit v1.2.3