From 507524b97ef3bedb42f6c15ec93eedff8ee4b150 Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)> Date: Wed, 26 Nov 2003 02:12:18 +0000 Subject: New repository initialized by cvs2svn. --- src/xmlcomposer.cpp | 1245 --------------------------------------------------- 1 file changed, 1245 deletions(-) delete mode 100644 src/xmlcomposer.cpp (limited to 'src/xmlcomposer.cpp') diff --git a/src/xmlcomposer.cpp b/src/xmlcomposer.cpp deleted file mode 100644 index 6f41b29..0000000 --- a/src/xmlcomposer.cpp +++ /dev/null @@ -1,1245 +0,0 @@ -/* - * 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 - * - */ - -#include "usuals.h" -#include "xmlcomposer.h" -#include "xmlfixups.h" -#include "domhelpers.h" -#include "tags.h" - - -wstring 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; -} - -/* ---------------------------------------------------------------------------------- - * CONSTRUCTION - */ - -XmlComposer::XmlComposer(const XmlComposerOptions& 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; -} - -XmlComposer::~XmlComposer() -{ - clear(); - - if(m_impl != NULL) - m_impl.release(); -} - -void XmlComposer::clear() -{ - if(m_document != NULL) - { - try - { - m_document.release(); - } - catch(...) { } - - m_document = NULL; - } - LevelHandler::clear(); -} - - -/* ---------------------------------------------------------------------------------- - * HANDLER OVERRIDES - */ - -void XmlComposer::startDocument(RtfParser* reader) -{ - LevelHandler::startDocument(reader); - ASSERT(m_curLevel != NULL); - - // Create a new document - m_document = m_impl.createDocument("", kElDoc, DOM::DocumentType()); - - // TODO: Throw error if document is null - ASSERT(m_document != NULL); - - // Hook up the top level element - DOM::Element top = m_document.getDocumentElement(); - m_curLevel->setElement(top, true); - - // Set the attributes on the top level - setAnalyser(AnalyserPtr(new Root)); - setDestination(DestinationPtr(new Content)); - getTextFormatting().resetPara(); - getTextFormatting().resetText(); - - // Create the options element - m_docOptions = m_document.createElement(kElOptions); - top.appendChild(m_docOptions); -} - -void XmlComposer::endDocument() -{ - LevelHandler::endDocument(); - - XmlFixups fix; - - // Pass 0: Cleanup the tree - // XmlFixups::combineDuplicates(m_document); - // XmlFixups::consolidateStartTags(m_document); - // XmlFixups::consolidateEndTags(m_document); - - // Pass 1: Block breakout - fix.breakTables(m_document); - fix.breakTags(m_document, kElTable, kElRow); - fix.breakTags(m_document, kElRow, kElCell); - fix.wrapTags(m_document, kElCell, kElDest); - fix.breakBlocks(m_document); - fix.breakLists(m_document); - - // Pass 2: Fixups - fix.runPassTwo(m_document); - - // XmlFixups::fixLists(m_document); - // XmlFixups::fixStyles(m_document); - // XmlFixups::fixBlocks(m_document); - // XmlFixups::removeTags(m_document); - // XmlFixups::breakBreak(m_document, kElDoc, kElPage); - // XmlFixups::breakBreak(m_document, kElDoc, kElSect); - - // Pass 3: Final cleanup - // XmlFixups::combineDuplicates(m_document); - - DOM::Element top = m_document.getDocumentElement(); - ASSERT(top != NULL); - top.setAttribute(kNSPrefix, kNSRtfx); - - return; -} - -void XmlComposer::charData(wstring data) -{ - ASSERT(m_curLevel != NULL); - DestinationPtr destination = m_curLevel->getDestination(); - - if(!destination) - { - destination = DestinationPtr(new Content); - setDestination(destination); - } - - destination->charData(data); -} - -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(); -} - -void XmlComposer::groupEnd() -{ - LevelHandler::groupEnd(); - - ASSERT(m_curLevel != NULL); - AnalyserPtr analyser = m_curLevel->getAnalyser(); - if(analyser) - analyser->groupEnd(); -} - - -/* ---------------------------------------------------------------------------------- - * HELPER FUNCTIONS - */ - -DOM::Element XmlComposer::createElement(const string& name) -{ - ASSERT(name.length() > 0); - return m_document.createElement(name); -} - -void XmlComposer::replaceElement(const DOM::Element& element) -{ - ASSERT(m_curLevel != NULL); - m_curLevel->setElement(element, true); -} - -void XmlComposer::pushElement(const DOM::Element& element) -{ - ASSERT(m_curLevel != NULL); - getElement().appendChild(element); - m_curLevel->setElement(element); -} - -void XmlComposer::pushTopElement(const DOM::Element& element) -{ - ASSERT(m_curLevel != NULL); - DOM::Element top = m_document.getDocumentElement(); - if(top.hasChildNodes()) - top.insertBefore(element, top.getFirstChild()); - else - top.appendChild(element); - - m_curLevel->setElement(element); -} - -DOM::Element XmlComposer::popElement() -{ - DOM::Element element = getElement(); - ASSERT(m_curLevel != NULL); - - DOM::Node parent = element.getParentNode(); - ASSERT(parent != NULL && parent.getNodeType() == DOM::Node::ELEMENT_NODE); - - // Set it deep so it replaces the current element - m_curLevel->setElement((DOM::Element&)parent, true); - return element; -} - -void XmlComposer::setAttribute(const string& name, const wstring& value, DOM::Element el) -{ - ASSERT(name.length() > 0); - if(el == NULL) - el = getElement(); - el.setAttribute(name, value); -} - -void XmlComposer::setAttribute(const string& name, int value, DOM::Element el) -{ - ASSERT(name.length() > 0); - if(el == NULL) - el = getElement(); - el.setAttribute(name, formatInt(value)); -} - -void XmlComposer::setDestination(DestinationPtr dest) -{ - ASSERT(m_curLevel); - - m_curLevel->setDestination(dest); - dest->m_composer = this; - dest->initialize(); -} - -DestinationPtr XmlComposer::replaceDestination(DestinationPtr dest) -{ - ASSERT(m_curLevel); - - DestinationPtr old = m_curLevel->getDestination(); - m_curLevel->setDestination(dest, true); - dest->m_composer = this; - dest->initialize(); - - return old; -} - - -void XmlComposer::setAnalyser(AnalyserPtr analy) -{ - ASSERT(m_curLevel); - ASSERT(analy != NULL); - - analy->m_composer = this; - m_curLevel->setAnalyser(analy); - analy->initialize(); -} - -AnalyserPtr XmlComposer::getAnalyser() -{ - ASSERT(m_curLevel); - return m_curLevel->getAnalyser(); -} - -DestinationPtr XmlComposer::getDestination() -{ - ASSERT(m_curLevel); - return m_curLevel->getDestination(); -} - -RtfFormatting& XmlComposer::getTextFormatting() -{ - ASSERT(m_curLevel); - return m_curLevel->getFormatting(); -} - -int XmlComposer::getAutoCount(int type) -{ - ASSERT(type < AUTOCOUNT_MAX); - return m_autocount[type]; -} - -void XmlComposer::incrementAutoCount(int type) -{ - ASSERT(type < AUTOCOUNT_MAX); - m_autocount[type]++; -} - -void XmlComposer::addDocumentOption(DOM::Element& option) -{ - ASSERT(m_docOptions != NULL); - m_docOptions.appendChild(option); -} - - -/* ---------------------------------------------------------------------------------- - * CONVENIENCE MACROS USED BELOW - */ - -#define AN_ELEMENT(name) \ - m_composer->pushElement(m_composer->createElement(name)) -#define AN_TOP_ELEMENT(name) \ - m_composer->pushTopElement(m_composer->createElement(name)) -#define AN_POP_ELEMENT() \ - m_composer->popElement() -#define AN_ATTRIBUTE(name, value) \ - m_composer->setAttribute(name, value) -#define AN_DESTINATION_ATTR(name) \ - m_composer->setDestination(new Attribute(name)) -#define AN_DESTINATION(cls) \ - m_composer->setDestination(new cls) -#define AN_ANALYSER(cls) \ - m_composer->setAnalyser(AnalyserPtr(new cls)) -#define AN_SET_ANALYSER(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(x) formatInt(x) -#define DO_EXTRAS() (m_composer->getOptions().extras) - -/* ---------------------------------------------------------------------------------- - * BASE ANALYSER - */ - -bool XmlComposer::BaseAnalyser::processDefault(const string& cw, int flags, int param) -{ - // Unicode blocks go to a special analyser - if(cw == "upr") - { - AnalyserPtr analy = m_composer->getAnalyser(); - ASSERT(analy != NULL); - AN_SET_ANALYSER(new Upr(analy)); - return true; - } - - return false; -} - -void XmlComposer::BaseAnalyser::applyParaFormatting(RtfFormatting* format, - DOM::Element& el) -{ - if(format == NULL) - format = &(m_composer->getTextFormatting()); - - wstring fix = kValPara; - - // Is it a list? - int list = format->paraList(); - if(list != -1) - el.setAttribute(kAtList, NUM_ATTR(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)); - else - el.removeAttribute(kElStyle); - - // These fix elements are later picked up in XmlFixups::fixBlocks - el.setAttribute(kAtFix, fix); -} - -DOM::Element XmlComposer::BaseAnalyser::getCurrentBlock() -{ - DOM::Node node = m_composer->getElement(); - - if(node.hasChildNodes()) - node = node.getLastChild(); - - return DOMHelpers::getPriorElement(node, kElBlock); -} - -bool XmlComposer::BaseAnalyser::processTextContent(const string& cw, int flags, int param) -{ - DOM::Element el; - bool process = false; - - RtfFormatting& format = m_composer->getTextFormatting(); - - // New paragraph - if(cw == "par") - { - el = getCurrentBlock(); - if(el != NULL) - applyParaFormatting(&format, el); - - 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_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_composer->createElement(kElRow); - - // A tab - else if(cw == "tab") - el = m_composer->createElement(kElTab); - - // A section break - else if(cw == "sect") - el = m_composer->createElement(kElSect); - - // A page break - else if(cw == "page") - 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_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_composer->getDestination(); - ASSERT(dest != NULL); - dest->charData(kValNull); - - m_composer->pushElement(el); - m_composer->popElement(); - } - - return (el != NULL) || process; -} - -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(); - } - - // Rest are pretty much self-explanatory - else if(cw == "plain") - format.resetText(); - else if(cw == "b") - format.textSetBold(on); - else if(cw == "i") - format.textSetItalic(on); - else if(cw == "v") - format.textSetHidden(on); - else if(cw == "ul") - format.textSetUnderline(on); - else if(cw == "super") - format.textSetSuScript(RtfFormatting::SUPERSCRIPT); - else if(cw == "sub") - format.textSetSuScript(RtfFormatting::SUBSCRIPT); - else if(cw == "cf" && HAS_PARAM) - format.textSetColor(param); - else if(cw == "f" && HAS_PARAM) - format.textSetFont(param); - else if(cw == "fs" && HAS_PARAM) - format.textSetFontSize(param); - else - return false; - - return true; -} - -bool XmlComposer::BaseAnalyser::processTextFormatting(const string& cw, int flags, int param) -{ - return processTextFormatting(cw, flags, param, m_composer->getTextFormatting()); -} - -bool XmlComposer::BaseAnalyser::processTextAutoContent(const string& cw, int flags, int param) -{ - DestinationPtr dest = m_composer->getDestination(); - ASSERT(dest != NULL); - dest->charData(kValNull); - - // Auto generated content - - if(cw == "chftn") - { - // Footnote auto numbering - int ac = m_composer->getAutoCount(AUTOCOUNT_FOOTNOTE); - - AN_ELEMENT(kElRef); - AN_ATTRIBUTE(kAtType, kValFootNote); - AN_ATTRIBUTE(kAtTo, ac); - - // Only output the actual link text in this case - if(DO_EXTRAS()) - dest->charData(formatInt(ac)); - - AN_POP_ELEMENT(); - return true; - } - - 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); } - - -// Upr Analyser --------------------------------------------------------------------- - -XmlComposer::Upr::Upr(AnalyserPtr prv) -{ - ASSERT(prv); - prev = prv; -} - -ON_GROUPSTART(Upr) -{ - AN_ANALYSER(Skip); -} - -ON_GROUPEND(Upr) -{ - ASSERT(prev); - m_composer->setAnalyser(prev); - prev = NULL; -} - - -// Stylesheet Analyser -------------------------------------------------------------- - -ON_INITIALIZE(Stylesheet) -{ - AN_TOP_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) -{ - // Were not sure if this element is really something - // so we can't always create - haveStyle = false; -} - -ON_CONTROLWORD(Style) -{ - // Get the style id - if(flags & kAsterisk) - { - AN_ANALYSER(Skip); - return; - } - - // Create the style tag if necessary - if(!haveStyle) - { - AN_ELEMENT(kElStyle); - AN_DESTINATION_ATTR(kAtName); - haveStyle = true; - } - - // The style id - if(cw == "s" && flags & kHasParam) - { - AN_ATTRIBUTE(kAtId, param); - } - - // Otherwise get as much formatting out of the tag as possible - else if(processTextFormatting(cw, flags, param)) - DUMMY; - - else - DEFAULT_CONTROLWORD; -} - -ON_GROUPSTART(Style) -{ - AN_ANALYSER(Skip); -} - -ON_GROUPEND(Style) -{ - RtfFormatting& props = m_composer->getTextFormatting(); - - // Dig out all the formatting attributes - if(props.textIsBold()) - AN_ATTRIBUTE(kAtBold, kValTrue); - if(props.textIsHidden()) - AN_ATTRIBUTE(kAtHidden, kValTrue); - if(props.textIsItalic()) - AN_ATTRIBUTE(kAtItalic, kValTrue); - if(props.textIsStrike()) - AN_ATTRIBUTE(kAtStrike, kValTrue); - if(props.textIsUnderline()) - AN_ATTRIBUTE(kAtUnderline, kValTrue); - - // TODO: Do fonts and colors here -} - - -// Font Table Analyser -------------------------------------------------------------- - -ON_INITIALIZE(FontTable) -{ - AN_TOP_ELEMENT(kElFontTable); - AN_DESTINATION(Null); -} - -ON_GROUPSTART(FontTable) -{ - // Each group should be a font - AN_ANALYSER(Font); -} - -ON_DONE(FontTable) -{ - DOM::Element deffont = m_composer->createElement(kElFont); - - // Default font is always the first in the list - deffont->setAttribute(kAtId, kValZero); - - // Default size is always 12 pt - deffont->setAttribute(kAtSize, L"12"); - - // TODO: Is this correct? - deffont->setAttribute(kAtColor, kValZero); - - m_composer->addDocumentOption(deffont); -} - -// Font Analyser -------------------------------------------------------------------- - -ON_INITIALIZE(Font) -{ - AN_ELEMENT(kElFontDef); - AN_DESTINATION_ATTR(kAtName); -} - -ON_CONTROLWORD(Font) -{ - // The font id - if(cw == "f" && flags & kHasParam) - AN_ATTRIBUTE(kAtId, param); - - else - DEFAULT_CONTROLWORD; -} - -ON_GROUPSTART(Font) -{ - AN_ANALYSER(Skip); -} - - -// List Table Analyser -------------------------------------------------------------- - -ON_INITIALIZE(ListTable) -{ - AN_TOP_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) -{ - // Create a default element - AN_ELEMENT(kElListdef); - - if(DO_EXTRAS()) - 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, param); - - // We let listlevel in here too - else if(cw == "levelstartat" && HAS_PARAM) - AN_ATTRIBUTE(kAtStart, param); - - // The list type - else if(cw == "levelnfc" && HAS_PARAM) - { - if(DO_EXTRAS()) - { - switch(param) - { - case 0: // 1, 2, 3 - case 5: // 1st, 2nd, 3rd - case 6: // One, Two, Three - case 7: // First, Second, Third - case 22: // 01, 02, 03 - AN_ATTRIBUTE(kAtType, kValArabic); - break; - case 1: // I, II, III - AN_ATTRIBUTE(kAtType, kValUpperRoman); - break; - case 2: // i, ii, iii - AN_ATTRIBUTE(kAtType, kValLowerRoman); - break; - case 3: // A, B, C - AN_ATTRIBUTE(kAtType, kValUpperAlpha); - break; - case 4: // a, b, c - AN_ATTRIBUTE(kAtType, kValLowerAlpha); - break; - default: - AN_ATTRIBUTE(kAtType, kValDisc); - break; - } - } - - switch(param) - { - case 0: case 5: case 6: case 7: case 22: - case 1: case 2: case 3: case 4: - AN_ATTRIBUTE(kAtOrdered, L"1"); - break; - default: - AN_ATTRIBUTE(kAtOrdered, L"0"); - } - } - - 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) -{ - // 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 - if(cw == "listoverride") - curList = NULL; - - // List id for current listoverride - else if(cw == "listid" && HAS_PARAM) - { - wstring id = formatInt(param); - - if(lists != NULL) - { - // Find the list in question - for(int i = 0; i < lists->getLength(); i++) - { - DOM::Node node = lists->item(i); - if(node != NULL && node.getNodeType() == DOM::Node::ELEMENT_NODE) - { - DOM::Element element = (DOM::Element&)node; - if(element.getAttribute(kAtId) == id) - { - curList = element; - break; - } - } - } - } - } - - // The actual list code - else if(cw == "ls" && HAS_PARAM) - lsId = param; - - // Override the starting level for the node - else if(cw == "levelstartat" && HAS_PARAM) - { - if(curList != NULL) - curList.setAttribute(kAtStart, NUM_ATTR(param)); - } - - else - DEFAULT_CONTROLWORD; - - - // Okay before any overrides take effect we need to duplicate - // the list node for overriding, using the 'listid' and 'ls' we gathered - if(curList != NULL && lsId != -1) - { - DOM::Element parent = (const DOM::Element&)curList.getParentNode(); - if(parent != NULL) - { - curList = (const DOM::Element&)curList.cloneNode(true); - if(curList != NULL) - { - parent.appendChild(curList); - curList.setAttribute(kAtId, NUM_ATTR(lsId)); - } - } - - lsId = -1; - } - -} - - -// Info Block Analyser -------------------------------------------------------------- - -ON_INITIALIZE(Info) -{ - // Create a new element - AN_TOP_ELEMENT(kElInfo); - AN_DESTINATION(Null); -} - -ON_CONTROLWORD(Info) -{ - 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") - AN_ANALYSER(ListTable); - else if(cw == "listoverridetable") - AN_ANALYSER(ListOverrideTable); - else if(cw == "info") - AN_ANALYSER(Info); - else if(cw == "fonttbl") - { - if(DO_EXTRAS()) - AN_ANALYSER(FontTable); - else - AN_ANALYSER(Skip); - } - else if(cw == "colortbl") - AN_ANALYSER(Skip); - else if(cw == "footnote") - AN_ANALYSER(FootNote); - else if(cw == "pict") - { - AN_ANALYSER(Skip); - AN_DESTINATION(Null); - } - else if(flags & kAsterisk) - 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 - DEFAULT_CONTROLWORD; -} - - -// Content Destination -------------------------------------------------------------- - -ON_INITIALIZE(Content) -{ - parent = m_composer->getElement(); - created = false; -} - -ON_CHARDATA(Content) -{ - // Create the first time we get content - if(!created) - { - DOM::Element dest = m_composer->createElement(kElDest); - parent.appendChild(dest); - m_composer->replaceElement(dest); - - DOM::Element el = m_composer->createElement(kElBlock); - m_composer->pushElement(el); - m_composer->popElement(); - - created = true; - } - - if(data.length() == 0) - return; - - int elements = 0; - RtfFormatting& format = m_composer->getTextFormatting(); - - // Extra elements written out here are consolidated in - // XmlFixups::combineDuplicates - - // Handle fonts etc... - if(DO_EXTRAS()) - { - int font = format.textFont(); - int fontsize = format.textFontSize(); - - if(font != -1 || fontsize != -1) - { - AN_ELEMENT(kElFont); - - if(font != -1) - AN_ATTRIBUTE(kAtName, font); - - if(fontsize != -1) - { - // Little hack for half point sizes - wstring size = NUM_ATTR(fontsize / 2); - if(fontsize % 2) - size.append(L".5"); - - AN_ATTRIBUTE(kAtSize, size); - } - - if(format.textColor() != -1) - AN_ATTRIBUTE(kAtColor, format.textColor()); - - elements++; - } - } - - // Now do text Properties if necessary - - if(format.textIsBold()) - { - 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.textSuScript() == RtfFormatting::SUPERSCRIPT) - { - AN_ELEMENT(kElSuper); - elements++; - } - - if(format.textSuScript() == RtfFormatting::SUBSCRIPT) - { - AN_ELEMENT(kElSub); - elements++; - } - - // Write the data to the element - m_composer->getElement().appendChild( - m_composer->getDocument().createTextNode(data)); - - // Now drop out of all the above formatting - while(elements-- > 0) - AN_POP_ELEMENT(); -} - - -// FootNote Analyser ---------------------------------------------------------------- - -ON_INITIALIZE(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") - { - // Only put actual text when in extras mode - if(DO_EXTRAS()) - { - DestinationPtr dest = m_composer->getDestination(); - ASSERT(dest != NULL); - int ac = m_composer->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_composer->incrementAutoCount(AUTOCOUNT_FOOTNOTE); -} - - -// Raw Destination ------------------------------------------------------------------ - -ON_CHARDATA(Raw) -{ - // Write the data to the element - m_composer->getElement().appendChild( - m_composer->getDocument().createTextNode(data)); -} - - -// Attribute Destination ------------------------------------------------------------ - -ON_INITIALIZE(Attribute) -{ - element = m_composer->getElement(); - ASSERT(element != NULL); -} - -ON_CHARDATA(Attribute) -{ - // Get the current value - wstring cur = element.getAttribute(name); - - if(data.at(data.size() - 1) == L';') - data.resize(data.size() - 1); - - // Append data - cur.append(data); - - // Write it back - element.setAttribute(name, cur); -} - -- cgit v1.2.3