/*************************************************************************** dtdparser.cpp - description ------------------- begin : Sun Oct 19 16:47:20 EEST 2003 copyright : (C) 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; version 2 of the License. * * * ***************************************************************************/ //qt includes #include #include #include #include #include #include #include //kde includes #include #include #include #include #include #include #include //other includes #ifdef LIBXML_2_5 #include #endif #include #include //own includes #include "dtepeditdlg.h" #include "dtdparser.h" #include "qtag.h" #include "dtepcreationdlg.h" #include "quantacommon.h" #include "qextfileinfo.h" #define MAX_CHILD_ELEMENTS 100 namespace DTD { TQString dirName; xmlDtdPtr dtd_ptr; /* Pointer to the parsed DTD */ TQTextStream entityStream; } void saveElement(xmlElementPtr elem, xmlBufferPtr buf); void saveEntity(xmlEntityPtr entity, xmlBufferPtr buf); DTDParser::DTDParser(const KURL& dtdURL, const TQString &dtepDir) { m_dtdURL = dtdURL; m_dtepDir = dtepDir; } DTDParser::~DTDParser() { } bool DTDParser::parse(const TQString &targetDir, bool entitiesOnly) { bool fineTune = false; TQString fileName = TQString::null; if (!KIO::NetAccess::download(m_dtdURL, fileName, 0)) { KMessageBox::error(0, i18n("Cannot download the DTD from %1.").arg( m_dtdURL.prettyURL(0, KURL::StripFileProtocol))); return false; } DTD::dtd_ptr = xmlParseDTD(NULL, xmlCharStrndup(fileName.utf8(), fileName.utf8().length())); if( DTD::dtd_ptr == NULL ) { TQString errorStr = i18n("Unknown"); #ifndef LIBXML_2_5 xmlErrorPtr errorPtr = xmlGetLastError(); if (errorPtr != NULL) { TQString s = TQString::fromLatin1(errorPtr->message); if (!s.isEmpty()) errorStr = s; s = TQString::fromLatin1(errorPtr->str1); if (!s.isEmpty()) errorStr += "
" + s; s = TQString::fromLatin1(errorPtr->str2); if (!s.isEmpty()) errorStr += "
" + s; s = TQString::fromLatin1(errorPtr->str2); if (!s.isEmpty()) errorStr += "
" + s; errorStr += TQString("(%1, %2)").arg(errorPtr->line).arg(errorPtr->int2); xmlResetError(errorPtr); } #endif KMessageBox::error(0, i18n("Error while parsing the DTD.
The error message is:
%1
").arg(errorStr)); return false; } if (targetDir.isEmpty()) { KDialogBase dlg(0L, 0L, true, i18n("DTD - > DTEP Conversion"), KDialogBase::Ok | KDialogBase::Cancel); DTEPCreationDlg w(&dlg); dlg.setMainWidget(&w); TQString name = TQString((const char*)DTD::dtd_ptr->name); if (name == "none") name = TQFileInfo(m_dtdURL.fileName()).baseName(); w.dtdName->setText(name); w.nickName->setText(name); w.directory->setText(TQFileInfo(m_dtdURL.fileName()).baseName()); w.doctype->setText(TQString((const char*)DTD::dtd_ptr->ExternalID)); w.dtdURL->setText(TQString((const char*)DTD::dtd_ptr->SystemID)); if (!dlg.exec()) return false; m_name = w.dtdName->text(); m_nickName = w.nickName->text(); m_doctype = w.doctype->text(); m_doctype.replace(TQRegExp("")); m_dtdURLLine = w.dtdURL->text(); m_defaultExtension = w.defaultExtension->text(); m_caseSensitive = w.caseSensitive->isChecked(); DTD::dirName = m_dtepDir + "/" + w.directory->text(); fineTune = w.fineTune->isChecked(); } else DTD::dirName = targetDir; KURL u; u.setPath(DTD::dirName); if (!QExtFileInfo::createDir(u, 0L)) { QuantaCommon::dirCreationError(0L, u); return false; } DTD::dirName.append("/"); if (DTD::dtd_ptr->entities) { TQFile file( DTD::dirName + "entities.tag" ); if ( file.open( IO_WriteOnly ) ) { DTD::entityStream.setDevice(&file); DTD::entityStream.setEncoding(TQTextStream::UnicodeUTF8); DTD::entityStream << "" << endl; DTD::entityStream << "" << endl << "" << endl; xmlHashScan((xmlEntitiesTablePtr)DTD::dtd_ptr->entities, (xmlHashScanner)saveEntity, 0); DTD::entityStream << "" << endl; file.close(); } else { KMessageBox::error(0L, i18n("Cannot create the
%1 file.
Check that you have write permission in the parent folder.
") .arg(file.name())); return false; } } if (!entitiesOnly) { if (DTD::dtd_ptr->elements) { xmlHashScan((xmlElementTablePtr)DTD::dtd_ptr->elements, (xmlHashScanner)saveElement, 0); } else { KMessageBox::error(0, i18n("No elements were found in the DTD.")); return false; } } xmlFreeDtd(DTD::dtd_ptr); if (!entitiesOnly) { writeDescriptionRC(); if (fineTune) { KDialogBase editDlg(0L, "edit_dtep", true, i18n("Configure DTEP"), KDialogBase::Ok | KDialogBase::Cancel); DTEPEditDlg dtepDlg(DTD::dirName + "description.rc", &editDlg); editDlg.setMainWidget(&dtepDlg); if (editDlg.exec()) { dtepDlg.saveResult(); } } } return true; } void DTDParser::writeDescriptionRC() { KConfig config(DTD::dirName + "description.rc"); config.setGroup("General"); config.writeEntry("Name", m_name); config.writeEntry("NickName", m_nickName); config.writeEntry("DoctypeString", m_doctype); config.writeEntry("URL", m_dtdURLLine); config.writeEntry("DefaultExtension", m_defaultExtension); config.writeEntry("Family", "1"); config.writeEntry("CaseSensitive", m_caseSensitive); // config.setGroup("Parsing rules"); // config.writeEntry("SpecialAreas",",,"); // config.writeEntry("SpecialAreaNames","comment,XML PI,DTD"); config.sync(); } void saveElement(xmlElementPtr elem, xmlBufferPtr buf) { Q_UNUSED(buf); if (elem) { TQString elemName = TQString((const char*)elem->name); TQFile file( DTD::dirName + elemName + ".tag" ); if ( file.open( IO_WriteOnly ) ) { TQTextStream stream( &file ); stream.setEncoding(TQTextStream::UnicodeUTF8); stream << "" << endl; stream << "" << endl << "" << endl << "" << endl << endl; xmlElementPtr el_ptr; /* Pointer to an element description */ xmlAttributePtr at_ptr; el_ptr = xmlGetDtdElementDesc(DTD::dtd_ptr, elem->name); AttributeList attributes; attributes.setAutoDelete(true); if (el_ptr) { at_ptr = el_ptr->attributes; while (at_ptr) { Attribute *attr = new Attribute; attr->name = TQString((const char*)at_ptr->name); switch (at_ptr->def) { case 1: {attr->status = "optional"; break;} //NONE case 2: {attr->status = "required"; break;} //REQUIRED case 3: {attr->status = "implied"; break;} //IMPLIED case 4: {attr->status = "fixed"; break;} //FIXED } attr->defaultValue = TQString((const char*)at_ptr->defaultValue); xmlEnumerationPtr enum_ptr; enum_ptr = at_ptr->tree; while (enum_ptr) { attr->values += TQString((const char*)enum_ptr->name); enum_ptr = enum_ptr->next; } TQString attrtype; switch (at_ptr->atype) { case 9: {attrtype = "list"; break;} default: {attrtype = "input"; break;} //TODO handle the rest of types } attr->type = attrtype; attributes.append(attr); at_ptr = at_ptr->nexth; } if (!attributes.isEmpty()) stream << QuantaCommon::xmlFromAttributes(&attributes); const xmlChar *list_ptr[MAX_CHILD_ELEMENTS]; int childNum = 0; childNum = xmlValidGetPotentialChildren(el_ptr->content, list_ptr, &childNum, MAX_CHILD_ELEMENTS); if (childNum > 0) { stream << "" << endl; for( int i = 0; i < childNum; i++ ) { stream << " content && child_ptr->content->ocur) { //if (child_ptr->content->ocur == XML_ELEMENT_CONTENT_PLUS) //{ // stream << " usage=\"required\""; // } TQString ocur; switch (child_ptr->content->ocur) { case 1: {ocur = "once"; break;} case 2: {ocur = "opt"; break;} case 3: {ocur = "mult"; break;} case 4: {ocur = "plus"; break;} } stream << " usage=\"" << ocur << "\""; TQString name = TQString((const char*)child_ptr->content->name); if (name == "#PCDATA") name == "#text"; stream << " name2=\"" << name << "\""; } stream << " />" << endl; } stream << "" << endl; stream << endl; } /* xmlElementContentPtr content_ptr = el_ptr->content; if (content_ptr) { stream << "" << endl; while (content_ptr) { if (!TQString((const char*)content_ptr->name).isEmpty()) { stream << " name) << "\""; TQString ocur; switch (content_ptr->ocur) { case 1: {ocur = "once"; break;} case 2: {ocur = "opt"; break;} case 3: {ocur = "mult"; break;} case 4: {ocur = "plus"; break;} } stream << " usage=\"" << ocur << "\""; stream << " />" << endl; } if (content_ptr->c1) content_ptr = content_ptr->c1; else if (content_ptr->c2) content_ptr = content_ptr->c2; else { if (content_ptr == el_ptr->content) break; if (content_ptr->parent) { if (content_ptr == content_ptr->parent->c1) content_ptr->c1 = 0L; else content_ptr->c2 = 0L; } content_ptr = content_ptr->parent; } } stream << "" << endl; } */ } stream << "" << endl << "" << endl; file.close(); } } } void saveEntity(xmlEntityPtr entity, xmlBufferPtr buf) { Q_UNUSED(buf); if (entity) { TQString name = TQString((const char*)entity->name); DTD::entityStream << "" << endl << endl; } } TQString DTDParser::dirName() { return DTD::dirName; }