summaryrefslogtreecommitdiff
path: root/src/xmlcomposer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmlcomposer.cpp')
-rw-r--r--src/xmlcomposer.cpp475
1 files changed, 289 insertions, 186 deletions
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;
-}
-