32#include <QtCore/qlist.h>
33#include <QtCore/qmap.h>
34#include <QtCore/quuid.h>
35#include <QtCore/qurl.h>
36#include <QtCore/qregularexpression.h>
37#include <QtCore/qversionnumber.h>
43using namespace Qt::StringLiterals;
45static const char dbNamespace[] =
"http://docbook.org/ns/docbook";
53 m_writer->writeCharacters(
"\n");
61 m_writer->writeAttribute(
"xml:id", registerRef(id,
true));
74 QString id = Generator::cleanRef(refForNode(node),
true);
76 m_writer->writeAttribute(
"xml:id", id);
83 m_writer->writeStartElement(dbNamespace,
"section");
86 m_writer->writeStartElement(dbNamespace,
"title");
91 m_writer->writeStartElement(dbNamespace,
"section");
94 m_writer->writeStartElement(dbNamespace,
"title");
99 m_writer->writeEndElement();
105 startSectionBegin(id);
106 m_writer->writeCharacters(title);
112 startSectionBegin(node);
113 m_writer->writeCharacters(title);
120 startSection(
"", title);
125 m_writer->writeEndElement();
134 m_writer->writeEmptyElement(dbNamespace,
"anchor");
140
141
142
147 m_config = &Config::instance();
153 if (m_projectDescription.isEmpty() && !m_project.isEmpty())
154 m_projectDescription = m_project + QLatin1String(
" Reference Documentation");
157 if (m_naturalLanguage.isEmpty())
158 m_naturalLanguage = QLatin1String(
"en");
162 m_config->get(format() + Config::dot +
"usedocbookextensions").asBool();
163 m_useITS = m_config->get(format() + Config::dot +
"its").asBool();
172
173
180
181
182
183
198 QString rewritten = code;
199 static const QRegularExpression re(
"(<@[^>&]*>)|(<\\/@[^&>]*>)");
200 rewritten.replace(re,
"");
205
206
212 qsizetype skipAhead = 0;
213 Genus genus = Genus::DontCare;
221 if (!m_inLink && !m_inContents && !m_inSectionHeading) {
222 const Node *node =
nullptr;
223 QString link = getAutoLink(atom, relative, &node, genus);
228 if (link.isEmpty()) {
229 m_writer->writeCharacters(atom->string());
231 beginLink(link, node, relative);
236 m_writer->writeCharacters(atom->string());
246 m_writer->writeStartElement(dbNamespace,
"para");
252 m_writer->writeEndElement();
262 m_writer->writeCharacters(plainCode(atom->string()));
264 m_writer->writeTextElement(dbNamespace,
"code", plainCode(atom->string()));
266 case Atom::CaptionLeft:
267 m_writer->writeStartElement(dbNamespace,
"title");
271 m_writer->writeEndElement();
275 m_writer->writeStartElement(dbNamespace,
"programlisting");
276 m_writer->writeAttribute(
"language",
"qml");
278 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
279 m_writer->writeCharacters(plainCode(removeCodeMarkers(atom->string())));
280 m_writer->writeEndElement();
284 m_writer->writeStartElement(dbNamespace,
"programlisting");
286 if (atom->strings().count() == 2)
287 m_writer->writeAttribute(
"language", atom->string(1));
289 m_writer->writeAttribute(
"language",
"cpp");
291 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
292 m_writer->writeCharacters(plainCode(removeCodeMarkers(atom->string())));
293 m_writer->writeEndElement();
297 m_writer->writeStartElement(dbNamespace,
"programlisting");
298 m_writer->writeAttribute(
"language",
"cpp");
299 m_writer->writeAttribute(
"role",
"bad");
301 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
302 m_writer->writeCharacters(plainCode(removeCodeMarkers(atom->string())));
303 m_writer->writeEndElement();
310 qsizetype offset{ 0 };
319 case Atom::FootnoteLeft:
320 m_writer->writeStartElement(dbNamespace,
"footnote");
322 m_writer->writeStartElement(dbNamespace,
"para");
325 case Atom::FootnoteRight:
326 m_writer->writeEndElement();
329 m_writer->writeEndElement();
337 m_writer->writeStartElement(dbNamespace,
"emphasis");
338 m_writer->writeAttribute(
"role",
"bold");
340 m_writer->writeStartElement(dbNamespace,
"emphasis");
342 m_writer->writeStartElement(dbNamespace,
"emphasis");
343 m_writer->writeAttribute(
"role",
"underline");
345 m_writer->writeStartElement(dbNamespace,
"subscript");
347 m_writer->writeStartElement(dbNamespace,
"superscript");
350 m_writer->writeStartElement(dbNamespace,
"code");
352 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
355 m_writer->writeAttribute(
"role",
"parameter");
359 m_writer->writeStartElement(dbNamespace,
"guilabel");
361 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
363 m_writer->writeStartElement(dbNamespace,
364 appendTrademark(atom->find(Atom::FormattingRight)) ?
365 "trademark" :
"phrase");
367 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
369 m_writer->writeStartElement(dbNamespace,
"phrase");
371 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
373 relative
->location().warning(QStringLiteral(
"Unsupported formatting: %1").arg(atom->string()));
386 m_writer->writeEndElement();
389 m_inTeletype =
false;
392 relative
->location().warning(QStringLiteral(
"Unsupported formatting: %1").arg(atom->string()));
396 if (
const CollectionNode *cn = m_qdb->getCollectionNode(atom->string(), NodeType::Group))
397 generateList(cn, atom->string(), Generator::sortOrder(atom->strings().last()));
400 const auto sortOrder{Generator::sortOrder(atom->strings().last())};
401 bool hasGeneratedSomething =
false;
402 if (atom->string() == QLatin1String(
"annotatedclasses")
403 || atom->string() == QLatin1String(
"attributions")
404 || atom->string() == QLatin1String(
"namespaces")) {
405 const NodeMultiMap things = atom->string() == QLatin1String(
"annotatedclasses")
406 ? m_qdb->getCppClasses()
407 : atom->string() == QLatin1String(
"attributions") ? m_qdb->getAttributions()
408 : m_qdb->getNamespaces();
409 generateAnnotatedList(relative, things.values(), atom->string(), Auto, sortOrder);
410 hasGeneratedSomething = !things.isEmpty();
411 }
else if (atom->string() == QLatin1String(
"annotatedexamples")
412 || atom->string() == QLatin1String(
"annotatedattributions")) {
413 const NodeMultiMap things = atom->string() == QLatin1String(
"annotatedexamples")
414 ? m_qdb->getAttributions()
415 : m_qdb->getExamples();
416 generateAnnotatedLists(relative, things, atom->string());
417 hasGeneratedSomething = !things.isEmpty();
418 }
else if (atom->string() == QLatin1String(
"classes")
419 || atom->string() == QLatin1String(
"qmlbasictypes")
420 || atom->string() == QLatin1String(
"qmlvaluetypes")
421 || atom->string() == QLatin1String(
"qmltypes")) {
422 const NodeMultiMap things = atom->string() == QLatin1String(
"classes")
423 ? m_qdb->getCppClasses()
424 : (atom->string() == QLatin1String(
"qmlvaluetypes")
425 || atom->string() == QLatin1String(
"qmlbasictypes"))
426 ? m_qdb->getQmlValueTypes()
427 : m_qdb->getQmlTypes();
428 generateCompactList(relative, things,
true, QString(), atom->string());
429 hasGeneratedSomething = !things.isEmpty();
430 }
else if (atom->string().contains(
"classes ")) {
431 QString rootName = atom->string().mid(atom->string().indexOf(
"classes") + 7).trimmed();
434 hasGeneratedSomething = !things.isEmpty();
435 generateCompactList(relative, things,
true, rootName, atom->string());
436 }
else if ((idx = atom->string().indexOf(QStringLiteral(
"bymodule"))) != -1) {
437 QString moduleName = atom->string().mid(idx + 8).trimmed();
440 if (
const CollectionNode *cn = qdb->getCollectionNode(moduleName, moduleType)) {
442 switch (moduleType) {
448 if (atom->string().contains(QLatin1String(
"qmlvaluetypes")))
454 generateAnnotatedList(relative, cn->members(), atom->string(), Auto, sortOrder);
458 if (!map.isEmpty()) {
459 generateAnnotatedList(relative, map.values(), atom->string(), Auto, sortOrder);
460 hasGeneratedSomething =
true;
463 }
else if (atom->string() == QLatin1String(
"classhierarchy")) {
464 generateClassHierarchy(relative, m_qdb->getCppClasses());
465 hasGeneratedSomething = !m_qdb->getCppClasses().isEmpty();
466 }
else if (atom->string().startsWith(
"obsolete")) {
467 QString prefix = atom->string().contains(
"cpp") ? QStringLiteral(
"Q") : QString();
468 const NodeMultiMap &things = atom->string() == QLatin1String(
"obsoleteclasses")
469 ? m_qdb->getObsoleteClasses()
470 : atom->string() == QLatin1String(
"obsoleteqmltypes")
471 ? m_qdb->getObsoleteQmlTypes()
472 : atom->string() == QLatin1String(
"obsoletecppmembers")
473 ? m_qdb->getClassesWithObsoleteMembers()
474 : m_qdb->getQmlTypesWithObsoleteMembers();
475 generateCompactList(relative, things,
false, prefix, atom->string());
476 hasGeneratedSomething = !things.isEmpty();
477 }
else if (atom->string() == QLatin1String(
"functionindex")) {
478 generateFunctionIndex(relative);
479 hasGeneratedSomething = !m_qdb->getFunctionIndex().isEmpty();
480 }
else if (atom->string() == QLatin1String(
"legalese")) {
481 generateLegaleseList(relative);
482 hasGeneratedSomething = !m_qdb->getLegaleseTexts().isEmpty();
483 }
else if (atom->string() == QLatin1String(
"overviews")
484 || atom->string() == QLatin1String(
"cpp-modules")
485 || atom->string() == QLatin1String(
"qml-modules")
486 || atom->string() == QLatin1String(
"related")) {
487 generateList(relative, atom->string());
488 hasGeneratedSomething =
true;
490 }
else if (
const auto *cn = m_qdb->getCollectionNode(atom->string(), NodeType::Group); cn) {
491 generateAnnotatedList(cn, cn->members(), atom->string(), ItemizedList, sortOrder);
492 hasGeneratedSomething =
true;
497 if (!hasGeneratedSomething && !m_inPara) {
498 m_writer->writeEmptyElement(dbNamespace,
"para");
530 m_writer->writeStartElement(dbNamespace,
"figure");
537 generateAtom(current, relative,
nullptr);
542 generateAtom(current, relative,
nullptr);
548 generateAtom(current, relative,
nullptr);
552 m_closeFigureWrapper =
true;
563 m_writer->writeStartElement(dbNamespace,
"figure");
570 generateAtom(current, relative,
nullptr);
575 generateAtom(current, relative,
nullptr);
581 generateAtom(current, relative,
nullptr);
585 m_closeFigureWrapper =
true;
608 m_writer->writeStartElement(dbNamespace, tag);
611 auto maybe_resolved_file{file_resolver.resolve(atom->string())};
612 if (!maybe_resolved_file) {
614 relative
->location().warning(QStringLiteral(
"Missing image: %1").arg(atom->string()));
616 m_writer->writeStartElement(dbNamespace,
"textobject");
618 m_writer->writeStartElement(dbNamespace,
"para");
619 m_writer->writeTextElement(dbNamespace,
"emphasis",
620 "[Missing image " + atom->string() +
"]");
621 m_writer->writeEndElement();
623 m_writer->writeEndElement();
627 QString file_name{QFileInfo{file.get_path()}.fileName()};
631 "%1/%2"_L1.arg(outputDir(), imagesOutputDir()));
635 m_writer->writeTextElement(dbNamespace,
"alt", atom->next()->string());
639 m_writer->writeStartElement(dbNamespace,
"imageobject");
641 m_writer->writeEmptyElement(dbNamespace,
"imagedata");
642 const auto &imgPath =
"%1/%2"_L1.arg(imagesOutputDir(), file_name);
644 m_writer->writeAttribute(
"fileref", imgPath);
646 m_writer->writeEndElement();
650 setImageFileName(relative, imgPath);
653 m_writer->writeEndElement();
657 if (m_closeFigureWrapper) {
658 m_writer->writeEndElement();
660 m_closeFigureWrapper =
false;
668 QString admonType = atom->typeString().toLower();
671 m_writer->writeStartElement(dbNamespace, admonType);
673 m_writer->writeStartElement(dbNamespace,
"para");
676 case Atom::ImportantRight:
677 case Atom::NoteRight:
678 case Atom::WarningRight:
679 m_writer->writeEndElement();
682 m_writer->writeEndElement();
690 const Node *node =
nullptr;
691 QString link = getLink(atom, relative, &node);
692 beginLink(link, node, relative);
696 const Node *node =
static_cast<
const Node*>(Utilities::nodeForString(atom->string()));
697 beginLink(linkForNode(node, relative), node, relative);
707 m_writer->writeEndElement();
713 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
716 m_writer->writeStartElement(dbNamespace,
"variablelist");
719 m_writer->writeStartElement(dbNamespace,
"informaltable");
721 m_writer->writeStartElement(dbNamespace,
"thead");
723 m_writer->writeStartElement(dbNamespace,
"tr");
725 m_writer->writeTextElement(dbNamespace,
"th",
"Constant");
728 m_threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
729 if (m_threeColumnEnumValueTable && relative->isEnumType(Genus::CPP)) {
731 m_writer->writeTextElement(dbNamespace,
"th",
"Value");
736 m_writer->writeTextElement(dbNamespace,
"th",
"Description");
740 m_writer->writeEndElement();
742 m_writer->writeEndElement();
745 m_writer->writeStartElement(dbNamespace,
"orderedlist");
747 if (atom->next() !=
nullptr && atom->next()->string().toInt() != 1)
748 m_writer->writeAttribute(
"startingnumber", atom->next()->string());
751 m_writer->writeAttribute(
"numeration",
"upperalpha");
753 m_writer->writeAttribute(
"numeration",
"loweralpha");
755 m_writer->writeAttribute(
"numeration",
"upperroman");
757 m_writer->writeAttribute(
"numeration",
"lowerroman");
759 m_writer->writeAttribute(
"numeration",
"arabic");
769 m_writer->writeStartElement(dbNamespace,
"varlistentry");
771 m_writer->writeStartElement(dbNamespace,
"item");
773 std::pair<QString,
int> pair = getAtomListValue(atom);
774 skipAhead = pair.second;
776 m_writer->writeStartElement(dbNamespace,
"tr");
778 m_writer->writeStartElement(dbNamespace,
"td");
780 m_writer->writeStartElement(dbNamespace,
"para");
782 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
783 generateEnumValue(pair.first, relative);
784 m_writer->writeEndElement();
786 m_writer->writeEndElement();
790 const auto enume =
static_cast<
const EnumNode *>(relative);
791 QString itemValue = enume->itemValue(atom
->next()->string());
793 m_writer->writeStartElement(dbNamespace,
"td");
794 if (itemValue.isEmpty())
795 m_writer->writeCharacters(
"?");
797 m_writer->writeStartElement(dbNamespace,
"code");
799 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
800 m_writer->writeCharacters(itemValue);
801 m_writer->writeEndElement();
803 m_writer->writeEndElement();
811 m_writer->writeEndElement();
817 m_writer->writeEndElement();
824 m_inListItemLineOpen =
false;
826 m_writer->writeStartElement(dbNamespace,
"listitem");
828 m_writer->writeStartElement(dbNamespace,
"para");
831 if (m_threeColumnEnumValueTable) {
833 m_writer->writeEmptyElement(dbNamespace,
"td");
835 m_inListItemLineOpen =
false;
837 m_writer->writeStartElement(dbNamespace,
"td");
839 m_inListItemLineOpen =
true;
843 m_writer->writeStartElement(dbNamespace,
"listitem");
852 m_writer->writeEndElement();
855 m_writer->writeEndElement();
857 m_writer->writeEndElement();
860 if (m_inListItemLineOpen) {
861 m_writer->writeEndElement();
863 m_inListItemLineOpen =
false;
865 m_writer->writeEndElement();
868 m_writer->writeEndElement();
873 case Atom::ListRight:
879 m_writer->writeEndElement();
886 m_writer->writeStartElement(dbNamespace,
"para");
892 m_writer->writeEndElement();
897 case Atom::QuotationLeft:
898 m_writer->writeStartElement(dbNamespace,
"blockquote");
899 m_inBlockquote =
true;
901 case Atom::QuotationRight:
902 m_writer->writeEndElement();
904 m_inBlockquote =
false;
907 m_writer->device()->write(atom->string().toUtf8());
913 currentSectionLevel = atom->string().toInt() +
hOffset(relative
);
915 if (currentSectionLevel > 1) {
918 while (!sectionLevels.empty() && sectionLevels.top() >= currentSectionLevel) {
920 m_writer->writeEndElement();
924 sectionLevels.push(currentSectionLevel);
926 m_writer->writeStartElement(dbNamespace,
"section");
927 writeXmlId(Tree::refForAtom(atom));
940 generateAtom(atom->next(), relative,
nullptr);
941 generateAtom(atom->next()->next(), relative,
nullptr);
942 generateAtom(atom->next()->next()->next(), relative,
nullptr);
944 m_closeSectionAfterGeneratedList =
true;
951 m_writer->writeTextElement(dbNamespace,
"title",
"");
960 if (currentSectionLevel > 1) {
961 m_writer->writeStartElement(dbNamespace,
"title");
962 m_inSectionHeading =
true;
967 if (currentSectionLevel > 1) {
968 m_writer->writeEndElement();
970 m_inSectionHeading =
false;
973 case Atom::SidebarLeft:
974 m_writer->writeStartElement(dbNamespace,
"sidebar");
976 case Atom::SidebarRight:
977 m_writer->writeEndElement();
981 if (m_inLink && !m_inContents && !m_inSectionHeading)
984 m_writer->writeCharacters(atom->string());
987 std::pair<QString, QString> pair = getTableWidthAttr(atom);
988 QString attr = pair.second;
989 QString width = pair.first;
992 m_writer->writeEndElement();
997 m_tableHeaderAlreadyOutput =
false;
999 m_writer->writeStartElement(dbNamespace,
"informaltable");
1000 m_writer->writeAttribute(
"style", attr);
1001 if (!width.isEmpty())
1002 m_writer->writeAttribute(
"width", width);
1005 case Atom::TableRight:
1006 m_tableWidthAttr = {
"",
""};
1007 m_writer->writeEndElement();
1016 if (m_tableHeaderAlreadyOutput) {
1019 m_writer->writeEndElement();
1022 const QString &attr = m_tableWidthAttr.second;
1023 const QString &width = m_tableWidthAttr.first;
1025 m_writer->writeStartElement(dbNamespace,
"informaltable");
1026 m_writer->writeAttribute(
"style", attr);
1027 if (!width.isEmpty())
1028 m_writer->writeAttribute(
"width", width);
1031 m_tableHeaderAlreadyOutput =
true;
1037 id = Utilities::asAsciiPrintable(next->string());
1042 m_writer->writeStartElement(dbNamespace,
"thead");
1044 m_writer->writeStartElement(dbNamespace,
"tr");
1047 m_inTableHeader =
true;
1050 m_closeTableCell =
true;
1051 m_writer->writeStartElement(dbNamespace,
"td");
1057 if (m_closeTableCell) {
1058 m_closeTableCell =
false;
1059 m_writer->writeEndElement();
1063 m_writer->writeEndElement();
1067 m_writer->writeStartElement(dbNamespace,
"tr");
1070 m_writer->writeEndElement();
1072 m_inTableHeader =
false;
1082 bool hasTarget {
false};
1084 id = Utilities::asAsciiPrintable(atom
->next()->string());
1089 m_writer->writeStartElement(dbNamespace,
"tr");
1092 if (atom->string().isEmpty()) {
1093 m_writer->writeAttribute(
"valign",
"top");
1098 QStringList args = atom->string().split(
"\"", Qt::SkipEmptyParts);
1101 const int nArgs = args.size();
1106 QStringLiteral(
"Error when parsing attributes for the table: got \"%1\"")
1107 .arg(atom->string()));
1109 for (
int i = 0; i + 1 < nArgs; i += 2) {
1112 const QString &attr = args.at(i).chopped(1);
1115 writeXmlId(args.at(i + 1));
1117 m_writer->writeAttribute(attr, args.at(i + 1));
1133 m_closeTableRow =
true;
1134 m_writer->writeEndElement();
1140 if (m_closeTableRow) {
1141 m_closeTableRow =
false;
1142 m_writer->writeEndElement();
1146 m_writer->writeEndElement();
1149 case Atom::TableItemLeft:
1150 m_writer->writeStartElement(dbNamespace, m_inTableHeader ?
"th" :
"td");
1152 for (
int i = 0; i < atom->count(); ++i) {
1153 const QString &p = atom->string(i);
1154 if (p.contains(
'=')) {
1155 QStringList lp = p.split(QLatin1Char(
'='));
1156 m_writer->writeAttribute(lp.at(0), lp.at(1));
1158 QStringList spans = p.split(QLatin1Char(
','));
1159 if (spans.size() == 2) {
1160 if (spans.at(0) !=
"1")
1161 m_writer->writeAttribute(
"colspan", spans.at(0).trimmed());
1162 if (spans.at(1) !=
"1")
1163 m_writer->writeAttribute(
"rowspan", spans.at(1).trimmed());
1170 case Atom::TableItemRight:
1171 m_writer->writeEndElement();
1183 QString nextId = Utilities::asAsciiPrintable(
1185 QString ownId = Utilities::asAsciiPrintable(atom->string());
1186 if (nextId == ownId)
1190 writeAnchor(Utilities::asAsciiPrintable(atom->string()));
1192 case Atom::UnhandledFormat:
1193 m_writer->writeStartElement(dbNamespace,
"emphasis");
1194 m_writer->writeAttribute(
"role",
"bold");
1195 m_writer->writeCharacters(
"<Missing DocBook>");
1196 m_writer->writeEndElement();
1198 case Atom::UnknownCommand:
1199 m_writer->writeStartElement(dbNamespace,
"emphasis");
1200 m_writer->writeAttribute(
"role",
"bold");
1202 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
1203 m_writer->writeCharacters(
"<Unknown command>");
1204 m_writer->writeStartElement(dbNamespace,
"code");
1205 m_writer->writeCharacters(atom->string());
1206 m_writer->writeEndElement();
1207 m_writer->writeEndElement();
1227 if (classMap.isEmpty())
1230 std::function<
void(
ClassNode *)> generateClassAndChildren
1231 = [
this, &relative, &generateClassAndChildren](ClassNode * classe) {
1232 m_writer->writeStartElement(dbNamespace,
"listitem");
1236 m_writer->writeStartElement(dbNamespace,
"para");
1237 generateFullName(classe, relative);
1238 m_writer->writeEndElement();
1242 bool hasChild =
false;
1243 for (
const RelatedClass &relatedClass : classe->derivedClasses()) {
1244 if (relatedClass.m_node && relatedClass.m_node->isInAPI()) {
1251 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
1254 for (
const RelatedClass &relatedClass: classe->derivedClasses()) {
1255 if (relatedClass.m_node && relatedClass.m_node->isInAPI()) {
1256 generateClassAndChildren(relatedClass.m_node);
1260 m_writer->writeEndElement();
1265 m_writer->writeEndElement();
1269 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
1272 for (
const auto &it : classMap) {
1273 auto *classe =
static_cast<ClassNode *>(it);
1274 if (classe->baseClasses().isEmpty())
1275 generateClassAndChildren(classe);
1278 m_writer->writeEndElement();
1287 if (m_linkNode && m_linkNode->isFunction()) {
1289 if (match.hasMatch()) {
1291 qsizetype leftParenLoc = match.capturedStart(1);
1292 m_writer->writeCharacters(atom->string().left(leftParenLoc));
1294 m_writer->writeCharacters(atom->string().mid(leftParenLoc));
1298 m_writer->writeCharacters(atom->string());
1302
1303
1304
1308 m_writer->writeStartElement(dbNamespace,
"link");
1309 m_writer->writeAttribute(xlinkNamespace,
"href", link);
1310 if (node && !(relative && node->status() == relative->status())
1311 && node->isDeprecated())
1312 m_writer->writeAttribute(
"role",
"deprecated");
1321 m_writer->writeEndElement();
1323 m_linkNode =
nullptr;
1327 Qt::SortOrder sortOrder)
1332 if (selector == QLatin1String(
"overviews"))
1334 else if (selector == QLatin1String(
"cpp-modules"))
1336 else if (selector == QLatin1String(
"qml-modules"))
1341 m_qdb->mergeCollections(type, cnm, relative);
1342 const QList<CollectionNode *> collectionList = cnm.values();
1343 nodeList.reserve(collectionList.size());
1344 for (
auto *collectionNode : collectionList)
1345 nodeList.append(collectionNode);
1346 generateAnnotatedList(relative, nodeList, selector, Auto, sortOrder);
1349
1350
1351
1352 Node *n =
const_cast<
Node *>(relative);
1353 auto *cn =
static_cast<CollectionNode *>(n);
1354 m_qdb->mergeCollections(cn);
1355 generateAnnotatedList(cn, cn->members(), selector, Auto, sortOrder);
1360
1361
1362
1364 const QString &selector, GeneratedListType type,
1365 Qt::SortOrder sortOrder)
1367 if (nodeList.isEmpty())
1371 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
1372 if (
std::all_of(nodeList.cbegin(), nodeList.cend(), [&policy](
const Node *n) {
1374 return !InclusionFilter::isIncluded(policy, context) || n->isDeprecated();
1381 bool noItemsHaveTitle =
1382 type == ItemizedList ||
std::all_of(nodeList.begin(), nodeList.end(),
1383 [](
const Node* node) {
1384 return node->doc().briefText().toString().isEmpty();
1388 if (type == AutoSection && m_hasSection)
1389 startSection(
"",
"Contents");
1392 if (!nodeList.isEmpty()) {
1393 m_writer->writeStartElement(dbNamespace, noItemsHaveTitle ?
"itemizedlist" :
"variablelist");
1394 m_writer->writeAttribute(
"role", selector);
1398 if (sortOrder == Qt::DescendingOrder)
1402 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
1403 for (
const auto &node : std::as_const(members)) {
1404 const NodeContext context = node->createContext();
1405 if (!InclusionFilter::isIncluded(policy, context) || node->isDeprecated())
1408 if (noItemsHaveTitle) {
1409 m_writer->writeStartElement(dbNamespace,
"listitem");
1411 m_writer->writeStartElement(dbNamespace,
"para");
1413 m_writer->writeStartElement(dbNamespace,
"varlistentry");
1415 m_writer->writeStartElement(dbNamespace,
"term");
1417 generateFullName(node, relative);
1418 if (noItemsHaveTitle) {
1419 m_writer->writeEndElement();
1421 m_writer->writeEndElement();
1423 m_writer->writeEndElement();
1425 m_writer->writeStartElement(dbNamespace,
"listitem");
1427 m_writer->writeStartElement(dbNamespace,
"para");
1428 m_writer->writeCharacters(node->doc().briefText().toString());
1429 m_writer->writeEndElement();
1431 m_writer->writeEndElement();
1433 m_writer->writeEndElement();
1438 m_writer->writeEndElement();
1442 if (type == AutoSection && m_hasSection)
1447
1448
1449
1451 const QString &selector)
1454 for (
const QString &name : nmm.uniqueKeys()) {
1455 if (!name.isEmpty())
1456 startSection(name.toLower(), name);
1457 generateAnnotatedList(relative, nmm.values(name), selector);
1458 if (!name.isEmpty())
1464
1465
1466
1467
1468
1469
1470
1471
1472
1474 bool includeAlphabet,
const QString &commonPrefix,
1475 const QString &selector)
1485 const int NumParagraphs = 37;
1486 qsizetype commonPrefixLen = commonPrefix.size();
1489
1490
1491
1492
1493
1495 QString paragraphName[NumParagraphs + 1];
1496 QSet<
char> usedParagraphNames;
1498 for (
auto c = nmm.constBegin(); c != nmm.constEnd(); ++c) {
1499 QStringList pieces = c.key().split(
"::");
1500 int idx = commonPrefixLen;
1501 if (idx > 0 && !pieces.last().startsWith(commonPrefix, Qt::CaseInsensitive))
1503 QString last = pieces.last().toLower();
1504 QString key = last.mid(idx);
1506 int paragraphNr = NumParagraphs - 1;
1508 if (key[0].digitValue() != -1) {
1509 paragraphNr = key[0].digitValue();
1510 }
else if (key[0] >= QLatin1Char(
'a') && key[0] <= QLatin1Char(
'z')) {
1511 paragraphNr = 10 + key[0].unicode() -
'a';
1514 paragraphName[paragraphNr] = key[0].toUpper();
1515 usedParagraphNames.insert(key[0].toLower().cell());
1516 paragraph[paragraphNr].insert(last, c.value());
1520
1521
1522
1523
1524
1525
1526
1527 int paragraphOffset[NumParagraphs + 1];
1528 paragraphOffset[0] = 0;
1529 for (
int i = 0; i < NumParagraphs; i++)
1530 paragraphOffset[i + 1] = paragraphOffset[i] + paragraph[i].size();
1533 if (includeAlphabet && !usedParagraphNames.isEmpty()) {
1534 m_writer->writeStartElement(dbNamespace,
"simplelist");
1537 for (
int i = 0; i < 26; i++) {
1539 if (usedParagraphNames.contains(
char(
'a' + i))) {
1540 m_writer->writeStartElement(dbNamespace,
"member");
1541 generateSimpleLink(ch, ch.toUpper());
1542 m_writer->writeEndElement();
1547 m_writer->writeEndElement();
1552 QHash<QString,
int> nameOccurrences;
1553 for (
const auto &[key, node] : nmm.asKeyValueRange()) {
1554 QStringList pieces{node->fullName(relative).split(
"::"_L1)};
1555 const QString &name{pieces.last()};
1556 nameOccurrences[name]++;
1561 int curParOffset = 0;
1563 m_writer->writeStartElement(dbNamespace,
"variablelist");
1564 m_writer->writeAttribute(
"role", selector);
1567 for (
int i = 0; i < nmm.size(); i++) {
1568 while ((curParNr < NumParagraphs) && (curParOffset == paragraph[curParNr].size())) {
1575 if (curParOffset == 0) {
1577 m_writer->writeEndElement();
1579 m_writer->writeEndElement();
1581 m_writer->writeEndElement();
1585 m_writer->writeStartElement(dbNamespace,
"varlistentry");
1586 if (includeAlphabet)
1587 writeXmlId(paragraphName[curParNr][0].toLower());
1590 m_writer->writeStartElement(dbNamespace,
"term");
1591 m_writer->writeStartElement(dbNamespace,
"emphasis");
1592 m_writer->writeAttribute(
"role",
"bold");
1593 m_writer->writeCharacters(paragraphName[curParNr]);
1594 m_writer->writeEndElement();
1595 m_writer->writeEndElement();
1598 m_writer->writeStartElement(dbNamespace,
"listitem");
1600 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
1605 m_writer->writeStartElement(dbNamespace,
"listitem");
1607 m_writer->writeStartElement(dbNamespace,
"para");
1609 if ((curParNr < NumParagraphs) && !paragraphName[curParNr].isEmpty()) {
1610 NodeMultiMap::Iterator it;
1611 NodeMultiMap::Iterator next;
1612 it = paragraph[curParNr].begin();
1613 for (
int j = 0; j < curParOffset; j++)
1618 QStringList pieces{it.value()->fullName(relative).split(
"::"_L1)};
1619 const auto &name{pieces.last()};
1622 if (nameOccurrences[name] > 1) {
1623 const QString moduleName = it.value()->isQmlNode() ? it.value()->logicalModuleName()
1624 : it.value()->tree()->camelCaseModuleName();
1625 pieces.last().append(
": %1"_L1.arg(moduleName));
1629 m_writer->writeStartElement(dbNamespace,
"link");
1630 m_writer->writeAttribute(xlinkNamespace,
"href", linkForNode(*it, relative));
1631 if (
const QString type = targetType(it.value()); !type.isEmpty())
1632 m_writer->writeAttribute(
"role", type);
1633 m_writer->writeCharacters(pieces.last());
1634 m_writer->writeEndElement();
1637 if (pieces.size() > 1) {
1638 m_writer->writeCharacters(
" (");
1639 generateFullName(it.value()->parent(), relative);
1640 m_writer->writeCharacters(
")");
1644 m_writer->writeEndElement();
1646 m_writer->writeEndElement();
1651 m_writer->writeEndElement();
1653 m_writer->writeEndElement();
1655 m_writer->writeEndElement();
1658 m_writer->writeEndElement();
1667 m_writer->writeStartElement(dbNamespace,
"simplelist");
1668 m_writer->writeAttribute(
"role",
"functionIndex");
1670 for (
int i = 0; i < 26; i++) {
1672 m_writer->writeStartElement(dbNamespace,
"member");
1673 m_writer->writeAttribute(xlinkNamespace,
"href", QString(
"#") + ch);
1674 m_writer->writeCharacters(ch.toUpper());
1675 m_writer->writeEndElement();
1678 m_writer->writeEndElement();
1683 if (m_qdb->getFunctionIndex().isEmpty())
1685 char nextLetter =
'a';
1688 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
1691 NodeMapMap &funcIndex = m_qdb->getFunctionIndex();
1692 QMap<QString, NodeMap>::ConstIterator f = funcIndex.constBegin();
1693 while (f != funcIndex.constEnd()) {
1694 m_writer->writeStartElement(dbNamespace,
"listitem");
1696 m_writer->writeStartElement(dbNamespace,
"para");
1697 m_writer->writeCharacters(f.key() +
": ");
1699 currentLetter = f.key()[0].unicode();
1700 while (islower(currentLetter) && currentLetter >= nextLetter) {
1701 writeAnchor(QString(nextLetter));
1705 NodeMap::ConstIterator s = (*f).constBegin();
1706 while (s != (*f).constEnd()) {
1707 m_writer->writeCharacters(
" ");
1708 generateFullName((*s)->parent(), relative);
1712 m_writer->writeEndElement();
1714 m_writer->writeEndElement();
1718 m_writer->writeEndElement();
1726 for (
auto it = legaleseTexts.cbegin(), end = legaleseTexts.cend(); it != end; ++it) {
1727 Text text = it.key();
1729 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
1732 m_writer->writeStartElement(dbNamespace,
"listitem");
1734 m_writer->writeStartElement(dbNamespace,
"para");
1735 generateFullName(it.value(), relative);
1736 m_writer->writeEndElement();
1738 m_writer->writeEndElement();
1741 }
while (it != legaleseTexts.constEnd() && it.key() == text);
1742 m_writer->writeEndElement();
1757 m_writer->writeStartElement(dbNamespace,
"para");
1759 m_writer->writeEndElement();
1767 if (!node->since().isEmpty()) {
1768 m_writer->writeStartElement(dbNamespace,
"para");
1770 const auto &collective =
static_cast<
const SharedCommentNode *>(node)->collective();
1771 QString typeStr = collective.size() > 1 ? typeString(collective.first()) +
"s" : typeString(node);
1772 m_writer->writeCharacters(
"These " + typeStr +
" were introduced in ");
1774 m_writer->writeCharacters(
"This " + typeString(node) +
" was introduced in ");
1776 m_writer->writeCharacters(formatSince(node) +
".");
1777 m_writer->writeEndElement();
1787
1788
1789
1796 m_writer->writeStartElement(dbNamespace,
"info");
1798 m_writer->writeStartElement(dbNamespace,
"title");
1799 if (isApiGenus(node->genus()) && m_useITS)
1800 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
1802 m_writer->writeEndElement();
1805 if (!subTitle.isEmpty()) {
1806 m_writer->writeStartElement(dbNamespace,
"subtitle");
1807 if (isApiGenus(node->genus()) && m_useITS)
1808 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
1809 m_writer->writeCharacters(subTitle);
1810 m_writer->writeEndElement();
1814 if (!m_productName.isEmpty() || !m_project.isEmpty()) {
1815 m_writer->writeTextElement(dbNamespace,
"productname", m_productName.isEmpty() ?
1816 m_project : m_productName);
1820 if (!m_buildVersion.isEmpty()) {
1821 m_writer->writeTextElement(dbNamespace,
"edition", m_buildVersion);
1825 if (!m_projectDescription.isEmpty()) {
1826 m_writer->writeTextElement(dbNamespace,
"titleabbrev", m_projectDescription);
1834 if (node && !node->links().empty()) {
1835 std::pair<QString, QString> linkPair;
1836 std::pair<QString, QString> anchorPair;
1837 const Node *linkNode;
1839 if (node->links().contains(Node::PreviousLink)) {
1840 linkPair = node->links()[Node::PreviousLink];
1841 linkNode = m_qdb->findNodeForTarget(linkPair.first, node);
1842 if (!linkNode || linkNode == node)
1843 anchorPair = linkPair;
1845 anchorPair = anchorForNode(linkNode);
1847 m_writer->writeStartElement(dbNamespace,
"extendedlink");
1848 m_writer->writeAttribute(xlinkNamespace,
"type",
"extended");
1849 m_writer->writeEmptyElement(dbNamespace,
"link");
1850 m_writer->writeAttribute(xlinkNamespace,
"to", anchorPair.first);
1851 m_writer->writeAttribute(xlinkNamespace,
"type",
"arc");
1852 m_writer->writeAttribute(xlinkNamespace,
"arcrole",
"prev");
1853 if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
1854 m_writer->writeAttribute(xlinkNamespace,
"title", anchorPair.second);
1856 m_writer->writeAttribute(xlinkNamespace,
"title", linkPair.second);
1857 m_writer->writeEndElement();
1860 if (node->links().contains(Node::NextLink)) {
1861 linkPair = node->links()[Node::NextLink];
1862 linkNode = m_qdb->findNodeForTarget(linkPair.first, node);
1863 if (!linkNode || linkNode == node)
1864 anchorPair = linkPair;
1866 anchorPair = anchorForNode(linkNode);
1868 m_writer->writeStartElement(dbNamespace,
"extendedlink");
1869 m_writer->writeAttribute(xlinkNamespace,
"type",
"extended");
1870 m_writer->writeEmptyElement(dbNamespace,
"link");
1871 m_writer->writeAttribute(xlinkNamespace,
"to", anchorPair.first);
1872 m_writer->writeAttribute(xlinkNamespace,
"type",
"arc");
1873 m_writer->writeAttribute(xlinkNamespace,
"arcrole",
"next");
1874 if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
1875 m_writer->writeAttribute(xlinkNamespace,
"title", anchorPair.second);
1877 m_writer->writeAttribute(xlinkNamespace,
"title", linkPair.second);
1878 m_writer->writeEndElement();
1881 if (node->links().contains(Node::StartLink)) {
1882 linkPair = node->links()[Node::StartLink];
1883 linkNode = m_qdb->findNodeForTarget(linkPair.first, node);
1884 if (!linkNode || linkNode == node)
1885 anchorPair = linkPair;
1887 anchorPair = anchorForNode(linkNode);
1889 m_writer->writeStartElement(dbNamespace,
"extendedlink");
1890 m_writer->writeAttribute(xlinkNamespace,
"type",
"extended");
1891 m_writer->writeEmptyElement(dbNamespace,
"link");
1892 m_writer->writeAttribute(xlinkNamespace,
"to", anchorPair.first);
1893 m_writer->writeAttribute(xlinkNamespace,
"type",
"arc");
1894 m_writer->writeAttribute(xlinkNamespace,
"arcrole",
"start");
1895 if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
1896 m_writer->writeAttribute(xlinkNamespace,
"title", anchorPair.second);
1898 m_writer->writeAttribute(xlinkNamespace,
"title", linkPair.second);
1899 m_writer->writeEndElement();
1911 m_writer->writeStartElement(dbNamespace,
"abstract");
1914 bool generatedSomething =
false;
1918 node->isNamespace() ?
static_cast<
const NamespaceNode *>(node) :
nullptr;
1921 brief <<
"The " << ns->name()
1922 <<
" namespace includes the following elements from module "
1923 << ns
->tree()->camelCaseModuleName() <<
". The full namespace is "
1924 <<
"documented in module " << NS
->tree()->camelCaseModuleName();
1925 addNodeLink(brief, fullDocumentLocation(NS),
" here.");
1934 m_writer->writeStartElement(dbNamespace,
"para");
1936 m_writer->writeEndElement();
1939 generatedSomething =
true;
1949 if (!generatedSomething)
1950 m_writer->writeTextElement(dbNamespace,
"para", m_projectDescription +
".");
1952 m_writer->writeEndElement();
1957 m_writer->writeEndElement();
1963 while (!sectionLevels.isEmpty()) {
1964 sectionLevels.pop();
1971 if (m_closeSectionAfterGeneratedList) {
1972 m_closeSectionAfterGeneratedList =
false;
1975 if (m_closeSectionAfterRawTitle) {
1976 m_closeSectionAfterRawTitle =
false;
1981 m_writer->writeEndElement();
1984void DocBookGenerator::generateSimpleLink(
const QString &href,
const QString &text)
1986 m_writer->writeStartElement(dbNamespace,
"link");
1987 m_writer->writeAttribute(xlinkNamespace,
"href", href);
1988 m_writer->writeCharacters(text);
1989 m_writer->writeEndElement();
1993
1994
1995
1998 static const QHash<QString, QString> extrefUrls = {
1999 {u"cpp-explicitly-defaulted"_s,
2000 u"https://en.cppreference.com/w/cpp/language/function#Defaulted_functions"_s},
2001 {u"cpp-deleted-functions"_s,
2002 u"https://en.cppreference.com/w/cpp/language/function#Deleted_functions"_s},
2005 static const QRegularExpression extrefRegex(
2006 u"<@extref target=\"([^\"]+)\">([^<]*)</@extref>"_s);
2009 auto it = extrefRegex.globalMatch(extra);
2010 while (it.hasNext()) {
2011 auto match = it.next();
2012 if (match.capturedStart() > pos)
2013 m_writer->writeCharacters(extra.mid(pos, match.capturedStart() - pos));
2015 QString target = match.captured(1);
2016 QString text = match.captured(2);
2017 QString url = extrefUrls.value(target);
2019 generateSimpleLink(url, text);
2021 m_writer->writeCharacters(text);
2023 pos = match.capturedEnd();
2025 if (pos < extra.size())
2026 m_writer->writeCharacters(extra.mid(pos));
2038 startSection(
"obsolete",
"Obsolete Members for " + aggregate->plainFullName());
2040 m_writer->writeStartElement(dbNamespace,
"para");
2041 m_writer->writeStartElement(dbNamespace,
"emphasis");
2042 m_writer->writeAttribute(
"role",
"bold");
2043 m_writer->writeCharacters(
"The following members of class ");
2044 generateSimpleLink(linkForNode(aggregate,
nullptr), aggregate->name());
2045 m_writer->writeCharacters(
" are deprecated.");
2046 m_writer->writeEndElement();
2047 m_writer->writeCharacters(
" We strongly advise against using them in new code.");
2048 m_writer->writeEndElement();
2051 for (
const Section *section : details_spv) {
2052 const QString &title =
"Obsolete " + section->title();
2053 startSection(title.toLower(), title);
2055 const NodeVector &members = section->obsoleteMembers();
2056 NodeVector::ConstIterator m = members.constBegin();
2057 while (m != members.constEnd()) {
2058 if ((*m)->access() != Access::Private)
2059 generateDetailedMember(*m, aggregate);
2070
2071
2072
2073
2074
2075
2076
2086 startSection(
"obsolete",
"Obsolete Members for " + aggregate->name());
2088 m_writer->writeStartElement(dbNamespace,
"para");
2089 m_writer->writeStartElement(dbNamespace,
"emphasis");
2090 m_writer->writeAttribute(
"role",
"bold");
2091 m_writer->writeCharacters(
"The following members of QML type ");
2092 generateSimpleLink(linkForNode(aggregate,
nullptr), aggregate->name());
2093 m_writer->writeCharacters(
" are deprecated.");
2094 m_writer->writeEndElement();
2095 m_writer->writeCharacters(
" We strongly advise against using them in new code.");
2096 m_writer->writeEndElement();
2099 for (
const auto *section : details_spv) {
2100 const QString &title =
"Obsolete " + section->title();
2101 startSection(title.toLower(), title);
2103 const NodeVector &members = section->obsoleteMembers();
2104 NodeVector::ConstIterator m = members.constBegin();
2105 while (m != members.constEnd()) {
2106 if ((*m)->access() != Access::Private)
2107 generateDetailedQmlMember(*m, aggregate);
2121 return QStringLiteral(
"classsynopsis");
2123 return QStringLiteral(
"packagesynopsis");
2129 return QStringLiteral(
"enumsynopsis");
2131 return QStringLiteral(
"typedefsynopsis");
2134 const auto fn =
static_cast<
const FunctionNode *>(node);
2135 if (fn->isCtor() || fn->isCCtor() || fn->isMCtor())
2136 return QStringLiteral(
"constructorsynopsis");
2138 return QStringLiteral(
"destructorsynopsis");
2139 return QStringLiteral(
"methodsynopsis");
2142 return QStringLiteral(
"fieldsynopsis");
2144 node
->doc().location().warning(QString(
"Unknown node tag %1").arg(node->nodeTypeString()));
2145 return QStringLiteral(
"synopsis");
2150 m_writer->writeStartElement(dbNamespace,
"varlistentry");
2152 m_writer->writeTextElement(dbNamespace,
"term", description);
2154 m_writer->writeStartElement(dbNamespace,
"listitem");
2156 m_writer->writeStartElement(dbNamespace,
"para");
2162 m_writer->writeEndElement();
2165 m_writer->writeEndElement();
2167 m_writer->writeEndElement();
2171void DocBookGenerator::generateRequisite(
const QString &description,
const QString &value)
2173 generateStartRequisite(description);
2174 m_writer->writeCharacters(value);
2175 generateEndRequisite();
2179
2180
2181
2182void DocBookGenerator::generateCMakeRequisite(
const QString &findPackage,
const QString &linkLibraries)
2184 const QString description(
"CMake");
2185 generateStartRequisite(description);
2186 m_writer->writeCharacters(findPackage);
2187 m_writer->writeEndElement();
2190 m_writer->writeStartElement(dbNamespace,
"para");
2191 m_writer->writeCharacters(linkLibraries);
2192 generateEndRequisite();
2198 QMap<QString, ClassNode *> classMap;
2199 QList<RelatedClass>::ConstIterator r = rc.constBegin();
2200 while (r != rc.constEnd()) {
2203 && !rcn
->doc().isEmpty()) {
2204 classMap[rcn->plainFullName(cn).toLower()] = rcn;
2209 QStringList classNames = classMap.keys();
2213 for (
const QString &className : classNames) {
2214 generateFullName(classMap.value(className), cn);
2215 m_writer->writeCharacters(Utilities::comma(index++, classNames.size()));
2223 QMap<QString, Node *> classMap;
2224 QStringList typeNames(knownTypes);
2225 for (
const auto sub : subs)
2226 typeNames << sub->name();
2228 for (
auto sub : subs) {
2229 QString key{sub->plainFullName(base).toLower()};
2231 if (typeNames.count(sub->name()) > 1)
2232 key.append(
": (%1)"_L1.arg(sub->logicalModuleName()));
2233 classMap[key] = sub;
2236 QStringList names = classMap.keys();
2240 for (
const QString &name : names) {
2241 generateFullName(classMap.value(name), base);
2242 if (name.contains(
':'))
2243 m_writer->writeCharacters(name.section(
':', 1));
2244 m_writer->writeCharacters(Utilities::comma(index++, names.size()));
2249
2250
2259 QXmlStreamWriter* oldWriter = m_writer;
2261 m_writer =
new QXmlStreamWriter(&output);
2264 if (aggregate->includeFile()) generateRequisite(
"Header", *aggregate->includeFile());
2267 if (!aggregate->since().isEmpty())
2268 generateRequisite(
"Since", formatSince(aggregate));
2273 m_qdb->getCollectionNode(aggregate->physicalModuleName(), NodeType::Module);
2275 if (
const auto result = cmakeRequisite(cn)) {
2276 generateCMakeRequisite(result->first, result->second);
2279 if (cn && !cn->qtVariable().isEmpty())
2280 generateRequisite(
"qmake",
"QT += " + cn->qtVariable());
2285 auto *classe =
const_cast<ClassNode *>(
static_cast<
const ClassNode *>(aggregate));
2286 if (classe && classe->isQmlNativeType() && classe->status() !=
Status::Internal) {
2287 generateStartRequisite(
"In QML");
2290 QList<QmlTypeNode *> nativeTypes { classe->qmlNativeTypes().cbegin(), classe->qmlNativeTypes().cend()};
2293 for (
const auto &item : std::as_const(nativeTypes)) {
2294 generateFullName(item, classe);
2295 m_writer->writeCharacters(
2296 Utilities::comma(idx++, nativeTypes.size()));
2298 generateEndRequisite();
2302 QList<RelatedClass>::ConstIterator r;
2303 const auto *metaTags = classe ? classe->doc().metaTagMap() :
nullptr;
2304 bool suppressInherits = metaTags && metaTags->contains(u"qdoc-suppress-inheritance"_s);
2305 if (classe && !suppressInherits && !classe->baseClasses().isEmpty()) {
2306 generateStartRequisite(
"Inherits");
2308 r = classe->baseClasses().constBegin();
2310 while (r != classe->baseClasses().constEnd()) {
2312 generateFullName((*r).m_node, classe);
2314 if ((*r).m_access == Access::Protected)
2315 m_writer->writeCharacters(
" (protected)");
2316 else if ((*r).m_access == Access::Private)
2317 m_writer->writeCharacters(
" (private)");
2318 m_writer->writeCharacters(
2319 Utilities::comma(index++, classe->baseClasses().size()));
2324 generateEndRequisite();
2328 if (!classe->derivedClasses().isEmpty()) {
2329 generateStartRequisite(
"Inherited By");
2330 generateSortedNames(classe, classe->derivedClasses());
2331 generateEndRequisite();
2336 if (!aggregate->groupNames().empty()) {
2337 generateStartRequisite(
"Group");
2339 generateEndRequisite();
2343 if (
auto status = formatStatus(aggregate, m_qdb); status)
2344 generateRequisite(
"Status", status.value());
2348 m_writer = oldWriter;
2350 if (!output.isEmpty()) {
2353 static const QRegularExpression xmlTag(R"(<(/?)n\d+:)");
2354 static const QRegularExpression xmlnsDocBookDefinition(R"( xmlns:n\d+=")" + QString{dbNamespace} +
"\"");
2355 static const QRegularExpression xmlnsXLinkDefinition(R"( xmlns:n\d+=")" + QString{xlinkNamespace} +
"\"");
2356 static const QRegularExpression xmlAttr(R"( n\d+:)");
2358 const QString cleanOutput = output.replace(xmlTag, R"(<\1db:)")
2359 .replace(xmlnsDocBookDefinition,
"")
2360 .replace(xmlnsXLinkDefinition,
"")
2361 .replace(xmlAttr,
" xlink:");
2363 m_writer->writeStartElement(dbNamespace,
"variablelist");
2365 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
2368 m_writer->device()->write(cleanOutput.toUtf8());
2370 m_writer->writeEndElement();
2376
2377
2385 const QString importText =
"Import Statement";
2386 const QString sinceText =
"Since";
2387 const QString inheritedByText =
"Inherited By";
2388 const QString inheritsText =
"Inherits";
2389 const QString nativeTypeText =
"In C++";
2390 const QString groupText =
"Group";
2391 const QString statusText =
"Status";
2399 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
2408 bool generate_import_statement = !qcn->logicalModuleName().isEmpty();
2409 if (generate_import_statement && collection) {
2414 const bool generates_something = generate_import_statement || !qcn->since().isEmpty() || !subs.isEmpty() || base;
2416 if (!generates_something)
2419 QStringList knownTypeNames{qcn->name()};
2421 knownTypeNames << base->name();
2424 m_writer->writeStartElement(dbNamespace,
"variablelist");
2426 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
2429 if (generate_import_statement) {
2430 QStringList parts = QStringList() <<
"import" << qcn->logicalModuleName() << qcn->logicalModuleVersion();
2431 generateRequisite(importText, parts.join(
' ').trimmed());
2435 if (!qcn->since().isEmpty())
2436 generateRequisite(sinceText, formatSince(qcn));
2441 generateStartRequisite(nativeTypeText);
2442 generateSimpleLink(fullDocumentLocation(cn), cn->name());
2443 generateEndRequisite();
2448 generateStartRequisite(inheritsText);
2449 generateSimpleLink(fullDocumentLocation(base), base->name());
2451 for (
const auto sub : std::as_const(subs)) {
2452 if (knownTypeNames.contains(sub->name())) {
2453 m_writer->writeCharacters(
" (%1)"_L1.arg(base->logicalModuleName()));
2457 generateEndRequisite();
2461 if (!subs.isEmpty()) {
2462 generateStartRequisite(inheritedByText);
2463 generateSortedQmlNames(qcn, knownTypeNames, subs);
2464 generateEndRequisite();
2468 if (!qcn->groupNames().empty()) {
2469 generateStartRequisite(groupText);
2471 generateEndRequisite();
2475 if (
auto status = formatStatus(qcn, m_qdb); status)
2476 generateRequisite(statusText, status.value());
2478 m_writer->writeEndElement();
2489 const QString &state =
static_cast<
const CollectionNode*>(node)->state();
2490 if (!state.isEmpty()) {
2491 m_writer->writeStartElement(dbNamespace,
"para");
2492 m_writer->writeCharacters(
"This " + typeString(node) +
" is in ");
2493 m_writer->writeStartElement(dbNamespace,
"emphasis");
2494 m_writer->writeCharacters(state);
2495 m_writer->writeEndElement();
2496 m_writer->writeCharacters(
" state.");
2497 m_writer->writeEndElement();
2502 if (
const auto &version = node->deprecatedSince(); !version.isEmpty()) {
2503 m_writer->writeStartElement(dbNamespace,
"para");
2504 m_writer->writeCharacters(
"This " + typeString(node)
2505 +
" is scheduled for deprecation in version "
2507 m_writer->writeEndElement();
2512 case Status::Preliminary:
2513 m_writer->writeStartElement(dbNamespace,
"para");
2514 m_writer->writeStartElement(dbNamespace,
"emphasis");
2515 m_writer->writeAttribute(
"role",
"bold");
2516 m_writer->writeCharacters(
2520 .replace(
'\1'_L1, typeString(node)));
2521 m_writer->writeEndElement();
2522 m_writer->writeEndElement();
2525 case Status::Deprecated:
2526 m_writer->writeStartElement(dbNamespace,
"para");
2528 m_writer->writeStartElement(dbNamespace,
"emphasis");
2529 m_writer->writeAttribute(
"role",
"bold");
2531 m_writer->writeCharacters(
"This " + typeString(node) +
" is deprecated");
2532 if (
const QString &version = node->deprecatedSince(); !version.isEmpty()) {
2533 m_writer->writeCharacters(
" since ");
2534 if (node->isQmlNode() && !node->logicalModuleName().isEmpty())
2535 m_writer->writeCharacters(node->logicalModuleName() +
" ");
2536 m_writer->writeCharacters(version);
2538 m_writer->writeCharacters(
". We strongly advise against using it in new code.");
2539 if (node->isAggregate())
2540 m_writer->writeEndElement();
2541 m_writer->writeEndElement();
2551
2552
2553
2557 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
2560 NodeList::ConstIterator n = nodes.constBegin();
2561 while (n != nodes.constEnd()) {
2562 m_writer->writeStartElement(dbNamespace,
"listitem");
2564 m_writer->writeStartElement(dbNamespace,
"para");
2566 generateSimpleLink(currentGenerator()->fullDocumentLocation(*n),
2567 (*n)->signature(Node::SignaturePlain));
2569 m_writer->writeEndElement();
2571 m_writer->writeEndElement();
2576 m_writer->writeEndElement();
2581
2582
2583
2590 const auto aggregate =
static_cast<
const Aggregate *>(node);
2592 const QStringList &groups_names{aggregate->groupNames()};
2593 if (!groups_names.empty()) {
2594 m_writer->writeCharacters(aggregate->name() +
" is part of ");
2595 m_writer->writeStartElement(dbNamespace,
"simplelist");
2597 for (qsizetype index{0}; index < groups_names.size(); ++index) {
2599 m_qdb->mergeCollections(group);
2601 m_writer->writeStartElement(dbNamespace,
"member");
2602 if (QString target{linkForNode(group,
nullptr)}; !target.isEmpty())
2603 generateSimpleLink(target, group->fullTitle());
2605 m_writer->writeCharacters(group->name());
2606 m_writer->writeEndElement();
2609 m_writer->writeEndElement();
2615
2616
2617
2623 const Node *reentrantNode;
2625 QString linkReentrant = getAutoLink(&reentrantAtom, node, &reentrantNode);
2626 const Node *threadSafeNode;
2628 QString linkThreadSafe = getAutoLink(&threadSafeAtom, node, &threadSafeNode);
2631 m_writer->writeStartElement(dbNamespace,
"warning");
2633 m_writer->writeStartElement(dbNamespace,
"para");
2634 m_writer->writeCharacters(
"This " + typeString(node) +
" is not ");
2635 generateSimpleLink(linkReentrant,
"reentrant");
2636 m_writer->writeCharacters(
".");
2637 m_writer->writeEndElement();
2639 m_writer->writeEndElement();
2643 m_writer->writeStartElement(dbNamespace,
"note");
2645 m_writer->writeStartElement(dbNamespace,
"para");
2648 m_writer->writeCharacters(
"All functions in this " + typeString(node) +
" are ");
2649 if (ts == Node::ThreadSafe)
2650 generateSimpleLink(linkThreadSafe,
"thread-safe");
2652 generateSimpleLink(linkReentrant,
"reentrant");
2657 bool exceptions = hasExceptions(node, reentrant, threadsafe, nonreentrant);
2658 if (!exceptions || (ts ==
Node::Reentrant && !threadsafe.isEmpty())) {
2659 m_writer->writeCharacters(
".");
2660 m_writer->writeEndElement();
2663 m_writer->writeCharacters(
" with the following exceptions:");
2664 m_writer->writeEndElement();
2666 m_writer->writeStartElement(dbNamespace,
"para");
2669 if (!nonreentrant.isEmpty()) {
2670 m_writer->writeCharacters(
"These functions are not ");
2671 generateSimpleLink(linkReentrant,
"reentrant");
2672 m_writer->writeCharacters(
":");
2673 m_writer->writeEndElement();
2675 generateSignatureList(nonreentrant);
2677 if (!threadsafe.isEmpty()) {
2678 m_writer->writeCharacters(
"These functions are also ");
2679 generateSimpleLink(linkThreadSafe,
"thread-safe");
2680 m_writer->writeCharacters(
":");
2681 m_writer->writeEndElement();
2683 generateSignatureList(threadsafe);
2686 if (!reentrant.isEmpty()) {
2687 m_writer->writeCharacters(
"These functions are only ");
2688 generateSimpleLink(linkReentrant,
"reentrant");
2689 m_writer->writeCharacters(
":");
2690 m_writer->writeEndElement();
2692 generateSignatureList(reentrant);
2694 if (!nonreentrant.isEmpty()) {
2695 m_writer->writeCharacters(
"These functions are not ");
2696 generateSimpleLink(linkReentrant,
"reentrant");
2697 m_writer->writeCharacters(
":");
2698 m_writer->writeEndElement();
2700 generateSignatureList(nonreentrant);
2705 m_writer->writeCharacters(
"This " + typeString(node) +
" is ");
2706 if (ts == Node::ThreadSafe)
2707 generateSimpleLink(linkThreadSafe,
"thread-safe");
2709 generateSimpleLink(linkReentrant,
"reentrant");
2710 m_writer->writeCharacters(
".");
2711 m_writer->writeEndElement();
2714 m_writer->writeEndElement();
2724
2725
2726
2730 const FunctionNode *fn = node->isFunction() ?
static_cast<
const FunctionNode *>(node) :
nullptr;
2734
2735
2736
2740 t =
"Destroys the instance of " + fn
->parent()->name() +
".";
2742 t +=
" The destructor is virtual.";
2744 t =
"Default constructs an instance of " + fn
->parent()->name() +
".";
2746 t =
"Copy constructor.";
2748 t =
"Move-copy constructor.";
2750 t =
"Copy-assignment constructor.";
2752 t =
"Move-assignment constructor.";
2756 m_writer->writeTextElement(dbNamespace,
"para", t);
2760 if (fn && !fn->overridesThis().isEmpty())
2761 generateReimplementsClause(fn);
2763 if (
static_cast<
const PropertyNode *>(node)->propertyType() != PropertyNode::PropertyType::StandardProperty)
2792 generateRequiredLinks(node);
2796
2797
2798
2799
2800
2807 const auto en =
static_cast<
const ExampleNode *>(node);
2810 if (exampleUrl.isEmpty()) {
2811 if (!en->noAutoList()) {
2812 generateFileList(en,
false);
2813 generateFileList(en,
true);
2816 generateLinkToExample(en, exampleUrl);
2821
2822
2823
2824
2825
2829 QString exampleUrl(baseUrl);
2831#ifndef QT_BOOTSTRAPPED
2832 link = QUrl(exampleUrl).host();
2834 if (!link.isEmpty())
2835 link.prepend(
" @ ");
2836 link.prepend(
"Example project");
2838 const QLatin1Char separator(
'/');
2839 const QLatin1Char placeholder(
'\1');
2840 if (!exampleUrl.contains(placeholder)) {
2841 if (!exampleUrl.endsWith(separator))
2842 exampleUrl += separator;
2843 exampleUrl += placeholder;
2847 QStringList path = QStringList()
2849 path.removeAll(QString());
2853 startSection(
"Example project");
2855 m_writer->writeStartElement(dbNamespace,
"para");
2856 generateSimpleLink(exampleUrl.replace(placeholder, path.join(separator)), link);
2857 m_writer->writeEndElement();
2866
2867
2868
2869
2870
2871
2887 paths = en->images();
2890 paths = en->files();
2893 std::sort(paths.begin(), paths.end(), Generator::comparePaths);
2895 if (paths.isEmpty())
2898 startSection(
"",
"List of Files");
2900 m_writer->writeStartElement(dbNamespace,
"para");
2901 m_writer->writeCharacters(tag);
2902 m_writer->writeEndElement();
2905 startSection(
"List of Files");
2907 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
2910 for (
const auto &path : std::as_const(paths)) {
2911 auto maybe_resolved_file{file_resolver.resolve(path)};
2912 if (!maybe_resolved_file) {
2914 QString details = std::transform_reduce(
2915 file_resolver.get_search_directories().cbegin(),
2916 file_resolver.get_search_directories().cend(),
2917 u"Searched directories:"_s,
2919 [](
const DirectoryPath &directory_path) -> QString {
return u' ' + directory_path.value(); }
2922 en->location().warning(u"Cannot find file to quote from: %1"_s.arg(path), details);
2927 const auto &file{*maybe_resolved_file};
2928 if (images) addImageToCopy(en, file);
2929 else generateExampleFilePage(en, file);
2931 m_writer->writeStartElement(dbNamespace,
"listitem");
2933 m_writer->writeStartElement(dbNamespace,
"para");
2934 generateSimpleLink(file.get_query(), file.get_query());
2935 m_writer->writeEndElement();
2936 m_writer->writeEndElement();
2940 m_writer->writeEndElement();
2947
2948
2958 const auto en =
static_cast<
const ExampleNode *>(node);
2961 QXmlStreamWriter *currentWriter = m_writer;
2962 m_writer = startDocument(en, resolved_file.get_query());
2963 generateHeader(en->doc().title(), en->subtitle(), en);
2968 QString code = quoter.quoteTo(en->location(), QString(), QString());
2969 CodeMarker *codeMarker = CodeMarker::markerForFileName(resolved_file.get_path());
2975 m_writer = currentWriter;
2981 if (fn->overridesThis().isEmpty() || !fn
->parent()->isClassNode())
2986 if (
const FunctionNode *overrides = cn->findOverriddenFunction(fn);
2989 m_writer->writeStartElement(dbNamespace,
"para");
2990 m_writer->writeCharacters(
"Reimplements: ");
2993 generateFullName(overrides
->parent(), fullName, overrides);
2994 m_writer->writeCharacters(
".");
2995 m_writer->writeEndElement();
3001 if (
const PropertyNode *sameName = cn->findOverriddenProperty(fn); sameName && sameName
->hasDoc()) {
3002 m_writer->writeStartElement(dbNamespace,
"para");
3003 m_writer->writeCharacters(
"Reimplements an access function for property: ");
3004 QString fullName = sameName
->parent()->name() +
"::" + sameName->name();
3005 generateFullName(sameName
->parent(), fullName, sameName);
3006 m_writer->writeCharacters(
".");
3007 m_writer->writeEndElement();
3016 QList<Text> alsoList = node
->doc().alsoList();
3017 supplementAlsoList(node, alsoList);
3019 if (!alsoList.isEmpty()) {
3020 startSection(
"See Also");
3022 m_writer->writeStartElement(dbNamespace,
"para");
3023 m_writer->writeStartElement(dbNamespace,
"emphasis");
3024 m_writer->writeCharacters(
"See also ");
3025 m_writer->writeEndElement();
3028 m_writer->writeStartElement(dbNamespace,
"simplelist");
3029 m_writer->writeAttribute(
"type",
"vert");
3030 m_writer->writeAttribute(
"role",
"see-also");
3033 for (
const Text &text : alsoList) {
3034 m_writer->writeStartElement(dbNamespace,
"member");
3035 generateText(text, node);
3036 m_writer->writeEndElement();
3040 m_writer->writeEndElement();
3043 m_writer->writeEndElement();
3051
3052
3053
3054QXmlStreamWriter *
DocBookGenerator::startGenericDocument(
const Node *node,
const QString &fileName)
3057 QFile *outFile = openSubPageFile(
static_cast<
const PageNode*>(node), fileName);
3058 m_writer =
new QXmlStreamWriter(outFile);
3059 m_writer->setAutoFormatting(
false);
3061 m_writer->writeStartDocument();
3063 m_writer->writeNamespace(dbNamespace,
"db");
3064 m_writer->writeNamespace(xlinkNamespace,
"xlink");
3066 m_writer->writeNamespace(itsNamespace,
"its");
3067 m_writer->writeStartElement(dbNamespace,
"article");
3068 m_writer->writeAttribute(
"version",
"5.2");
3069 if (!m_naturalLanguage.isEmpty())
3070 m_writer->writeAttribute(
"xml:lang", m_naturalLanguage);
3074 sectionLevels.resize(0);
3083 m_hasSection =
false;
3086 QString fileName = Generator::fileName(node, fileExtension());
3087 return startGenericDocument(node, fileName);
3092 m_hasSection =
false;
3094 QString fileName = linkForExampleFile(file);
3095 return startGenericDocument(en, fileName);
3100 m_writer->writeEndElement();
3101 m_writer->writeEndDocument();
3103 m_writer->device()->close();
3104 delete m_writer->device();
3110
3111
3112
3117 const auto aggregate =
static_cast<
const Aggregate *>(node);
3121 QString subtitleText;
3122 const QString typeWord{aggregate->typeWord(
true)};
3123 if (aggregate->isNamespace()) {
3124 title =
"%1 %2"_L1.arg(aggregate->plainFullName(), typeWord);
3125 }
else if (aggregate->isClass()) {
3126 auto templateDecl = node->templateDecl();
3128 subtitleText =
"%1 %2 %3"_L1.arg((*templateDecl).to_qstring(),
3129 aggregate->typeWord(
false),
3130 aggregate->plainFullName());
3131 title =
"%1 %2"_L1.arg(aggregate->plainFullName(), typeWord);
3132 }
else if (aggregate->isHeader()) {
3133 title = aggregate->fullTitle();
3134 if (!aggregate->doc().title().isEmpty())
3135 titleText << aggregate->name() <<
" - "_L1 << aggregate->doc().title();
3139 m_writer = startDocument(node);
3142 if (!titleText.isEmpty())
3143 generateHeader(titleText, subtitleText, aggregate);
3145 generateHeader(title, subtitleText, aggregate);
3154 if (!aggregate->doc().isEmpty()) {
3155 startSection(
"details",
"Detailed Description");
3157 generateBody(aggregate);
3165 for (
const Section §ion : sectionVector) {
3166 if (section.members().isEmpty())
3169 startSection(section.title().toLower(), section.title());
3171 for (
const Node *member : section.members()) {
3172 if (member->nodeType() != NodeType::Class) {
3174 generateDetailedMember(member, aggregate);
3176 startSectionBegin();
3177 m_writer->writeCharacters(
"class ");
3178 generateFullName(member, aggregate);
3181 generateBrief(member);
3190 generateObsoleteMembers(sections);
3195void DocBookGenerator::generateSynopsisInfo(
const QString &key,
const QString &value)
3197 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3198 m_writer->writeAttribute(
"role", key);
3199 m_writer->writeCharacters(value);
3200 m_writer->writeEndElement();
3206 m_writer->writeTextElement(dbNamespace,
"modifier", value);
3211
3212
3222 if (!m_useDocBook52)
3232 node->isAggregate() ?
static_cast<
const Aggregate *>(node) :
nullptr;
3233 const ClassNode *classNode = node->isClass() ?
static_cast<
const ClassNode *>(node) :
nullptr;
3235 node->isFunction() ?
static_cast<
const FunctionNode *>(node) :
nullptr;
3237 node->isProperty() ?
static_cast<
const PropertyNode *>(node) :
nullptr;
3239 node->isVariable() ?
static_cast<
const VariableNode *>(node) :
nullptr;
3240 const EnumNode *enumNode = node->isEnumType() ?
static_cast<
const EnumNode *>(node) :
nullptr;
3242 node->isQmlProperty() ?
static_cast<
const QmlPropertyNode *>(node) :
nullptr;
3243 const QmlTypeNode *qcn = node->isQmlType() ?
static_cast<
const QmlTypeNode *>(node) :
nullptr;
3249 QString synopsisTag = nodeToSynopsisTag(node);
3250 m_writer->writeStartElement(dbNamespace, synopsisTag);
3255 m_writer->writeStartElement(dbNamespace,
"ooclass");
3256 m_writer->writeTextElement(dbNamespace,
"classname", node->plainName());
3257 m_writer->writeEndElement();
3260 m_writer->writeTextElement(dbNamespace,
"namespacename", node->plainName());
3263 m_writer->writeStartElement(dbNamespace,
"ooclass");
3264 m_writer->writeTextElement(dbNamespace,
"classname", node->plainName());
3265 m_writer->writeEndElement();
3267 if (!qcn->groupNames().isEmpty())
3268 m_writer->writeAttribute(
"groups", qcn->groupNames().join(QLatin1Char(
',')));
3270 m_writer->writeTextElement(dbNamespace,
"modifier",
"(Qt property)");
3272 m_writer->writeTextElement(dbNamespace,
"type", propertyNode->dataType());
3274 m_writer->writeTextElement(dbNamespace,
"varname", node->plainName());
3278 m_writer->writeTextElement(dbNamespace,
"modifier",
"static");
3281 m_writer->writeTextElement(dbNamespace,
"type", variableNode->dataType());
3283 m_writer->writeTextElement(dbNamespace,
"varname", node->plainName());
3287 m_writer->writeTextElement(dbNamespace,
"enumname", node->plainName());
3291 QString name = node->name();
3293 name.prepend(qpn->element() + QLatin1Char(
'.'));
3295 m_writer->writeTextElement(dbNamespace,
"type", qpn->dataType());
3297 m_writer->writeTextElement(dbNamespace,
"varname", name);
3305 m_writer->writeTextElement(dbNamespace,
"modifier",
"attached");
3309 m_writer->writeTextElement(dbNamespace,
"modifier",
"writable");
3313 m_writer->writeTextElement(dbNamespace,
"modifier",
"required");
3318 generateModifier(
"[read-only]");
3322 generateModifier(
"[default]");
3326 if (functionNode->virtualness() !=
"non")
3327 generateModifier(
"virtual");
3328 if (functionNode->isConst())
3329 generateModifier(
"const");
3330 if (functionNode->isStatic())
3331 generateModifier(
"static");
3336 if (functionNode->returnType() ==
"void")
3337 m_writer->writeEmptyElement(dbNamespace,
"void");
3339 m_writer->writeTextElement(dbNamespace,
"type", functionNode->returnTypeString());
3344 QString name = node->plainName();
3345 if (name.endsWith(
"()"))
3347 m_writer->writeTextElement(dbNamespace,
"methodname", name);
3351 m_writer->writeEmptyElement(dbNamespace,
"void");
3356 for (
int i = 0; i < lp
.count(); ++i) {
3358 m_writer->writeStartElement(dbNamespace,
"methodparam");
3360 m_writer->writeTextElement(dbNamespace,
"type", parameter.type());
3362 m_writer->writeTextElement(dbNamespace,
"parameter", parameter.name());
3364 if (!parameter.defaultValue().isEmpty()) {
3365 m_writer->writeTextElement(dbNamespace,
"initializer", parameter.defaultValue());
3368 m_writer->writeEndElement();
3372 if (functionNode->isImplicitlyGenerated())
3373 generateModifier(
"implicit");
3374 else if (functionNode->isExplicitlyDefaulted())
3375 generateModifier(
"default");
3376 else if (functionNode->isDeletedAsWritten())
3377 generateModifier(
"delete");
3378 if (functionNode->isFinal())
3379 generateModifier(
"final");
3380 if (functionNode->isOverride())
3381 generateModifier(
"override");
3383 m_writer->writeTextElement(dbNamespace,
"typedefname", node->plainName());
3387 QStringLiteral(
"Unexpected node type in generateDocBookSynopsis: %1")
3388 .arg(node->nodeTypeString()));
3394 for (
const EnumItem &item : enumNode->items()) {
3395 m_writer->writeStartElement(dbNamespace,
"enumitem");
3397 m_writer->writeTextElement(dbNamespace,
"enumidentifier", item.name());
3399 m_writer->writeTextElement(dbNamespace,
"enumvalue", item.value());
3401 m_writer->writeEndElement();
3405 if (enumNode->items().isEmpty()) {
3408 m_writer->writeStartElement(dbNamespace,
"enumitem");
3410 m_writer->writeEmptyElement(dbNamespace,
"enumidentifier");
3412 m_writer->writeEndElement();
3423 generateSynopsisInfo(
"meta", functionNode->metanessString());
3426 generateSynopsisInfo(
"overload",
"overload");
3427 generateSynopsisInfo(
"overload-number",
3428 QString::number(functionNode->overloadNumber()));
3431 if (functionNode->isRef())
3432 generateSynopsisInfo(
"refness", QString::number(1));
3433 else if (functionNode->isRefRef())
3434 generateSynopsisInfo(
"refness", QString::number(2));
3437 QStringList associatedProperties;
3438 const auto &nodes = functionNode->associatedProperties();
3439 for (
const Node *n : nodes) {
3440 const auto pn =
static_cast<
const PropertyNode *>(n);
3441 associatedProperties << pn->name();
3443 associatedProperties.sort();
3444 generateSynopsisInfo(
"associated-property",
3445 associatedProperties.join(QLatin1Char(
',')));
3451 signature +=
" final";
3453 signature +=
" override";
3455 signature +=
" = 0";
3457 signature +=
" = default";
3459 signature +=
" = delete";
3460 if (
const auto &req = functionNode->trailingRequiresClause(); req && !req->isEmpty())
3461 signature +=
" requires " + *req;
3462 generateSynopsisInfo(
"signature", signature);
3468 case Access::Public:
3469 generateSynopsisInfo(
"access",
"public");
3471 case Access::Protected:
3472 generateSynopsisInfo(
"access",
"protected");
3474 case Access::Private:
3475 generateSynopsisInfo(
"access",
"private");
3480 if (node->isAbstract())
3481 generateSynopsisInfo(
"abstract",
"true");
3486 case Status::Active:
3487 generateSynopsisInfo(
"status",
"active");
3489 case Status::Preliminary:
3490 generateSynopsisInfo(
"status",
3493 case Status::Deprecated:
3494 generateSynopsisInfo(
"status",
"deprecated");
3496 case Status::Internal:
3497 generateSynopsisInfo(
"status",
"internal");
3500 generateSynopsisInfo(
"status",
"main");
3507 if (aggregate->includeFile()) generateSynopsisInfo(
"headers", *aggregate->includeFile());
3510 if (!aggregate->since().isEmpty())
3511 generateSynopsisInfo(
"since", formatSince(aggregate));
3515 if (!aggregate->physicalModuleName().isEmpty()) {
3517 m_qdb->getCollectionNode(aggregate->physicalModuleName(), NodeType::Module);
3519 if (
const auto result = cmakeRequisite(cn)) {
3520 generateSynopsisInfo(
"cmake-find-package", result->first);
3521 generateSynopsisInfo(
"cmake-target-link-libraries", result->second);
3524 if (cn && !cn->qtVariable().isEmpty())
3525 generateSynopsisInfo(
"qmake",
"QT += " + cn->qtVariable());
3531 auto *classe =
const_cast<ClassNode *>(
static_cast<
const ClassNode *>(aggregate));
3532 if (classe && classe->isQmlNativeType() && classe->status() !=
Status::Internal) {
3533 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3534 m_writer->writeAttribute(
"role",
"nativeTypeFor");
3536 QList<QmlTypeNode *> nativeTypes { classe->qmlNativeTypes().cbegin(), classe->qmlNativeTypes().cend()};
3539 for (
auto item : std::as_const(nativeTypes)) {
3540 const Node *otherNode{
nullptr};
3541 Atom a = Atom(Atom::LinkNode, Utilities::stringForNode(item));
3542 const QString &link = getAutoLink(&a, aggregate, &otherNode);
3543 generateSimpleLink(link, item->name());
3546 m_writer->writeEndElement();
3550 QList<RelatedClass>::ConstIterator r;
3551 if (!classe->baseClasses().isEmpty()) {
3552 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3553 m_writer->writeAttribute(
"role",
"inherits");
3555 r = classe->baseClasses().constBegin();
3557 while (r != classe->baseClasses().constEnd()) {
3559 generateFullName((*r).m_node, classe);
3562 m_writer->writeCharacters(
" (protected)");
3564 m_writer->writeCharacters(
" (private)");
3566 m_writer->writeCharacters(
3567 Utilities::comma(index++, classe->baseClasses().size()));
3572 m_writer->writeEndElement();
3577 if (!classe->derivedClasses().isEmpty()) {
3578 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3579 m_writer->writeAttribute(
"role",
"inheritedBy");
3580 generateSortedNames(classe, classe->derivedClasses());
3581 m_writer->writeEndElement();
3590 QString logicalModuleVersion;
3592 m_qdb->getCollectionNode(qcn->logicalModuleName(), qcn->nodeType());
3594 logicalModuleVersion = collection->logicalModuleVersion();
3596 logicalModuleVersion = qcn->logicalModuleVersion();
3598 QStringList importText;
3599 importText <<
"import " + qcn->logicalModuleName();
3600 if (!logicalModuleVersion.isEmpty())
3601 importText << logicalModuleVersion;
3602 generateSynopsisInfo(
"import", importText.join(
' '));
3605 if (!qcn->since().isEmpty())
3606 generateSynopsisInfo(
"since", formatSince(qcn));
3609 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
3617 QStringList knownTypeNames{qcn->name()};
3619 knownTypeNames << base->name();
3624 if (!subs.isEmpty()) {
3625 m_writer->writeTextElement(dbNamespace,
"synopsisinfo");
3626 m_writer->writeAttribute(
"role",
"inheritedBy");
3627 generateSortedQmlNames(qcn, knownTypeNames, subs);
3628 m_writer->writeEndElement();
3634 const Node *otherNode =
nullptr;
3636 QString link = getAutoLink(&a, base, &otherNode);
3638 m_writer->writeTextElement(dbNamespace,
"synopsisinfo");
3639 m_writer->writeAttribute(
"role",
"inherits");
3640 generateSimpleLink(link, base->name());
3642 for (
const auto sub : std::as_const(subs)) {
3643 if (knownTypeNames.contains(sub->name())) {
3644 m_writer->writeCharacters(
" (%1)"_L1.arg(base->logicalModuleName()));
3648 m_writer->writeEndElement();
3656 const Node *otherNode =
nullptr;
3658 QString link = getAutoLink(&a, cn, &otherNode);
3660 m_writer->writeTextElement(dbNamespace,
"synopsisinfo");
3661 m_writer->writeAttribute(
"role",
"nativeType");
3662 generateSimpleLink(link, cn->name());
3663 m_writer->writeEndElement();
3670 case Node::UnspecifiedSafeness:
3671 generateSynopsisInfo(
"threadsafeness",
"unspecified");
3673 case Node::NonReentrant:
3674 generateSynopsisInfo(
"threadsafeness",
"non-reentrant");
3676 case Node::Reentrant:
3677 generateSynopsisInfo(
"threadsafeness",
"reentrant");
3679 case Node::ThreadSafe:
3680 generateSynopsisInfo(
"threadsafeness",
"thread safe");
3683 generateSynopsisInfo(
"threadsafeness",
"unspecified");
3688 if (!node->physicalModuleName().isEmpty())
3689 generateSynopsisInfo(
"module", node->physicalModuleName());
3692 if (classNode && !classNode->groupNames().isEmpty()) {
3693 generateSynopsisInfo(
"groups", classNode->groupNames().join(QLatin1Char(
',')));
3694 }
else if (qcn && !qcn->groupNames().isEmpty()) {
3695 generateSynopsisInfo(
"groups", qcn->groupNames().join(QLatin1Char(
',')));
3700 for (
const Node *fnNode : propertyNode->getters()) {
3702 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3703 generateSynopsisInfo(
"getter", funcNode->name());
3706 for (
const Node *fnNode : propertyNode->setters()) {
3708 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3709 generateSynopsisInfo(
"setter", funcNode->name());
3712 for (
const Node *fnNode : propertyNode->resetters()) {
3714 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3715 generateSynopsisInfo(
"resetter", funcNode->name());
3718 for (
const Node *fnNode : propertyNode->notifiers()) {
3720 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3721 generateSynopsisInfo(
"notifier", funcNode->name());
3726 m_writer->writeEndElement();
3732 m_writer->writeStartElement(dbNamespace,
"typedefsynopsis");
3735 m_writer->writeTextElement(dbNamespace,
"typedefname",
3736 enumNode->flagsType()->fullDocumentName());
3739 m_writer->writeEndElement();
3750 return node->name().mid(4);
3751 return node->name();
3755
3756
3757
3758void DocBookGenerator::typified(
const QString &string,
const Node *relative,
bool trailingSpace,
3763 QString pendingWord;
3765 for (
int i = 0; i <= string.size(); ++i) {
3767 if (i != string.size())
3770 QChar lower = ch.toLower();
3771 if ((lower >= QLatin1Char(
'a') && lower <= QLatin1Char(
'z')) || ch.digitValue() >= 0
3772 || ch == QLatin1Char(
'_') || ch == QLatin1Char(
':')) {
3775 if (!pendingWord.isEmpty()) {
3776 bool isProbablyType = (pendingWord != QLatin1String(
"const"));
3777 if (generateType && isProbablyType) {
3779 m_writer->writeCharacters(result);
3783 const Node *n = m_qdb->findTypeNode(pendingWord, relative, Genus::DontCare);
3788 href = linkForNode(n, relative);
3791 m_writer->writeStartElement(dbNamespace,
"type");
3793 m_writer->writeCharacters(pendingWord);
3795 generateSimpleLink(href, pendingWord);
3796 m_writer->writeEndElement();
3798 result += pendingWord;
3801 pendingWord.clear();
3803 if (ch.unicode() !=
'\0')
3808 if (trailingSpace && string.size()) {
3809 if (!string.endsWith(QLatin1Char(
'*')) && !string.endsWith(QLatin1Char(
'&')))
3810 result += QLatin1Char(
' ');
3813 m_writer->writeCharacters(result);
3817 bool generateNameLink)
3821 QString name = taggedNode(node);
3823 if (!generateNameLink) {
3824 m_writer->writeCharacters(name);
3828 m_writer->writeStartElement(dbNamespace,
"emphasis");
3829 m_writer->writeAttribute(
"role",
"bold");
3830 generateSimpleLink(linkForNode(node, relative), name);
3831 m_writer->writeEndElement();
3835 bool generateExtra,
bool generateType)
3837 const QString &pname = parameter.name();
3838 const QString &ptype = parameter.type();
3840 qsizetype insertPos = !pname.isEmpty() ? parameter.nameInsertionPoint() : -1;
3841 if (!pname.isEmpty()) {
3842 if (insertPos >= 0) {
3844 typified(ptype.left(insertPos), relative,
false, generateType);
3846 typified(ptype, relative,
true, generateType);
3853 if (generateExtra || pname.isEmpty()) {
3854 m_writer->writeStartElement(dbNamespace,
"emphasis");
3855 m_writer->writeCharacters(paramName);
3856 m_writer->writeEndElement();
3860 typified(ptype.mid(insertPos), relative,
false, generateType);
3862 const QString &pvalue = parameter.defaultValue();
3863 if (generateExtra && !pvalue.isEmpty())
3864 m_writer->writeCharacters(
" = " + pvalue);
3876 const int MaxEnumValues = 6;
3878 if (generateExtra) {
3879 if (
auto extra = CodeMarker::extraSynopsis(node, style); !extra.isEmpty()) {
3880 generateExtraSynopsis(extra);
3881 m_writer->writeCharacters(u" "_s);
3886 QString namePrefix {};
3890 namePrefix = taggedNode(node->parent()) +
"::";
3895 case NodeType::Namespace:
3896 m_writer->writeCharacters(
"namespace ");
3897 m_writer->writeCharacters(namePrefix);
3898 generateSynopsisName(node, relative, generateNameLink);
3900 case NodeType::Class:
3901 m_writer->writeCharacters(
"class ");
3902 m_writer->writeCharacters(namePrefix);
3903 generateSynopsisName(node, relative, generateNameLink);
3909 if (
auto templateDecl = func->templateDecl()) {
3910 if (templateDecl->visibleParameterCount() > QDoc::MultilineTemplateParamThreshold)
3911 m_writer->writeCharacters(templateDecl->to_qstring_multiline() + QLatin1Char(
'\n'));
3913 m_writer->writeCharacters(templateDecl->to_qstring() + QLatin1Char(
' '));
3919 if (!func->isNonvirtual())
3920 m_writer->writeCharacters(QStringLiteral(
"virtual "));
3924 if (style != Section::AllMembers && !func->returnType().isEmpty())
3925 typified(func->returnTypeString(), relative,
true, generateType);
3926 m_writer->writeCharacters(namePrefix);
3927 generateSynopsisName(node, relative, generateNameLink);
3930 m_writer->writeCharacters(QStringLiteral(
"("));
3933 for (
int i = 0; i < parameters
.count(); i++) {
3935 m_writer->writeCharacters(QStringLiteral(
", "));
3936 generateParameter(parameters
.at(i
), relative, generateExtra, generateType);
3939 m_writer->writeCharacters(QStringLiteral(
")"));
3942 if (func->isConst())
3943 m_writer->writeCharacters(QStringLiteral(
" const"));
3949 synopsis += QStringLiteral(
" final");
3951 synopsis += QStringLiteral(
" override");
3953 synopsis += QStringLiteral(
" = 0");
3955 synopsis += QStringLiteral(
" &");
3957 synopsis += QStringLiteral(
" &&");
3958 m_writer->writeCharacters(synopsis);
3960 if (!func->returnType().isEmpty() && func->returnType() !=
"void") {
3961 m_writer->writeCharacters(QStringLiteral(
" : "));
3962 typified(func->returnTypeString(), relative,
false, generateType);
3967 synopsis += QStringLiteral(
" &");
3969 synopsis += QStringLiteral(
" &&");
3970 if (
const auto &req = func->trailingRequiresClause(); req && !req->isEmpty())
3971 synopsis +=
" requires " + *req;
3972 m_writer->writeCharacters(synopsis);
3976 const auto enume =
static_cast<
const EnumNode *>(node);
3977 if (!enume->isAnonymous()) {
3978 m_writer->writeCharacters(
"enum "_L1);
3979 m_writer->writeCharacters(namePrefix);
3980 generateSynopsisName(node, relative, generateNameLink);
3981 }
else if (generateNameLink) {
3982 m_writer->writeStartElement(dbNamespace,
"emphasis");
3983 m_writer->writeAttribute(
"role",
"bold");
3984 generateSimpleLink(linkForNode(node, relative),
"enum");
3985 m_writer->writeEndElement();
3987 m_writer->writeCharacters(
"enum"_L1);
3994 QStringList documentedItems = enume->doc().enumItemNames();
3995 if (documentedItems.isEmpty()) {
3996 const auto &enumItems = enume->items();
3997 for (
const auto &item : enumItems)
3998 documentedItems << item.name();
4000 const QStringList omitItems = enume->doc().omitEnumItemNames();
4001 for (
const auto &item : omitItems)
4002 documentedItems.removeAll(item);
4004 if (documentedItems.size() > MaxEnumValues) {
4006 const QString last = documentedItems.last();
4007 documentedItems = documentedItems.mid(0, MaxEnumValues - 1);
4008 documentedItems +=
"…";
4009 documentedItems += last;
4011 synopsis += documentedItems.join(QLatin1String(
", "));
4013 if (!documentedItems.isEmpty())
4014 synopsis += QLatin1Char(
' ');
4015 synopsis += QLatin1Char(
'}');
4017 m_writer->writeCharacters(synopsis);
4021 if (
auto templateDecl = node->templateDecl()) {
4022 if (templateDecl->visibleParameterCount() > QDoc::MultilineTemplateParamThreshold)
4023 m_writer->writeCharacters(templateDecl->to_qstring_multiline() + QLatin1Char(
'\n'));
4025 m_writer->writeCharacters(templateDecl->to_qstring() + QLatin1Char(
' '));
4028 m_writer->writeCharacters(namePrefix);
4029 generateSynopsisName(node, relative, generateNameLink);
4032 if (
static_cast<
const TypedefNode *>(node)->associatedEnum())
4033 m_writer->writeCharacters(
"flags ");
4034 m_writer->writeCharacters(namePrefix);
4035 generateSynopsisName(node, relative, generateNameLink);
4038 const auto property =
static_cast<
const PropertyNode *>(node);
4039 m_writer->writeCharacters(namePrefix);
4040 generateSynopsisName(node, relative, generateNameLink);
4041 m_writer->writeCharacters(
" : ");
4042 typified(property->qualifiedDataType(), relative,
false, generateType);
4045 const auto variable =
static_cast<
const VariableNode *>(node);
4047 generateSynopsisName(node, relative, generateNameLink);
4048 m_writer->writeCharacters(
" : ");
4049 typified(variable->dataType(), relative,
false, generateType);
4051 typified(variable->leftType(), relative,
false, generateType);
4052 m_writer->writeCharacters(
" ");
4053 m_writer->writeCharacters(namePrefix);
4054 generateSynopsisName(node, relative, generateNameLink);
4055 m_writer->writeCharacters(variable->rightType());
4059 m_writer->writeCharacters(namePrefix);
4060 generateSynopsisName(node, relative, generateNameLink);
4075 if (nativeEnum && nativeEnum
->enumNode() && !enumValue.startsWith(
"%1."_L1.arg(nativeEnum->prefix()))) {
4076 m_writer->writeCharacters(
"%1.%2"_L1.arg(nativeEnum->prefix(), enumValue));
4082 && enumValue.section(
' ', 0, 0).contains(
'.'_L1))) {
4083 m_writer->writeCharacters(enumValue);
4087 QList<
const Node *> parents;
4089 parents.prepend(node);
4094 if (
static_cast<
const EnumNode *>(relative)->isScoped())
4095 parents << relative;
4097 m_writer->writeStartElement(dbNamespace,
"code");
4098 for (
auto parent : parents) {
4099 generateSynopsisName(parent, relative,
true);
4100 m_writer->writeCharacters((relative->genus() == Genus::QML) ?
"."_L1 :
"::"_L1);
4103 m_writer->writeCharacters(enumValue);
4104 m_writer->writeEndElement();
4108
4109
4110
4115 Q_ASSERT(node && !node->name().isEmpty());
4121 m_writer->writeStartElement(dbNamespace,
"note");
4128 m_writer->writeStartElement(dbNamespace,
"para");
4129 m_writer->writeCharacters(
4130 "This function can be invoked via the meta-object system and from QML. See ");
4131 generateSimpleLink(node->url(),
"Q_INVOKABLE");
4132 m_writer->writeCharacters(
".");
4133 m_writer->writeEndElement();
4137 m_writer->writeTextElement(
4138 dbNamespace,
"para",
4139 "This is a private signal. It can be used in signal connections but "
4140 "cannot be emitted by the user.");
4144 QString handler(node->name());
4145 int prefixLocation = handler.lastIndexOf(
'.', -2) + 1;
4146 handler[prefixLocation] = handler[prefixLocation].toTitleCase();
4147 handler.insert(prefixLocation, QLatin1String(
"on"));
4148 m_writer->writeStartElement(dbNamespace,
"para");
4149 m_writer->writeCharacters(
"The corresponding handler is ");
4150 m_writer->writeTextElement(dbNamespace,
"code", handler);
4151 m_writer->writeCharacters(
".");
4152 m_writer->writeEndElement();
4160 const auto *fn =
static_cast<
const FunctionNode *>(node);
4161 auto nodes = fn->associatedProperties();
4162 if (nodes.isEmpty())
4167 QMap<PropertyNode::FunctionRole, QList<
const PropertyNode *>> roleGroups;
4168 for (
const auto *n : std::as_const(nodes)) {
4169 const auto *pn =
static_cast<
const PropertyNode *>(n);
4170 PropertyNode::FunctionRole role = pn->role(fn);
4171 roleGroups[role].append(pn);
4183 for (
auto role : roleOrder) {
4184 const auto it = roleGroups.constFind(role);
4185 if (it == roleGroups.cend())
4188 const auto &properties = it.value();
4193 msg = QStringLiteral(
"Getter function");
4196 msg = QStringLiteral(
"Setter function");
4199 msg = QStringLiteral(
"Resetter function");
4202 msg = QStringLiteral(
"Notifier signal");
4205 msg = QStringLiteral(
"Bindable function");
4211 m_writer->writeStartElement(dbNamespace,
"para");
4212 if (properties.size() == 1) {
4213 const auto *pn = properties.first();
4214 m_writer->writeCharacters(msg +
" for property ");
4215 generateSimpleLink(linkForNode(pn,
nullptr), pn->name());
4216 m_writer->writeCharacters(
". ");
4218 m_writer->writeCharacters(msg +
" for properties ");
4219 for (qsizetype i = 0; i < properties.size(); ++i) {
4220 const auto *pn = properties.at(i);
4221 generateSimpleLink(linkForNode(pn,
nullptr), pn->name());
4222 m_writer->writeCharacters(Utilities::separator(i, properties.size()));
4224 m_writer->writeCharacters(
" ");
4226 m_writer->writeEndElement();
4233 const Node *linkNode;
4235 QString link = getAutoLink(&linkAtom, node, &linkNode);
4236 m_writer->writeStartElement(dbNamespace,
"para");
4237 m_writer->writeCharacters(
"This property supports ");
4238 generateSimpleLink(link,
"QProperty");
4239 m_writer->writeCharacters(
" bindings.");
4240 m_writer->writeEndElement();
4245 const auto *func =
static_cast<
const FunctionNode *>(node);
4248 if (func->isPrimaryOverload())
4251 m_writer->writeStartElement(dbNamespace,
"para");
4253 if (func->isSignal() || func->isSlot()) {
4254 auto writeDocBookLink = [&](
const QString &target,
const QString &label) {
4255 const Node *linkNode =
nullptr;
4257 const QString &link = getAutoLink(&linkAtom, node, &linkNode);
4259 m_writer->writeStartElement(dbNamespace,
"link");
4260 if (!link.isEmpty() && linkNode) {
4261 m_writer->writeAttribute(xlinkNamespace,
"href", link);
4263 m_writer->writeAttribute(dbNamespace,
"linkend", target);
4265 m_writer->writeCharacters(label);
4266 m_writer->writeEndElement();
4269 const QString &functionType = func->isSignal() ?
"signal" :
"slot";
4270 const QString &configKey = func->isSignal() ?
"overloadedsignalstarget" :
"overloadedslotstarget";
4271 const QString &defaultTarget = func->isSignal() ?
"connecting-overloaded-signals" :
"connecting-overloaded-slots";
4272 const QString &linkTarget = Config::instance().get(configKey).asString(defaultTarget);
4274 m_writer->writeCharacters(
"This " + functionType +
" is overloaded. ");
4276 QString snippet = generateOverloadSnippet(func);
4277 if (!snippet.isEmpty()) {
4278 m_writer->writeCharacters(
"To connect to this " + functionType +
":");
4279 m_writer->writeEndElement();
4281 m_writer->writeStartElement(dbNamespace,
"programlisting");
4282 m_writer->writeCharacters(snippet);
4283 m_writer->writeEndElement();
4288 m_writer->writeStartElement(dbNamespace,
"para");
4289 if (!linkTarget.isEmpty()) {
4290 m_writer->writeCharacters(
"For more examples and approaches, see ");
4291 writeDocBookLink(linkTarget,
"connecting to overloaded " + functionType +
"s");
4292 m_writer->writeCharacters(
".");
4294 }
else if (!linkTarget.isEmpty()) {
4295 m_writer->writeCharacters(
"For more examples and approaches, see ");
4296 writeDocBookLink(linkTarget,
"connecting to overloaded " + functionType +
"s");
4297 m_writer->writeCharacters(
".");
4301 const auto &args = node
->doc().overloadList();
4302 if (args.first().first.isEmpty()) {
4303 m_writer->writeCharacters(
"This is an overloaded function.");
4305 QString target = args.first().first;
4308 if (!target.contains(
"::")) {
4311 target = parent->name() +
"::" + target;
4314 m_writer->writeCharacters(
"This function overloads ");
4316 const Node *linkNode =
nullptr;
4318 QString link = getAutoLink(&linkAtom, node, &linkNode);
4319 if (!link.isEmpty() && linkNode)
4320 generateSimpleLink(link, target);
4322 m_writer->writeCharacters(target);
4323 m_writer->writeCharacters(
".");
4327 m_writer->writeEndElement();
4336 m_writer->writeEndElement();
4344 bool closeSupplementarySection =
false;
4348 const QList<Node *> &collective = scn->collective();
4350 bool firstFunction =
true;
4351 for (
const auto *sharedNode : collective) {
4352 if (firstFunction) {
4353 startSectionBegin(sharedNode);
4355 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4356 m_writer->writeAttribute(
"renderas",
"sect2");
4357 writeXmlId(sharedNode);
4360 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4362 generateSynopsis(sharedNode, relative, Section::Details);
4364 if (firstFunction) {
4366 firstFunction =
false;
4368 m_writer->writeEndElement();
4374 if (node->isEnumType(Genus::CPP) && (etn =
static_cast<
const EnumNode *>(node))->flagsType()) {
4375 startSectionBegin(node);
4377 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4381 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4382 m_writer->writeAttribute(
"renderas",
"sect2");
4384 m_writer->writeEndElement();
4387 startSectionBegin(node);
4389 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4394 Q_ASSERT(m_hasSection);
4403 closeSupplementarySection =
true;
4404 startSection(
"",
"Notes");
4408 const auto *func =
static_cast<
const FunctionNode *>(node);
4409 if (func->hasOverloads() && (func->isSignal() || func->isSlot()))
4417 const auto property =
static_cast<
const PropertyNode *>(node);
4426 m_writer->writeStartElement(dbNamespace,
"para");
4428 m_writer->writeStartElement(dbNamespace,
"emphasis");
4429 m_writer->writeAttribute(
"role",
"bold");
4430 m_writer->writeCharacters(
"Access functions:");
4432 m_writer->writeEndElement();
4434 m_writer->writeEndElement();
4436 generateSectionList(section, node);
4443 m_writer->writeStartElement(dbNamespace,
"para");
4445 m_writer->writeStartElement(dbNamespace,
"emphasis");
4446 m_writer->writeAttribute(
"role",
"bold");
4447 m_writer->writeCharacters(
"Notifier signal:");
4449 m_writer->writeEndElement();
4451 m_writer->writeEndElement();
4453 generateSectionList(notifiers, node);
4457 const auto en =
static_cast<
const EnumNode *>(node);
4459 if (m_qflagsHref.isEmpty()) {
4460 Node *qflags = m_qdb->findClassNode(QStringList(
"QFlags"));
4462 m_qflagsHref = linkForNode(qflags,
nullptr);
4465 if (en->flagsType()) {
4466 m_writer->writeStartElement(dbNamespace,
"para");
4467 m_writer->writeCharacters(
"The ");
4468 m_writer->writeStartElement(dbNamespace,
"code");
4469 m_writer->writeCharacters(en->flagsType()->name());
4470 m_writer->writeEndElement();
4471 m_writer->writeCharacters(
" type is a typedef for ");
4472 m_writer->writeStartElement(dbNamespace,
"code");
4473 generateSimpleLink(m_qflagsHref,
"QFlags");
4474 m_writer->writeCharacters(
"<" + en->name() +
">. ");
4475 m_writer->writeEndElement();
4476 m_writer->writeCharacters(
"It stores an OR combination of ");
4477 m_writer->writeStartElement(dbNamespace,
"code");
4478 m_writer->writeCharacters(en->name());
4479 m_writer->writeEndElement();
4480 m_writer->writeCharacters(
" values.");
4481 m_writer->writeEndElement();
4486 if (closeSupplementarySection)
4497 bool useObsoleteMembers)
4502 if (!members.isEmpty()) {
4503 bool hasPrivateSignals =
false;
4504 bool isInvokable =
false;
4506 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
4508 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4511 NodeVector::ConstIterator m = members.constBegin();
4512 while (m != members.constEnd()) {
4518 m_writer->writeStartElement(dbNamespace,
"listitem");
4520 m_writer->writeStartElement(dbNamespace,
"para");
4523 generateSynopsis(*m, relative, section
.style());
4524 if ((*m)->isFunction()) {
4526 if (fn->isPrivateSignal())
4527 hasPrivateSignals =
true;
4528 else if (fn->isInvokable())
4532 m_writer->writeEndElement();
4534 m_writer->writeEndElement();
4540 m_writer->writeEndElement();
4543 if (hasPrivateSignals)
4550 && !section.inheritedMembers().isEmpty()) {
4551 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
4553 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4556 generateSectionInheritedList(section, relative);
4558 m_writer->writeEndElement();
4566 QList<std::pair<
const Aggregate *,
int>>::ConstIterator p = section.inheritedMembers().constBegin();
4567 while (p != section.inheritedMembers().constEnd()) {
4568 m_writer->writeStartElement(dbNamespace,
"listitem");
4569 m_writer->writeCharacters(QString::number((*p).second) + u' ');
4570 if ((*p).second == 1)
4571 m_writer->writeCharacters(section.singular());
4573 m_writer->writeCharacters(section.plural());
4574 m_writer->writeCharacters(
" inherited from ");
4575 generateSimpleLink(fileName((*p).first) +
'#'
4576 + Generator::cleanRef(section.title().toLower()),
4577 (*p).first->plainFullName(relative));
4583
4584
4585
4589 Q_ASSERT(m_writer ==
nullptr);
4590 m_writer = startDocument(pn);
4592 generateHeader(pn->doc().title(), pn->subtitle(), pn);
4601
4602
4607 Q_ASSERT(m_writer ==
nullptr);
4608 m_writer = startDocument(qcn);
4611 QString title = qcn->name();
4613 title.append(
" QML Value Type");
4615 title.append(
" QML Type");
4618 title.append(
" (Singleton)");
4624 generateHeader(title, qcn->subtitle(), qcn);
4629 m_writer->writeStartElement(dbNamespace,
"note");
4630 m_writer->writeStartElement(dbNamespace,
"para");
4631 m_writer->writeStartElement(dbNamespace,
"emphasis");
4632 m_writer->writeAttribute(
"role",
"bold");
4633 m_writer->writeCharacters(
"Note: ");
4634 m_writer->writeEndElement();
4635 m_writer->writeCharacters(
"This type is a QML singleton. "
4636 "There is only one instance of this type in the QML engine.");
4637 m_writer->writeEndElement();
4638 m_writer->writeEndElement();
4641 startSection(
"details",
"Detailed Description");
4649 for (
const auto §ion : sections.detailsSections()) {
4650 if (!section.isEmpty()) {
4651 startSection(section.title().toLower(), section.title());
4653 for (
const auto &member : section.members())
4654 generateDetailedQmlMember(member, qcn);
4660 generateObsoleteQmlMembers(sections);
4669
4670
4671
4678 if (!title.isEmpty())
4682 title += n->element() + QLatin1Char(
'.');
4683 title += n->name() +
" : " + n->dataType();
4688 auto generateQmlMethodTitle = [&](
Node *node) {
4693 const auto *scn =
static_cast<
const SharedCommentNode *>(node);
4696 if (!scn->name().isEmpty())
4697 heading = scn->name() +
" group";
4699 heading = node->name();
4700 startSection(scn, heading);
4705 const QList<Node *> sharedNodes = scn->collective();
4706 for (
const auto &sharedNode : sharedNodes) {
4707 if (sharedNode->isQmlProperty()) {
4708 auto *qpn =
static_cast<QmlPropertyNode *>(sharedNode);
4710 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4711 m_writer->writeAttribute(
"renderas",
"sect2");
4713 m_writer->writeCharacters(getQmlPropertyTitle(qpn));
4714 m_writer->writeEndElement();
4717 generateDocBookSynopsis(qpn);
4721 auto qpn =
static_cast<QmlPropertyNode *>(node);
4722 startSection(qpn, getQmlPropertyTitle(qpn));
4726 const QList<Node *> &sharedNodes = scn->collective();
4731 for (
const auto &sharedNode : sharedNodes) {
4733 if (!sharedNode->isFunction(Genus::QML) && !sharedNode->isQmlProperty()) {
4739 startSectionBegin(sharedNode);
4741 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4742 m_writer->writeAttribute(
"renderas",
"sect2");
4746 if (sharedNode->isFunction(Genus::QML))
4747 generateQmlMethodTitle(sharedNode);
4748 else if (sharedNode->isQmlProperty())
4749 m_writer->writeCharacters(
4750 getQmlPropertyTitle(
static_cast<QmlPropertyNode *>(sharedNode)));
4756 m_writer->writeEndElement();
4757 generateDocBookSynopsis(sharedNode);
4763 startSectionBegin(refForNode(node));
4766 generateQmlMethodTitle(node);
4767 else if (node->isQmlProperty())
4768 m_writer->writeCharacters(
4769 getQmlPropertyTitle(
static_cast<QmlPropertyNode *>(node)));
4774 startSectionBegin(node);
4778 startSectionBegin(node);
4779 generateQmlMethodTitle(node);
4793
4794
4801 if (!node->url().isNull())
4805 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833 auto cn =
static_cast<CollectionNode *>(node);
4834 if (cn->wasSeen()) {
4835 m_qdb->mergeCollections(cn);
4836 generateCollectionNode(cn);
4837 }
else if (cn->isGenericCollection()) {
4841 generateGenericCollectionPage(cn);
4844 generatePageNode(
static_cast<PageNode *>(node));
4848 generateCppReferencePage(
static_cast<Aggregate *>(node));
4850 generateQmlTypePage(
static_cast<QmlTypeNode *>(node));
4852 generateProxyPage(
static_cast<Aggregate *>(node));
4858 auto *aggregate =
static_cast<Aggregate *>(node);
4859 for (
auto c : aggregate->childNodes()) {
4860 if (node->isPageNode())
4861 generateDocumentation(c);
4872 Q_ASSERT(m_writer ==
nullptr);
4873 m_writer = startDocument(aggregate);
4876 generateHeader(aggregate->plainFullName(),
"", aggregate);
4881 if (!aggregate
->doc().isEmpty()) {
4882 startSection(
"details",
"Detailed Description");
4884 generateBody(aggregate);
4893 for (
const auto §ion : detailsSections) {
4894 if (section.isEmpty())
4897 startSection(section.title().toLower(), section.title());
4899 const QList<Node *> &members = section.members();
4900 for (
const auto &member : members) {
4901 if (!member->isClassNode()) {
4902 generateDetailedMember(member, aggregate);
4904 startSectionBegin();
4905 generateFullName(member, aggregate);
4908 generateBrief(member);
4922
4923
4928 Q_ASSERT(m_writer ==
nullptr);
4929 m_writer = startDocument(cn);
4932 generateHeader(cn->doc().title(), cn->subtitle(), cn);
4938 if (cn
->genus() != Genus::DOC && cn
->genus() != Genus::DontCare) {
4949 if (!nmm.isEmpty()) {
4950 startSection(
"namespaces",
"Namespaces");
4951 generateAnnotatedList(cn, nmm.values(),
"namespaces");
4955 if (!nmm.isEmpty()) {
4956 startSection(
"classes",
"Classes");
4957 generateAnnotatedList(cn, nmm.values(),
"classes");
4963 bool generatedTitle =
false;
4965 startSection(
"details",
"Detailed Description");
4966 generatedTitle =
true;
4971 !cn
->doc().body().isEmpty() ||
4973 !cn
->doc().alsoList().empty() ||
4976 writeAnchor(
"details");
4982 if (!cn->noAutoList() && (cn->isGroup() || cn->isQmlModule()))
4983 generateAnnotatedList(cn, cn->members(),
"members", AutoSection);
4994
4995
4996
4997
5002 QString name = cn->name().toLower();
5003 name.replace(QChar(
' '), QString(
"-"));
5004 QString filename = cn->tree()->physicalModuleName() +
"-" + name +
"." + fileExtension();
5007 Q_ASSERT(m_writer ==
nullptr);
5008 m_writer = startGenericDocument(cn, filename);
5011 generateHeader(cn->fullTitle(), cn->subtitle(), cn);
5017 m_writer->writeStartElement(dbNamespace,
"para");
5018 m_writer->writeCharacters(
"Each function or type documented here is related to a class or "
5019 "namespace that is documented in a different module. The reference "
5020 "page for that class or namespace will link to the function or type "
5022 m_writer->writeEndElement();
5026 for (
const auto &member : members)
5027 generateDetailedMember(member, cnc);
5040 m_writer->writeStartElement(dbNamespace,
"link");
5041 m_writer->writeAttribute(xlinkNamespace,
"href", fullDocumentLocation(node));
5042 m_writer->writeAttribute(xlinkNamespace,
"role", targetType(node));
5043 m_writer->writeCharacters(node->fullName(relative));
5044 m_writer->writeEndElement();
5048 const Node *actualNode)
5050 Q_ASSERT(apparentNode);
5051 Q_ASSERT(actualNode);
5054 m_writer->writeStartElement(dbNamespace,
"link");
5055 m_writer->writeAttribute(xlinkNamespace,
"href", fullDocumentLocation(actualNode));
5056 m_writer->writeAttribute(
"role", targetType(actualNode));
5057 m_writer->writeCharacters(fullName);
5058 m_writer->writeEndElement();
#define ATOM_FORMATTING_TELETYPE
#define ATOM_LIST_LOWERALPHA
#define ATOM_FORMATTING_UNDERLINE
#define ATOM_LIST_UPPERALPHA
#define ATOM_FORMATTING_NOTRANSLATE
#define ATOM_LIST_LOWERROMAN
#define ATOM_FORMATTING_SUBSCRIPT
#define ATOM_FORMATTING_BOLD
#define ATOM_FORMATTING_TRADEMARK
#define ATOM_FORMATTING_ITALIC
#define ATOM_LIST_UPPERROMAN
#define ATOM_FORMATTING_LINK
#define ATOM_FORMATTING_SUPERSCRIPT
#define ATOM_FORMATTING_UICONTROL
#define ATOM_FORMATTING_PARAMETER
The Atom class is the fundamental unit for representing documents internally.
AtomType type() const
Return the type of this atom.
const Atom * next() const
Return the next atom in the atom list.
The ClassNode represents a C++ class.
virtual Atom::AtomType atomType() const
A class for holding the members of a collection of doc pages.
const NodeList & members() const
NodeMap getMembers(NodeType type) const
void generatePageNode(PageNode *pn)
Generate the DocBook page for an entity that doesn't map to any underlying parsable C++ or QML elemen...
void generateQmlTypePage(QmlTypeNode *qcn)
Generate the DocBook page for a QML type.
void generateAlsoList(const Node *node) override
void generateQmlRequisites(const QmlTypeNode *qcn)
Lists the required imports and includes.
void generateAddendum(const Node *node, Generator::Addendum type, CodeMarker *marker, AdmonitionPrefix prefix) override
Generates an addendum note of type type for node.
void initializeGenerator() override
Initializes the DocBook output generator's data structures from the configuration (Config).
bool generateText(const Text &text, const Node *relative) override
Generate the documentation for relative.
void generateCppReferencePage(Node *node)
Generate a reference page for the C++ class, namespace, or header file documented in node.
void generateSortedQmlNames(const Node *base, const QStringList &knownTypes, const NodeList &subs)
DocBookGenerator(FileResolver &file_resolver)
bool generateThreadSafeness(const Node *node)
Generates text that explains how threadsafe and/or reentrant node is.
void generateCollectionNode(CollectionNode *cn)
Generate the HTML page for a group, module, or QML module.
void generateHeader(const Text &title, const QString &subtitle, const Node *node)
void generateDocBookSynopsis(const Node *node)
Generate the metadata for the given node in DocBook.
void generateGenericCollectionPage(CollectionNode *cn)
Generate the HTML page for a generic collection.
void generateList(const Node *relative, const QString &selector, Qt::SortOrder sortOrder=Qt::AscendingOrder)
void generateBody(const Node *node)
Generate the body of the documentation from the qdoc comment found with the entity represented by the...
qsizetype generateAtom(const Atom *atom, const Node *relative, CodeMarker *) override
Generate DocBook from an instance of Atom.
void generateProxyPage(Aggregate *aggregate)
bool generateStatus(const Node *node)
void generateRequisites(const Aggregate *inner)
Lists the required imports and includes.
void generateSortedNames(const ClassNode *cn, const QList< RelatedClass > &rc)
void generateDocumentation(Node *node) override
Recursive writing of DocBook files from the root node.
void generateGroupReferenceText(const Node *node)
Return a string representing a text that exposes information about the groups that the node is part o...
QString format() const override
Returns the format identifier for this producer (e.g., "HTML", "DocBook", "template").
void generateExampleFilePage(const PageNode *en, ResolvedFile resolved_file, CodeMarker *=nullptr) override
Generate a file with the contents of a C++ or QML source file.
QString fileExtension() const override
Returns "xml" for this subclass of Generator.
bool generateSince(const Node *node)
const Location & location() const
Returns the starting location of a qdoc comment.
static void quoteFromFile(const Location &location, Quoter "er, ResolvedFile resolved_file, CodeMarker *marker=nullptr)
const Text & body() const
Text briefText(bool inclusive=false) const
const TypedefNode * flagsType() const
Encapsulate the logic that QDoc uses to find files whose path is provided by the user and that are re...
This node is used to represent any kind of function being documented.
bool isMacroWithoutParams() const
bool isPrivateSignal() const
const Parameters & parameters() const
bool isPureVirtual() const override
bool hasOverloads() const
Returns true if this function has overloads.
bool isMacro() const override
returns true if either FunctionNode::isMacroWithParams() or FunctionNode::isMacroWithoutParams() retu...
bool isDeletedAsWritten() const
bool isExplicitlyDefaulted() const
bool hasAssociatedProperties() const
bool generateComparisonCategory(const Node *node, CodeMarker *marker=nullptr)
static void setQmlTypeContext(QmlTypeNode *t)
const Atom * generateAtomList(const Atom *atom, const Node *relative, CodeMarker *marker, bool generate, int &numGeneratedAtoms)
void unknownAtom(const Atom *atom)
static bool matchAhead(const Atom *atom, Atom::AtomType expectedAtomType)
void generateEnumValuesForQmlReference(const Node *node, CodeMarker *marker)
virtual int skipAtoms(const Atom *atom, Atom::AtomType type) const
bool generateComparisonTable(const Node *node)
Generates a table of comparison categories for node, combining both self-comparison (from \compares) ...
virtual void initializeGenerator()
No-op base implementation.
void initializeTextOutput()
Resets the variables used during text output.
static bool isIncluded(const InclusionPolicy &policy, const NodeContext &context)
This class represents a C++ namespace.
NamespaceNode * docNode() const
Returns a pointer to the NamespaceNode that represents where the namespace documentation is actually ...
Tree * tree() const override
Returns a pointer to the Tree that contains this NamespaceNode.
Interface implemented by Node subclasses that can refer to a C++ enum.
virtual const NativeEnum * nativeEnum() const =0
Encapsulates information about native (C++) enum values.
const EnumNode * enumNode() const
A PageNode is a Node that generates a documentation page.
bool noAutoList() const
Returns the value of the no auto-list flag.
The Parameter class describes one function parameter.
This class describes one instance of using the Q_PROPERTY macro.
This class provides exclusive access to the qdoc database, which consists of a forrest of trees and a...
static QDocDatabase * qdocDB()
Creates the singleton.
Status
Specifies the status of the QQmlIncubator.
bool isDefault() const override
Returns true if the QML property node is marked as default.
bool isReadOnly() const
Returns true if this QML property node is marked as a read-only property.
bool isRequired() const
Const overloads that delegate to the resolving non-const versions when the attribute hasn't been cach...
bool isAttached() const override
Returns true if the QML property or QML method node is marked as attached.
ClassNode * classNode() const override
If this is a QmlTypeNode, this function returns the pointer to the C++ ClassNode that this QML type r...
static void subclasses(const Node *base, NodeList &subs, bool recurse=false)
Loads the list subs with the nodes of all the subclasses of base.
QmlTypeNode * qmlBaseNode() const override
If this Aggregate is a QmlTypeNode, this function returns a pointer to the QmlTypeNode that is its ba...
CollectionNode * logicalModule() const override
If this is a QmlTypeNode, a pointer to its QML module is returned, which is a pointer to a Collection...
A class for containing the elements of one documentation section.
const NodeVector & obsoleteMembers() const
void appendMembers(const NodeVector &nv)
const NodeVector & members() const
A class for creating vectors of collections for documentation.
const Aggregate * aggregate() const
Sections(const Aggregate *aggregate)
This constructor builds the section vectors based on the type of the aggregate node.
bool hasObsoleteMembers(SectionPtrVector *summary_spv, SectionPtrVector *details_spv) const
Returns true if any sections in this object contain obsolete members.
SectionVector & detailsSections()
static Text sectionHeading(const Atom *sectionBegin)
const Atom * firstAtom() const
Text & operator=(const Text &text)
const Atom * lastAtom() const
bool isStatic() const override
Returns true if the FunctionNode represents a static function.
static bool isOneColumnValueTable(const Atom *atom)
Determines whether the list atom should be shown with just one column (value).
static void rewritePropertyBrief(const Atom *atom, const Node *relative)
Rewrites the brief of this node depending on its first word.
static int hOffset(const Node *node)
Header offset depending on the type of the node.
static bool hasBrief(const Node *node)
Do not display.
XmlGenerator(FileResolver &file_resolver)
static const QRegularExpression m_funcLeftParen
static NodeType typeFromString(const Atom *atom)
Returns the type of this atom as an enumeration.
#define CONFIG_DOCBOOKEXTENSIONS
#define CONFIG_PRELIMINARY
#define CONFIG_DESCRIPTION
#define CONFIG_EXAMPLESINSTALLPATH
#define CONFIG_NATURALLANGUAGE
#define CONFIG_PRODUCTNAME
#define CONFIG_BUILDVERSION
static const char xlinkNamespace[]
static QString nodeToSynopsisTag(const Node *node)
QString removeCodeMarkers(const QString &code)
static const char dbNamespace[]
QString taggedNode(const Node *node)
static const char itsNamespace[]
Combined button and popup list for selecting options.
QList< Node * > NodeVector
QMap< QString, Node * > NodeMap
QMap< QString, NodeMap > NodeMapMap
QMap< QString, CollectionNode * > CNMap
QT_BEGIN_NAMESPACE typedef QMultiMap< Text, const Node * > TextToNodeMap
QList< const Section * > SectionPtrVector
QList< Section > SectionVector
The Node class is the base class for all the nodes in QDoc's parse tree.
bool isExternalPage() const
Returns true if the node type is ExternalPage.
const Doc & doc() const
Returns a reference to the node's Doc data member.
bool isQmlNode() const
Returns true if this node's Genus value is QML.
bool isEnumType(Genus g) const
bool isGroup() const
Returns true if the node type is Group.
virtual bool docMustBeGenerated() const
This function is called to perform a test to decide if the node must have documentation generated.
bool isPrivate() const
Returns true if this node's access is Private.
bool isNamespace() const
Returns true if the node type is Namespace.
bool isTypedef() const
Returns true if the node type is Typedef.
bool isQmlBasicType() const
Returns true if the node type is QmlBasicType.
bool isQmlType() const
Returns true if the node type is QmlType or QmlValueType.
bool isSharedCommentNode() const
Returns true if the node type is SharedComment.
bool isHeader() const
Returns true if the node type is HeaderFile.
NodeType nodeType() const override
Returns this node's type.
Genus genus() const override
Returns this node's Genus.
virtual bool isPageNode() const
Returns true if this node represents something that generates a documentation page.
bool isEnumType() const
Returns true if the node type is Enum.
virtual Status status() const
Returns the node's status value.
virtual bool isTextPageNode() const
Returns true if the node is a PageNode but not an Aggregate.
Aggregate * parent() const
Returns the node's parent pointer.
bool isVariable() const
Returns true if the node type is Variable.
virtual bool isDeprecated() const
Returns true if this node's status is Deprecated.
virtual bool isAggregate() const
Returns true if this node is an aggregate, which means it inherits Aggregate and can therefore have c...
static bool nodeNameLessThan(const Node *first, const Node *second)
Returns true if the node n1 is less than node n2.
const Location & location() const
If this node's definition location is empty, this function returns this node's declaration location.
bool isProxyNode() const
Returns true if the node type is Proxy.
Access access() const
Returns the node's Access setting, which can be Public, Protected, or Private.
bool isFunction(Genus g=Genus::DontCare) const
Returns true if this is a FunctionNode and its Genus is set to g.
ThreadSafeness threadSafeness() const
Returns the thread safeness value for whatever this node represents.
virtual bool isMarkedReimp() const
Returns true if the FunctionNode is marked as a reimplemented function.
bool isProperty() const
Returns true if the node type is Property.
NodeContext createContext() const
bool isModule() const
Returns true if the node type is Module.
bool isClass() const
Returns true if the node type is Class.
virtual bool isPropertyGroup() const
Returns true if the node is a SharedCommentNode for documenting multiple C++ properties or multiple Q...
ThreadSafeness
An unsigned char that specifies the degree of thread-safeness of the element.
bool isSharingComment() const
This function returns true if the node is sharing a comment with other nodes.
bool hasDoc() const
Returns true if this node is documented, or it represents a documented node read from the index ('had...
bool isRelatedNonmember() const
Returns true if this is a related nonmember of something.
virtual bool isClassNode() const
Returns true if this is an instance of ClassNode.
virtual bool isCollectionNode() const
Returns true if this is an instance of CollectionNode.
static bool nodeSortKeyOrNameLessThan(const Node *n1, const Node *n2)
Returns true if node n1 is less than node n2 when comparing the sort keys, defined with.
bool isQmlModule() const
Returns true if the node type is QmlModule.
bool isExample() const
Returns true if the node type is Example.
bool isIndexNode() const
Returns true if this node was created from something in an index file.
bool isQmlProperty() const
Returns true if the node type is QmlProperty.
A class for parsing and managing a function parameter list.
const Parameter & at(int i) const
Represents a file that is reachable by QDoc based on its current configuration.