summaryrefslogtreecommitdiffstats
path: root/src/tools/qdoc/ditaxmlgenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/qdoc/ditaxmlgenerator.cpp')
-rw-r--r--src/tools/qdoc/ditaxmlgenerator.cpp230
1 files changed, 127 insertions, 103 deletions
diff --git a/src/tools/qdoc/ditaxmlgenerator.cpp b/src/tools/qdoc/ditaxmlgenerator.cpp
index bbd32204ce..c2a5cdb8b8 100644
--- a/src/tools/qdoc/ditaxmlgenerator.cpp
+++ b/src/tools/qdoc/ditaxmlgenerator.cpp
@@ -765,7 +765,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
case Atom::AutoLink:
if (!noLinks && !inLink_ && !inContents_ && !inSectionHeading_) {
const Node* node = 0;
- QString link = getLink(atom, relative, &node);
+ QString link = getAutoLink(atom, relative, &node);
if (!link.isEmpty()) {
beginLink(link);
generateLink(atom, marker);
@@ -1308,13 +1308,11 @@ int DitaXmlGenerator::generateAtom(const Atom *atom,
case Atom::Link:
{
const Node *node = 0;
- QString myLink = getLink(atom, relative, &node);
- //if (myLink.isEmpty())
- //myLink = getCollisionLink(atom);
- if (myLink.isEmpty() && !noLinkErrors())
+ QString link = getLink(atom, relative, &node);
+ if (link.isEmpty() && !noLinkErrors())
relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string()));
else if (!inSectionHeading_)
- beginLink(myLink);
+ beginLink(link);
skipAhead = 1;
}
break;
@@ -3722,6 +3720,129 @@ QString DitaXmlGenerator::fileName(const Node* node)
return Generator::fileName(node);
}
+/*!
+ This function is called for links, i.e. for words that
+ are marked with the qdoc link command. For autolinks
+ that are not marked with the qdoc link command, qdoc
+ calls getAutoLink().
+
+ Return the link represented by the \a atom, and set \a node
+ to point to the target node for that link. \a relative points
+ to the node holding the qdoc comment where the link command
+ was found.
+ */
+QString DitaXmlGenerator::getLink(const Atom *atom, const Node *relative, const Node** node)
+{
+ if (atom->string().contains(QLatin1Char(':')) && (atom->string().startsWith("file:") ||
+ atom->string().startsWith("http:") ||
+ atom->string().startsWith("https:") ||
+ atom->string().startsWith("ftp:") ||
+ atom->string().startsWith("mailto:"))) {
+ return atom->string(); // It's some kind of protocol.
+ }
+
+ QString ref;
+ QString link;
+ QStringList path = atom->string().split("#");
+ QString first = path.first().trimmed();
+
+ *node = 0;
+ if (first.isEmpty())
+ *node = relative; // search for a target on the current page.
+ else {
+ if (first.endsWith(".html")) { // The target is an html file.
+ *node = qdb_->findNodeByNameAndType(QStringList(first), Node::Document);
+ }
+ else if (first.endsWith("()")) { // The target is a C++ function or QML method.
+ *node = qdb_->resolveFunctionTarget(first, relative);
+ }
+ else {
+ *node = qdb_->resolveTarget(first, relative);
+ if (!(*node))
+ *node = qdb_->findDocNodeByTitle(first);
+ if (!(*node)) {
+ *node = qdb_->findUnambiguousTarget(first, ref);
+ if (*node && !(*node)->url().isEmpty() && !ref.isEmpty()) {
+ QString final = (*node)->url() + "#" + ref;
+ return final;
+ }
+ }
+ }
+ }
+ if (!(*node))
+ return link; // empty
+
+ if (!(*node)->url().isEmpty())
+ return (*node)->url();
+
+ if (!path.isEmpty()) {
+ ref = qdb_->findTarget(path.first(), *node);
+ if (ref.isEmpty())
+ return link; // empty
+ }
+
+ /*
+ Given that *node is not null, we now cconstruct a link
+ to the page that *node represents, and then if we found
+ a target on that page, we connect the target to the link
+ with '#'.
+ */
+ link = linkForNode(*node, relative);
+ if (*node && (*node)->subType() == Node::Image)
+ link = "images/used-in-examples/" + link;
+ if (!ref.isEmpty())
+ link += QLatin1Char('#') + ref;
+ return link;
+}
+
+/*!
+ This function is called for autolinks, i.e. for words that
+ are not marked with the qdoc link command that qdoc has
+ reason to believe should be links. For links marked with
+ the qdoc link command, qdoc calls getLink().
+
+ Return the link represented by the \a atom, and set \a node
+ to point to the target node for that link. \a relative points
+ to the node holding the qdoc comment where the link command
+ was found.
+ */
+QString DitaXmlGenerator::getAutoLink(const Atom *atom, const Node *relative, const Node** node)
+{
+ QString ref;
+ QString link;
+ QString target = atom->string().trimmed();
+ *node = 0;
+
+ if (target.endsWith("()")) { // The target is a C++ function or QML method.
+ *node = qdb_->resolveFunctionTarget(target, relative);
+ }
+ else {
+ *node = qdb_->resolveTarget(target, relative);
+ if (!(*node)) {
+ *node = qdb_->findDocNodeByTitle(target);
+ }
+ if (!(*node)) {
+ *node = qdb_->findUnambiguousTarget(target, ref);
+ if (*node && !(*node)->url().isEmpty() && !ref.isEmpty()) {
+ QString final = (*node)->url() + "#" + ref;
+ return final;
+ }
+ }
+ }
+
+ if (!(*node))
+ return link; // empty
+
+ if (!(*node)->url().isEmpty())
+ return (*node)->url();
+
+ link = linkForNode(*node, relative);
+ if (!ref.isEmpty())
+ link += QLatin1Char('#') + ref;
+ return link;
+}
+
+
QString DitaXmlGenerator::linkForNode(const Node* node, const Node* relative)
{
if (node == 0 || node == relative)
@@ -3832,103 +3953,6 @@ const QPair<QString,QString> DitaXmlGenerator::anchorForNode(const Node* node)
return anchorPair;
}
-QString DitaXmlGenerator::getLink(const Atom* atom, const Node* relative, const Node** node)
-{
- QString link;
- *node = 0;
- inObsoleteLink = false;
-
- if (atom->string().contains(QLatin1Char(':')) &&
- (atom->string().startsWith("file:")
- || atom->string().startsWith("http:")
- || atom->string().startsWith("https:")
- || atom->string().startsWith("ftp:")
- || atom->string().startsWith("mailto:"))) {
-
- link = atom->string();
- }
- else {
- QStringList path;
- if (atom->string().contains('#'))
- path = atom->string().split('#');
- else
- path.append(atom->string());
-
- QString ref;
- QString first = path.first().trimmed();
-
- if (first.isEmpty())
- *node = relative;
- else if (first.endsWith(".html"))
- *node = qdb_->findNodeByNameAndType(QStringList(first), Node::Document);
- else if (first.endsWith("()")) // The target is a C++ function or QML method.
- *node = qdb_->resolveFunctionTarget(first, relative);
- else {
- *node = qdb_->resolveTarget(first, relative);
- if (!(*node))
- *node = qdb_->findDocNodeByTitle(first);
- if (!*node)
- *node = qdb_->findUnambiguousTarget(first, ref);
- }
-
- if (*node) {
- if (!(*node)->url().isEmpty())
- return (*node)->url();
- else
- path.removeFirst();
- }
- else
- *node = relative;
-
- if (*node && (*node)->status() == Node::Obsolete) {
- if (relative && (relative->parent() != *node) &&
- (relative->status() != Node::Obsolete)) {
- bool porting = false;
- if (relative->isDocNode()) {
- const DocNode* fake = static_cast<const DocNode*>(relative);
- if (fake->title().startsWith("Porting"))
- porting = true;
- }
- QString name = relative->plainFullName();
- if (!porting && !name.startsWith("Q3")) {
- if (obsoleteLinks) {
- relative->doc().location().warning(tr("Link to obsolete item '%1' in %2")
- .arg(atom->string())
- .arg(name));
- }
- inObsoleteLink = true;
- }
- }
- }
-
- while (!path.isEmpty()) {
- ref = qdb_->findTarget(path.first(), *node);
- if (ref.isEmpty())
- break;
- path.removeFirst();
- }
-
- if (path.isEmpty()) {
- link = linkForNode(*node, relative);
- if (*node && (*node)->subType() == Node::Image)
- link = "images/used-in-examples/" + link;
- if (!ref.isEmpty()) {
- if (link.isEmpty())
- link = outFileName();
- QString guid = lookupGuid(link, ref);
- link += QLatin1Char('#') + guid;
- }
- else if (!link.isEmpty() && *node && (link.endsWith(".xml") || link.endsWith(".dita"))) {
- link += QLatin1Char('#') + (*node)->guid();
- }
- }
- }
- if (!link.isEmpty() && link[0] == '#') {
- link.prepend(outFileName());
- }
- return link;
-}
-
void DitaXmlGenerator::generateStatus(const Node* node, CodeMarker* marker)
{
Text text;