summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/qdoc3/atom.cpp1
-rw-r--r--tools/qdoc3/atom.h1
-rw-r--r--tools/qdoc3/ditaxmlgenerator.cpp215
-rw-r--r--tools/qdoc3/ditaxmlgenerator.h11
-rw-r--r--tools/qdoc3/pagegenerator.cpp17
-rw-r--r--tools/qdoc3/text.cpp4
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();
}