From 284958c2221cabc9b5cbc9cacb2fc848204c9369 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Thu, 14 Feb 2013 10:39:37 +0100 Subject: [PATCH] Doc: Support for meta-content in manifest XML files This change makes qdoc support additional attributes and tags written to example/demo manifest files. The goal is to enable highlighting of selected items, as well as having additional content to make searching for specific categories work better in Qt Creator welcome screen. This meta-content is stored in manifest-meta.qdocconf, which is loaded globally for all modules. Tag handling is also changed to use a QSet to eliminate possible duplicate tags. Task-number: QTBUG-29354 Change-Id: I2c4b2dff6229172efbecc2bfc1c269017edc4d56 Reviewed-by: Martin Smith Reviewed-by: Jerome Pasion --- doc/global/manifest-meta.qdocconf | 33 ++++++++++++++ doc/global/qt-module-defaults.qdocconf | 1 + src/tools/qdoc/config.h | 1 + src/tools/qdoc/htmlgenerator.cpp | 60 +++++++++++++++++++++++--- src/tools/qdoc/htmlgenerator.h | 9 ++++ 5 files changed, 99 insertions(+), 5 deletions(-) create mode 100644 doc/global/manifest-meta.qdocconf diff --git a/doc/global/manifest-meta.qdocconf b/doc/global/manifest-meta.qdocconf new file mode 100644 index 00000000000..3bfc3e12d4d --- /dev/null +++ b/doc/global/manifest-meta.qdocconf @@ -0,0 +1,33 @@ +# Additional meta information (attributes for matched entries, as well as tags) +# to be added to manifest.xml files. +# +# manifestmeta.filters = ,,... +# +# manifestmeta..names = /,/,.. +# manifestmeta..attributes = ,,.. +# manifestmeta..tags = ,,.. +# +# .names specify all the module/name combinations to apply the +# attributes/tags to. You can use simple wildcard matching by appending +# '*' at the end of name. +# +# Note: You cannot use operators (+, =, -) in the names. +# +# Examples: add a 'isHighlighted' attribute for two 'Analog Clock' examples, +# add a 'database' tag for QtSql all examples, a 'webkit' tag for QtWebKit +# examples, and a 'qt5' tag for all examples +# +# manifestmeta.filters = highlighted sql webkit global +# +# manifestmeta.highlighted.names = "QtGui/Analog Clock Window Example" \ +# "QtWidgets/Analog Clock Example" +# manifestmeta.highlighted.attributes = isHighlighted:true +# +# manifestmeta.sql.names = "QtSql/*" +# manifestmeta.sql.tags = database +# +# manifestmeta.webkit.names = "QtWebKitExamples/*" +# manifestmeta.webkit.tags = webkit +# +# manifestmeta.global.names = * +# manifestmeta.global.tags = qt5 diff --git a/doc/global/qt-module-defaults.qdocconf b/doc/global/qt-module-defaults.qdocconf index 15b3724355b..0365d5a6cd4 100644 --- a/doc/global/qt-module-defaults.qdocconf +++ b/doc/global/qt-module-defaults.qdocconf @@ -3,6 +3,7 @@ include(qt-cpp-ignore.qdocconf) include(qt-defines.qdocconf) include(qt-html-templates-offline.qdocconf) include(compat.qdocconf) +include(manifest-meta.qdocconf) dita.metadata.default.author = Qt Project dita.metadata.default.permissions = all diff --git a/src/tools/qdoc/config.h b/src/tools/qdoc/config.h index 2c655cdf236..521f1c12b81 100644 --- a/src/tools/qdoc/config.h +++ b/src/tools/qdoc/config.h @@ -188,6 +188,7 @@ private: #define CONFIG_INDEXES "indexes" #define CONFIG_LANGUAGE "language" #define CONFIG_MACRO "macro" +#define CONFIG_MANIFESTMETA "manifestmeta" #define CONFIG_NATURALLANGUAGE "naturallanguage" #define CONFIG_NOLINKERRORS "nolinkerrors" #define CONFIG_OBSOLETELINKS "obsoletelinks" diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index 87181617030..2666f10eb43 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -223,6 +223,7 @@ void HtmlGenerator::initializeGenerator(const Config &config) QString prefix = CONFIG_QHP + Config::dot + project + Config::dot; manifestDir = "qthelp://" + config.getString(prefix + "namespace"); manifestDir += QLatin1Char('/') + config.getString(prefix + "virtualFolder") + QLatin1Char('/'); + readManifestMetaContent(config); examplesPath = config.getString(CONFIG_EXAMPLESINSTALLPATH); if (!examplesPath.isEmpty()) examplesPath += QLatin1Char('/'); @@ -3991,10 +3992,11 @@ void HtmlGenerator::generateManifestFiles() generateManifestFile("examples", "example"); generateManifestFile("demos", "demo"); ExampleNode::exampleNodeMap.clear(); + manifestMetaContent.clear(); } /*! - This function is called by generaqteManiferstFile(), once + This function is called by generateManifestFiles(), once for each manifest file to be generated. \a manifest is the type of manifest file. */ @@ -4086,6 +4088,36 @@ void HtmlGenerator::generateManifestFile(QString manifest, QString element) } if (!en->imageFileName().isEmpty()) writer.writeAttribute("imageUrl", manifestDir + en->imageFileName()); + + QString fullName = project + QLatin1Char('/') + en->title(); + QSet tags; + for (int idx=0; idx < manifestMetaContent.size(); ++idx) { + foreach (const QString &name, manifestMetaContent[idx].names) { + bool match = false; + int wildcard = name.indexOf(QChar('*')); + switch (wildcard) { + case -1: // no wildcard, exact match + match = (fullName == name); + break; + case 0: // '*' matches all + match = true; + break; + default: // match with wildcard at the end + match = fullName.startsWith(name.left(wildcard)); + } + if (match) { + tags += manifestMetaContent[idx].tags; + foreach (const QString &attr, manifestMetaContent[idx].attributes) { + QStringList attrList = attr.split(QLatin1Char(':'), QString::SkipEmptyParts); + if (attrList.count() == 1) + attrList.append(QStringLiteral("true")); + if (attrList.count() == 2) + writer.writeAttribute(attrList[0], attrList[1]); + } + } + } + } + writer.writeStartElement("description"); Text brief = en->doc().briefText(); if (!brief.isEmpty()) @@ -4093,12 +4125,11 @@ void HtmlGenerator::generateManifestFile(QString manifest, QString element) else writer.writeCDATA(QString("No description available")); writer.writeEndElement(); // description - QStringList tags = en->title().toLower().split(QLatin1Char(' ')); + tags += QSet::fromList(en->title().toLower().split(QLatin1Char(' '))); if (!tags.isEmpty()) { writer.writeStartElement("tags"); bool wrote_one = false; - for (int n=0; n0 && wrote_one) + if (wrote_one) writer.writeCharacters(","); writer.writeCharacters(tag); wrote_one = true; @@ -4162,6 +4193,25 @@ void HtmlGenerator::generateManifestFile(QString manifest, QString element) file.close(); } +/*! + Reads metacontent - additional attributes and tags to apply + when generating manifest files, read from config. Takes the + configuration class \a config as a parameter. + */ +void HtmlGenerator::readManifestMetaContent(const Config &config) +{ + QStringList names = config.getStringList(CONFIG_MANIFESTMETA + Config::dot + QStringLiteral("filters")); + + foreach (const QString &manifest, names) { + ManifestMetaFilter filter; + QString prefix = CONFIG_MANIFESTMETA + Config::dot + manifest + Config::dot; + filter.names = config.getStringSet(prefix + QStringLiteral("names")); + filter.attributes = config.getStringSet(prefix + QStringLiteral("attributes")); + filter.tags = config.getStringSet(prefix + QStringLiteral("tags")); + manifestMetaContent.append(filter); + } +} + /*! Find global entities that have documentation but no \e{relates} comand. Report these as errors if they diff --git a/src/tools/qdoc/htmlgenerator.h b/src/tools/qdoc/htmlgenerator.h index 65d874f619a..f2efab78a1b 100644 --- a/src/tools/qdoc/htmlgenerator.h +++ b/src/tools/qdoc/htmlgenerator.h @@ -108,6 +108,7 @@ protected: virtual QString linkForNode(const Node *node, const Node *relative); void generateManifestFile(QString manifest, QString element); + void readManifestMetaContent(const Config &config); private: enum SubTitleSize { SmallSubTitle, LargeSubTitle }; @@ -118,6 +119,13 @@ private: EndMark }; + struct ManifestMetaFilter + { + QSet names; + QSet attributes; + QSet tags; + }; + const QPair anchorForNode(const Node *node); void generateBreadCrumbs(const QString& title, const Node *node, @@ -242,6 +250,7 @@ private: bool obsoleteLinks; QStack xmlWriterStack; static int id; + QList manifestMetaContent; public: static bool debugging_on; static QString divNavTop;