From ae28df20927567f2d62b575ed4aef2d127569265 Mon Sep 17 00:00:00 2001 From: Stef Date: Thu, 22 Jul 2004 22:30:48 +0000 Subject: - Comments and formatting changes. --- src/xmlcomposer.cpp | 475 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 289 insertions(+), 186 deletions(-) (limited to 'src/xmlcomposer.cpp') diff --git a/src/xmlcomposer.cpp b/src/xmlcomposer.cpp index 7e74f70..6072375 100644 --- a/src/xmlcomposer.cpp +++ b/src/xmlcomposer.cpp @@ -42,20 +42,21 @@ #include "domhelpers.h" #include "tags.h" -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// +/* ---------------------------------------------------------------------------------- + * CONSTRUCTION + */ -RtfParser::RtfParser(const RtfParserOptions& options) +XmlComposer::XmlComposer(const RtfParserOptions& options) { m_document = NULL; memcpy(&m_options, &options, sizeof(options)); + // All autocounters start at 1 for(int i = 0; i < AUTOCOUNT_MAX; i++) m_autocount[i] = 1; } -RtfParser::~RtfParser() +XmlComposer::~XmlComposer() { clear(); @@ -63,7 +64,7 @@ RtfParser::~RtfParser() m_impl.release(); } -void RtfParser::clear() +void XmlComposer::clear() { if(m_document != NULL) { @@ -78,9 +79,15 @@ void RtfParser::clear() LevelHandler::clear(); } -void RtfParser::startDocument(RtfReader* reader) + +/* ---------------------------------------------------------------------------------- + * HANDLER OVERRIDES + */ + +void XmlComposer::startDocument(RtfReader* reader) { LevelHandler::startDocument(reader); + ASSERT(m_curLevel != NULL); // Create a new document m_document = m_impl.createDocument("", kElDoc, DOM::DocumentType()); @@ -88,7 +95,7 @@ void RtfParser::startDocument(RtfReader* reader) // TODO: Throw error if document is null ASSERT(m_document != NULL); - ASSERT(m_curLevel != NULL); + // Hook up the top level element m_curLevel->setElement(m_document.getDocumentElement(), true); // Set the attributes on the top level @@ -98,59 +105,106 @@ void RtfParser::startDocument(RtfReader* reader) getTextFormatting().resetText(); } -void RtfParser::endDocument() +void XmlComposer::endDocument() { LevelHandler::endDocument(); - // Cleanup the tree + // Pass 0: Cleanup the tree RtfFixups::removeDuplicates(m_document); RtfFixups::consolidateStartTags(m_document); RtfFixups::consolidateEndTags(m_document); + + // Pass 1: Block breakout RtfFixups::breakTables(m_document); RtfFixups::breakTags(m_document, kElTable, kElRow); RtfFixups::breakTags(m_document, kElRow, kElCell); RtfFixups::wrapTags(m_document, kElCell, kElDest); RtfFixups::breakBlocks(m_document); RtfFixups::breakLists(m_document); + + // Pass 2: Fixups RtfFixups::fixLists(m_document); RtfFixups::fixStyles(m_document); RtfFixups::fixBlocks(m_document); RtfFixups::removeTags(m_document); RtfFixups::breakBreak(m_document, kElDoc, kElPage); RtfFixups::breakBreak(m_document, kElDoc, kElSect); + + // Pass 3: Final cleanup RtfFixups::removeDuplicates(m_document); return; } +void XmlComposer::charData(wstring data) +{ + ASSERT(m_curLevel != NULL); + DestinationPtr destination = m_curLevel->getDestination(); + if(destination) + { + destination->charData(data); + } + else + { + // TODO: Change this so it sends char data to new destination + // We should always have a destination + destination = DestinationPtr(new Content); + setDestination(destination); + } +} +void XmlComposer::controlWord(const string& cw, int flags, int param) +{ + ASSERT(m_curLevel != NULL); + AnalyserPtr analyser = m_curLevel->getAnalyser(); + if(analyser) + analyser->controlWord(cw, flags, param); +} +void XmlComposer::groupStart() +{ + LevelHandler::groupStart(); + ASSERT(m_curLevel != NULL); + AnalyserPtr analyser = m_curLevel->getAnalyser(); + if(analyser) + analyser->groupStart(); +} -// ----------------------------------------------------------------------- -// Helper functions +void XmlComposer::groupEnd() +{ + LevelHandler::groupEnd(); + + ASSERT(m_curLevel != NULL); + AnalyserPtr analyser = m_curLevel->getAnalyser(); + if(analyser) + analyser->groupEnd(); +} + + +/* ---------------------------------------------------------------------------------- + * HELPER FUNCTIONS + */ -DOM::Element RtfParser::createElement(const string& name) +DOM::Element XmlComposer::createElement(const string& name) { ASSERT(name.length() > 0); return m_document.createElement(name); - - // TODO: Throw exception here if necessary } -void RtfParser::replaceElement(const DOM::Element& element) +void XmlComposer::replaceElement(const DOM::Element& element) { ASSERT(m_curLevel != NULL); m_curLevel->setElement(element, true); } -void RtfParser::pushElement(const DOM::Element& element) +void XmlComposer::pushElement(const DOM::Element& element) { ASSERT(m_curLevel != NULL); getElement().appendChild(element); m_curLevel->setElement(element); } -DOM::Element RtfParser::popElement() +DOM::Element XmlComposer::popElement() { DOM::Element element = getElement(); ASSERT(m_curLevel != NULL); @@ -163,7 +217,7 @@ DOM::Element RtfParser::popElement() return element; } -void RtfParser::setAttribute(const string& name, const wstring& value, DOM::Element el) +void XmlComposer::setAttribute(const string& name, const wstring& value, DOM::Element el) { ASSERT(name.length() > 0); if(el == NULL) @@ -171,7 +225,7 @@ 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) +void XmlComposer::setAttribute(const string& name, int value, DOM::Element el) { ASSERT(name.length() > 0); if(el == NULL) @@ -179,153 +233,116 @@ void RtfParser::setAttribute(const string& name, int value, DOM::Element el) el.setAttribute(name, formatInt(value)); } -void RtfParser::setDestination(DestinationPtr dest) +void XmlComposer::setDestination(DestinationPtr dest) { ASSERT(m_curLevel); m_curLevel->setDestination(dest); - dest->m_parser = this; + dest->m_composer = this; dest->initialize(); } -DestinationPtr RtfParser::replaceDestination(DestinationPtr dest) +DestinationPtr XmlComposer::replaceDestination(DestinationPtr dest) { ASSERT(m_curLevel); DestinationPtr old = m_curLevel->getDestination(); m_curLevel->setDestination(dest, true); - dest->m_parser = this; + dest->m_composer = this; dest->initialize(); return old; } -void RtfParser::setAnalyser(AnalyserPtr analy) +void XmlComposer::setAnalyser(AnalyserPtr analy) { ASSERT(m_curLevel); ASSERT(analy != NULL); - analy->m_parser = this; + analy->m_composer = this; m_curLevel->setAnalyser(analy); analy->initialize(); } -AnalyserPtr RtfParser::getAnalyser() +AnalyserPtr XmlComposer::getAnalyser() { ASSERT(m_curLevel); return m_curLevel->getAnalyser(); } -DestinationPtr RtfParser::getDestination() +DestinationPtr XmlComposer::getDestination() { ASSERT(m_curLevel); return m_curLevel->getDestination(); } -RtfFormatting& RtfParser::getTextFormatting() +RtfFormatting& XmlComposer::getTextFormatting() { ASSERT(m_curLevel); return m_curLevel->getFormatting(); } -int RtfParser::getAutoCount(int type) +int XmlComposer::getAutoCount(int type) { ASSERT(type < AUTOCOUNT_MAX); return m_autocount[type]; } -void RtfParser::incrementAutoCount(int type) +void XmlComposer::incrementAutoCount(int type) { ASSERT(type < AUTOCOUNT_MAX); m_autocount[type]++; } -// --------------------------------------------------------------------------------- -// Pass this stuff on through to the appropriate analysers etc... - -void RtfParser::charData(wstring data) +wstring XmlComposer::formatInt(int num) { - ASSERT(m_curLevel != NULL); - DestinationPtr destination = m_curLevel->getDestination(); - if(destination) - { - destination->charData(data); - } - else - { - destination = DestinationPtr(new Content); - setDestination(destination); - } - -} + char buff[16]; -void RtfParser::controlWord(const string& cw, int flags, int param) -{ - ASSERT(m_curLevel != NULL); - AnalyserPtr analyser = m_curLevel->getAnalyser(); - if(analyser) - analyser->controlWord(cw, flags, param); -} + // Certain OSs don't support swprintf :( + sprintf(buff, "%d", num); -void RtfParser::groupStart() -{ - LevelHandler::groupStart(); + wstring n; + for(char* s = buff; *s; s++) + n.append(1, *s); - ASSERT(m_curLevel != NULL); - AnalyserPtr analyser = m_curLevel->getAnalyser(); - if(analyser) - analyser->groupStart(); + return n; } -void RtfParser::groupEnd() -{ - ASSERT(m_curLevel != NULL); - bool done = true; - LevelHandler::groupEnd(); - - AnalyserPtr analyser = m_curLevel->getAnalyser(); - if(analyser) - analyser->groupEnd(); -} +/* ---------------------------------------------------------------------------------- + * CONVENIENCE MACROS USED BELOW + */ -#define ON_INITIALIZE(cls) \ - void RtfParser::cls::initialize() -#define ON_CONTROLWORD(cls) \ - void RtfParser::cls::controlWord(const string& cw, int flags, int param) -#define ON_CHARDATA(cls) \ - void RtfParser::cls::charData(wstring data) -#define ON_GROUPSTART(cls) \ - void RtfParser::cls::groupStart() -#define ON_GROUPEND(cls) \ - void RtfParser::cls::groupEnd() -#define ON_DONE(cls) \ - void RtfParser::cls::done() #define AN_ELEMENT(name) \ - m_parser->pushElement(m_parser->createElement(name)) + m_composer->pushElement(m_composer->createElement(name)) #define AN_POP_ELEMENT() \ - m_parser->popElement() + m_composer->popElement() #define AN_ATTRIBUTE(name, value) \ - m_parser->setAttribute(name, value) + m_composer->setAttribute(name, value) #define AN_DESTINATION_ATTR(name) \ - m_parser->setDestination(new Attribute(name)) + m_composer->setDestination(new Attribute(name)) #define AN_DESTINATION(cls) \ - m_parser->setDestination(new cls) + m_composer->setDestination(new cls) #define AN_ANALYSER(cls) \ - m_parser->setAnalyser(AnalyserPtr(new cls)) + m_composer->setAnalyser(AnalyserPtr(new cls)) #define AN_SET_ANALYSER(cls) \ - m_parser->setAnalyser(AnalyserPtr(cls)) + m_composer->setAnalyser(AnalyserPtr(cls)) #define HAS_PARAM (flags & kHasParam) #define DEFAULT_CONTROLWORD processDefault(cw, flags, param) -#define DUMMY 1 == 1 -#define NUM_ATTR(n) m_parser->formatInt(n) +#define DUMMY 1 == 1 + + +/* ---------------------------------------------------------------------------------- + * BASE ANALYSER + */ -bool RtfParser::ParseAnalyser::processDefault(const string& cw, int flags, int param) +bool XmlComposer::BaseAnalyser::processDefault(const string& cw, int flags, int param) { + // Unicode blocks go to a special analyser if(cw == "upr") { - AnalyserPtr analy = m_parser->getAnalyser(); + AnalyserPtr analy = m_composer->getAnalyser(); ASSERT(analy != NULL); AN_SET_ANALYSER(new Upr(analy)); return true; @@ -334,41 +351,41 @@ bool RtfParser::ParseAnalyser::processDefault(const string& cw, int flags, int p return false; } -void RtfParser::ParseAnalyser::applyParaFormatting(RtfFormatting* format, - DOM::Element& el) +void XmlComposer::BaseAnalyser::applyParaFormatting(RtfFormatting* format, + DOM::Element& el) { if(format == NULL) - format = &(m_parser->getTextFormatting()); + format = &(m_composer->getTextFormatting()); wstring fix = kValPara; + // Is it a list? int list = format->paraList(); if(list != -1) - { - el.setAttribute(kAtList, NUM_ATTR(list)); - } + el.setAttribute(kAtList, list); else - { el.removeAttribute(kAtList); - } + // Is it a cell? if(format->paraInTable()) el.setAttribute(kAtCell, L"1"); else el.removeAttribute(kAtCell); + // Paragraph styles int style = format->paraStyle(); if(style != -1) - el.setAttribute(kElStyle, NUM_ATTR(style)); + el.setAttribute(kElStyle, style); else el.removeAttribute(kElStyle); + // These fix elements are later picked up in XmlFixups::fixBlocks el.setAttribute(kAtFix, fix); } -DOM::Element RtfParser::ParseAnalyser::getCurrentBlock() +DOM::Element XmlComposer::BaseAnalyser::getCurrentBlock() { - DOM::Node node = m_parser->getElement(); + DOM::Node node = m_composer->getElement(); if(node.hasChildNodes()) node = node.getLastChild(); @@ -377,97 +394,115 @@ DOM::Element RtfParser::ParseAnalyser::getCurrentBlock() } -bool RtfParser::ParseAnalyser::processTextContent(const string& cw, int flags, int param) +bool XmlComposer::BaseAnalyser::processTextContent(const string& cw, int flags, int param) { DOM::Element el; bool process = false; - RtfFormatting& format = m_parser->getTextFormatting(); + RtfFormatting& format = m_composer->getTextFormatting(); + // New paragraph if(cw == "par") { el = getCurrentBlock(); if(el != NULL) applyParaFormatting(&format, el); - el = m_parser->createElement(kElBlock); + el = m_composer->createElement(kElBlock); applyParaFormatting(&format, el); } + // Cells (used later in applyParaFormatting) else if(cw == "intbl") format.paraSetTable(true); + // Start of a cell else if(cw == "cell") { el = getCurrentBlock(); if(el != NULL) applyParaFormatting(&format, el); - el = m_parser->createElement(kElCell); - m_parser->pushElement(el); - m_parser->popElement(); - el = m_parser->createElement(kElBlock); + el = m_composer->createElement(kElCell); + m_composer->pushElement(el); + m_composer->popElement(); + el = m_composer->createElement(kElBlock); applyParaFormatting(&format, el); } + // Start of a row else if(cw == "trowd") - el = m_parser->createElement(kElRow); + el = m_composer->createElement(kElRow); + // A tab else if(cw == "tab") - el = m_parser->createElement(kElTab); + el = m_composer->createElement(kElTab); + // A section break else if(cw == "sect") - el = m_parser->createElement(kElSect); + el = m_composer->createElement(kElSect); + // A page break else if(cw == "page") - el = m_parser->createElement(kElPage); + el = m_composer->createElement(kElPage); + // A paragraph style else if(cw == "s" && HAS_PARAM) format.paraSetStyle(param); + // A line break else if(cw == "line") - el = m_parser->createElement(kElLine); + el = m_composer->createElement(kElLine); + // A page header (not implemented) else if(cw == "header") AN_ANALYSER(Skip); + + // A page footer (not implemented) else if(cw == "footer") AN_ANALYSER(Skip); + + // A bookmark (not implemented) else if(cw == "bkmkstart") AN_ANALYSER(Skip); + + // List text (not implemented) else if(cw == "listtext") AN_ANALYSER(Skip); + // Set list style (used in applyFormatting) else if(cw == "ls" && HAS_PARAM) format.paraSetList(param); if(el != NULL) { // This ensures that our content destination is open and ready - DestinationPtr dest = m_parser->getDestination(); + DestinationPtr dest = m_composer->getDestination(); ASSERT(dest != NULL); dest->charData(kValNull); - m_parser->pushElement(el); - m_parser->popElement(); + m_composer->pushElement(el); + m_composer->popElement(); } return (el != NULL) || process; - - /* TODO: cell, row, intbl, cellx, trowd*/ } -bool RtfParser::ParseAnalyser::processTextFormatting(const string& cw, int flags, +bool XmlComposer::BaseAnalyser::processTextFormatting(const string& cw, int flags, int param, RtfFormatting& format) { bool on = true; if(flags & HAS_PARAM && param == 0) on = false; + // Clears all paragraph formatting if(cw == "pard") { format.resetPara(); -// applyParaFormatting(); + // applyParaFormatting(); } + + // Rest are pretty much self-explanatory else if(cw == "plain") format.resetText(); else if(cw == "b") @@ -490,21 +525,22 @@ bool RtfParser::ParseAnalyser::processTextFormatting(const string& cw, int flags return true; } -bool RtfParser::ParseAnalyser::processTextFormatting(const string& cw, int flags, int param) +bool XmlComposer::BaseAnalyser::processTextFormatting(const string& cw, int flags, int param) { - return processTextFormatting(cw, flags, param, m_parser->getTextFormatting()); + return processTextFormatting(cw, flags, param, m_composer->getTextFormatting()); } -bool RtfParser::ParseAnalyser::processTextAutoContent(const string& cw, int flags, int param) +bool XmlComposer::BaseAnalyser::processTextAutoContent(const string& cw, int flags, int param) { - DestinationPtr dest = m_parser->getDestination(); + DestinationPtr dest = m_composer->getDestination(); ASSERT(dest != NULL); dest->charData(kValNull); // Auto generated content if(cw == "chftn") { - int ac = m_parser->getAutoCount(AUTOCOUNT_FOOTNOTE); + // Footnote auto numbering + int ac = m_composer->getAutoCount(AUTOCOUNT_FOOTNOTE); AN_ELEMENT(kElRef); AN_ATTRIBUTE(kAtType, kValFootNote); @@ -517,38 +553,72 @@ bool RtfParser::ParseAnalyser::processTextAutoContent(const string& cw, int flag return false; } +/* ---------------------------------------------------------------------------------- + * ANALYSER/DESTINATION DEFINITIONS + */ + +#define ON_INITIALIZE(cls) \ + void XmlComposer::cls::initialize() +#define ON_CONTROLWORD(cls) \ + void XmlComposer::cls::controlWord(const string& cw, int flags, int param) +#define ON_CHARDATA(cls) \ + void XmlComposer::cls::charData(wstring data) +#define ON_GROUPSTART(cls) \ + void XmlComposer::cls::groupStart() +#define ON_GROUPEND(cls) \ + void XmlComposer::cls::groupEnd() +#define ON_DONE(cls) \ + void XmlComposer::cls::done() + + +// Skip Analyser -------------------------------------------------------------------- + ON_INITIALIZE(Skip) { AN_DESTINATION(Null); } + ON_GROUPSTART(Skip) { AN_ANALYSER(Skip); } -RtfParser::Upr::Upr(AnalyserPtr prv) +// Upr Analyser --------------------------------------------------------------------- + +XmlComposer::Upr::Upr(AnalyserPtr prv) { ASSERT(prv); prev = prv; } + ON_GROUPSTART(Upr) - { AN_ANALYSER(Skip); } +{ + AN_ANALYSER(Skip); +} + ON_GROUPEND(Upr) { ASSERT(prev); - m_parser->setAnalyser(prev); + m_composer->setAnalyser(prev); prev = NULL; } +// Stylesheet Analyser -------------------------------------------------------------- + ON_INITIALIZE(Stylesheet) { AN_ELEMENT(kElStylesheet); } + ON_GROUPSTART(Stylesheet) { + // Each group should be a style AN_ANALYSER(Style); + + // Without any character data AN_DESTINATION(Null); } +// Stylesheet Style Analyser -------------------------------------------------------- ON_INITIALIZE(Style) { @@ -556,6 +626,7 @@ ON_INITIALIZE(Style) // so we can't always create haveStyle = false; } + ON_CONTROLWORD(Style) { // Get the style id @@ -565,6 +636,7 @@ ON_CONTROLWORD(Style) return; } + // Create the style tag if necessary if(!haveStyle) { AN_ELEMENT(kElStyle); @@ -572,9 +644,10 @@ ON_CONTROLWORD(Style) haveStyle = true; } + // The style id if(cw == "s" && flags & kHasParam) { - AN_ATTRIBUTE(kAtId, NUM_ATTR(param)); + AN_ATTRIBUTE(kAtId, param); } // Otherwise get as much formatting out of the tag as possible @@ -584,13 +657,17 @@ ON_CONTROLWORD(Style) else DEFAULT_CONTROLWORD; } + ON_GROUPSTART(Style) { AN_ANALYSER(Skip); } + ON_GROUPEND(Style) { - RtfFormatting& props = m_parser->getTextFormatting(); + RtfFormatting& props = m_composer->getTextFormatting(); + + // Dig out all the formatting attributes if(props.textIsBold()) AN_ATTRIBUTE(kAtBold, L"1"); if(props.textIsHidden()) @@ -601,42 +678,54 @@ ON_GROUPEND(Style) AN_ATTRIBUTE(kAtStrike, L"1"); if(props.textIsUnderline()) AN_ATTRIBUTE(kAtUnderline, L"1"); - if(props.textColor() != -1 && m_parser->getOptions().doColors) - AN_ATTRIBUTE(kAtColor, NUM_ATTR(props.textColor())); + if(props.textColor() != -1 && m_composer->getOptions().doColors) + AN_ATTRIBUTE(kAtColor, props.textColor()); } +// List Table Analyser -------------------------------------------------------------- ON_INITIALIZE(ListTable) { AN_ELEMENT(kElListtable); } + ON_GROUPSTART(ListTable) { + // Everything in here should be a list AN_ANALYSER(List); + + // Content doesn't matter AN_DESTINATION(Null); } +// List (in List Table) Analyser ---------------------------------------------------- ON_INITIALIZE(List) { - AN_ELEMENT(kElListdef); + // Create a default element + AN_ELEMENT(kElListdef); AN_ATTRIBUTE(kAtType, kValDisc); AN_ATTRIBUTE(kAtOrdered, L"0"); levelsSeen = 0; } + ON_CONTROLWORD(List) { + // The name if(cw == "listname") AN_DESTINATION_ATTR(kAtName); + + // The list id else if(cw == "listid" && HAS_PARAM) - AN_ATTRIBUTE(kAtId, NUM_ATTR(param)); + AN_ATTRIBUTE(kAtId, param); // We let listlevel in here too else if(cw == "levelstartat" && HAS_PARAM) - AN_ATTRIBUTE(kAtStart, NUM_ATTR(param)); + AN_ATTRIBUTE(kAtStart, param); + // The list type else if(cw == "levelnfc" && HAS_PARAM) { switch(param) @@ -679,27 +768,35 @@ ON_CONTROLWORD(List) else DEFAULT_CONTROLWORD; } + ON_GROUPSTART(List) { + // Skip internal groups and content + if(levelsSeen > 0) AN_ANALYSER(Skip); + levelsSeen++; } - +// The List Override Table ---------------------------------------------------------- ON_INITIALIZE(ListOverrideTable) { - DOM::Document document = m_parser->getDocument(); + // Get all of the current lists + DOM::Document document = m_composer->getDocument(); lists = document.getElementsByTagName(kElListdef); curList = NULL; lsId = -1; } + ON_GROUPSTART(ListOverrideTable) { + // Content doesn't matter AN_DESTINATION(Null); } + ON_CONTROLWORD(ListOverrideTable) { // New list override clear @@ -709,10 +806,11 @@ ON_CONTROLWORD(ListOverrideTable) // List id for current listoverride else if(cw == "listid" && HAS_PARAM) { - wstring id = NUM_ATTR(param); + wstring id = XmlComposer::formatInt(param); if(lists != NULL) { + // Find the list in question for(int i = 0; i < lists->getLength(); i++) { DOM::Node node = lists->item(i); @@ -737,7 +835,7 @@ ON_CONTROLWORD(ListOverrideTable) else if(cw == "levelstartat" && HAS_PARAM) { if(curList != NULL) - curList.setAttribute(kAtStart, NUM_ATTR(param)); + curList.setAttribute(kAtStart, param); } else @@ -755,7 +853,7 @@ ON_CONTROLWORD(ListOverrideTable) if(curList != NULL) { parent.appendChild(curList); - curList.setAttribute(kAtList, NUM_ATTR(lsId)); + curList.setAttribute(kAtList, lsId); } } @@ -763,13 +861,9 @@ ON_CONTROLWORD(ListOverrideTable) } } -ON_GROUPEND(ListOverrideTable) -{ - -} - +// Info Block Analyser -------------------------------------------------------------- ON_INITIALIZE(Info) { @@ -777,39 +871,45 @@ ON_INITIALIZE(Info) AN_ELEMENT(kElInfo); AN_DESTINATION(Null); } + ON_CONTROLWORD(Info) { - // The title if(cw == "title") { AN_ELEMENT(kElTitle); AN_DESTINATION(Raw); } + else if(cw == "author") { AN_ELEMENT(kElAuthor); AN_DESTINATION(Raw); } + else if(cw == "operator") { AN_ELEMENT(kElOperator); AN_DESTINATION(Raw); } + else if(flags & kAsterisk) AN_ANALYSER(Skip); + else DEFAULT_CONTROLWORD; } - +// Root Analyser -------------------------------------------------------------------- ON_INITIALIZE(Root) { } + ON_CONTROLWORD(Root) { + // All the main RTF sections if(cw == "stylesheet") AN_ANALYSER(Stylesheet); else if(cw == "listtable") @@ -842,23 +942,26 @@ ON_CONTROLWORD(Root) } +// Content Destination -------------------------------------------------------------- + ON_INITIALIZE(Content) { - parent = m_parser->getElement(); + parent = m_composer->getElement(); created = false; } + ON_CHARDATA(Content) { // Create the first time we get content if(!created) { - DOM::Element dest = m_parser->createElement(kElDest); + DOM::Element dest = m_composer->createElement(kElDest); parent.appendChild(dest); - m_parser->replaceElement(dest); + m_composer->replaceElement(dest); - DOM::Element el = m_parser->createElement(kElBlock); - m_parser->pushElement(el); - m_parser->popElement(); + DOM::Element el = m_composer->createElement(kElBlock); + m_composer->pushElement(el); + m_composer->popElement(); created = true; } @@ -867,7 +970,10 @@ ON_CHARDATA(Content) return; int elements = 0; - RtfFormatting& format = m_parser->getTextFormatting(); + RtfFormatting& format = m_composer->getTextFormatting(); + + // Extra elements written out here are consolidated in + // XmlFixups::combineDuplicates // Now do text Properties if necessary if(format.textIsBold()) @@ -875,37 +981,44 @@ ON_CHARDATA(Content) AN_ELEMENT(kElB); elements++; } + if(format.textIsHidden()) { AN_ELEMENT(kElHide); elements++; } + if(format.textIsItalic()) { AN_ELEMENT(kElI); elements++; } + if(format.textIsStrike()) { AN_ELEMENT(kElStrike); elements++; } + if(format.textIsUnderline()) { AN_ELEMENT(kElU); elements++; } - if(format.textColor() != -1 && m_parser->getOptions().doColors) + + if(format.textColor() != -1 && m_composer->getOptions().doColors) { AN_ELEMENT(kElColor); - AN_ATTRIBUTE(kAtIndex, NUM_ATTR(format.textColor())); + AN_ATTRIBUTE(kAtIndex, format.textColor()); elements++; } + if(format.textSuScript() == RtfFormatting::SUPERSCRIPT) { AN_ELEMENT(kElSuper); elements++; } + if(format.textSuScript() == RtfFormatting::SUBSCRIPT) { AN_ELEMENT(kElSub); @@ -913,8 +1026,8 @@ ON_CHARDATA(Content) } // Write the data to the element - m_parser->getElement().appendChild( - m_parser->getDocument().createTextNode(data)); + m_composer->getElement().appendChild( + m_composer->getDocument().createTextNode(data)); // Now drop out of all the above formatting while(elements-- > 0) @@ -922,22 +1035,25 @@ ON_CHARDATA(Content) } +// FootNote Analyser ---------------------------------------------------------------- + ON_INITIALIZE(FootNote) { - int ac = m_parser->getAutoCount(AUTOCOUNT_FOOTNOTE); + int ac = m_composer->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(); + DestinationPtr dest = m_composer->getDestination(); ASSERT(dest != NULL); - int ac = m_parser->getAutoCount(AUTOCOUNT_FOOTNOTE); + int ac = m_composer->getAutoCount(AUTOCOUNT_FOOTNOTE); dest->charData(formatInt(ac)); return; } @@ -952,27 +1068,28 @@ ON_CONTROLWORD(FootNote) else DEFAULT_CONTROLWORD; } + ON_DONE(FootNote) { - m_parser->incrementAutoCount(AUTOCOUNT_FOOTNOTE); + m_composer->incrementAutoCount(AUTOCOUNT_FOOTNOTE); } - +// Raw Destination ------------------------------------------------------------------ ON_CHARDATA(Raw) { // Write the data to the element - m_parser->getElement().appendChild( - m_parser->getDocument().createTextNode(data)); + m_composer->getElement().appendChild( + m_composer->getDocument().createTextNode(data)); } - +// Attribute Destination ------------------------------------------------------------ ON_INITIALIZE(Attribute) { - element = m_parser->getElement(); + element = m_composer->getElement(); ASSERT(element != NULL); } @@ -991,17 +1108,3 @@ ON_CHARDATA(Attribute) element.setAttribute(name, cur); } -wstring RtfParser::formatInt(int num) -{ - char buff[16]; - - // Certain OSs don't support swprintf :( - sprintf(buff, "%d", num); - - wstring n; - for(char* s = buff; *s; s++) - n.append(1, *s); - - return n; -} - -- cgit v1.2.3