summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDavid Boddie <david.boddie@nokia.com>2011-04-05 14:43:20 (GMT)
committerDavid Boddie <david.boddie@nokia.com>2011-04-05 14:43:20 (GMT)
commita343e8674947415f8ef3319c62a88f72458f25ad (patch)
tree54cf25c81f94911bf66b1f9f564970e91df3fdbe /tools
parent87a28f7ab7b1b94072e75740d690192bbdcfdaa5 (diff)
parenta01e0d1928aa17690d3e0ebadbac7b95bf0f0e84 (diff)
downloadQt-a343e8674947415f8ef3319c62a88f72458f25ad.zip
Qt-a343e8674947415f8ef3319c62a88f72458f25ad.tar.gz
Qt-a343e8674947415f8ef3319c62a88f72458f25ad.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-doc-team into 4.7
Diffstat (limited to 'tools')
-rw-r--r--tools/qdoc3/config.cpp6
-rw-r--r--tools/qdoc3/config.h4
-rw-r--r--tools/qdoc3/ditaxmlgenerator.cpp89
-rw-r--r--tools/qdoc3/ditaxmlgenerator.h4
-rw-r--r--tools/qdoc3/doc.cpp74
-rw-r--r--tools/qdoc3/doc.h3
-rw-r--r--tools/qdoc3/doc/qdoc-manual.qdoc180
-rw-r--r--tools/qdoc3/generator.cpp77
-rw-r--r--tools/qdoc3/generator.h5
-rw-r--r--tools/qdoc3/htmlgenerator.cpp1
-rw-r--r--tools/qdoc3/quoter.cpp3
-rw-r--r--tools/qdoc3/quoter.h2
12 files changed, 346 insertions, 102 deletions
diff --git a/tools/qdoc3/config.cpp b/tools/qdoc3/config.cpp
index 267a09c..838f6ac 100644
--- a/tools/qdoc3/config.cpp
+++ b/tools/qdoc3/config.cpp
@@ -338,7 +338,7 @@ QSet<QString> Config::subVars(const QString& var) const
{
QSet<QString> result;
QString varDot = var + QLatin1Char('.');
- QMap<QString, QString>::ConstIterator v = stringValueMap.begin();
+ QStringMultiMap::ConstIterator v = stringValueMap.begin();
while (v != stringValueMap.end()) {
if (v.key().startsWith(varDot)) {
QString subVar = v.key().mid(varDot.length());
@@ -357,10 +357,10 @@ QSet<QString> Config::subVars(const QString& var) const
with the matching keys (stripped of the prefix \a var and
mapped to their values. The pairs are inserted into \a t
*/
-void Config::subVarsAndValues(const QString& var, QStringMap& t) const
+void Config::subVarsAndValues(const QString& var, QStringMultiMap& t) const
{
QString varDot = var + QLatin1Char('.');
- QMap<QString, QString>::ConstIterator v = stringValueMap.begin();
+ QStringMultiMap::ConstIterator v = stringValueMap.begin();
while (v != stringValueMap.end()) {
if (v.key().startsWith(varDot)) {
QString subVar = v.key().mid(varDot.length());
diff --git a/tools/qdoc3/config.h b/tools/qdoc3/config.h
index 767acb1..8e19ed2 100644
--- a/tools/qdoc3/config.h
+++ b/tools/qdoc3/config.h
@@ -54,7 +54,7 @@
QT_BEGIN_NAMESPACE
-typedef QMap<QString,QString> QStringMap;
+typedef QMultiMap<QString, QString> QStringMultiMap;
class Config
{
@@ -76,7 +76,7 @@ class Config
QRegExp getRegExp(const QString& var) const;
QList<QRegExp> getRegExpList(const QString& var) const;
QSet<QString> subVars(const QString& var) const;
- void subVarsAndValues(const QString& var, QStringMap& t) const;
+ void subVarsAndValues(const QString& var, QStringMultiMap& t) const;
QStringList getAllFiles(const QString& filesVar,
const QString& dirsVar,
const QSet<QString> &excludedDirs = QSet<QString>());
diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp
index 4b4f776..1bc4992 100644
--- a/tools/qdoc3/ditaxmlgenerator.cpp
+++ b/tools/qdoc3/ditaxmlgenerator.cpp
@@ -5566,24 +5566,12 @@ void DitaXmlGenerator::writeDitaMap()
\note If \a t is found in the metadata map, it is erased.
i.e. Once you call this function for a particular \a t,
you consume \a t.
-
- At the moment, it doesn't chaeck to see if there is a
- default value for the tag. But it will eventually.
*/
bool DitaXmlGenerator::writeMetadataElement(const InnerNode* inner,
DitaXmlGenerator::DitaTag t,
bool force)
{
- QString s;
- QStringMap& metaTagMap = const_cast<QStringMap&>(inner->doc().metaTagMap());
- QStringMap::iterator i = metaTagMap.find(ditaTags[t]);
- if (i == metaTagMap.end()) {
- s = metadataDefault(t);
- }
- else {
- s = i.value();
- metaTagMap.erase(i);
- }
+ QString s = getMetadataElement(inner,t);
if (s.isEmpty() && !force)
return false;
writeStartTag(t);
@@ -5593,6 +5581,34 @@ bool DitaXmlGenerator::writeMetadataElement(const InnerNode* inner,
return true;
}
+
+/*!
+ Looks up the tag name for \a t in the map of metadata
+ values for the current topic in \a inner. If one or more
+ value sfor the tag are found, the elements are written.
+ Otherwise nothing is written.
+
+ Returns true or false depending on whether it writes
+ at least one element using the tag \a t.
+
+ \note If \a t is found in the metadata map, it is erased.
+ i.e. Once you call this function for a particular \a t,
+ you consume \a t.
+ */
+bool DitaXmlGenerator::writeMetadataElements(const InnerNode* inner,
+ DitaXmlGenerator::DitaTag t)
+{
+ QStringList s = getMetadataElements(inner,t);
+ if (s.isEmpty())
+ return false;
+ for (int i=0; i<s.size(); ++i) {
+ writeStartTag(t);
+ xmlWriter().writeCharacters(s[i]);
+ writeEndTag();
+ }
+ return true;
+}
+
/*!
Looks up the tag name for \a t in the map of metadata
values for the current topic in \a inner. If a value
@@ -5604,16 +5620,29 @@ bool DitaXmlGenerator::writeMetadataElement(const InnerNode* inner,
*/
QString DitaXmlGenerator::getMetadataElement(const InnerNode* inner, DitaXmlGenerator::DitaTag t)
{
- QString s;
- QStringMap& metaTagMap = const_cast<QStringMap&>(inner->doc().metaTagMap());
- QStringMap::iterator i = metaTagMap.find(ditaTags[t]);
- if (i != metaTagMap.end()) {
- s = i.value();
- metaTagMap.erase(i);
- }
- else {
+ QString s = Generator::getMetadataElement(inner, ditaTags[t]);
+ if (s.isEmpty())
s = metadataDefault(t);
- }
+ return s;
+}
+
+/*!
+ Looks up the tag name for \a t in the map of metadata
+ values for the current topic in \a inner. If values
+ for the tag are found, they are returned in a string
+ list.
+
+ \note If \a t is found in the metadata map, all the
+ pairs having the key \a t are erased. i.e. Once you
+ all this function for a particular \a t, you consume
+ \a t.
+ */
+QStringList DitaXmlGenerator::getMetadataElements(const InnerNode* inner,
+ DitaXmlGenerator::DitaTag t)
+{
+ QStringList s = Generator::getMetadataElements(inner,ditaTags[t]);
+ if (s.isEmpty())
+ s.append(metadataDefault(t));
return s;
}
@@ -5671,7 +5700,7 @@ DitaXmlGenerator::writeProlog(const InnerNode* inner, CodeMarker* marker)
if (!inner)
return;
writeStartTag(DT_prolog);
- writeMetadataElement(inner,DT_author);
+ writeMetadataElements(inner,DT_author);
writeMetadataElement(inner,DT_publisher);
QString s = getMetadataElement(inner,DT_copyryear);
QString t = getMetadataElement(inner,DT_copyrholder);
@@ -5690,11 +5719,13 @@ DitaXmlGenerator::writeProlog(const InnerNode* inner, CodeMarker* marker)
xmlWriter().writeAttribute("view",s);
writeEndTag(); // </permissions>
writeStartTag(DT_metadata);
- s = getMetadataElement(inner,DT_audience);
- if (!s.isEmpty()) {
- writeStartTag(DT_audience);
- xmlWriter().writeAttribute("type",s);
- writeEndTag(); // </audience>
+ QStringList sl = getMetadataElements(inner,DT_audience);
+ if (!sl.isEmpty()) {
+ for (int i=0; i<sl.size(); ++i) {
+ writeStartTag(DT_audience);
+ xmlWriter().writeAttribute("type",sl[i]);
+ writeEndTag(); // </audience>
+ }
}
if (!writeMetadataElement(inner,DT_category,false)) {
writeStartTag(DT_category);
@@ -5755,7 +5786,7 @@ DitaXmlGenerator::writeProlog(const InnerNode* inner, CodeMarker* marker)
}
writeEndTag(); // </prodinfo>
}
- const QStringMap& metaTagMap = inner->doc().metaTagMap();
+ const QStringMultiMap& metaTagMap = inner->doc().metaTagMap();
QMapIterator<QString, QString> i(metaTagMap);
while (i.hasNext()) {
i.next();
diff --git a/tools/qdoc3/ditaxmlgenerator.h b/tools/qdoc3/ditaxmlgenerator.h
index c7400bb..ffca234 100644
--- a/tools/qdoc3/ditaxmlgenerator.h
+++ b/tools/qdoc3/ditaxmlgenerator.h
@@ -319,7 +319,9 @@ class DitaXmlGenerator : public PageGenerator
bool writeMetadataElement(const InnerNode* inner,
DitaXmlGenerator::DitaTag t,
bool force=true);
+ bool writeMetadataElements(const InnerNode* inner, DitaXmlGenerator::DitaTag t);
QString getMetadataElement(const InnerNode* inner, DitaXmlGenerator::DitaTag t);
+ QStringList getMetadataElements(const InnerNode* inner, DitaXmlGenerator::DitaTag t);
private:
enum SubTitleSize { SmallSubTitle, LargeSubTitle };
@@ -516,7 +518,7 @@ class DitaXmlGenerator : public PageGenerator
static QString ditaTags[];
QStack<QXmlStreamWriter*> xmlWriterStack;
QStack<DitaTag> tagStack;
- QStringMap metadataDefaults;
+ QStringMultiMap metadataDefaults;
};
#define DITAXMLGENERATOR_ADDRESS "address"
diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp
index 945b765..2239f43 100644
--- a/tools/qdoc3/doc.cpp
+++ b/tools/qdoc3/doc.cpp
@@ -63,6 +63,7 @@ Q_GLOBAL_STATIC(QSet<QString>, null_Set_QString)
Q_GLOBAL_STATIC(QStringList, null_QStringList)
Q_GLOBAL_STATIC(QList<Text>, null_QList_Text)
Q_GLOBAL_STATIC(QStringMap, null_QStringMap)
+Q_GLOBAL_STATIC(QStringMultiMap, null_QStringMultiMap)
struct Macro
{
@@ -228,7 +229,7 @@ class DocPrivateExtra
QList<int> tableOfContentsLevels;
QList<Atom*> keywords;
QList<Atom*> targets;
- QStringMap metaMap;
+ QStringMultiMap metaMap;
DocPrivateExtra()
: granularity(Doc::Part) { }
@@ -360,7 +361,7 @@ class DocParser
void checkExpiry(const QString& date);
void insertBaseName(const QString &baseName);
void insertTarget(const QString& target, bool keyword);
- void include(const QString& fileName);
+ void include(const QString& fileName, const QString& identifier);
void startFormat(const QString& format, int cmd);
bool openCommand(int cmd);
bool closeCommand(int endCmd);
@@ -804,7 +805,11 @@ void DocParser::parse(const QString& source,
append(Atom::ImageText, getRestOfLine());
break;
case CMD_INCLUDE:
- include(getArgument());
+ {
+ QString fileName = getArgument();
+ QString identifier = getRestOfLine();
+ include(fileName, identifier);
+ }
break;
case CMD_INLINEIMAGE:
enterPara();
@@ -1578,7 +1583,7 @@ void DocParser::insertTarget(const QString &target, bool keyword)
}
}
-void DocParser::include(const QString& fileName)
+void DocParser::include(const QString& fileName, const QString& identifier)
{
if (location().depth() > 16)
location().fatal(tr("Too many nested '\\%1's")
@@ -1592,12 +1597,12 @@ void DocParser::include(const QString& fileName)
fileName,
userFriendlyFilePath);
if (filePath.isEmpty()) {
- location().warning(tr("Cannot find leaf file '%1'").arg(fileName));
+ location().warning(tr("Cannot find qdoc include file '%1'").arg(fileName));
}
else {
QFile inFile(filePath);
if (!inFile.open(QFile::ReadOnly)) {
- location().warning(tr("Cannot open leaf file '%1'")
+ location().warning(tr("Cannot open qdoc include file '%1'")
.arg(userFriendlyFilePath));
}
else {
@@ -1607,9 +1612,56 @@ void DocParser::include(const QString& fileName)
QString includedStuff = inStream.readAll();
inFile.close();
- in.insert(pos, includedStuff);
- len = in.length();
- openedInputs.push(pos + includedStuff.length());
+ if (identifier.isEmpty()) {
+ in.insert(pos, includedStuff);
+ len = in.length();
+ openedInputs.push(pos + includedStuff.length());
+ }
+ else {
+ QStringList lineBuffer = includedStuff.split(QLatin1Char('\n'));
+ int i = 0;
+ int startLine = -1;
+ while (i < lineBuffer.size()) {
+ if (lineBuffer[i].startsWith("//!")) {
+ if (lineBuffer[i].contains(identifier)) {
+ startLine = i+1;
+ break;
+ }
+ }
+ ++i;
+ }
+ if (startLine < 0) {
+ location().warning(tr("Cannot find '%1' in '%2'")
+ .arg(identifier)
+ .arg(userFriendlyFilePath));
+ return;
+
+ }
+ QString result;
+ i = startLine;
+ do {
+ if (lineBuffer[i].startsWith("//!")) {
+ if (i<lineBuffer.size()) {
+ if (lineBuffer[i].contains(identifier)) {
+ break;
+ }
+ }
+ }
+ else
+ result += lineBuffer[i] + "\n";
+ ++i;
+ } while (i < lineBuffer.size());
+ if (result.isEmpty()) {
+ location().warning(tr("Empty qdoc snippet '%1' in '%2'")
+ .arg(identifier)
+ .arg(userFriendlyFilePath));
+ }
+ else {
+ in.insert(pos, result);
+ len = in.length();
+ openedInputs.push(pos + result.length());
+ }
+ }
}
}
}
@@ -2909,9 +2961,9 @@ const QList<Atom *> &Doc::targets() const
return priv->extra->targets;
}
-const QStringMap &Doc::metaTagMap() const
+const QStringMultiMap &Doc::metaTagMap() const
{
- return priv && priv->extra ? priv->extra->metaMap : *null_QStringMap();
+ return priv && priv->extra ? priv->extra->metaMap : *null_QStringMultiMap();
}
void Doc::initialize(const Config& config)
diff --git a/tools/qdoc3/doc.h b/tools/qdoc3/doc.h
index ea832b1..e043b3a 100644
--- a/tools/qdoc3/doc.h
+++ b/tools/qdoc3/doc.h
@@ -64,7 +64,6 @@ class FakeNode;
typedef QMap<QString, QStringList> QCommandMap;
typedef QMap<QString, QString> QStringMap;
-typedef QStringMap::const_iterator QStringMapEntry;
typedef QMultiMap<QString, QString> QStringMultiMap;
class Doc
@@ -118,7 +117,7 @@ class Doc
const QList<int> &tableOfContentsLevels() const;
const QList<Atom *> &keywords() const;
const QList<Atom *> &targets() const;
- const QStringMap &metaTagMap() const;
+ const QStringMultiMap &metaTagMap() const;
static void initialize( const Config &config );
static void terminate();
diff --git a/tools/qdoc3/doc/qdoc-manual.qdoc b/tools/qdoc3/doc/qdoc-manual.qdoc
index 0fbd4b7..0e4055b 100644
--- a/tools/qdoc3/doc/qdoc-manual.qdoc
+++ b/tools/qdoc3/doc/qdoc-manual.qdoc
@@ -58,7 +58,7 @@
\endlist
\o \l {The QDoc Configuration File}
\list
- \o \l {General Configuration Variables}
+ \o \l {Generic Configuration Variables}
\o \l {Creating Help Project Files}
\o \l {C++ Specific Configuration Variables}
\o \l {HTML Specific Configuration Variables}
@@ -79,12 +79,13 @@
\title Introduction to QDoc
- QDoc is a tool used by Qt Developers to generate documentation of
- software projects by extracting the documentation from the project
- source files and then formatting it as HTML pages or DITA XML
- documents, etc. The documentation is embedded in the source files
- in \e {qdoc comments}. A qdoc comment begins with an exclamation
- mark \bold{(!)} e.g.:
+ QDoc is a tool used by Qt Developers to generate documentation for
+ software projects. It works by extracting \e {qdoc comments} from
+ project source files and then formatting these comments as HTML
+ pages or DITA XML documents, etc. QDoc finds qdoc comments in \c
+ {.cpp} files and in \c {.qdoc} files. QDoc does not look for qdoc
+ comments in \c {.h} files. A qdoc comment always begins with an
+ exclamation mark \bold{!} e.g.:
\code
/ *!
@@ -124,13 +125,14 @@
* /
\endcode
- From this snippet, QDoc generates the now famous HTML page \l
- {http://doc.trolltech.com/4.7/qobject.html#details} {QObject Class Reference}.
+ From the qdoc comment above, QDoc generates the now famous HTML
+ page \l {http://doc.trolltech.com/4.7/qobject.html#details}
+ {QObject Class Reference}.
- This manual explains how to use the QDoc commands to write useful
- qdoc comments in your source files. It also explains how to create
- a \l {The QDoc Configuration File} {QDoc configuration file},
- which you must pass to QDoc on the command line when you run it.
+ This manual explains how to use the QDoc commands in qdoc comments
+ to embed good documentation in your source files. It also explains
+ how to make a \l {The QDoc Configuration File} {QDoc configuration
+ file}, which you will pass to QDoc on the command line.
\section1 Running QDoc
@@ -138,20 +140,64 @@
from the command line, give it the name of a configuration file:
\quotation
- \c {/current/dir$ ../../bin/qdoc3 ./config.qdocconf}
+ \c {$ ../../bin/qdoc3 ./config.qdocconf}
\endquotation
- In the command line above, \c{config.qdocconf} is a \l{The QDoc
+ QDoc recognizes the \c {.qdocconf} suffix as a \l{The QDoc
Configuration File} {QDoc configuration file}. The configuration
- file is where you tell QDoc where to find the source files that
- contain the QDoc comments that will become the documentation. It
- is also where you tell QDoc what kind of output to generate (HTML,
- DITA XML,...), and where to put the generated output. The
- configuration file also contains other information for QDoc.
+ file is where you tell QDoc where to find the project source
+ files, header files, and \c {.qdoc} files. It is also where you
+ tell QDoc what kind of output to generate (HTML, DITA XML,...),
+ and where to put the generated documentation. The configuration
+ file also contains other information for QDoc.
- See \l{The QDoc Configuration File} for a instructions on how ro
+ See \l{The QDoc Configuration File} for a instructions on how to
build a Qdoc configuration file.
+ \section1 How QDoc Works
+
+ QDoc begins by reading the configuarion file you specified on the
+ command line. It stores all the variables from the configuration
+ file for later use. One of the first variables it uses is \c
+ {outputformats}. This variable tells QDoc which output generators
+ it will run. The default value is \e {HTML}, so if you don't set
+ \c {outputformats} in your configuration file, QDoc will generate
+ HTML output. That's usually what you will want anyway, but you can
+ also specify \e {DITAXML} to get DITA XML output instead.
+
+ Next, QDoc uses the values of the \l
+ {22-qdoc-configuration-generalvariables.html#headerdirs-variable}
+ {headerdirs} variable and/or the \l
+ {22-qdoc-configuration-generalvariables.html#headers-variable}
+ {headers} variable to find and parse all the header files for your
+ project. QDoc does \e not scan header files for qdoc comments. It
+ parses the header files to build a master tree of all the items
+ that should be documented (i.e. the items that QDoc should find
+ qdoc comments for).
+
+ After parsing all the header files and building the master tree of
+ items to be documented, QDoc uses the value of the \l
+ {22-qdoc-configuration-generalvariables.html#sourcedirs-variable}
+ {sourcedirs} variable and/or the value of the \l
+ {22-qdoc-configuration-generalvariables.html#sources-variable}
+ {sources} variable to find and parse all the \c {.cpp} and \c
+ {.qdoc} files for your project. These are the files QDoc scans for
+ \e {qdoc comments}. Remember that a qdoc comment begins with
+ an exclamation mark, i.e. \bold {/*!} .
+
+ For each qdoc comment it finds, it searches the master tree for
+ the item where the documentation belongs. The it interprets the
+ qdoc commands in the comment and stores the interpreted commands
+ and the comment text in the tree node for the item.
+
+ Finally, QDoc traverses the master tree. For each node, if the
+ node has stored documentation, QDoc calls the output generator
+ specified by the \c {outputformats} variable to format and write
+ the documentation in the directory specified in the configuration
+ file in the \l
+ {22-qdoc-configuration-generalvariables.html#outputdir-variable}
+ {outputdir} variable.
+
\section1 Command Types
QDoc interprets three types of commands:
@@ -213,6 +259,7 @@
\o \l {12-0-qdoc-commands-miscellaneous.html#if-command} {\\if}
\o \l {09-qdoc-commands-includingimages.html#image-command} {\\image}
\o \l {12-0-qdoc-commands-miscellaneous.html#include-command} {\\include}
+ \o \l {12-0-qdoc-commands-miscellaneous.html#include-command} {\\input}
\o \l {09-qdoc-commands-includingimages.html#inlineimage-command} {\\inlineimage}
\o \l {08-qdoc-commands-creatinglinks.html#keyword-command} {\\keyword}
\o \l {08-qdoc-commands-creatinglinks.html#l-command} {\\l}
@@ -1391,9 +1438,6 @@
application up and running.
\endquotation
- \warning If you use the \l {Compatibility Issues}
- {compat.qdocconf} file this command is called \\include.
-
See also \l {quotefromfile-command} {\\quotefromfile} and
\l {code-command} {\\code}.
@@ -3919,24 +3963,28 @@
\target include-command
\section1 \\include
- The \\include command expands to the contents of the
- file specified by the command's argument.
-
- \warning This is preliminary functionality. For more information,
- see the \l
- {26-qdoc-commands-compatibility.html#include-versus-input}
- {compatibility} section.
-
- The command takes a file name as an argument, and is useful when
- some piece of the documentation is used repeatedly: Move the
- repetetive text into a separate file, and use the \\include
- command whenever you want to insert the separate documentation.
-
- The contents of such a file should follow QDoc syntax, excluding
- the enclosing \c{/}\c{*!} ... \c{*}\c{/} marks. To ensure that
- QDoc won't attempt to read the file as a stand-alone piece of
- documentation, we recommend that you use the \c .qdocinc
- extension.
+ The \\include command sends all or part of the file specified by
+ its first argument to the QDoc input stream to be processed as a
+ qdoc comment snippet. This command is often assigned the alias,
+ \e {input}, in the QDoc configuration file, e.g. \e {alias.include
+ = input}.
+
+ The command is useful when some snippet of commands and text is to
+ be used in multiple places in the documentation. In that case,
+ move the snippet into a separate file and use the \\include
+ command wherever you want to insert the snippet into the
+ documentation. To prevent QDoc from reading the file as a
+ stand-alone page of documentation, we recommend that you use the
+ \c .qdocinc extension for these \e {include} files.
+
+ The command can have either one or two arguments. The first
+ argument is always a file name. The contents of the file must be
+ QDoc input, i.e. a sequence of QDoc commands and text, but without
+ the enclosing qdoc comment \c{/}\c{*!} ... \c{*}\c{/} delimeters.
+ If you want to include the entire named file, don't use the second
+ argument. If you want to include only part of the file, see the
+ \l{2-argument-form}{two argument form} below. Here is an example
+ of the one argument form:
\code
/ *!
@@ -3949,7 +3997,9 @@
* /
\endcode
- QDoc renders this as:
+ Here are links to the \c .qdocinc files used above:
+ \l{signalandslots.qdocinc}, \l{objectmodel.qdocinc},
+ \l{layoutmanagement.qdocinc}. QDoc renders this page as:
\quotation
\raw HTML
@@ -3961,8 +4011,40 @@
\input examples/layoutmanagement.qdocinc
\endquotation
- Here is the actual \c .qdocinc files: \l signalandslots.qdocinc,
- \l objectmodel.qdocinc, \l layoutmanagement.qdocinc
+ \target 2-argument-form}
+ \section2 \\include filename snippet-identifier
+
+ It is kind of a pain to make a separate \c .qdocinc file for every
+ QDoc include snippet you want to use in multiple places in the
+ documentation, especially given that you probably have to put the
+ copyright/license notice in every one of these files. So if you
+ have lots of these include snippets, you can put them all in a
+ single file if you want, and surround each one with:
+ \code
+ //! [snippet-id1]
+
+ QDoc commands and text...
+
+ //! [snippet-id1]
+
+ //! [snippet-id2]
+
+ More QDoc commands and text...
+
+ //! [snippet-id2]
+ \endcode
+
+ Then you can use the two-argument form of the command:
+
+ \code
+ \input examples/signalandslots.qdocinc snippet-id2
+ \input examples/objectmodel.qdocinc another-snippet-id
+ \endcode
+
+ It works as expected. The sequence of QDoc commands and text found
+ between the two tags with the same name as the second argument is
+ sent to the QDoc input stream. You can even nest these snippets,
+ although it's not clear why you would want to do that.
\target meta-command
\section1 \\meta
@@ -6739,7 +6821,7 @@
\page 21-0-qdoc-configuration.html
\previouspage Miscellaneous
\contentspage Table of Contents
- \nextpage General Configuration Variables
+ \nextpage Generic Configuration Variables
\title The QDoc Configuration File
@@ -6833,7 +6915,7 @@
\section1 Categories
\list
- \o \l {General Configuration Variables}
+ \o \l {Generic Configuration Variables}
\o \l {C++ Specific Configuration Variables}
\o \l {HTML Specific Configuration Variables}
\endlist
@@ -6874,7 +6956,7 @@
\contentspage Table of Contents
\nextpage Creating Help Project Files
- \title General Configuration Variables
+ \title Generic Configuration Variables
With the general QDoc configuration variables, you can define
where QDoc will find the various source files it needs to generate
@@ -7751,7 +7833,7 @@
/*!
\page 22-creating-help-project-files.html
- \previouspage General Configuration Variables
+ \previouspage Generic Configuration Variables
\contentspage Table of Contents
\nextpage C++ Specific Configuration Variables
diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp
index b4768db..f05c030 100644
--- a/tools/qdoc3/generator.cpp
+++ b/tools/qdoc3/generator.cpp
@@ -549,7 +549,10 @@ void Generator::generateAlsoList(const Node *node, CodeMarker *marker)
if (!alsoList.isEmpty()) {
Text text;
- text << Atom::ParaLeft << "See also ";
+ text << Atom::ParaLeft
+ << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD)
+ << "See also "
+ << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD);
for (int i = 0; i < alsoList.size(); ++i)
text << alsoList.at(i) << separator(i, alsoList.size());
@@ -559,6 +562,28 @@ void Generator::generateAlsoList(const Node *node, CodeMarker *marker)
}
}
+/*!
+ Generate a list of maintainers in the output
+ */
+void Generator::generateMaintainerList(const InnerNode* node, CodeMarker* marker)
+{
+ QStringList sl = getMetadataElements(node,"maintainer");
+
+ if (!sl.isEmpty()) {
+ Text text;
+ text << Atom::ParaLeft
+ << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD)
+ << "Maintained by: "
+ << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD);
+
+ for (int i = 0; i < sl.size(); ++i)
+ text << sl.at(i) << separator(i, sl.size());
+
+ text << Atom::ParaRight;
+ generateText(text, node, marker);
+ }
+}
+
void Generator::generateInherits(const ClassNode *classe, CodeMarker *marker)
{
QList<RelatedClass>::ConstIterator r;
@@ -566,7 +591,10 @@ void Generator::generateInherits(const ClassNode *classe, CodeMarker *marker)
if (!classe->baseClasses().isEmpty()) {
Text text;
- text << Atom::ParaLeft << "Inherits ";
+ text << Atom::ParaLeft
+ << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD)
+ << "Inherits: "
+ << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD);
r = classe->baseClasses().begin();
index = 0;
@@ -604,7 +632,10 @@ void Generator::generateInheritedBy(const ClassNode *classe,
{
if (!classe->derivedClasses().isEmpty()) {
Text text;
- text << Atom::ParaLeft << "Inherited by ";
+ text << Atom::ParaLeft
+ << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD)
+ << "Inherited by: "
+ << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD);
appendSortedNames(text, classe, classe->derivedClasses(), marker);
text << Atom::ParaRight;
@@ -1275,4 +1306,44 @@ QString Generator::outputPrefix(const QString &nodeType)
return outputPrefixes[nodeType];
}
+/*!
+ Looks up the tag \a t in the map of metadata values for the
+ current topic in \a inner. If a value for the tag is found,
+ the value is returned.
+
+ \note If \a t is found in the metadata map, it is erased.
+ i.e. Once you call this function for a particular \a t,
+ you consume \a t.
+ */
+QString Generator::getMetadataElement(const InnerNode* inner, const QString& t)
+{
+ QString s;
+ QStringMultiMap& metaTagMap = const_cast<QStringMultiMap&>(inner->doc().metaTagMap());
+ QStringMultiMap::iterator i = metaTagMap.find(t);
+ if (i != metaTagMap.end()) {
+ s = i.value();
+ metaTagMap.erase(i);
+ }
+ return s;
+}
+
+/*!
+ Looks up the tag \a t in the map of metadata values for the
+ current topic in \a inner. If values for the tag are found,
+ they are returned in a string list.
+
+ \note If \a t is found in the metadata map, all the pairs
+ having the key \a t are erased. i.e. Once you call this
+ function for a particular \a t, you consume \a t.
+ */
+QStringList Generator::getMetadataElements(const InnerNode* inner, const QString& t)
+{
+ QStringList s;
+ QStringMultiMap& metaTagMap = const_cast<QStringMultiMap&>(inner->doc().metaTagMap());
+ s = metaTagMap.values(t);
+ if (!s.isEmpty())
+ metaTagMap.remove(t);
+ return s;
+}
+
QT_END_NAMESPACE
diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h
index 4482313..8fd5370 100644
--- a/tools/qdoc3/generator.h
+++ b/tools/qdoc3/generator.h
@@ -106,6 +106,7 @@ class Generator
#endif
virtual void generateBody(const Node *node, CodeMarker *marker);
virtual void generateAlsoList(const Node *node, CodeMarker *marker);
+ virtual void generateMaintainerList(const InnerNode* node, CodeMarker* marker);
virtual void generateInherits(const ClassNode *classe,
CodeMarker *marker);
virtual void generateInheritedBy(const ClassNode *classe,
@@ -141,7 +142,6 @@ class Generator
void unknownAtom(const Atom *atom);
QMap<QString, QString> &formattingLeftMap();
QMap<QString, QString> &formattingRightMap();
-
QMap<QString, QStringList> editionModuleMap;
QMap<QString, QStringList> editionGroupMap;
@@ -150,6 +150,9 @@ class Generator
static void supplementAlsoList(const Node *node, QList<Text> &alsoList);
static QString outputPrefix(const QString &nodeType);
+ QString getMetadataElement(const InnerNode* inner, const QString& t);
+ QStringList getMetadataElements(const InnerNode* inner, const QString& t);
+
private:
void generateReimplementedFrom(const FunctionNode *func,
CodeMarker *marker);
diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp
index a4300b8..114db26 100644
--- a/tools/qdoc3/htmlgenerator.cpp
+++ b/tools/qdoc3/htmlgenerator.cpp
@@ -1327,6 +1327,7 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
generateBody(inner, marker);
out() << "</div>\n"; // QTBUG-9504
generateAlsoList(inner, marker);
+ generateMaintainerList(inner, marker);
generateExtractionMark(inner, EndMark);
}
diff --git a/tools/qdoc3/quoter.cpp b/tools/qdoc3/quoter.cpp
index dadf67c..d9210e3 100644
--- a/tools/qdoc3/quoter.cpp
+++ b/tools/qdoc3/quoter.cpp
@@ -41,6 +41,7 @@
#include <qfileinfo.h>
#include <qregexp.h>
+#include <qdebug.h>
#include "quoter.h"
@@ -65,7 +66,7 @@ static void replaceMultipleNewlines(QString &s)
}
// This is equivalent to line.split( QRegExp("\n(?!\n|$)") ) but much faster
-static QStringList splitLines(const QString &line)
+QStringList Quoter::splitLines(const QString &line)
{
QStringList result;
int i = line.size();
diff --git a/tools/qdoc3/quoter.h b/tools/qdoc3/quoter.h
index 6a59ab4..ee515b2 100644
--- a/tools/qdoc3/quoter.h
+++ b/tools/qdoc3/quoter.h
@@ -69,6 +69,8 @@ public:
const QString& pattern );
QString quoteSnippet(const Location &docLocation, const QString &identifier);
+ static QStringList splitLines(const QString &line);
+
private:
QString getLine(int unindent = 0);
void failedAtEnd( const Location& docLocation, const QString& command );