aboutsummaryrefslogtreecommitdiffstats
path: root/sources
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2018-05-04 16:27:39 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2018-05-07 15:08:42 +0000
commitc2d0e1ac39b7aa96263e9311128eda56fa0f9aa7 (patch)
tree525f2fcb9551471238f78841511684590fff5fd2 /sources
parent4c54e22072765f0b3654e03482943d0fe1a6a0e7 (diff)
QtXmlToSphinx: Refactor link handling
Forward declare QtXmlToSphinx::LinkContext as a public struct and move the definition to the source file. Replace the linkTag/linkTagEnding strings by an enumeration for the type and flags for storing the bold/italic state. Move the formatting to an operator<<(QTextStream,LinkContext) for clarity. Streamline the code checking the link text against the reference in handleLinkText(), avoiding some unnecessary tests. Add an 'External' type for external pages which do not have a role keyword. This fixes: - Undoes a breakage introduced by c5582d3120249a902681454b2319df765ffa2cd8 converting all link refs to RST labels, clobbering the '~' used for some function references. This is now limited to page type links. - Broken handling of links within italic/bold: The assignment to the linkTag variable by type would clobber the previously assigned italic/bold markers - Enable external links without role Task-number: PYSIDE-363 Change-Id: I2e9a8cd80df93a77f3c6c9f8593243b35eeeb56e Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'sources')
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp162
-rw-r--r--sources/shiboken2/generator/qtdoc/qtdocgenerator.h15
2 files changed, 131 insertions, 46 deletions
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
index 98cdbf286..7206d7ca8 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp
@@ -230,6 +230,78 @@ static QString msgFallbackWarning(const QXmlStreamReader &reader, const QString
return msgTagWarning(reader, context, tag, message);
}
+struct QtXmlToSphinx::LinkContext
+{
+ enum Type
+ {
+ Method = 0x1, Function = 0x2,
+ FunctionMask = Method | Function,
+ Class = 0x4, Attribute = 0x8, Module = 0x10,
+ Reference = 0x20, External= 0x40
+ };
+
+ enum Flags { InsideBold = 0x1, InsideItalic = 0x2 };
+
+ explicit LinkContext(const QString &ref) : linkRef(ref) {}
+
+ QString linkRef;
+ QString linkText;
+ Type type = Reference;
+ int flags = 0;
+};
+
+static const char *linkKeyWord(QtXmlToSphinx::LinkContext::Type type)
+{
+ switch (type) {
+ case QtXmlToSphinx::LinkContext::Method:
+ return ":meth:";
+ case QtXmlToSphinx::LinkContext::Function:
+ return ":func:";
+ case QtXmlToSphinx::LinkContext::Class:
+ return ":class:";
+ case QtXmlToSphinx::LinkContext::Attribute:
+ return ":attr:";
+ case QtXmlToSphinx::LinkContext::Module:
+ return ":mod:";
+ case QtXmlToSphinx::LinkContext::Reference:
+ return ":ref:";
+ case QtXmlToSphinx::LinkContext::External:
+ break;
+ }
+ return "";
+}
+
+QTextStream &operator<<(QTextStream &str, const QtXmlToSphinx::LinkContext &linkContext)
+{
+ // Temporarily turn off bold/italic since links do not work within
+ if (linkContext.flags & QtXmlToSphinx::LinkContext::InsideBold)
+ str << "**";
+ else if (linkContext.flags & QtXmlToSphinx::LinkContext::InsideItalic)
+ str << '*';
+ str << ' ' << linkKeyWord(linkContext.type) << '`';
+ const bool isExternal = linkContext.type == QtXmlToSphinx::LinkContext::External;
+ if (!linkContext.linkText.isEmpty()) {
+ writeEscapedRstText(str, linkContext.linkText);
+ if (isExternal && !linkContext.linkText.endsWith(QLatin1Char(' ')))
+ str << ' ';
+ str << '<';
+ }
+ // Convert page titles to RST labels
+ str << (linkContext.type == QtXmlToSphinx::LinkContext::Reference
+ ? toRstLabel(linkContext.linkRef) : linkContext.linkRef);
+ if (!linkContext.linkText.isEmpty())
+ str << '>';
+ str << '`';
+ if (isExternal)
+ str << '_';
+ str << ' ';
+ if (linkContext.flags & QtXmlToSphinx::LinkContext::InsideBold)
+ str << "**";
+ else if (linkContext.flags & QtXmlToSphinx::LinkContext::InsideItalic)
+ str << '*';
+ return str;
+}
+
QtXmlToSphinx::QtXmlToSphinx(QtDocGenerator* generator, const QString& doc, const QString& context)
: m_context(context), m_generator(generator), m_insideBold(false), m_insideItalic(false)
{
@@ -893,20 +965,15 @@ QtXmlToSphinx::LinkContext *QtXmlToSphinx::handleLinkStart(const QString &type,
{
ref.replace(QLatin1String("::"), QLatin1String("."));
ref.remove(QLatin1String("()"));
- LinkContext *result = new LinkContext(toRstLabel(ref), type);
-
- result->linkTagEnding = QLatin1String("` ");
- if (m_insideBold) {
- result->linkTag.prepend(QLatin1String("**"));
- result->linkTagEnding.append(QLatin1String("**"));
- } else if (m_insideItalic) {
- result->linkTag.prepend(QLatin1Char('*'));
- result->linkTagEnding.append(QLatin1Char('*'));
- }
+ LinkContext *result = new LinkContext(ref);
+ if (m_insideBold)
+ result->flags |= LinkContext::InsideBold;
+ else if (m_insideItalic)
+ result->flags |= LinkContext::InsideItalic;
- if (result->type == functionLinkType() && !m_context.isEmpty()) {
- result->linkTag = QLatin1String(" :meth:`");
+ if (type == functionLinkType() && !m_context.isEmpty()) {
+ result->type = LinkContext::Method;
const QVector<QStringRef> rawlinklist = result->linkRef.splitRef(QLatin1Char('.'));
if (rawlinklist.size() == 1 || rawlinklist.constFirst() == m_context) {
QString context = resolveContextForMethod(rawlinklist.constLast().toString());
@@ -915,10 +982,10 @@ QtXmlToSphinx::LinkContext *QtXmlToSphinx::handleLinkStart(const QString &type,
} else {
result->linkRef = expandFunction(result->linkRef);
}
- } else if (result->type == functionLinkType() && m_context.isEmpty()) {
- result->linkTag = QLatin1String(" :func:`");
- } else if (result->type == classLinkType()) {
- result->linkTag = QLatin1String(" :class:`");
+ } else if (type == functionLinkType() && m_context.isEmpty()) {
+ result->type = LinkContext::Function;
+ } else if (type == classLinkType()) {
+ result->type = LinkContext::Class;
if (const TypeEntry *type = TypeDatabase::instance()->findType(result->linkRef)) {
result->linkRef = type->qualifiedTargetLangName();
} else { // fall back to the old heuristic if the type wasn't found.
@@ -930,37 +997,64 @@ QtXmlToSphinx::LinkContext *QtXmlToSphinx::handleLinkStart(const QString &type,
+ QLatin1Char('.'));
}
}
- } else if (result->type == QLatin1String("enum")) {
- result->linkTag = QLatin1String(" :attr:`");
- } else if (result->type == QLatin1String("page") && result->linkRef == m_generator->moduleName()) {
- result->linkTag = QLatin1String(" :mod:`");
+ } else if (type == QLatin1String("enum")) {
+ result->type = LinkContext::Attribute;
+ } else if (type == QLatin1String("page")) {
+ // Module, external web page or reference
+ if (result->linkRef == m_generator->moduleName())
+ result->type = LinkContext::Module;
+ else if (result->linkRef.startsWith(QLatin1String("http")))
+ result->type = LinkContext::External;
+ else
+ result->type = LinkContext::Reference;
} else {
- result->linkTag = QLatin1String(" :ref:`");
+ result->type = LinkContext::Reference;
}
return result;
}
-void QtXmlToSphinx::handleLinkText(LinkContext *linkContext, QString linktext) const
+// <link raw="Model/View Classes" href="model-view-programming.html#model-view-classes"
+// type="page" page="Model/View Programming">Model/View Classes</link>
+// <link type="page" page="http://doc.qt.io/qt-5/class.html">QML types</link>
+// <link raw="Qt Quick" href="qtquick-index.html" type="page" page="Qt Quick">Qt Quick</link>
+// <link raw="QObject" href="qobject.html" type="class">QObject</link>
+// <link raw="Qt::Window" href="qt.html#WindowType-enum" type="enum" enum="Qt::WindowType">Qt::Window</link>
+// <link raw="QNetworkSession::reject()" href="qnetworksession.html#reject" type="function">QNetworkSession::reject()</link>
+
+static QString fixLinkText(const QtXmlToSphinx::LinkContext *linkContext,
+ QString linktext)
{
+ if (linkContext->type == QtXmlToSphinx::LinkContext::External
+ || linkContext->type == QtXmlToSphinx::LinkContext::Reference) {
+ return linktext;
+ }
+ // For the language reference documentation, clear the link text if it matches
+ // the function/class/enumeration name.
linktext.replace(QLatin1String("::"), QLatin1String("."));
+ if (linkContext->linkRef == linktext)
+ return QString();
+ if ((linkContext->type & QtXmlToSphinx::LinkContext::FunctionMask) != 0
+ && (linkContext->linkRef + QLatin1String("()")) == linktext) {
+ return QString();
+ }
const QStringRef item = linkContext->linkRef.splitRef(QLatin1Char('.')).constLast();
- if (linkContext->linkRef == linktext
- || (linkContext->linkRef + QLatin1String("()")) == linktext
- || item == linktext
- || (item + QLatin1String("()")) == linktext) {
- linkContext->linkText.clear();
- } else {
- linkContext->linkText = linktext + QLatin1Char('<');
+ if (item == linktext)
+ return QString();
+ if ((linkContext->type & QtXmlToSphinx::LinkContext::FunctionMask) != 0
+ && (item + QLatin1String("()")) == linktext) {
+ return QString();
}
+ return linktext;
+}
+
+void QtXmlToSphinx::handleLinkText(LinkContext *linkContext, const QString &linktext) const
+{
+ linkContext->linkText = fixLinkText(linkContext, linktext);
}
void QtXmlToSphinx::handleLinkEnd(LinkContext *linkContext)
{
- if (!linkContext->linkText.isEmpty())
- linkContext->linkTagEnding.prepend(QLatin1Char('>'));
- m_output << linkContext->linkTag << linkContext->linkText;
- writeEscapedRstText(m_output, linkContext->linkRef);
- m_output << linkContext->linkTagEnding;
+ m_output << *linkContext;
}
// Copy images that are placed in a subdirectory "images" under the webxml files
diff --git a/sources/shiboken2/generator/qtdoc/qtdocgenerator.h b/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
index d68eb1ea5..e467abe90 100644
--- a/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
+++ b/sources/shiboken2/generator/qtdoc/qtdocgenerator.h
@@ -49,6 +49,8 @@ class QtDocGenerator;
class QtXmlToSphinx
{
public:
+ struct LinkContext;
+
struct InlineImage
{
QString tag;
@@ -114,17 +116,6 @@ public:
}
private:
- struct LinkContext
- {
- LinkContext(const QString &ref, const QString &lType) : linkRef(ref), type(lType) {}
-
- QString linkTag;
- QString linkRef;
- QString linkText;
- QString linkTagEnding;
- QString type;
- };
-
QString resolveContextForMethod(const QString& methodName) const;
QString expandFunction(const QString& function) const;
QString transform(const QString& doc);
@@ -161,7 +152,7 @@ private:
void handleAnchorTag(QXmlStreamReader& reader);
LinkContext *handleLinkStart(const QString &type, QString ref) const;
- void handleLinkText(LinkContext *linkContext, QString linktext) const;
+ void handleLinkText(LinkContext *linkContext, const QString &linktext) const;
void handleLinkEnd(LinkContext *linkContext);
typedef void (QtXmlToSphinx::*TagHandler)(QXmlStreamReader&);