diff options
-rw-r--r-- | tools/qdoc3/atom.cpp | 1 | ||||
-rw-r--r-- | tools/qdoc3/atom.h | 1 | ||||
-rw-r--r-- | tools/qdoc3/ditaxmlgenerator.cpp | 215 | ||||
-rw-r--r-- | tools/qdoc3/ditaxmlgenerator.h | 11 | ||||
-rw-r--r-- | tools/qdoc3/pagegenerator.cpp | 17 | ||||
-rw-r--r-- | 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(); // </pre> + { + xmlWriter().writeStartElement("pre"); + xmlWriter().writeAttribute("outputclass","highlightedcode"); + QString chars = trimmedTrailing(atom->string()); + writeText(chars, marker, relative); + xmlWriter().writeEndElement(); // </pre> + } 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(); // </xref> + xmlWriter().writeEndElement(); // </li> ++p; } xmlWriter().writeEndElement(); // </ul> @@ -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<const FakeNode*>(node)->subType() == Node::ExternalPage) - return node->name(); - if (static_cast<const FakeNode*>(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<const TypedefNode *>(node); - if (typedeffe->associatedEnum()) { - return refForNode(typedeffe->associatedEnum()); + tdn = static_cast<const TypedefNode *>(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<const TypedefNode*>(node); + if (tdn->associatedEnum()) + return guidForNode(tdn->associatedEnum()); + } + return node->guid(); + case Node::Function: + { + const FunctionNode* fn = static_cast<const FunctionNode*>(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<const FakeNode*>(node)->subType() == Node::ExternalPage) + return node->name(); + if (static_cast<const FakeNode*>(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<Node*, NodeMultiMap> ParentMaps; typedef QMap<QString, const Node*> NodeMap; typedef QMap<QString, NodeMap> NewClassMaps; -class HelpProjectWriter; +typedef QMap<QString, QString> GuidMap; +typedef QMap<QString, GuidMap*> 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<QString, QString> refMap; QMap<QString, QString> 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<QFile *>(out().device())->fileName()).fileName(); + return QFileInfo(static_cast<QFile*>(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(); } |