/*************************************************************************** parsercommon.cpp - description ------------------- begin : Wed Feb 11 2004 copyright : (C) 2004 Andras Mantia ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ //qt includes #include //kde includes #include #include #include //own includes #include "parsercommon.h" #include "node.h" #include "document.h" #include "qtag.h" #include "quantacommon.h" #include "resource.h" #include "dtds.h" class KDirWatch; int nodeNum; //for memory debugging - remove if not needed namespace ParserCommon { TQStringList includedFiles; TQPtrList includedFilesDTD; KDirWatch *includeWatch; //common methods. TQString getLine(Document *write, int line, int endLine, int endCol) { TQString textLine = write->editIf->textLine(line); if (line == endLine) { if (endCol >0) textLine.truncate(endCol + 1); else textLine = ""; } return textLine; } void appendAreaToTextNode(Document *write, const AreaStruct &area, Node *node) { TQString tagStr = write->text(area); TQString cleanStr = node->tag->cleanStr; node->tag->setStr(node->tag->tagStr() + tagStr); if (node->tag->type == Tag::Empty) { TQString s = tagStr; if (s.simplifyWhiteSpace().isEmpty()) { node->tag->type = Tag::Empty; } else { node->tag->type = Tag::Text; } } TQString cleanedTagStr = tagStr; QuantaCommon::removeCommentsAndQuotes(cleanedTagStr, node->tag->dtd()); node->tag->cleanStr = cleanStr + cleanedTagStr; int bLine, bCol; node->tag->beginPos(bLine, bCol); node->tag->setTagPosition(bLine, bCol, area.eLine, area.eCol); } Node* createTextNode(Document *write, Node *node, int eLine, int eCol, Node *parentNode) { Tag *textTag = 0L; Node *textNode = 0L; int bLine = 0; int bCol = 0; const DTDStruct *dtd = write->defaultDTD(); if (node) { node->tag->endPos(bLine, bCol); } else if (parentNode) parentNode->tag->endPos(bLine, bCol); if (parentNode) dtd = parentNode->tag->dtd(); eCol--; if (bLine == 0 && bCol == 0) bCol = -1; if ( !(bLine == eLine && bCol == eCol) ) { AreaStruct area(bLine, bCol + 1, eLine, eCol); textTag = new Tag(area, write, dtd); TQString s = textTag->tagStr(); textTag->single = true; if (s.simplifyWhiteSpace().isEmpty()) { textTag->type = Tag::Empty; } else { textTag->type = Tag::Text; } if (parentNode && parentNode->tag->single) { textNode = new Node(parentNode->parent); nodeNum++; textNode->prev = parentNode; parentNode->next = textNode; parentNode = parentNode->parent; } else { if ( node && (node->tag->type == Tag::Empty || node->tag->type == Tag::Text) ) //merge two consquent text or empty nodes { AreaStruct area(bLine, bCol, eLine, eCol); appendAreaToTextNode(write, area, node); delete textTag; textTag = 0L; } else { textNode = new Node(parentNode); nodeNum++; if (node && node != parentNode) { node->next = textNode; textNode->prev = node; } else { if (parentNode) { Node *n = parentNode->child; while (n && n->next) n = n->next; if (!n) parentNode->child = textNode; else { n->next = textNode; textNode->prev = n; } } } } } if (textTag) { textNode->tag = textTag; node = textNode; } } return node; } Node* createScriptTagNode(Document *write, const AreaStruct &area, const TQString &areaName, const DTDStruct *dtd, Node *parentNode, Node *currentNode) { Tag *tag = new Tag(); tag->setTagPosition(area); tag->setStr(areaName); tag->setWrite(write); const DTDStruct *d = DTDs::ref()->find(dtd->specialAreaNames[areaName]); if (d) tag->setDtd(d); else tag->setDtd(dtd); tag->name = i18n("%1 block").arg(dtd->specialAreaNames[areaName].upper()); tag->type = Tag::ScriptTag; tag->validXMLTag = false; Node *node = new Node(parentNode); nodeNum++; node->tag = tag; node->insideSpecial = true; if (parentNode) { if (!parentNode->child) parentNode->child = node; else { Node *n = parentNode->child; while (n->next) n = n->next; n->next = node; node->prev = n; } } else if (currentNode) { node->prev = currentNode; currentNode->next = node; } return node; } void coutTree(Node *node, int indent) { TQString output; int bLine, bCol, eLine, eCol; if (!node) kdDebug(24000)<< "undoRedo::coutTree() - bad node!" << endl; while (node) { output = ""; output.fill('.', indent); node->tag->beginPos(bLine, bCol); node->tag->endPos(eLine, eCol); if (node->tag->type != Tag::Text) output += node->tag->name.replace('\n'," "); else output+= node->tag->tagStr().replace('\n'," "); kdDebug(24000) << output <<" (" << node->tag->type << ") at pos " << bLine << ":" << bCol << " - " << eLine << ":" << eCol << " This: "<< node << " Parent: " << node->parent << " Prev: " << node->prev << " Next: " << node->next << " Child: " << node->child << " Tag:" << node->tag << endl; /* for(j = 0; j < node->tag->attrCount(); j++) { kdDebug(24000)<< " attr" << j << " " << node->tag->getAttribute(j).nameLine << ":" << node->tag->getAttribute(j).nameCol << " - " << node->tag->getAttribute(j).valueLine << ":" << node->tag->getAttribute(j).valueCol << endl; } */ if (node->child) coutTree(node->child, indent + 4); node = node->next; } } void verifyTree(Node *node) { TQString output; int bLine, bCol, eLine, eCol; while (node) { if (!node->tag) { kdDebug(24000) << "Bad node: " << node << endl; kdDebug(24000) << "Parent: " << node->parent << " " << node->parent->tag->tagStr() << endl; } if (node->child) verifyTree(node->child); node = node->next; } } }