From 4ea898fe70fd7a77a95c87668807f8af8342780b Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Fri, 24 Sep 2010 15:30:29 +0200 Subject: qdoc: Corrected many GUIDs. Still more to do here. --- tools/qdoc3/atom.cpp | 1 + tools/qdoc3/atom.h | 1 + tools/qdoc3/ditaxmlgenerator.cpp | 215 +++++++++++++++++++++++++++++---------- tools/qdoc3/ditaxmlgenerator.h | 11 +- tools/qdoc3/pagegenerator.cpp | 17 +++- tools/qdoc3/text.cpp | 4 +- 6 files changed, 189 insertions(+), 60 deletions(-) diff --git a/tools/qdoc3/atom.cpp b/tools/qdoc3/atom.cpp index 6f1602e..d18c3c4 100644 --- a/tools/qdoc3/atom.cpp +++ b/tools/qdoc3/atom.cpp @@ -190,6 +190,7 @@ static const struct { { "FormattingLeft", Atom::FormattingLeft }, { "FormattingRight", Atom::FormattingRight }, { "GeneratedList", Atom::GeneratedList }, + { "GuidLink", Atom::GuidLink}, { "Image", Atom::Image }, { "ImageText", Atom::ImageText }, { "InlineImage", Atom::InlineImage }, diff --git a/tools/qdoc3/atom.h b/tools/qdoc3/atom.h index 70fbae9..13df07b 100644 --- a/tools/qdoc3/atom.h +++ b/tools/qdoc3/atom.h @@ -83,6 +83,7 @@ class Atom FormattingLeft, FormattingRight, GeneratedList, + GuidLink, Image, ImageText, InlineImage, diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp index 921fdbc..16215cd 100644 --- a/tools/qdoc3/ditaxmlgenerator.cpp +++ b/tools/qdoc3/ditaxmlgenerator.cpp @@ -395,6 +395,7 @@ DitaXmlGenerator::DitaXmlGenerator() noLinks(0), tableColumnCount(0) { + // nothing yet. } /*! @@ -402,7 +403,11 @@ DitaXmlGenerator::DitaXmlGenerator() */ DitaXmlGenerator::~DitaXmlGenerator() { - // nothing yet. + GuidMaps::iterator i = guidMaps.begin(); + while (i != guidMaps.end()) { + delete i.value(); + ++i; + } } /*! @@ -526,7 +531,7 @@ QString DitaXmlGenerator::format() */ QString DitaXmlGenerator::writeGuidAttribute(QString text) { - QString guid = lookupGuid(text); + QString guid = lookupGuid(outFileName(),text); xmlWriter().writeAttribute("id",guid); return guid; } @@ -559,6 +564,41 @@ QString DitaXmlGenerator::lookupGuid(QString text) } /*! + First, look up the GUID map for \a fileName. If there isn't + a GUID map for \a fileName, create one and insert it into + the map of GUID maps. Then look up \a text in that GUID map. + If \a text is found, return the associated GUID. Otherwise, + insert \a text into the GUID map with a new GUID, and return + the new GUID. + */ +QString DitaXmlGenerator::lookupGuid(const QString& fileName, const QString& text) +{ + GuidMap* gm = lookupGuidMap(fileName); + GuidMap::const_iterator i = gm->find(text); + if (i != gm->end()) + return i.value(); + QString guid = QUuid::createUuid().toString(); + gm->insert(text,guid); + return guid; +} + +/*! + Looks up \a fileName in the map of GUID maps. If it finds + \a fileName, it returns a pointer to the associated GUID + map. Otherwise it creates a new GUID map and inserts it + into the map of GUID maps with \a fileName as its key. + */ +GuidMap* DitaXmlGenerator::lookupGuidMap(const QString& fileName) +{ + GuidMaps::const_iterator i = guidMaps.find(fileName); + if (i != guidMaps.end()) + return i.value(); + GuidMap* gm = new GuidMap; + guidMaps.insert(fileName,gm); + return gm; +} + +/*! This is where the DITA XML files are written. \note The file generation is done in the base class, PageGenerator::generateTree(). @@ -688,10 +728,13 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, xmlWriter().writeEndElement(); // sse writeStartElement() above break; case Atom::Code: - xmlWriter().writeStartElement("pre"); - xmlWriter().writeAttribute("outputclass","highlightedcode"); - writeText(trimmedTrailing(atom->string()), marker, relative); - xmlWriter().writeEndElement(); // + { + xmlWriter().writeStartElement("pre"); + xmlWriter().writeAttribute("outputclass","highlightedcode"); + QString chars = trimmedTrailing(atom->string()); + writeText(chars, marker, relative); + xmlWriter().writeEndElement(); // + } break; case Atom::Qml: xmlWriter().writeStartElement("pre"); @@ -1060,14 +1103,27 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, const Node *node = 0; QString myLink = getLink(atom, relative, marker, &node); if (myLink.isEmpty()) { - relative->doc().location().warning(tr("Cannot link to '%1' in %2") + relative->doc().location().warning(tr("Can't link to '%1' in %2") .arg(atom->string()) .arg(marker->plainFullName(relative))); } +#if 0 + else + qDebug() << "MYLINK:" << myLink << outFileName();; +#endif beginLink(myLink, node, relative, marker); skipAhead = 1; } break; + case Atom::GuidLink: + { +#if 0 + qDebug() << "GUID LINK:" << atom->string() << outFileName(); +#endif + beginLink(atom->string(), 0, relative, marker); + skipAhead = 1; + } + break; case Atom::LinkNode: { const Node *node = CodeMarker::nodeForString(atom->string()); @@ -3089,12 +3145,14 @@ void DitaXmlGenerator::generateSectionInheritedList(const Section& section, text += " inherited from "; xmlWriter().writeCharacters(text); xmlWriter().writeStartElement("xref"); + // zzz text = fileName((*p).first) + "#"; text += DitaXmlGenerator::cleanRef(section.name.toLower()); xmlWriter().writeAttribute("href",text); text = protectEnc(marker->plainFullName((*p).first, relative)); xmlWriter().writeCharacters(text); xmlWriter().writeEndElement(); // + xmlWriter().writeEndElement(); // ++p; } xmlWriter().writeEndElement(); // @@ -3406,8 +3464,10 @@ QString DitaXmlGenerator::registerRef(const QString& ref) } else if (prevRef == ref) break; +#if 0 else qDebug() << "PREVREF:" << prevRef; +#endif clean += "x"; } return clean; @@ -3492,28 +3552,10 @@ QString DitaXmlGenerator::fileBase(const Node* node) const return result; } -/*! - Constructs a file name appropriate for the \a node - and returns the file name. If the \a node is not a - fake node, or if it is a fake node but it is neither - an external page node nor an image node, call the - PageGenerator::fileName() function. - */ -QString DitaXmlGenerator::fileName(const Node* node) -{ - if (node->type() == Node::Fake) { - if (static_cast(node)->subType() == Node::ExternalPage) - return node->name(); - if (static_cast(node)->subType() == Node::Image) - return node->name(); - } - return PageGenerator::fileName(node); -} - QString DitaXmlGenerator::refForNode(const Node* node) { const FunctionNode* func; - const TypedefNode* typedeffe; + const TypedefNode* tdn; QString ref; switch (node->type()) { @@ -3525,9 +3567,9 @@ QString DitaXmlGenerator::refForNode(const Node* node) ref = node->name() + "-enum"; break; case Node::Typedef: - typedeffe = static_cast(node); - if (typedeffe->associatedEnum()) { - return refForNode(typedeffe->associatedEnum()); + tdn = static_cast(node); + if (tdn->associatedEnum()) { + return refForNode(tdn->associatedEnum()); } else { ref = node->name() + "-typedef"; @@ -3566,12 +3608,77 @@ QString DitaXmlGenerator::refForNode(const Node* node) return registerRef(ref); } -QString DitaXmlGenerator::linkForNode(const Node* node, const Node* relative) +QString DitaXmlGenerator::guidForNode(const Node* node) { - QString link; - QString fn; QString ref; + switch (node->type()) { + case Node::Namespace: + case Node::Class: + default: + break; + case Node::Enum: + return node->guid(); + case Node::Typedef: + { + const TypedefNode* tdn = static_cast(node); + if (tdn->associatedEnum()) + return guidForNode(tdn->associatedEnum()); + } + return node->guid(); + case Node::Function: + { + const FunctionNode* fn = static_cast(node); + if (fn->associatedProperty()) { + return guidForNode(fn->associatedProperty()); + } + else { + ref = fn->name(); + if (fn->overloadNumber() != 1) { + ref += "-" + QString::number(fn->overloadNumber()); +#if 0 + qDebug() << "guidForNode() overloaded function:" << ref; +#endif + } + } + } + case Node::Fake: + if (node->subType() != Node::QmlPropertyGroup) + break; + case Node::QmlProperty: + case Node::Property: + return node->guid(); + case Node::QmlSignal: + return node->guid(); + case Node::QmlMethod: + return node->guid(); + case Node::Variable: + return node->guid(); + case Node::Target: + return node->guid(); + } + return registerRef(ref); +} + +/*! + Constructs a file name appropriate for the \a node and returns + it. If the \a node is not a fake node, or if it is a fake node but + it is neither an external page node nor an image node, call the + PageGenerator::fileName() function. + */ +QString DitaXmlGenerator::fileName(const Node* node) +{ + if (node->type() == Node::Fake) { + if (static_cast(node)->subType() == Node::ExternalPage) + return node->name(); + if (static_cast(node)->subType() == Node::Image) + return node->name(); + } + return PageGenerator::fileName(node); +} + +QString DitaXmlGenerator::linkForNode(const Node* node, const Node* relative) +{ if (node == 0 || node == relative) return QString(); if (!node->url().isEmpty()) @@ -3581,21 +3688,18 @@ QString DitaXmlGenerator::linkForNode(const Node* node, const Node* relative) if (node->access() == Node::Private) return QString(); - fn = fileName(node); - link += fn + "#" + node->guid(); - return link; + QString fn = fileName(node); + QString link = fn; -#if 0 if (!node->isInnerNode() || node->subType() == Node::QmlPropertyGroup) { - ref = refForNode(node); - if (relative && fn == fileName(relative) && ref == refForNode(relative)) + QString guid = guidForNode(node); + if (relative && fn == fileName(relative) && guid == guidForNode(relative)) { return QString(); - + } link += "#"; - link += ref; + link += guid; } return link; -#endif } QString DitaXmlGenerator::refForAtom(Atom* atom, const Node* /* node */) @@ -3983,26 +4087,33 @@ QString DitaXmlGenerator::getLink(const Atom* atom, Atom* targetAtom = 0; QString first = path.first().trimmed(); - if (first.isEmpty()) + if (first.isEmpty()) { *node = relative; - else if (first.endsWith(".html")) + } + else if (first.endsWith(".html")) { *node = myTree->root()->findNode(first, Node::Fake); + } else { *node = marker->resolveTarget(first, myTree, relative); - if (!*node) + if (!*node) { *node = myTree->findFakeNodeByTitle(first); - if (!*node) + } + if (!*node) { *node = myTree->findUnambiguousTarget(first, targetAtom); + } } if (*node) { - if (!(*node)->url().isEmpty()) + if (!(*node)->url().isEmpty()) { return (*node)->url(); - else + } + else { path.removeFirst(); + } } - else + else { *node = relative; + } if (*node && (*node)->status() == Node::Obsolete) { if (relative && (relative->parent() != *node) && @@ -4075,13 +4186,13 @@ void DitaXmlGenerator::generateStatus(const Node* node, CodeMarker* marker) Atom *targetAtom = 0; if (fakeNode && node->type() == Node::Class) { QString oldName(node->name()); - targetAtom = myTree->findTarget(oldName.replace("3", ""), - fakeNode); + targetAtom = myTree->findTarget(oldName.replace("3",""),fakeNode); } if (targetAtom) { - text << Atom(Atom::Link, linkForNode(fakeNode, node) + "#" + - refForAtom(targetAtom, fakeNode)); + QString fn = fileName(fakeNode); + QString guid = lookupGuid(fn,refForAtom(targetAtom,fakeNode)); + text << Atom(Atom::GuidLink, fn + "#" + guid); } else text << Atom(Atom::Link, "Porting to Qt 4"); diff --git a/tools/qdoc3/ditaxmlgenerator.h b/tools/qdoc3/ditaxmlgenerator.h index dd0d56e..f781290 100644 --- a/tools/qdoc3/ditaxmlgenerator.h +++ b/tools/qdoc3/ditaxmlgenerator.h @@ -39,10 +39,6 @@ ** ****************************************************************************/ -/* - ditaxmlgenerator.h -*/ - #ifndef DITAXMLGENERATOR_H #define DITAXMLGENERATOR_H @@ -61,7 +57,8 @@ typedef QMap ParentMaps; typedef QMap NodeMap; typedef QMap NewClassMaps; -class HelpProjectWriter; +typedef QMap GuidMap; +typedef QMap GuidMaps; class DitaXmlGenerator : public PageGenerator { @@ -107,6 +104,7 @@ class DitaXmlGenerator : public PageGenerator virtual void generateFakeNode(const FakeNode* fake, CodeMarker* marker); virtual QString fileExtension(const Node* node) const; virtual QString refForNode(const Node* node); + virtual QString guidForNode(const Node* node); virtual QString linkForNode(const Node* node, const Node* relative); virtual QString refForAtom(Atom* atom, const Node* node); @@ -250,6 +248,8 @@ class DitaXmlGenerator : public PageGenerator QString writeGuidAttribute(QString text); void writeGuidAttribute(Node* node); QString lookupGuid(QString text); + QString lookupGuid(const QString& fileName, const QString& text); + GuidMap* lookupGuidMap(const QString& fileName); virtual void beginSubPage(const Location& location, const QString& fileName); virtual void endSubPage(); QXmlStreamWriter& xmlWriter(); @@ -262,6 +262,7 @@ class DitaXmlGenerator : public PageGenerator private: QMap refMap; QMap name2guidMap; + GuidMaps guidMaps; int codeIndent; bool inLink; bool inObsoleteLink; diff --git a/tools/qdoc3/pagegenerator.cpp b/tools/qdoc3/pagegenerator.cpp index 39ee98b..f4c471c 100644 --- a/tools/qdoc3/pagegenerator.cpp +++ b/tools/qdoc3/pagegenerator.cpp @@ -257,7 +257,12 @@ QString PageGenerator::fileBase(const Node *node) const return res; } -QString PageGenerator::fileName(const Node *node) const +/*! + If the \a node has a URL, return the URL as the file name. + Otherwise, construct the file name from the fileBase() and + the fileExtension(), and return the constructed name. + */ +QString PageGenerator::fileName(const Node* node) const { if (!node->url().isEmpty()) return node->url(); @@ -268,9 +273,12 @@ QString PageGenerator::fileName(const Node *node) const return name; } +/*! + Return the current output file name. + */ QString PageGenerator::outFileName() { - return QFileInfo(static_cast(out().device())->fileName()).fileName(); + return QFileInfo(static_cast(out().device())->fileName()).fileName(); } /*! @@ -302,6 +310,11 @@ void PageGenerator::endSubPage() delete outStreamStack.pop(); } +/*! + Used for writing to the current output stream. Returns a + reference to the crrent output stream, which is then used + with the \c {<<} operator for writing. + */ QTextStream &PageGenerator::out() { return *outStreamStack.top(); diff --git a/tools/qdoc3/text.cpp b/tools/qdoc3/text.cpp index 7093a43..11d7edd 100644 --- a/tools/qdoc3/text.cpp +++ b/tools/qdoc3/text.cpp @@ -144,7 +144,9 @@ QString Text::toString() const QString str; const Atom *atom = firstAtom(); while ( atom != 0 ) { - if ( atom->type() == Atom::String || atom->type() == Atom::AutoLink ) + if ( atom->type() == Atom::String || + atom->type() == Atom::AutoLink || + atom->type() == Atom::GuidLink) str += atom->string(); atom = atom->next(); } -- cgit v0.12 From 7d61e1d6d32d93fa5a023caade59f3af4923f2e8 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Mon, 27 Sep 2010 12:13:16 +0200 Subject: qdoc: Corrected output for the AutoLink case. Now many more elements are generated correctly. --- tools/qdoc3/ditaxmlgenerator.cpp | 26 +++++++++++++------------- tools/qdoc3/ditaxmlgenerator.h | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp index 16215cd..9652f48 100644 --- a/tools/qdoc3/ditaxmlgenerator.cpp +++ b/tools/qdoc3/ditaxmlgenerator.cpp @@ -392,7 +392,7 @@ DitaXmlGenerator::DitaXmlGenerator() myTree(0), slow(false), obsoleteLinks(false), - noLinks(0), + noLinks(false), tableColumnCount(0) { // nothing yet. @@ -656,7 +656,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, case Atom::AbstractRight: break; case Atom::AutoLink: - if ((noLinks > 0) && !inLink && !inContents && !inSectionHeading) { + if (!noLinks && !inLink && !inContents && !inSectionHeading) { const Node* node = 0; QString link = getLink(atom, relative, marker, &node); if (!link.isEmpty()) { @@ -681,8 +681,10 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, } if (inApiDesc) xmlWriter().writeStartElement("p"); - else + else { + noLinks = true; xmlWriter().writeStartElement(SHORTDESC); + } if (relative->type() == Node::Property || relative->type() == Node::Variable) { QString str; @@ -715,6 +717,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, case Atom::BriefRight: if (relative->type() != Node::Fake) { xmlWriter().writeEndElement(); // or

+ noLinks = false; } break; case Atom::C: @@ -1126,7 +1129,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, break; case Atom::LinkNode: { - const Node *node = CodeMarker::nodeForString(atom->string()); + const Node* node = CodeMarker::nodeForString(atom->string()); beginLink(linkForNode(node, relative), node, relative, marker); skipAhead = 1; } @@ -2094,11 +2097,11 @@ void DitaXmlGenerator::generateBrief(const Node* node, CodeMarker* marker) { Text brief = node->doc().briefText(); if (!brief.isEmpty()) { - ++noLinks; + noLinks = true; xmlWriter().writeStartElement(SHORTDESC); generateText(brief, node, marker); xmlWriter().writeEndElement(); // - --noLinks; + noLinks = false; } } @@ -3610,8 +3613,6 @@ QString DitaXmlGenerator::refForNode(const Node* node) QString DitaXmlGenerator::guidForNode(const Node* node) { - QString ref; - switch (node->type()) { case Node::Namespace: case Node::Class: @@ -3633,14 +3634,13 @@ QString DitaXmlGenerator::guidForNode(const Node* node) return guidForNode(fn->associatedProperty()); } else { - ref = fn->name(); + QString ref = fn->name(); if (fn->overloadNumber() != 1) { ref += "-" + QString::number(fn->overloadNumber()); -#if 0 - qDebug() << "guidForNode() overloaded function:" << ref; -#endif + //qDebug() << "guidForNode() overloaded function:" << outFileName() << ref; } } + return fn->guid(); } case Node::Fake: if (node->subType() != Node::QmlPropertyGroup) @@ -3657,7 +3657,7 @@ QString DitaXmlGenerator::guidForNode(const Node* node) case Node::Target: return node->guid(); } - return registerRef(ref); + return QString(); } /*! diff --git a/tools/qdoc3/ditaxmlgenerator.h b/tools/qdoc3/ditaxmlgenerator.h index f781290..484ff2f 100644 --- a/tools/qdoc3/ditaxmlgenerator.h +++ b/tools/qdoc3/ditaxmlgenerator.h @@ -291,7 +291,7 @@ class DitaXmlGenerator : public PageGenerator const Tree* myTree; bool slow; bool obsoleteLinks; - int noLinks; + bool noLinks; int tableColumnCount; QMap moduleClassMap; QMap moduleNamespaceMap; -- cgit v0.12