/*************************************************************************** dtdparser.cpp - description ------------------- begin : Tue Jul 30 15:26:20 EEST 2002 copyright : (C) 2002 by Jason P. Hanley (C) 2002, 2003 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. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include "dtd.h" #include "../tquantacommon.h" #include "../tqextfileinfo.h" DTD::DTD(const KURL &dtdURL, const TQString &dtepDir) { m_dtdURL = dtdURL; m_dtepDir = dtepDir + "/"+TQFileInfo(dtdURL.fileName()).baseName(); //TODO: get the dir name from the DTD or from the user } DTD::~DTD() { } TQStringList DTD::getTags() { return tags; } AttributeList* DTD::getTagAttributes(TQString tag) { return tagAttributes.find(tag); } TQStringList DTD::getTextCompletion(TQString tag) { return TQStringList(); } void DTD::printContents() { for ( TQStringList::Iterator tagIt = tags.begin(); tagIt != tags.end(); ++tagIt ) { TQString tag = *tagIt; kdDebug(24000) << tag << endl; AttributeList *attributes = getTagAttributes(tag); for ( uint i = 0; i < attributes->count(); i++) { Attribute *attribute = attributes->at(i); TQString s = " " + attribute->name + ": "; for (uint j = 0; j < attribute->values.count(); j++) { s += attribute->values[j] + ", "; } kdDebug(24000) << s << endl; } } } void DTD::writeTagFiles() { TQString dirName = m_dtepDir; KURL u; u.setPath(dirName); if (!QExtFileInfo::createDir(dirName)) { QuantaCommon::dirCreationError(0, u); return; } dirName.append("/"); for ( TQStringList::Iterator tagIt = tags.begin(); tagIt != tags.end(); ++tagIt ) { TQString tag = *tagIt; TQFile file( dirName + tag.lower() + ".tag" ); if ( file.open( IO_WriteOnly ) ) { TQTextStream stream( &file ); stream.setEncoding(TQTextStream::UnicodeUTF8); stream << "" << endl << "" << endl << "" << endl << endl; AttributeList *attributes = getTagAttributes(tag); stream << QuantaCommon::xmlFromAttributes(attributes); stream << "" << endl << "" << endl; file.close(); } else { kdDebug(24000) << "Unable to write tag file: " << file.name() << endl; } } TDEConfig config(dirName + "description.rc"); config.setGroup("General"); config.writeEntry("Name", TQFileInfo(m_dtdURL.fileName()).baseName()); //TODO: get from the DTD! config.writeEntry("NickName", TQFileInfo(m_dtdURL.fileName()).baseName()); //TODO: get from the user! config.sync(); } bool DTD::parseDTD(const KURL &url) { TQString fileName = TQString(); if (!TDEIO::NetAccess::download(url, fileName)) { KMessageBox::error(0, i18n("Cannot download the DTD from %1.").arg(url.prettyURL(0, KURL::StripFileProtocol))); return false; } TQFile file(fileName); if (file.open(IO_ReadOnly)) { TQTextStream fileStream(&file); fileStream.setEncoding(TQTextStream::UnicodeUTF8); TQString entireDTD = fileStream.read(); file.close(); removeComments(entireDTD); TQString line; TQStringList lines = TQStringList::split("\n",entireDTD); TQStringList::Iterator it = lines.begin(); while (it != lines.end()) { line = *it; if (line.startsWith("<")) { while (!line.endsWith(">") && it != lines.end()) { ++it; line += " \\end" + *it; } } else if (line.startsWith("%")) { while (!line.endsWith(";") && it != lines.end()) { ++it; line += *it; } } line = line.stripWhiteSpace(); line = line.simplifyWhiteSpace(); //kdDebug(24000) << "Parsed line is: " << line << endl; if ( line.startsWith("")) { parseDTDEntity(line); } else if (line.startsWith("")) { parseDTDElement(line); } else if (line.startsWith("")) { parseDTDAttlist(line); } else if (line.startsWith("%") && line.endsWith(";")) { line.remove(0,1); line.truncate(line.length()-1); KURL entityURL = url; entityURL.setPath(url.directory()+ "/" + line + ".ent"); parseDTD(entityURL); } else { kdDebug(24000) << TQString("Unknown tag: [%1]").arg(line) << endl; } if (it != lines.end()) ++it; } } } void DTD::parseDTDEntity(TQString line) { TQString name; TQString *value; line.replace("\\end", " "); name = line.mid(11); int firstSpace = name.find(' '); name = name.remove(firstSpace, name.length()-firstSpace); value = new TQString(line.mid(11+firstSpace)); value->remove(0, value->find("\"")+1); value->remove(value->findRev("\""), value->length()); parseDTDReplace(value); stripSpaces(value); entities.insert(name, value); //kdDebug() << "Entity --- Name: " << name << " --- Value: " << *value << endl; } void DTD::parseDTDElement(const TQString &l) { TQString name; TQString *value; TQString line = l; line.replace("\\end", " "); name = line.mid(10); int firstSpace = name.find(' '); name.remove(firstSpace, name.length()-firstSpace); value = new TQString(line.mid(10+firstSpace)); //value->remove(0, value->find("\"")+1); value->remove(value->find(">"), 10000); parseDTDReplace(&name); parseDTDReplace(value); if ( name.startsWith("(") && name.endsWith(")") ) { name.remove(0,1); name.remove(name.length()-1,1); TQStringList multipleTags = TQStringList::split("|", name); TQStringList::Iterator it = multipleTags.begin(); while(it != multipleTags.end()) { name = *it; name = name.stripWhiteSpace(); elements.insert(name, value); tags.append(name); //kdDebug() << "Element --- Name: " << name << " --- Value: " << *value << endl; ++it; } } else { elements.insert(name, value); tags.append(name); //kdDebug() << "Element --- Name: " << name << " --- Value: " << *value << endl; } } void DTD::parseDTDAttlist(const TQString &l) { TQString name; TQString *value; TQString line = l; line.replace("\\end", " "); name = line.mid(10); int firstSpace = name.find(' '); name.remove(firstSpace, name.length()-firstSpace); value = new TQString(line.mid(10+firstSpace)); //value->remove(0, value->find("\"")+1); value->remove(value->find(">"), 10000); parseDTDReplace(&name); parseDTDReplace(value); if ( name.startsWith("(") && name.endsWith(")") ) { name.remove(0,1); name.remove(name.length()-1,1); TQStringList multipleTags = TQStringList::split("|", name); TQStringList::Iterator it = multipleTags.begin(); while(it != multipleTags.end()) { name = *it; name = name.stripWhiteSpace(); //elements.insert(name, value); parseTagAttributeValues(name, value); //kdDebug() << "Attlist --- Name: " << name << " --- Value: " << *value << endl; ++it; } } else { //elements.insert(name, value); parseTagAttributeValues(name, value); //kdDebug() << "Attlist --- Name: " << name << " --- Value: " << *value << endl; } } void DTD::parseTagAttributeValues(const TQString &name, TQString *value) { AttributeList *attributes = new AttributeList(); TQStringList attrLines = TQStringList::split("\\end",*value); TQStringList::Iterator lineIt = attrLines.begin(); while (lineIt != attrLines.end()) //iterate through the attribute lines { //split the attribute line TQStringList all = TQStringList::split(" ", *lineIt); TQStringList::Iterator it = all.begin(); while(it != all.end()) { Attribute *attr = new Attribute(); attr->name = *it; //kdDebug() << "Inserting for tag " << name << ": " << *it << endl; ++it; TQString values = *it; //list of possible values if ( values.startsWith("(") && values.endsWith(")") ) { values.remove(0,1); values.remove(values.length()-1,1); attr->values = TQStringList::split("|", values); TQString s = (attr->values[0]+attr->values[1]).lower(); stripSpaces(&s); if ((s == "truefalse") || (s == "falsetrue")) { attr->type = "check"; } else { attr->type = "list"; } } else { attr->values = values; attr->type = "input"; } //kdDebug() << " --- values: " << *it << endl; if (it != all.end()) { ++it; TQString s=*it; if (s.startsWith("\"") && s.endsWith("\"") && it!=all.end()) { s.remove(0,1); s.remove(s.length()-1,1); attr->defaultValue = s; } if (s.startsWith("#") && it != all.end()) { s.remove(0,1); attr->status = s.lower(); } if (*it == "#FIXED" && it != all.end()) { ++it; attr->values.append(*it); } } if (it != all.end()) { ++it; } attributes->append(attr); } ++lineIt; } tagAttributes.insert(name, attributes); } void DTD::parseDTDReplace(TQString *value) { int begin, end; begin = value->find("%"); end = value->find(";"); while (begin != -1 && end != -1) { TQString replaceText = value->mid(begin+1, end-begin-1); TQString *replaceValue = entities.find(replaceText); if (replaceValue != 0L) { value->replace(begin, end-begin+1, *replaceValue); } else { kdDebug(24000) << "Can not find entity: " << replaceText << endl; return; } begin = value->find("%"); end = value->find(";"); } } void DTD::stripSpaces(TQString *value) { int index=-1; while ( (index=value->find(' ',++index)) != -1 ) { if ( value->findRev('(',index) != -1 && value->find(')',index) != -1) value->remove(index,1); } } void DTD::removeComments(TQString &value) { int begin, end; begin = value.find("",begin+2); while (begin != -1 && end != -1) { value.remove(begin, end-begin+3); begin = value.find("",begin+2); } begin = value.find("--"); end = value.find("--",begin+2); while (begin != -1 && end != -1) { value.remove(begin, end-begin+2); begin = value.find("--"); end = value.find("--",begin+2); } value.replace(TQRegExp(""), ""); } bool DTD::parseDTD() { return parseDTD(m_dtdURL); }