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();
312 case Atom::FootnoteLeft:
313 m_writer->writeStartElement(dbNamespace,
"footnote");
315 m_writer->writeStartElement(dbNamespace,
"para");
318 case Atom::FootnoteRight:
319 m_writer->writeEndElement();
322 m_writer->writeEndElement();
330 m_writer->writeStartElement(dbNamespace,
"emphasis");
331 m_writer->writeAttribute(
"role",
"bold");
333 m_writer->writeStartElement(dbNamespace,
"emphasis");
335 m_writer->writeStartElement(dbNamespace,
"emphasis");
336 m_writer->writeAttribute(
"role",
"underline");
338 m_writer->writeStartElement(dbNamespace,
"subscript");
340 m_writer->writeStartElement(dbNamespace,
"superscript");
343 m_writer->writeStartElement(dbNamespace,
"code");
345 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
348 m_writer->writeAttribute(
"role",
"parameter");
352 m_writer->writeStartElement(dbNamespace,
"guilabel");
354 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
356 m_writer->writeStartElement(dbNamespace,
357 appendTrademark(atom->find(Atom::FormattingRight)) ?
358 "trademark" :
"phrase");
360 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
362 m_writer->writeStartElement(dbNamespace,
"phrase");
364 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
366 relative
->location().warning(QStringLiteral(
"Unsupported formatting: %1").arg(atom->string()));
379 m_writer->writeEndElement();
382 m_inTeletype =
false;
385 relative
->location().warning(QStringLiteral(
"Unsupported formatting: %1").arg(atom->string()));
389 if (
const CollectionNode *cn = m_qdb->getCollectionNode(atom->string(), NodeType::Group))
390 generateList(cn, atom->string(), Generator::sortOrder(atom->strings().last()));
393 const auto sortOrder{Generator::sortOrder(atom->strings().last())};
394 bool hasGeneratedSomething =
false;
395 if (atom->string() == QLatin1String(
"annotatedclasses")
396 || atom->string() == QLatin1String(
"attributions")
397 || atom->string() == QLatin1String(
"namespaces")) {
398 const NodeMultiMap things = atom->string() == QLatin1String(
"annotatedclasses")
399 ? m_qdb->getCppClasses()
400 : atom->string() == QLatin1String(
"attributions") ? m_qdb->getAttributions()
401 : m_qdb->getNamespaces();
402 generateAnnotatedList(relative, things.values(), atom->string(), Auto, sortOrder);
403 hasGeneratedSomething = !things.isEmpty();
404 }
else if (atom->string() == QLatin1String(
"annotatedexamples")
405 || atom->string() == QLatin1String(
"annotatedattributions")) {
406 const NodeMultiMap things = atom->string() == QLatin1String(
"annotatedexamples")
407 ? m_qdb->getAttributions()
408 : m_qdb->getExamples();
409 generateAnnotatedLists(relative, things, atom->string());
410 hasGeneratedSomething = !things.isEmpty();
411 }
else if (atom->string() == QLatin1String(
"classes")
412 || atom->string() == QLatin1String(
"qmlbasictypes")
413 || atom->string() == QLatin1String(
"qmlvaluetypes")
414 || atom->string() == QLatin1String(
"qmltypes")) {
415 const NodeMultiMap things = atom->string() == QLatin1String(
"classes")
416 ? m_qdb->getCppClasses()
417 : (atom->string() == QLatin1String(
"qmlvaluetypes")
418 || atom->string() == QLatin1String(
"qmlbasictypes"))
419 ? m_qdb->getQmlValueTypes()
420 : m_qdb->getQmlTypes();
421 generateCompactList(relative, things,
true, QString(), atom->string());
422 hasGeneratedSomething = !things.isEmpty();
423 }
else if (atom->string().contains(
"classes ")) {
424 QString rootName = atom->string().mid(atom->string().indexOf(
"classes") + 7).trimmed();
427 hasGeneratedSomething = !things.isEmpty();
428 generateCompactList(relative, things,
true, rootName, atom->string());
429 }
else if ((idx = atom->string().indexOf(QStringLiteral(
"bymodule"))) != -1) {
430 QString moduleName = atom->string().mid(idx + 8).trimmed();
433 if (
const CollectionNode *cn = qdb->getCollectionNode(moduleName, moduleType)) {
435 switch (moduleType) {
441 if (atom->string().contains(QLatin1String(
"qmlvaluetypes")))
447 generateAnnotatedList(relative, cn->members(), atom->string(), Auto, sortOrder);
451 if (!map.isEmpty()) {
452 generateAnnotatedList(relative, map.values(), atom->string(), Auto, sortOrder);
453 hasGeneratedSomething =
true;
456 }
else if (atom->string() == QLatin1String(
"classhierarchy")) {
457 generateClassHierarchy(relative, m_qdb->getCppClasses());
458 hasGeneratedSomething = !m_qdb->getCppClasses().isEmpty();
459 }
else if (atom->string().startsWith(
"obsolete")) {
460 QString prefix = atom->string().contains(
"cpp") ? QStringLiteral(
"Q") : QString();
461 const NodeMultiMap &things = atom->string() == QLatin1String(
"obsoleteclasses")
462 ? m_qdb->getObsoleteClasses()
463 : atom->string() == QLatin1String(
"obsoleteqmltypes")
464 ? m_qdb->getObsoleteQmlTypes()
465 : atom->string() == QLatin1String(
"obsoletecppmembers")
466 ? m_qdb->getClassesWithObsoleteMembers()
467 : m_qdb->getQmlTypesWithObsoleteMembers();
468 generateCompactList(relative, things,
false, prefix, atom->string());
469 hasGeneratedSomething = !things.isEmpty();
470 }
else if (atom->string() == QLatin1String(
"functionindex")) {
471 generateFunctionIndex(relative);
472 hasGeneratedSomething = !m_qdb->getFunctionIndex().isEmpty();
473 }
else if (atom->string() == QLatin1String(
"legalese")) {
474 generateLegaleseList(relative);
475 hasGeneratedSomething = !m_qdb->getLegaleseTexts().isEmpty();
476 }
else if (atom->string() == QLatin1String(
"overviews")
477 || atom->string() == QLatin1String(
"cpp-modules")
478 || atom->string() == QLatin1String(
"qml-modules")
479 || atom->string() == QLatin1String(
"related")) {
480 generateList(relative, atom->string());
481 hasGeneratedSomething =
true;
483 }
else if (
const auto *cn = m_qdb->getCollectionNode(atom->string(), NodeType::Group); cn) {
484 generateAnnotatedList(cn, cn->members(), atom->string(), ItemizedList, sortOrder);
485 hasGeneratedSomething =
true;
490 if (!hasGeneratedSomething && !m_inPara) {
491 m_writer->writeEmptyElement(dbNamespace,
"para");
523 m_writer->writeStartElement(dbNamespace,
"figure");
530 generateAtom(current, relative,
nullptr);
535 generateAtom(current, relative,
nullptr);
541 generateAtom(current, relative,
nullptr);
545 m_closeFigureWrapper =
true;
556 m_writer->writeStartElement(dbNamespace,
"figure");
563 generateAtom(current, relative,
nullptr);
568 generateAtom(current, relative,
nullptr);
574 generateAtom(current, relative,
nullptr);
578 m_closeFigureWrapper =
true;
601 m_writer->writeStartElement(dbNamespace, tag);
604 auto maybe_resolved_file{file_resolver.resolve(atom->string())};
605 if (!maybe_resolved_file) {
607 relative
->location().warning(QStringLiteral(
"Missing image: %1").arg(atom->string()));
609 m_writer->writeStartElement(dbNamespace,
"textobject");
611 m_writer->writeStartElement(dbNamespace,
"para");
612 m_writer->writeTextElement(dbNamespace,
"emphasis",
613 "[Missing image " + atom->string() +
"]");
614 m_writer->writeEndElement();
616 m_writer->writeEndElement();
620 QString file_name{QFileInfo{file.get_path()}.fileName()};
624 "%1/%2"_L1.arg(outputDir(), imagesOutputDir()));
628 m_writer->writeTextElement(dbNamespace,
"alt", atom->next()->string());
632 m_writer->writeStartElement(dbNamespace,
"imageobject");
634 m_writer->writeEmptyElement(dbNamespace,
"imagedata");
635 const auto &imgPath =
"%1/%2"_L1.arg(imagesOutputDir(), file_name);
637 m_writer->writeAttribute(
"fileref", imgPath);
639 m_writer->writeEndElement();
643 setImageFileName(relative, imgPath);
646 m_writer->writeEndElement();
650 if (m_closeFigureWrapper) {
651 m_writer->writeEndElement();
653 m_closeFigureWrapper =
false;
661 QString admonType = atom->typeString().toLower();
664 m_writer->writeStartElement(dbNamespace, admonType);
666 m_writer->writeStartElement(dbNamespace,
"para");
669 case Atom::ImportantRight:
670 case Atom::NoteRight:
671 case Atom::WarningRight:
672 m_writer->writeEndElement();
675 m_writer->writeEndElement();
683 const Node *node =
nullptr;
684 QString link = getLink(atom, relative, &node);
685 beginLink(link, node, relative);
689 const Node *node =
static_cast<
const Node*>(Utilities::nodeForString(atom->string()));
690 beginLink(linkForNode(node, relative), node, relative);
700 m_writer->writeEndElement();
706 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
709 m_writer->writeStartElement(dbNamespace,
"variablelist");
712 m_writer->writeStartElement(dbNamespace,
"informaltable");
714 m_writer->writeStartElement(dbNamespace,
"thead");
716 m_writer->writeStartElement(dbNamespace,
"tr");
718 m_writer->writeTextElement(dbNamespace,
"th",
"Constant");
721 m_threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
722 if (m_threeColumnEnumValueTable && relative->isEnumType(Genus::CPP)) {
724 m_writer->writeTextElement(dbNamespace,
"th",
"Value");
729 m_writer->writeTextElement(dbNamespace,
"th",
"Description");
733 m_writer->writeEndElement();
735 m_writer->writeEndElement();
738 m_writer->writeStartElement(dbNamespace,
"orderedlist");
740 if (atom->next() !=
nullptr && atom->next()->string().toInt() != 1)
741 m_writer->writeAttribute(
"startingnumber", atom->next()->string());
744 m_writer->writeAttribute(
"numeration",
"upperalpha");
746 m_writer->writeAttribute(
"numeration",
"loweralpha");
748 m_writer->writeAttribute(
"numeration",
"upperroman");
750 m_writer->writeAttribute(
"numeration",
"lowerroman");
752 m_writer->writeAttribute(
"numeration",
"arabic");
762 m_writer->writeStartElement(dbNamespace,
"varlistentry");
764 m_writer->writeStartElement(dbNamespace,
"item");
766 std::pair<QString,
int> pair = getAtomListValue(atom);
767 skipAhead = pair.second;
769 m_writer->writeStartElement(dbNamespace,
"tr");
771 m_writer->writeStartElement(dbNamespace,
"td");
773 m_writer->writeStartElement(dbNamespace,
"para");
775 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
776 generateEnumValue(pair.first, relative);
777 m_writer->writeEndElement();
779 m_writer->writeEndElement();
783 const auto enume =
static_cast<
const EnumNode *>(relative);
784 QString itemValue = enume->itemValue(atom
->next()->string());
786 m_writer->writeStartElement(dbNamespace,
"td");
787 if (itemValue.isEmpty())
788 m_writer->writeCharacters(
"?");
790 m_writer->writeStartElement(dbNamespace,
"code");
792 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
793 m_writer->writeCharacters(itemValue);
794 m_writer->writeEndElement();
796 m_writer->writeEndElement();
804 m_writer->writeEndElement();
810 m_writer->writeEndElement();
817 m_inListItemLineOpen =
false;
819 m_writer->writeStartElement(dbNamespace,
"listitem");
821 m_writer->writeStartElement(dbNamespace,
"para");
824 if (m_threeColumnEnumValueTable) {
826 m_writer->writeEmptyElement(dbNamespace,
"td");
828 m_inListItemLineOpen =
false;
830 m_writer->writeStartElement(dbNamespace,
"td");
832 m_inListItemLineOpen =
true;
836 m_writer->writeStartElement(dbNamespace,
"listitem");
845 m_writer->writeEndElement();
848 m_writer->writeEndElement();
850 m_writer->writeEndElement();
853 if (m_inListItemLineOpen) {
854 m_writer->writeEndElement();
856 m_inListItemLineOpen =
false;
858 m_writer->writeEndElement();
861 m_writer->writeEndElement();
866 case Atom::ListRight:
872 m_writer->writeEndElement();
879 m_writer->writeStartElement(dbNamespace,
"para");
885 m_writer->writeEndElement();
890 case Atom::QuotationLeft:
891 m_writer->writeStartElement(dbNamespace,
"blockquote");
892 m_inBlockquote =
true;
894 case Atom::QuotationRight:
895 m_writer->writeEndElement();
897 m_inBlockquote =
false;
900 m_writer->device()->write(atom->string().toUtf8());
906 currentSectionLevel = atom->string().toInt() +
hOffset(relative
);
908 if (currentSectionLevel > 1) {
911 while (!sectionLevels.empty() && sectionLevels.top() >= currentSectionLevel) {
913 m_writer->writeEndElement();
917 sectionLevels.push(currentSectionLevel);
919 m_writer->writeStartElement(dbNamespace,
"section");
920 writeXmlId(Tree::refForAtom(atom));
933 generateAtom(atom->next(), relative,
nullptr);
934 generateAtom(atom->next()->next(), relative,
nullptr);
935 generateAtom(atom->next()->next()->next(), relative,
nullptr);
937 m_closeSectionAfterGeneratedList =
true;
944 m_writer->writeTextElement(dbNamespace,
"title",
"");
953 if (currentSectionLevel > 1) {
954 m_writer->writeStartElement(dbNamespace,
"title");
955 m_inSectionHeading =
true;
960 if (currentSectionLevel > 1) {
961 m_writer->writeEndElement();
963 m_inSectionHeading =
false;
966 case Atom::SidebarLeft:
967 m_writer->writeStartElement(dbNamespace,
"sidebar");
969 case Atom::SidebarRight:
970 m_writer->writeEndElement();
974 if (m_inLink && !m_inContents && !m_inSectionHeading)
977 m_writer->writeCharacters(atom->string());
980 std::pair<QString, QString> pair = getTableWidthAttr(atom);
981 QString attr = pair.second;
982 QString width = pair.first;
985 m_writer->writeEndElement();
990 m_tableHeaderAlreadyOutput =
false;
992 m_writer->writeStartElement(dbNamespace,
"informaltable");
993 m_writer->writeAttribute(
"style", attr);
994 if (!width.isEmpty())
995 m_writer->writeAttribute(
"width", width);
998 case Atom::TableRight:
999 m_tableWidthAttr = {
"",
""};
1000 m_writer->writeEndElement();
1009 if (m_tableHeaderAlreadyOutput) {
1012 m_writer->writeEndElement();
1015 const QString &attr = m_tableWidthAttr.second;
1016 const QString &width = m_tableWidthAttr.first;
1018 m_writer->writeStartElement(dbNamespace,
"informaltable");
1019 m_writer->writeAttribute(
"style", attr);
1020 if (!width.isEmpty())
1021 m_writer->writeAttribute(
"width", width);
1024 m_tableHeaderAlreadyOutput =
true;
1030 id = Utilities::asAsciiPrintable(next->string());
1035 m_writer->writeStartElement(dbNamespace,
"thead");
1037 m_writer->writeStartElement(dbNamespace,
"tr");
1040 m_inTableHeader =
true;
1043 m_closeTableCell =
true;
1044 m_writer->writeStartElement(dbNamespace,
"td");
1050 if (m_closeTableCell) {
1051 m_closeTableCell =
false;
1052 m_writer->writeEndElement();
1056 m_writer->writeEndElement();
1060 m_writer->writeStartElement(dbNamespace,
"tr");
1063 m_writer->writeEndElement();
1065 m_inTableHeader =
false;
1075 bool hasTarget {
false};
1077 id = Utilities::asAsciiPrintable(atom
->next()->string());
1082 m_writer->writeStartElement(dbNamespace,
"tr");
1085 if (atom->string().isEmpty()) {
1086 m_writer->writeAttribute(
"valign",
"top");
1091 QStringList args = atom->string().split(
"\"", Qt::SkipEmptyParts);
1094 const int nArgs = args.size();
1099 QStringLiteral(
"Error when parsing attributes for the table: got \"%1\"")
1100 .arg(atom->string()));
1102 for (
int i = 0; i + 1 < nArgs; i += 2) {
1105 const QString &attr = args.at(i).chopped(1);
1108 writeXmlId(args.at(i + 1));
1110 m_writer->writeAttribute(attr, args.at(i + 1));
1126 m_closeTableRow =
true;
1127 m_writer->writeEndElement();
1133 if (m_closeTableRow) {
1134 m_closeTableRow =
false;
1135 m_writer->writeEndElement();
1139 m_writer->writeEndElement();
1142 case Atom::TableItemLeft:
1143 m_writer->writeStartElement(dbNamespace, m_inTableHeader ?
"th" :
"td");
1145 for (
int i = 0; i < atom->count(); ++i) {
1146 const QString &p = atom->string(i);
1147 if (p.contains(
'=')) {
1148 QStringList lp = p.split(QLatin1Char(
'='));
1149 m_writer->writeAttribute(lp.at(0), lp.at(1));
1151 QStringList spans = p.split(QLatin1Char(
','));
1152 if (spans.size() == 2) {
1153 if (spans.at(0) !=
"1")
1154 m_writer->writeAttribute(
"colspan", spans.at(0).trimmed());
1155 if (spans.at(1) !=
"1")
1156 m_writer->writeAttribute(
"rowspan", spans.at(1).trimmed());
1163 case Atom::TableItemRight:
1164 m_writer->writeEndElement();
1176 QString nextId = Utilities::asAsciiPrintable(
1178 QString ownId = Utilities::asAsciiPrintable(atom->string());
1179 if (nextId == ownId)
1183 writeAnchor(Utilities::asAsciiPrintable(atom->string()));
1185 case Atom::UnhandledFormat:
1186 m_writer->writeStartElement(dbNamespace,
"emphasis");
1187 m_writer->writeAttribute(
"role",
"bold");
1188 m_writer->writeCharacters(
"<Missing DocBook>");
1189 m_writer->writeEndElement();
1191 case Atom::UnknownCommand:
1192 m_writer->writeStartElement(dbNamespace,
"emphasis");
1193 m_writer->writeAttribute(
"role",
"bold");
1195 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
1196 m_writer->writeCharacters(
"<Unknown command>");
1197 m_writer->writeStartElement(dbNamespace,
"code");
1198 m_writer->writeCharacters(atom->string());
1199 m_writer->writeEndElement();
1200 m_writer->writeEndElement();
1220 if (classMap.isEmpty())
1223 std::function<
void(
ClassNode *)> generateClassAndChildren
1224 = [
this, &relative, &generateClassAndChildren](ClassNode * classe) {
1225 m_writer->writeStartElement(dbNamespace,
"listitem");
1229 m_writer->writeStartElement(dbNamespace,
"para");
1230 generateFullName(classe, relative);
1231 m_writer->writeEndElement();
1235 bool hasChild =
false;
1236 for (
const RelatedClass &relatedClass : classe->derivedClasses()) {
1237 if (relatedClass.m_node && relatedClass.m_node->isInAPI()) {
1244 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
1247 for (
const RelatedClass &relatedClass: classe->derivedClasses()) {
1248 if (relatedClass.m_node && relatedClass.m_node->isInAPI()) {
1249 generateClassAndChildren(relatedClass.m_node);
1253 m_writer->writeEndElement();
1258 m_writer->writeEndElement();
1262 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
1265 for (
const auto &it : classMap) {
1266 auto *classe =
static_cast<ClassNode *>(it);
1267 if (classe->baseClasses().isEmpty())
1268 generateClassAndChildren(classe);
1271 m_writer->writeEndElement();
1280 if (m_linkNode && m_linkNode->isFunction()) {
1282 if (match.hasMatch()) {
1284 qsizetype leftParenLoc = match.capturedStart(1);
1285 m_writer->writeCharacters(atom->string().left(leftParenLoc));
1287 m_writer->writeCharacters(atom->string().mid(leftParenLoc));
1291 m_writer->writeCharacters(atom->string());
1295
1296
1297
1301 m_writer->writeStartElement(dbNamespace,
"link");
1302 m_writer->writeAttribute(xlinkNamespace,
"href", link);
1303 if (node && !(relative && node->status() == relative->status())
1304 && node->isDeprecated())
1305 m_writer->writeAttribute(
"role",
"deprecated");
1314 m_writer->writeEndElement();
1316 m_linkNode =
nullptr;
1320 Qt::SortOrder sortOrder)
1325 if (selector == QLatin1String(
"overviews"))
1327 else if (selector == QLatin1String(
"cpp-modules"))
1329 else if (selector == QLatin1String(
"qml-modules"))
1334 m_qdb->mergeCollections(type, cnm, relative);
1335 const QList<CollectionNode *> collectionList = cnm.values();
1336 nodeList.reserve(collectionList.size());
1337 for (
auto *collectionNode : collectionList)
1338 nodeList.append(collectionNode);
1339 generateAnnotatedList(relative, nodeList, selector, Auto, sortOrder);
1342
1343
1344
1345 Node *n =
const_cast<
Node *>(relative);
1346 auto *cn =
static_cast<CollectionNode *>(n);
1347 m_qdb->mergeCollections(cn);
1348 generateAnnotatedList(cn, cn->members(), selector, Auto, sortOrder);
1353
1354
1355
1357 const QString &selector, GeneratedListType type,
1358 Qt::SortOrder sortOrder)
1360 if (nodeList.isEmpty())
1364 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
1365 if (
std::all_of(nodeList.cbegin(), nodeList.cend(), [&policy](
const Node *n) {
1367 return !InclusionFilter::isIncluded(policy, context) || n->isDeprecated();
1374 bool noItemsHaveTitle =
1375 type == ItemizedList ||
std::all_of(nodeList.begin(), nodeList.end(),
1376 [](
const Node* node) {
1377 return node->doc().briefText().toString().isEmpty();
1381 if (type == AutoSection && m_hasSection)
1382 startSection(
"",
"Contents");
1385 if (!nodeList.isEmpty()) {
1386 m_writer->writeStartElement(dbNamespace, noItemsHaveTitle ?
"itemizedlist" :
"variablelist");
1387 m_writer->writeAttribute(
"role", selector);
1391 if (sortOrder == Qt::DescendingOrder)
1395 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
1396 for (
const auto &node : std::as_const(members)) {
1397 const NodeContext context = node->createContext();
1398 if (!InclusionFilter::isIncluded(policy, context) || node->isDeprecated())
1401 if (noItemsHaveTitle) {
1402 m_writer->writeStartElement(dbNamespace,
"listitem");
1404 m_writer->writeStartElement(dbNamespace,
"para");
1406 m_writer->writeStartElement(dbNamespace,
"varlistentry");
1408 m_writer->writeStartElement(dbNamespace,
"term");
1410 generateFullName(node, relative);
1411 if (noItemsHaveTitle) {
1412 m_writer->writeEndElement();
1414 m_writer->writeEndElement();
1416 m_writer->writeEndElement();
1418 m_writer->writeStartElement(dbNamespace,
"listitem");
1420 m_writer->writeStartElement(dbNamespace,
"para");
1421 m_writer->writeCharacters(node->doc().briefText().toString());
1422 m_writer->writeEndElement();
1424 m_writer->writeEndElement();
1426 m_writer->writeEndElement();
1431 m_writer->writeEndElement();
1435 if (type == AutoSection && m_hasSection)
1440
1441
1442
1444 const QString &selector)
1447 for (
const QString &name : nmm.uniqueKeys()) {
1448 if (!name.isEmpty())
1449 startSection(name.toLower(), name);
1450 generateAnnotatedList(relative, nmm.values(name), selector);
1451 if (!name.isEmpty())
1457
1458
1459
1460
1461
1462
1463
1464
1465
1467 bool includeAlphabet,
const QString &commonPrefix,
1468 const QString &selector)
1478 const int NumParagraphs = 37;
1479 qsizetype commonPrefixLen = commonPrefix.size();
1482
1483
1484
1485
1486
1488 QString paragraphName[NumParagraphs + 1];
1489 QSet<
char> usedParagraphNames;
1491 for (
auto c = nmm.constBegin(); c != nmm.constEnd(); ++c) {
1492 QStringList pieces = c.key().split(
"::");
1493 int idx = commonPrefixLen;
1494 if (idx > 0 && !pieces.last().startsWith(commonPrefix, Qt::CaseInsensitive))
1496 QString last = pieces.last().toLower();
1497 QString key = last.mid(idx);
1499 int paragraphNr = NumParagraphs - 1;
1501 if (key[0].digitValue() != -1) {
1502 paragraphNr = key[0].digitValue();
1503 }
else if (key[0] >= QLatin1Char(
'a') && key[0] <= QLatin1Char(
'z')) {
1504 paragraphNr = 10 + key[0].unicode() -
'a';
1507 paragraphName[paragraphNr] = key[0].toUpper();
1508 usedParagraphNames.insert(key[0].toLower().cell());
1509 paragraph[paragraphNr].insert(last, c.value());
1513
1514
1515
1516
1517
1518
1519
1520 int paragraphOffset[NumParagraphs + 1];
1521 paragraphOffset[0] = 0;
1522 for (
int i = 0; i < NumParagraphs; i++)
1523 paragraphOffset[i + 1] = paragraphOffset[i] + paragraph[i].size();
1526 if (includeAlphabet && !usedParagraphNames.isEmpty()) {
1527 m_writer->writeStartElement(dbNamespace,
"simplelist");
1530 for (
int i = 0; i < 26; i++) {
1532 if (usedParagraphNames.contains(
char(
'a' + i))) {
1533 m_writer->writeStartElement(dbNamespace,
"member");
1534 generateSimpleLink(ch, ch.toUpper());
1535 m_writer->writeEndElement();
1540 m_writer->writeEndElement();
1545 QHash<QString,
int> nameOccurrences;
1546 for (
const auto &[key, node] : nmm.asKeyValueRange()) {
1547 QStringList pieces{node->fullName(relative).split(
"::"_L1)};
1548 const QString &name{pieces.last()};
1549 nameOccurrences[name]++;
1554 int curParOffset = 0;
1556 m_writer->writeStartElement(dbNamespace,
"variablelist");
1557 m_writer->writeAttribute(
"role", selector);
1560 for (
int i = 0; i < nmm.size(); i++) {
1561 while ((curParNr < NumParagraphs) && (curParOffset == paragraph[curParNr].size())) {
1568 if (curParOffset == 0) {
1570 m_writer->writeEndElement();
1572 m_writer->writeEndElement();
1574 m_writer->writeEndElement();
1578 m_writer->writeStartElement(dbNamespace,
"varlistentry");
1579 if (includeAlphabet)
1580 writeXmlId(paragraphName[curParNr][0].toLower());
1583 m_writer->writeStartElement(dbNamespace,
"term");
1584 m_writer->writeStartElement(dbNamespace,
"emphasis");
1585 m_writer->writeAttribute(
"role",
"bold");
1586 m_writer->writeCharacters(paragraphName[curParNr]);
1587 m_writer->writeEndElement();
1588 m_writer->writeEndElement();
1591 m_writer->writeStartElement(dbNamespace,
"listitem");
1593 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
1598 m_writer->writeStartElement(dbNamespace,
"listitem");
1600 m_writer->writeStartElement(dbNamespace,
"para");
1602 if ((curParNr < NumParagraphs) && !paragraphName[curParNr].isEmpty()) {
1603 NodeMultiMap::Iterator it;
1604 NodeMultiMap::Iterator next;
1605 it = paragraph[curParNr].begin();
1606 for (
int j = 0; j < curParOffset; j++)
1611 QStringList pieces{it.value()->fullName(relative).split(
"::"_L1)};
1612 const auto &name{pieces.last()};
1615 if (nameOccurrences[name] > 1) {
1616 const QString moduleName = it.value()->isQmlNode() ? it.value()->logicalModuleName()
1617 : it.value()->tree()->camelCaseModuleName();
1618 pieces.last().append(
": %1"_L1.arg(moduleName));
1622 m_writer->writeStartElement(dbNamespace,
"link");
1623 m_writer->writeAttribute(xlinkNamespace,
"href", linkForNode(*it, relative));
1624 if (
const QString type = targetType(it.value()); !type.isEmpty())
1625 m_writer->writeAttribute(
"role", type);
1626 m_writer->writeCharacters(pieces.last());
1627 m_writer->writeEndElement();
1630 if (pieces.size() > 1) {
1631 m_writer->writeCharacters(
" (");
1632 generateFullName(it.value()->parent(), relative);
1633 m_writer->writeCharacters(
")");
1637 m_writer->writeEndElement();
1639 m_writer->writeEndElement();
1644 m_writer->writeEndElement();
1646 m_writer->writeEndElement();
1648 m_writer->writeEndElement();
1651 m_writer->writeEndElement();
1660 m_writer->writeStartElement(dbNamespace,
"simplelist");
1661 m_writer->writeAttribute(
"role",
"functionIndex");
1663 for (
int i = 0; i < 26; i++) {
1665 m_writer->writeStartElement(dbNamespace,
"member");
1666 m_writer->writeAttribute(xlinkNamespace,
"href", QString(
"#") + ch);
1667 m_writer->writeCharacters(ch.toUpper());
1668 m_writer->writeEndElement();
1671 m_writer->writeEndElement();
1676 if (m_qdb->getFunctionIndex().isEmpty())
1678 char nextLetter =
'a';
1681 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
1684 NodeMapMap &funcIndex = m_qdb->getFunctionIndex();
1685 QMap<QString, NodeMap>::ConstIterator f = funcIndex.constBegin();
1686 while (f != funcIndex.constEnd()) {
1687 m_writer->writeStartElement(dbNamespace,
"listitem");
1689 m_writer->writeStartElement(dbNamespace,
"para");
1690 m_writer->writeCharacters(f.key() +
": ");
1692 currentLetter = f.key()[0].unicode();
1693 while (islower(currentLetter) && currentLetter >= nextLetter) {
1694 writeAnchor(QString(nextLetter));
1698 NodeMap::ConstIterator s = (*f).constBegin();
1699 while (s != (*f).constEnd()) {
1700 m_writer->writeCharacters(
" ");
1701 generateFullName((*s)->parent(), relative);
1705 m_writer->writeEndElement();
1707 m_writer->writeEndElement();
1711 m_writer->writeEndElement();
1719 for (
auto it = legaleseTexts.cbegin(), end = legaleseTexts.cend(); it != end; ++it) {
1720 Text text = it.key();
1722 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
1725 m_writer->writeStartElement(dbNamespace,
"listitem");
1727 m_writer->writeStartElement(dbNamespace,
"para");
1728 generateFullName(it.value(), relative);
1729 m_writer->writeEndElement();
1731 m_writer->writeEndElement();
1734 }
while (it != legaleseTexts.constEnd() && it.key() == text);
1735 m_writer->writeEndElement();
1750 m_writer->writeStartElement(dbNamespace,
"para");
1752 m_writer->writeEndElement();
1760 if (!node->since().isEmpty()) {
1761 m_writer->writeStartElement(dbNamespace,
"para");
1763 const auto &collective =
static_cast<
const SharedCommentNode *>(node)->collective();
1764 QString typeStr = collective.size() > 1 ? typeString(collective.first()) +
"s" : typeString(node);
1765 m_writer->writeCharacters(
"These " + typeStr +
" were introduced in ");
1767 m_writer->writeCharacters(
"This " + typeString(node) +
" was introduced in ");
1769 m_writer->writeCharacters(formatSince(node) +
".");
1770 m_writer->writeEndElement();
1780
1781
1782
1789 m_writer->writeStartElement(dbNamespace,
"info");
1791 m_writer->writeStartElement(dbNamespace,
"title");
1792 if (isApiGenus(node->genus()) && m_useITS)
1793 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
1795 m_writer->writeEndElement();
1798 if (!subTitle.isEmpty()) {
1799 m_writer->writeStartElement(dbNamespace,
"subtitle");
1800 if (isApiGenus(node->genus()) && m_useITS)
1801 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
1802 m_writer->writeCharacters(subTitle);
1803 m_writer->writeEndElement();
1807 if (!m_productName.isEmpty() || !m_project.isEmpty()) {
1808 m_writer->writeTextElement(dbNamespace,
"productname", m_productName.isEmpty() ?
1809 m_project : m_productName);
1813 if (!m_buildVersion.isEmpty()) {
1814 m_writer->writeTextElement(dbNamespace,
"edition", m_buildVersion);
1818 if (!m_projectDescription.isEmpty()) {
1819 m_writer->writeTextElement(dbNamespace,
"titleabbrev", m_projectDescription);
1827 if (node && !node->links().empty()) {
1828 std::pair<QString, QString> linkPair;
1829 std::pair<QString, QString> anchorPair;
1830 const Node *linkNode;
1832 if (node->links().contains(Node::PreviousLink)) {
1833 linkPair = node->links()[Node::PreviousLink];
1834 linkNode = m_qdb->findNodeForTarget(linkPair.first, node);
1835 if (!linkNode || linkNode == node)
1836 anchorPair = linkPair;
1838 anchorPair = anchorForNode(linkNode);
1840 m_writer->writeStartElement(dbNamespace,
"extendedlink");
1841 m_writer->writeAttribute(xlinkNamespace,
"type",
"extended");
1842 m_writer->writeEmptyElement(dbNamespace,
"link");
1843 m_writer->writeAttribute(xlinkNamespace,
"to", anchorPair.first);
1844 m_writer->writeAttribute(xlinkNamespace,
"type",
"arc");
1845 m_writer->writeAttribute(xlinkNamespace,
"arcrole",
"prev");
1846 if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
1847 m_writer->writeAttribute(xlinkNamespace,
"title", anchorPair.second);
1849 m_writer->writeAttribute(xlinkNamespace,
"title", linkPair.second);
1850 m_writer->writeEndElement();
1853 if (node->links().contains(Node::NextLink)) {
1854 linkPair = node->links()[Node::NextLink];
1855 linkNode = m_qdb->findNodeForTarget(linkPair.first, node);
1856 if (!linkNode || linkNode == node)
1857 anchorPair = linkPair;
1859 anchorPair = anchorForNode(linkNode);
1861 m_writer->writeStartElement(dbNamespace,
"extendedlink");
1862 m_writer->writeAttribute(xlinkNamespace,
"type",
"extended");
1863 m_writer->writeEmptyElement(dbNamespace,
"link");
1864 m_writer->writeAttribute(xlinkNamespace,
"to", anchorPair.first);
1865 m_writer->writeAttribute(xlinkNamespace,
"type",
"arc");
1866 m_writer->writeAttribute(xlinkNamespace,
"arcrole",
"next");
1867 if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
1868 m_writer->writeAttribute(xlinkNamespace,
"title", anchorPair.second);
1870 m_writer->writeAttribute(xlinkNamespace,
"title", linkPair.second);
1871 m_writer->writeEndElement();
1874 if (node->links().contains(Node::StartLink)) {
1875 linkPair = node->links()[Node::StartLink];
1876 linkNode = m_qdb->findNodeForTarget(linkPair.first, node);
1877 if (!linkNode || linkNode == node)
1878 anchorPair = linkPair;
1880 anchorPair = anchorForNode(linkNode);
1882 m_writer->writeStartElement(dbNamespace,
"extendedlink");
1883 m_writer->writeAttribute(xlinkNamespace,
"type",
"extended");
1884 m_writer->writeEmptyElement(dbNamespace,
"link");
1885 m_writer->writeAttribute(xlinkNamespace,
"to", anchorPair.first);
1886 m_writer->writeAttribute(xlinkNamespace,
"type",
"arc");
1887 m_writer->writeAttribute(xlinkNamespace,
"arcrole",
"start");
1888 if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
1889 m_writer->writeAttribute(xlinkNamespace,
"title", anchorPair.second);
1891 m_writer->writeAttribute(xlinkNamespace,
"title", linkPair.second);
1892 m_writer->writeEndElement();
1904 m_writer->writeStartElement(dbNamespace,
"abstract");
1907 bool generatedSomething =
false;
1911 node->isNamespace() ?
static_cast<
const NamespaceNode *>(node) :
nullptr;
1914 brief <<
"The " << ns->name()
1915 <<
" namespace includes the following elements from module "
1916 << ns
->tree()->camelCaseModuleName() <<
". The full namespace is "
1917 <<
"documented in module " << NS
->tree()->camelCaseModuleName();
1918 addNodeLink(brief, fullDocumentLocation(NS),
" here.");
1927 m_writer->writeStartElement(dbNamespace,
"para");
1929 m_writer->writeEndElement();
1932 generatedSomething =
true;
1942 if (!generatedSomething)
1943 m_writer->writeTextElement(dbNamespace,
"para", m_projectDescription +
".");
1945 m_writer->writeEndElement();
1950 m_writer->writeEndElement();
1956 while (!sectionLevels.isEmpty()) {
1957 sectionLevels.pop();
1964 if (m_closeSectionAfterGeneratedList) {
1965 m_closeSectionAfterGeneratedList =
false;
1968 if (m_closeSectionAfterRawTitle) {
1969 m_closeSectionAfterRawTitle =
false;
1974 m_writer->writeEndElement();
1977void DocBookGenerator::generateSimpleLink(
const QString &href,
const QString &text)
1979 m_writer->writeStartElement(dbNamespace,
"link");
1980 m_writer->writeAttribute(xlinkNamespace,
"href", href);
1981 m_writer->writeCharacters(text);
1982 m_writer->writeEndElement();
1986
1987
1988
1991 static const QHash<QString, QString> extrefUrls = {
1992 {u"cpp-explicitly-defaulted"_s,
1993 u"https://en.cppreference.com/w/cpp/language/function#Defaulted_functions"_s},
1994 {u"cpp-deleted-functions"_s,
1995 u"https://en.cppreference.com/w/cpp/language/function#Deleted_functions"_s},
1998 static const QRegularExpression extrefRegex(
1999 u"<@extref target=\"([^\"]+)\">([^<]*)</@extref>"_s);
2002 auto it = extrefRegex.globalMatch(extra);
2003 while (it.hasNext()) {
2004 auto match = it.next();
2005 if (match.capturedStart() > pos)
2006 m_writer->writeCharacters(extra.mid(pos, match.capturedStart() - pos));
2008 QString target = match.captured(1);
2009 QString text = match.captured(2);
2010 QString url = extrefUrls.value(target);
2012 generateSimpleLink(url, text);
2014 m_writer->writeCharacters(text);
2016 pos = match.capturedEnd();
2018 if (pos < extra.size())
2019 m_writer->writeCharacters(extra.mid(pos));
2031 startSection(
"obsolete",
"Obsolete Members for " + aggregate->plainFullName());
2033 m_writer->writeStartElement(dbNamespace,
"para");
2034 m_writer->writeStartElement(dbNamespace,
"emphasis");
2035 m_writer->writeAttribute(
"role",
"bold");
2036 m_writer->writeCharacters(
"The following members of class ");
2037 generateSimpleLink(linkForNode(aggregate,
nullptr), aggregate->name());
2038 m_writer->writeCharacters(
" are deprecated.");
2039 m_writer->writeEndElement();
2040 m_writer->writeCharacters(
" We strongly advise against using them in new code.");
2041 m_writer->writeEndElement();
2044 for (
const Section *section : details_spv) {
2045 const QString &title =
"Obsolete " + section->title();
2046 startSection(title.toLower(), title);
2048 const NodeVector &members = section->obsoleteMembers();
2049 NodeVector::ConstIterator m = members.constBegin();
2050 while (m != members.constEnd()) {
2051 if ((*m)->access() != Access::Private)
2052 generateDetailedMember(*m, aggregate);
2063
2064
2065
2066
2067
2068
2069
2079 startSection(
"obsolete",
"Obsolete Members for " + aggregate->name());
2081 m_writer->writeStartElement(dbNamespace,
"para");
2082 m_writer->writeStartElement(dbNamespace,
"emphasis");
2083 m_writer->writeAttribute(
"role",
"bold");
2084 m_writer->writeCharacters(
"The following members of QML type ");
2085 generateSimpleLink(linkForNode(aggregate,
nullptr), aggregate->name());
2086 m_writer->writeCharacters(
" are deprecated.");
2087 m_writer->writeEndElement();
2088 m_writer->writeCharacters(
" We strongly advise against using them in new code.");
2089 m_writer->writeEndElement();
2092 for (
const auto *section : details_spv) {
2093 const QString &title =
"Obsolete " + section->title();
2094 startSection(title.toLower(), title);
2096 const NodeVector &members = section->obsoleteMembers();
2097 NodeVector::ConstIterator m = members.constBegin();
2098 while (m != members.constEnd()) {
2099 if ((*m)->access() != Access::Private)
2100 generateDetailedQmlMember(*m, aggregate);
2114 return QStringLiteral(
"classsynopsis");
2116 return QStringLiteral(
"packagesynopsis");
2122 return QStringLiteral(
"enumsynopsis");
2124 return QStringLiteral(
"typedefsynopsis");
2127 const auto fn =
static_cast<
const FunctionNode *>(node);
2128 if (fn->isCtor() || fn->isCCtor() || fn->isMCtor())
2129 return QStringLiteral(
"constructorsynopsis");
2131 return QStringLiteral(
"destructorsynopsis");
2132 return QStringLiteral(
"methodsynopsis");
2135 return QStringLiteral(
"fieldsynopsis");
2137 node
->doc().location().warning(QString(
"Unknown node tag %1").arg(node->nodeTypeString()));
2138 return QStringLiteral(
"synopsis");
2143 m_writer->writeStartElement(dbNamespace,
"varlistentry");
2145 m_writer->writeTextElement(dbNamespace,
"term", description);
2147 m_writer->writeStartElement(dbNamespace,
"listitem");
2149 m_writer->writeStartElement(dbNamespace,
"para");
2155 m_writer->writeEndElement();
2158 m_writer->writeEndElement();
2160 m_writer->writeEndElement();
2164void DocBookGenerator::generateRequisite(
const QString &description,
const QString &value)
2166 generateStartRequisite(description);
2167 m_writer->writeCharacters(value);
2168 generateEndRequisite();
2172
2173
2174
2175void DocBookGenerator::generateCMakeRequisite(
const QString &findPackage,
const QString &linkLibraries)
2177 const QString description(
"CMake");
2178 generateStartRequisite(description);
2179 m_writer->writeCharacters(findPackage);
2180 m_writer->writeEndElement();
2183 m_writer->writeStartElement(dbNamespace,
"para");
2184 m_writer->writeCharacters(linkLibraries);
2185 generateEndRequisite();
2191 QMap<QString, ClassNode *> classMap;
2192 QList<RelatedClass>::ConstIterator r = rc.constBegin();
2193 while (r != rc.constEnd()) {
2196 && !rcn
->doc().isEmpty()) {
2197 classMap[rcn->plainFullName(cn).toLower()] = rcn;
2202 QStringList classNames = classMap.keys();
2206 for (
const QString &className : classNames) {
2207 generateFullName(classMap.value(className), cn);
2208 m_writer->writeCharacters(Utilities::comma(index++, classNames.size()));
2216 QMap<QString, Node *> classMap;
2217 QStringList typeNames(knownTypes);
2218 for (
const auto sub : subs)
2219 typeNames << sub->name();
2221 for (
auto sub : subs) {
2222 QString key{sub->plainFullName(base).toLower()};
2224 if (typeNames.count(sub->name()) > 1)
2225 key.append(
": (%1)"_L1.arg(sub->logicalModuleName()));
2226 classMap[key] = sub;
2229 QStringList names = classMap.keys();
2233 for (
const QString &name : names) {
2234 generateFullName(classMap.value(name), base);
2235 if (name.contains(
':'))
2236 m_writer->writeCharacters(name.section(
':', 1));
2237 m_writer->writeCharacters(Utilities::comma(index++, names.size()));
2242
2243
2252 QXmlStreamWriter* oldWriter = m_writer;
2254 m_writer =
new QXmlStreamWriter(&output);
2257 if (aggregate->includeFile()) generateRequisite(
"Header", *aggregate->includeFile());
2260 if (!aggregate->since().isEmpty())
2261 generateRequisite(
"Since", formatSince(aggregate));
2266 m_qdb->getCollectionNode(aggregate->physicalModuleName(), NodeType::Module);
2268 if (
const auto result = cmakeRequisite(cn)) {
2269 generateCMakeRequisite(result->first, result->second);
2272 if (cn && !cn->qtVariable().isEmpty())
2273 generateRequisite(
"qmake",
"QT += " + cn->qtVariable());
2278 auto *classe =
const_cast<ClassNode *>(
static_cast<
const ClassNode *>(aggregate));
2279 if (classe && classe->isQmlNativeType() && classe->status() !=
Status::Internal) {
2280 generateStartRequisite(
"In QML");
2283 QList<QmlTypeNode *> nativeTypes { classe->qmlNativeTypes().cbegin(), classe->qmlNativeTypes().cend()};
2286 for (
const auto &item : std::as_const(nativeTypes)) {
2287 generateFullName(item, classe);
2288 m_writer->writeCharacters(
2289 Utilities::comma(idx++, nativeTypes.size()));
2291 generateEndRequisite();
2295 QList<RelatedClass>::ConstIterator r;
2296 if (classe && !classe->baseClasses().isEmpty()) {
2297 generateStartRequisite(
"Inherits");
2299 r = classe->baseClasses().constBegin();
2301 while (r != classe->baseClasses().constEnd()) {
2303 generateFullName((*r).m_node, classe);
2305 if ((*r).m_access == Access::Protected)
2306 m_writer->writeCharacters(
" (protected)");
2307 else if ((*r).m_access == Access::Private)
2308 m_writer->writeCharacters(
" (private)");
2309 m_writer->writeCharacters(
2310 Utilities::comma(index++, classe->baseClasses().size()));
2315 generateEndRequisite();
2319 if (!classe->derivedClasses().isEmpty()) {
2320 generateStartRequisite(
"Inherited By");
2321 generateSortedNames(classe, classe->derivedClasses());
2322 generateEndRequisite();
2327 if (!aggregate->groupNames().empty()) {
2328 generateStartRequisite(
"Group");
2330 generateEndRequisite();
2334 if (
auto status = formatStatus(aggregate, m_qdb); status)
2335 generateRequisite(
"Status", status.value());
2339 m_writer = oldWriter;
2341 if (!output.isEmpty()) {
2344 static const QRegularExpression xmlTag(R"(<(/?)n\d+:)");
2345 static const QRegularExpression xmlnsDocBookDefinition(R"( xmlns:n\d+=")" + QString{dbNamespace} +
"\"");
2346 static const QRegularExpression xmlnsXLinkDefinition(R"( xmlns:n\d+=")" + QString{xlinkNamespace} +
"\"");
2347 static const QRegularExpression xmlAttr(R"( n\d+:)");
2349 const QString cleanOutput = output.replace(xmlTag, R"(<\1db:)")
2350 .replace(xmlnsDocBookDefinition,
"")
2351 .replace(xmlnsXLinkDefinition,
"")
2352 .replace(xmlAttr,
" xlink:");
2354 m_writer->writeStartElement(dbNamespace,
"variablelist");
2356 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
2359 m_writer->device()->write(cleanOutput.toUtf8());
2361 m_writer->writeEndElement();
2367
2368
2376 const QString importText =
"Import Statement";
2377 const QString sinceText =
"Since";
2378 const QString inheritedByText =
"Inherited By";
2379 const QString inheritsText =
"Inherits";
2380 const QString nativeTypeText =
"In C++";
2381 const QString groupText =
"Group";
2382 const QString statusText =
"Status";
2390 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
2399 bool generate_import_statement = !qcn->logicalModuleName().isEmpty();
2400 if (generate_import_statement && collection) {
2405 const bool generates_something = generate_import_statement || !qcn->since().isEmpty() || !subs.isEmpty() || base;
2407 if (!generates_something)
2410 QStringList knownTypeNames{qcn->name()};
2412 knownTypeNames << base->name();
2415 m_writer->writeStartElement(dbNamespace,
"variablelist");
2417 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
2420 if (generate_import_statement) {
2421 QStringList parts = QStringList() <<
"import" << qcn->logicalModuleName() << qcn->logicalModuleVersion();
2422 generateRequisite(importText, parts.join(
' ').trimmed());
2426 if (!qcn->since().isEmpty())
2427 generateRequisite(sinceText, formatSince(qcn));
2432 generateStartRequisite(nativeTypeText);
2433 generateSimpleLink(fullDocumentLocation(cn), cn->name());
2434 generateEndRequisite();
2439 generateStartRequisite(inheritsText);
2440 generateSimpleLink(fullDocumentLocation(base), base->name());
2442 for (
const auto sub : std::as_const(subs)) {
2443 if (knownTypeNames.contains(sub->name())) {
2444 m_writer->writeCharacters(
" (%1)"_L1.arg(base->logicalModuleName()));
2448 generateEndRequisite();
2452 if (!subs.isEmpty()) {
2453 generateStartRequisite(inheritedByText);
2454 generateSortedQmlNames(qcn, knownTypeNames, subs);
2455 generateEndRequisite();
2459 if (!qcn->groupNames().empty()) {
2460 generateStartRequisite(groupText);
2462 generateEndRequisite();
2466 if (
auto status = formatStatus(qcn, m_qdb); status)
2467 generateRequisite(statusText, status.value());
2469 m_writer->writeEndElement();
2480 const QString &state =
static_cast<
const CollectionNode*>(node)->state();
2481 if (!state.isEmpty()) {
2482 m_writer->writeStartElement(dbNamespace,
"para");
2483 m_writer->writeCharacters(
"This " + typeString(node) +
" is in ");
2484 m_writer->writeStartElement(dbNamespace,
"emphasis");
2485 m_writer->writeCharacters(state);
2486 m_writer->writeEndElement();
2487 m_writer->writeCharacters(
" state.");
2488 m_writer->writeEndElement();
2493 if (
const auto &version = node->deprecatedSince(); !version.isEmpty()) {
2494 m_writer->writeStartElement(dbNamespace,
"para");
2495 m_writer->writeCharacters(
"This " + typeString(node)
2496 +
" is scheduled for deprecation in version "
2498 m_writer->writeEndElement();
2503 case Status::Preliminary:
2504 m_writer->writeStartElement(dbNamespace,
"para");
2505 m_writer->writeStartElement(dbNamespace,
"emphasis");
2506 m_writer->writeAttribute(
"role",
"bold");
2507 m_writer->writeCharacters(
2511 .replace(
'\1'_L1, typeString(node)));
2512 m_writer->writeEndElement();
2513 m_writer->writeEndElement();
2516 case Status::Deprecated:
2517 m_writer->writeStartElement(dbNamespace,
"para");
2519 m_writer->writeStartElement(dbNamespace,
"emphasis");
2520 m_writer->writeAttribute(
"role",
"bold");
2522 m_writer->writeCharacters(
"This " + typeString(node) +
" is deprecated");
2523 if (
const QString &version = node->deprecatedSince(); !version.isEmpty()) {
2524 m_writer->writeCharacters(
" since ");
2525 if (node->isQmlNode() && !node->logicalModuleName().isEmpty())
2526 m_writer->writeCharacters(node->logicalModuleName() +
" ");
2527 m_writer->writeCharacters(version);
2529 m_writer->writeCharacters(
". We strongly advise against using it in new code.");
2530 if (node->isAggregate())
2531 m_writer->writeEndElement();
2532 m_writer->writeEndElement();
2542
2543
2544
2548 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
2551 NodeList::ConstIterator n = nodes.constBegin();
2552 while (n != nodes.constEnd()) {
2553 m_writer->writeStartElement(dbNamespace,
"listitem");
2555 m_writer->writeStartElement(dbNamespace,
"para");
2557 generateSimpleLink(currentGenerator()->fullDocumentLocation(*n),
2558 (*n)->signature(Node::SignaturePlain));
2560 m_writer->writeEndElement();
2562 m_writer->writeEndElement();
2567 m_writer->writeEndElement();
2572
2573
2574
2581 const auto aggregate =
static_cast<
const Aggregate *>(node);
2583 const QStringList &groups_names{aggregate->groupNames()};
2584 if (!groups_names.empty()) {
2585 m_writer->writeCharacters(aggregate->name() +
" is part of ");
2586 m_writer->writeStartElement(dbNamespace,
"simplelist");
2588 for (qsizetype index{0}; index < groups_names.size(); ++index) {
2590 m_qdb->mergeCollections(group);
2592 m_writer->writeStartElement(dbNamespace,
"member");
2593 if (QString target{linkForNode(group,
nullptr)}; !target.isEmpty())
2594 generateSimpleLink(target, group->fullTitle());
2596 m_writer->writeCharacters(group->name());
2597 m_writer->writeEndElement();
2600 m_writer->writeEndElement();
2606
2607
2608
2614 const Node *reentrantNode;
2616 QString linkReentrant = getAutoLink(&reentrantAtom, node, &reentrantNode);
2617 const Node *threadSafeNode;
2619 QString linkThreadSafe = getAutoLink(&threadSafeAtom, node, &threadSafeNode);
2622 m_writer->writeStartElement(dbNamespace,
"warning");
2624 m_writer->writeStartElement(dbNamespace,
"para");
2625 m_writer->writeCharacters(
"This " + typeString(node) +
" is not ");
2626 generateSimpleLink(linkReentrant,
"reentrant");
2627 m_writer->writeCharacters(
".");
2628 m_writer->writeEndElement();
2630 m_writer->writeEndElement();
2634 m_writer->writeStartElement(dbNamespace,
"note");
2636 m_writer->writeStartElement(dbNamespace,
"para");
2639 m_writer->writeCharacters(
"All functions in this " + typeString(node) +
" are ");
2640 if (ts == Node::ThreadSafe)
2641 generateSimpleLink(linkThreadSafe,
"thread-safe");
2643 generateSimpleLink(linkReentrant,
"reentrant");
2648 bool exceptions = hasExceptions(node, reentrant, threadsafe, nonreentrant);
2649 if (!exceptions || (ts ==
Node::Reentrant && !threadsafe.isEmpty())) {
2650 m_writer->writeCharacters(
".");
2651 m_writer->writeEndElement();
2654 m_writer->writeCharacters(
" with the following exceptions:");
2655 m_writer->writeEndElement();
2657 m_writer->writeStartElement(dbNamespace,
"para");
2660 if (!nonreentrant.isEmpty()) {
2661 m_writer->writeCharacters(
"These functions are not ");
2662 generateSimpleLink(linkReentrant,
"reentrant");
2663 m_writer->writeCharacters(
":");
2664 m_writer->writeEndElement();
2666 generateSignatureList(nonreentrant);
2668 if (!threadsafe.isEmpty()) {
2669 m_writer->writeCharacters(
"These functions are also ");
2670 generateSimpleLink(linkThreadSafe,
"thread-safe");
2671 m_writer->writeCharacters(
":");
2672 m_writer->writeEndElement();
2674 generateSignatureList(threadsafe);
2677 if (!reentrant.isEmpty()) {
2678 m_writer->writeCharacters(
"These functions are only ");
2679 generateSimpleLink(linkReentrant,
"reentrant");
2680 m_writer->writeCharacters(
":");
2681 m_writer->writeEndElement();
2683 generateSignatureList(reentrant);
2685 if (!nonreentrant.isEmpty()) {
2686 m_writer->writeCharacters(
"These functions are not ");
2687 generateSimpleLink(linkReentrant,
"reentrant");
2688 m_writer->writeCharacters(
":");
2689 m_writer->writeEndElement();
2691 generateSignatureList(nonreentrant);
2696 m_writer->writeCharacters(
"This " + typeString(node) +
" is ");
2697 if (ts == Node::ThreadSafe)
2698 generateSimpleLink(linkThreadSafe,
"thread-safe");
2700 generateSimpleLink(linkReentrant,
"reentrant");
2701 m_writer->writeCharacters(
".");
2702 m_writer->writeEndElement();
2705 m_writer->writeEndElement();
2715
2716
2717
2721 const FunctionNode *fn = node->isFunction() ?
static_cast<
const FunctionNode *>(node) :
nullptr;
2725
2726
2727
2731 t =
"Destroys the instance of " + fn
->parent()->name() +
".";
2733 t +=
" The destructor is virtual.";
2735 t =
"Default constructs an instance of " + fn
->parent()->name() +
".";
2737 t =
"Copy constructor.";
2739 t =
"Move-copy constructor.";
2741 t =
"Copy-assignment constructor.";
2743 t =
"Move-assignment constructor.";
2747 m_writer->writeTextElement(dbNamespace,
"para", t);
2751 if (fn && !fn->overridesThis().isEmpty())
2752 generateReimplementsClause(fn);
2754 if (
static_cast<
const PropertyNode *>(node)->propertyType() != PropertyNode::PropertyType::StandardProperty)
2783 generateRequiredLinks(node);
2787
2788
2789
2790
2791
2798 const auto en =
static_cast<
const ExampleNode *>(node);
2801 if (exampleUrl.isEmpty()) {
2802 if (!en->noAutoList()) {
2803 generateFileList(en,
false);
2804 generateFileList(en,
true);
2807 generateLinkToExample(en, exampleUrl);
2812
2813
2814
2815
2816
2820 QString exampleUrl(baseUrl);
2822#ifndef QT_BOOTSTRAPPED
2823 link = QUrl(exampleUrl).host();
2825 if (!link.isEmpty())
2826 link.prepend(
" @ ");
2827 link.prepend(
"Example project");
2829 const QLatin1Char separator(
'/');
2830 const QLatin1Char placeholder(
'\1');
2831 if (!exampleUrl.contains(placeholder)) {
2832 if (!exampleUrl.endsWith(separator))
2833 exampleUrl += separator;
2834 exampleUrl += placeholder;
2838 QStringList path = QStringList()
2840 path.removeAll(QString());
2844 startSection(
"Example project");
2846 m_writer->writeStartElement(dbNamespace,
"para");
2847 generateSimpleLink(exampleUrl.replace(placeholder, path.join(separator)), link);
2848 m_writer->writeEndElement();
2857
2858
2859
2860
2861
2862
2878 paths = en->images();
2881 paths = en->files();
2884 std::sort(paths.begin(), paths.end(), Generator::comparePaths);
2886 if (paths.isEmpty())
2889 startSection(
"",
"List of Files");
2891 m_writer->writeStartElement(dbNamespace,
"para");
2892 m_writer->writeCharacters(tag);
2893 m_writer->writeEndElement();
2896 startSection(
"List of Files");
2898 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
2901 for (
const auto &path : std::as_const(paths)) {
2902 auto maybe_resolved_file{file_resolver.resolve(path)};
2903 if (!maybe_resolved_file) {
2905 QString details = std::transform_reduce(
2906 file_resolver.get_search_directories().cbegin(),
2907 file_resolver.get_search_directories().cend(),
2908 u"Searched directories:"_s,
2910 [](
const DirectoryPath &directory_path) -> QString {
return u' ' + directory_path.value(); }
2913 en->location().warning(u"Cannot find file to quote from: %1"_s.arg(path), details);
2918 const auto &file{*maybe_resolved_file};
2919 if (images) addImageToCopy(en, file);
2920 else generateExampleFilePage(en, file);
2922 m_writer->writeStartElement(dbNamespace,
"listitem");
2924 m_writer->writeStartElement(dbNamespace,
"para");
2925 generateSimpleLink(file.get_query(), file.get_query());
2926 m_writer->writeEndElement();
2927 m_writer->writeEndElement();
2931 m_writer->writeEndElement();
2938
2939
2949 const auto en =
static_cast<
const ExampleNode *>(node);
2952 QXmlStreamWriter *currentWriter = m_writer;
2953 m_writer = startDocument(en, resolved_file.get_query());
2954 generateHeader(en->doc().title(), en->subtitle(), en);
2959 QString code = quoter.quoteTo(en->location(), QString(), QString());
2960 CodeMarker *codeMarker = CodeMarker::markerForFileName(resolved_file.get_path());
2966 m_writer = currentWriter;
2972 if (fn->overridesThis().isEmpty() || !fn
->parent()->isClassNode())
2977 if (
const FunctionNode *overrides = cn->findOverriddenFunction(fn);
2980 m_writer->writeStartElement(dbNamespace,
"para");
2981 m_writer->writeCharacters(
"Reimplements: ");
2984 generateFullName(overrides
->parent(), fullName, overrides);
2985 m_writer->writeCharacters(
".");
2986 m_writer->writeEndElement();
2992 if (
const PropertyNode *sameName = cn->findOverriddenProperty(fn); sameName && sameName
->hasDoc()) {
2993 m_writer->writeStartElement(dbNamespace,
"para");
2994 m_writer->writeCharacters(
"Reimplements an access function for property: ");
2995 QString fullName = sameName
->parent()->name() +
"::" + sameName->name();
2996 generateFullName(sameName
->parent(), fullName, sameName);
2997 m_writer->writeCharacters(
".");
2998 m_writer->writeEndElement();
3007 QList<Text> alsoList = node
->doc().alsoList();
3008 supplementAlsoList(node, alsoList);
3010 if (!alsoList.isEmpty()) {
3011 startSection(
"See Also");
3013 m_writer->writeStartElement(dbNamespace,
"para");
3014 m_writer->writeStartElement(dbNamespace,
"emphasis");
3015 m_writer->writeCharacters(
"See also ");
3016 m_writer->writeEndElement();
3019 m_writer->writeStartElement(dbNamespace,
"simplelist");
3020 m_writer->writeAttribute(
"type",
"vert");
3021 m_writer->writeAttribute(
"role",
"see-also");
3024 for (
const Text &text : alsoList) {
3025 m_writer->writeStartElement(dbNamespace,
"member");
3026 generateText(text, node);
3027 m_writer->writeEndElement();
3031 m_writer->writeEndElement();
3034 m_writer->writeEndElement();
3042
3043
3044
3045QXmlStreamWriter *
DocBookGenerator::startGenericDocument(
const Node *node,
const QString &fileName)
3048 QFile *outFile = openSubPageFile(
static_cast<
const PageNode*>(node), fileName);
3049 m_writer =
new QXmlStreamWriter(outFile);
3050 m_writer->setAutoFormatting(
false);
3052 m_writer->writeStartDocument();
3054 m_writer->writeNamespace(dbNamespace,
"db");
3055 m_writer->writeNamespace(xlinkNamespace,
"xlink");
3057 m_writer->writeNamespace(itsNamespace,
"its");
3058 m_writer->writeStartElement(dbNamespace,
"article");
3059 m_writer->writeAttribute(
"version",
"5.2");
3060 if (!m_naturalLanguage.isEmpty())
3061 m_writer->writeAttribute(
"xml:lang", m_naturalLanguage);
3065 sectionLevels.resize(0);
3074 m_hasSection =
false;
3077 QString fileName = Generator::fileName(node, fileExtension());
3078 return startGenericDocument(node, fileName);
3083 m_hasSection =
false;
3085 QString fileName = linkForExampleFile(file);
3086 return startGenericDocument(en, fileName);
3091 m_writer->writeEndElement();
3092 m_writer->writeEndDocument();
3094 m_writer->device()->close();
3095 delete m_writer->device();
3101
3102
3103
3108 const auto aggregate =
static_cast<
const Aggregate *>(node);
3112 QString subtitleText;
3113 const QString typeWord{aggregate->typeWord(
true)};
3114 if (aggregate->isNamespace()) {
3115 title =
"%1 %2"_L1.arg(aggregate->plainFullName(), typeWord);
3116 }
else if (aggregate->isClass()) {
3117 auto templateDecl = node->templateDecl();
3119 subtitleText =
"%1 %2 %3"_L1.arg((*templateDecl).to_qstring(),
3120 aggregate->typeWord(
false),
3121 aggregate->plainFullName());
3122 title =
"%1 %2"_L1.arg(aggregate->plainFullName(), typeWord);
3123 }
else if (aggregate->isHeader()) {
3124 title = aggregate->fullTitle();
3125 if (!aggregate->doc().title().isEmpty())
3126 titleText << aggregate->name() <<
" - "_L1 << aggregate->doc().title();
3130 m_writer = startDocument(node);
3133 if (!titleText.isEmpty())
3134 generateHeader(titleText, subtitleText, aggregate);
3136 generateHeader(title, subtitleText, aggregate);
3145 if (!aggregate->doc().isEmpty()) {
3146 startSection(
"details",
"Detailed Description");
3148 generateBody(aggregate);
3156 for (
const Section §ion : sectionVector) {
3157 if (section.members().isEmpty())
3160 startSection(section.title().toLower(), section.title());
3162 for (
const Node *member : section.members()) {
3163 if (member->nodeType() != NodeType::Class) {
3165 generateDetailedMember(member, aggregate);
3167 startSectionBegin();
3168 m_writer->writeCharacters(
"class ");
3169 generateFullName(member, aggregate);
3172 generateBrief(member);
3181 generateObsoleteMembers(sections);
3186void DocBookGenerator::generateSynopsisInfo(
const QString &key,
const QString &value)
3188 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3189 m_writer->writeAttribute(
"role", key);
3190 m_writer->writeCharacters(value);
3191 m_writer->writeEndElement();
3197 m_writer->writeTextElement(dbNamespace,
"modifier", value);
3202
3203
3213 if (!m_useDocBook52)
3223 node->isAggregate() ?
static_cast<
const Aggregate *>(node) :
nullptr;
3224 const ClassNode *classNode = node->isClass() ?
static_cast<
const ClassNode *>(node) :
nullptr;
3226 node->isFunction() ?
static_cast<
const FunctionNode *>(node) :
nullptr;
3228 node->isProperty() ?
static_cast<
const PropertyNode *>(node) :
nullptr;
3230 node->isVariable() ?
static_cast<
const VariableNode *>(node) :
nullptr;
3231 const EnumNode *enumNode = node->isEnumType() ?
static_cast<
const EnumNode *>(node) :
nullptr;
3233 node->isQmlProperty() ?
static_cast<
const QmlPropertyNode *>(node) :
nullptr;
3234 const QmlTypeNode *qcn = node->isQmlType() ?
static_cast<
const QmlTypeNode *>(node) :
nullptr;
3240 QString synopsisTag = nodeToSynopsisTag(node);
3241 m_writer->writeStartElement(dbNamespace, synopsisTag);
3246 m_writer->writeStartElement(dbNamespace,
"ooclass");
3247 m_writer->writeTextElement(dbNamespace,
"classname", node->plainName());
3248 m_writer->writeEndElement();
3251 m_writer->writeTextElement(dbNamespace,
"namespacename", node->plainName());
3254 m_writer->writeStartElement(dbNamespace,
"ooclass");
3255 m_writer->writeTextElement(dbNamespace,
"classname", node->plainName());
3256 m_writer->writeEndElement();
3258 if (!qcn->groupNames().isEmpty())
3259 m_writer->writeAttribute(
"groups", qcn->groupNames().join(QLatin1Char(
',')));
3261 m_writer->writeTextElement(dbNamespace,
"modifier",
"(Qt property)");
3263 m_writer->writeTextElement(dbNamespace,
"type", propertyNode->dataType());
3265 m_writer->writeTextElement(dbNamespace,
"varname", node->plainName());
3269 m_writer->writeTextElement(dbNamespace,
"modifier",
"static");
3272 m_writer->writeTextElement(dbNamespace,
"type", variableNode->dataType());
3274 m_writer->writeTextElement(dbNamespace,
"varname", node->plainName());
3278 m_writer->writeTextElement(dbNamespace,
"enumname", node->plainName());
3282 QString name = node->name();
3284 name.prepend(qpn->element() + QLatin1Char(
'.'));
3286 m_writer->writeTextElement(dbNamespace,
"type", qpn->dataType());
3288 m_writer->writeTextElement(dbNamespace,
"varname", name);
3296 m_writer->writeTextElement(dbNamespace,
"modifier",
"attached");
3300 m_writer->writeTextElement(dbNamespace,
"modifier",
"writable");
3304 m_writer->writeTextElement(dbNamespace,
"modifier",
"required");
3309 generateModifier(
"[read-only]");
3313 generateModifier(
"[default]");
3317 if (functionNode->virtualness() !=
"non")
3318 generateModifier(
"virtual");
3319 if (functionNode->isConst())
3320 generateModifier(
"const");
3321 if (functionNode->isStatic())
3322 generateModifier(
"static");
3327 if (functionNode->returnType() ==
"void")
3328 m_writer->writeEmptyElement(dbNamespace,
"void");
3330 m_writer->writeTextElement(dbNamespace,
"type", functionNode->returnTypeString());
3335 QString name = node->plainName();
3336 if (name.endsWith(
"()"))
3338 m_writer->writeTextElement(dbNamespace,
"methodname", name);
3342 m_writer->writeEmptyElement(dbNamespace,
"void");
3347 for (
int i = 0; i < lp
.count(); ++i) {
3349 m_writer->writeStartElement(dbNamespace,
"methodparam");
3351 m_writer->writeTextElement(dbNamespace,
"type", parameter.type());
3353 m_writer->writeTextElement(dbNamespace,
"parameter", parameter.name());
3355 if (!parameter.defaultValue().isEmpty()) {
3356 m_writer->writeTextElement(dbNamespace,
"initializer", parameter.defaultValue());
3359 m_writer->writeEndElement();
3363 if (functionNode->isImplicitlyGenerated())
3364 generateModifier(
"implicit");
3365 else if (functionNode->isExplicitlyDefaulted())
3366 generateModifier(
"default");
3367 else if (functionNode->isDeletedAsWritten())
3368 generateModifier(
"delete");
3369 if (functionNode->isFinal())
3370 generateModifier(
"final");
3371 if (functionNode->isOverride())
3372 generateModifier(
"override");
3374 m_writer->writeTextElement(dbNamespace,
"typedefname", node->plainName());
3378 QStringLiteral(
"Unexpected node type in generateDocBookSynopsis: %1")
3379 .arg(node->nodeTypeString()));
3385 for (
const EnumItem &item : enumNode->items()) {
3386 m_writer->writeStartElement(dbNamespace,
"enumitem");
3388 m_writer->writeTextElement(dbNamespace,
"enumidentifier", item.name());
3390 m_writer->writeTextElement(dbNamespace,
"enumvalue", item.value());
3392 m_writer->writeEndElement();
3396 if (enumNode->items().isEmpty()) {
3399 m_writer->writeStartElement(dbNamespace,
"enumitem");
3401 m_writer->writeEmptyElement(dbNamespace,
"enumidentifier");
3403 m_writer->writeEndElement();
3414 generateSynopsisInfo(
"meta", functionNode->metanessString());
3417 generateSynopsisInfo(
"overload",
"overload");
3418 generateSynopsisInfo(
"overload-number",
3419 QString::number(functionNode->overloadNumber()));
3422 if (functionNode->isRef())
3423 generateSynopsisInfo(
"refness", QString::number(1));
3424 else if (functionNode->isRefRef())
3425 generateSynopsisInfo(
"refness", QString::number(2));
3428 QStringList associatedProperties;
3429 const auto &nodes = functionNode->associatedProperties();
3430 for (
const Node *n : nodes) {
3431 const auto pn =
static_cast<
const PropertyNode *>(n);
3432 associatedProperties << pn->name();
3434 associatedProperties.sort();
3435 generateSynopsisInfo(
"associated-property",
3436 associatedProperties.join(QLatin1Char(
',')));
3442 signature +=
" final";
3444 signature +=
" override";
3446 signature +=
" = 0";
3448 signature +=
" = default";
3450 signature +=
" = delete";
3451 if (
const auto &req = functionNode->trailingRequiresClause(); req && !req->isEmpty())
3452 signature +=
" requires " + *req;
3453 generateSynopsisInfo(
"signature", signature);
3459 case Access::Public:
3460 generateSynopsisInfo(
"access",
"public");
3462 case Access::Protected:
3463 generateSynopsisInfo(
"access",
"protected");
3465 case Access::Private:
3466 generateSynopsisInfo(
"access",
"private");
3471 if (node->isAbstract())
3472 generateSynopsisInfo(
"abstract",
"true");
3477 case Status::Active:
3478 generateSynopsisInfo(
"status",
"active");
3480 case Status::Preliminary:
3481 generateSynopsisInfo(
"status",
3484 case Status::Deprecated:
3485 generateSynopsisInfo(
"status",
"deprecated");
3487 case Status::Internal:
3488 generateSynopsisInfo(
"status",
"internal");
3491 generateSynopsisInfo(
"status",
"main");
3498 if (aggregate->includeFile()) generateSynopsisInfo(
"headers", *aggregate->includeFile());
3501 if (!aggregate->since().isEmpty())
3502 generateSynopsisInfo(
"since", formatSince(aggregate));
3506 if (!aggregate->physicalModuleName().isEmpty()) {
3508 m_qdb->getCollectionNode(aggregate->physicalModuleName(), NodeType::Module);
3510 if (
const auto result = cmakeRequisite(cn)) {
3511 generateSynopsisInfo(
"cmake-find-package", result->first);
3512 generateSynopsisInfo(
"cmake-target-link-libraries", result->second);
3515 if (cn && !cn->qtVariable().isEmpty())
3516 generateSynopsisInfo(
"qmake",
"QT += " + cn->qtVariable());
3522 auto *classe =
const_cast<ClassNode *>(
static_cast<
const ClassNode *>(aggregate));
3523 if (classe && classe->isQmlNativeType() && classe->status() !=
Status::Internal) {
3524 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3525 m_writer->writeAttribute(
"role",
"nativeTypeFor");
3527 QList<QmlTypeNode *> nativeTypes { classe->qmlNativeTypes().cbegin(), classe->qmlNativeTypes().cend()};
3530 for (
auto item : std::as_const(nativeTypes)) {
3531 const Node *otherNode{
nullptr};
3532 Atom a = Atom(Atom::LinkNode, Utilities::stringForNode(item));
3533 const QString &link = getAutoLink(&a, aggregate, &otherNode);
3534 generateSimpleLink(link, item->name());
3537 m_writer->writeEndElement();
3541 QList<RelatedClass>::ConstIterator r;
3542 if (!classe->baseClasses().isEmpty()) {
3543 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3544 m_writer->writeAttribute(
"role",
"inherits");
3546 r = classe->baseClasses().constBegin();
3548 while (r != classe->baseClasses().constEnd()) {
3550 generateFullName((*r).m_node, classe);
3553 m_writer->writeCharacters(
" (protected)");
3555 m_writer->writeCharacters(
" (private)");
3557 m_writer->writeCharacters(
3558 Utilities::comma(index++, classe->baseClasses().size()));
3563 m_writer->writeEndElement();
3568 if (!classe->derivedClasses().isEmpty()) {
3569 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3570 m_writer->writeAttribute(
"role",
"inheritedBy");
3571 generateSortedNames(classe, classe->derivedClasses());
3572 m_writer->writeEndElement();
3581 QString logicalModuleVersion;
3583 m_qdb->getCollectionNode(qcn->logicalModuleName(), qcn->nodeType());
3585 logicalModuleVersion = collection->logicalModuleVersion();
3587 logicalModuleVersion = qcn->logicalModuleVersion();
3589 QStringList importText;
3590 importText <<
"import " + qcn->logicalModuleName();
3591 if (!logicalModuleVersion.isEmpty())
3592 importText << logicalModuleVersion;
3593 generateSynopsisInfo(
"import", importText.join(
' '));
3596 if (!qcn->since().isEmpty())
3597 generateSynopsisInfo(
"since", formatSince(qcn));
3600 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
3608 QStringList knownTypeNames{qcn->name()};
3610 knownTypeNames << base->name();
3615 if (!subs.isEmpty()) {
3616 m_writer->writeTextElement(dbNamespace,
"synopsisinfo");
3617 m_writer->writeAttribute(
"role",
"inheritedBy");
3618 generateSortedQmlNames(qcn, knownTypeNames, subs);
3619 m_writer->writeEndElement();
3625 const Node *otherNode =
nullptr;
3627 QString link = getAutoLink(&a, base, &otherNode);
3629 m_writer->writeTextElement(dbNamespace,
"synopsisinfo");
3630 m_writer->writeAttribute(
"role",
"inherits");
3631 generateSimpleLink(link, base->name());
3633 for (
const auto sub : std::as_const(subs)) {
3634 if (knownTypeNames.contains(sub->name())) {
3635 m_writer->writeCharacters(
" (%1)"_L1.arg(base->logicalModuleName()));
3639 m_writer->writeEndElement();
3647 const Node *otherNode =
nullptr;
3649 QString link = getAutoLink(&a, cn, &otherNode);
3651 m_writer->writeTextElement(dbNamespace,
"synopsisinfo");
3652 m_writer->writeAttribute(
"role",
"nativeType");
3653 generateSimpleLink(link, cn->name());
3654 m_writer->writeEndElement();
3661 case Node::UnspecifiedSafeness:
3662 generateSynopsisInfo(
"threadsafeness",
"unspecified");
3664 case Node::NonReentrant:
3665 generateSynopsisInfo(
"threadsafeness",
"non-reentrant");
3667 case Node::Reentrant:
3668 generateSynopsisInfo(
"threadsafeness",
"reentrant");
3670 case Node::ThreadSafe:
3671 generateSynopsisInfo(
"threadsafeness",
"thread safe");
3674 generateSynopsisInfo(
"threadsafeness",
"unspecified");
3679 if (!node->physicalModuleName().isEmpty())
3680 generateSynopsisInfo(
"module", node->physicalModuleName());
3683 if (classNode && !classNode->groupNames().isEmpty()) {
3684 generateSynopsisInfo(
"groups", classNode->groupNames().join(QLatin1Char(
',')));
3685 }
else if (qcn && !qcn->groupNames().isEmpty()) {
3686 generateSynopsisInfo(
"groups", qcn->groupNames().join(QLatin1Char(
',')));
3691 for (
const Node *fnNode : propertyNode->getters()) {
3693 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3694 generateSynopsisInfo(
"getter", funcNode->name());
3697 for (
const Node *fnNode : propertyNode->setters()) {
3699 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3700 generateSynopsisInfo(
"setter", funcNode->name());
3703 for (
const Node *fnNode : propertyNode->resetters()) {
3705 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3706 generateSynopsisInfo(
"resetter", funcNode->name());
3709 for (
const Node *fnNode : propertyNode->notifiers()) {
3711 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3712 generateSynopsisInfo(
"notifier", funcNode->name());
3717 m_writer->writeEndElement();
3723 m_writer->writeStartElement(dbNamespace,
"typedefsynopsis");
3726 m_writer->writeTextElement(dbNamespace,
"typedefname",
3727 enumNode->flagsType()->fullDocumentName());
3730 m_writer->writeEndElement();
3741 return node->name().mid(4);
3742 return node->name();
3746
3747
3748
3749void DocBookGenerator::typified(
const QString &string,
const Node *relative,
bool trailingSpace,
3754 QString pendingWord;
3756 for (
int i = 0; i <= string.size(); ++i) {
3758 if (i != string.size())
3761 QChar lower = ch.toLower();
3762 if ((lower >= QLatin1Char(
'a') && lower <= QLatin1Char(
'z')) || ch.digitValue() >= 0
3763 || ch == QLatin1Char(
'_') || ch == QLatin1Char(
':')) {
3766 if (!pendingWord.isEmpty()) {
3767 bool isProbablyType = (pendingWord != QLatin1String(
"const"));
3768 if (generateType && isProbablyType) {
3770 m_writer->writeCharacters(result);
3774 const Node *n = m_qdb->findTypeNode(pendingWord, relative, Genus::DontCare);
3779 href = linkForNode(n, relative);
3782 m_writer->writeStartElement(dbNamespace,
"type");
3784 m_writer->writeCharacters(pendingWord);
3786 generateSimpleLink(href, pendingWord);
3787 m_writer->writeEndElement();
3789 result += pendingWord;
3792 pendingWord.clear();
3794 if (ch.unicode() !=
'\0')
3799 if (trailingSpace && string.size()) {
3800 if (!string.endsWith(QLatin1Char(
'*')) && !string.endsWith(QLatin1Char(
'&')))
3801 result += QLatin1Char(
' ');
3804 m_writer->writeCharacters(result);
3808 bool generateNameLink)
3812 QString name = taggedNode(node);
3814 if (!generateNameLink) {
3815 m_writer->writeCharacters(name);
3819 m_writer->writeStartElement(dbNamespace,
"emphasis");
3820 m_writer->writeAttribute(
"role",
"bold");
3821 generateSimpleLink(linkForNode(node, relative), name);
3822 m_writer->writeEndElement();
3826 bool generateExtra,
bool generateType)
3828 const QString &pname = parameter.name();
3829 const QString &ptype = parameter.type();
3831 if (!pname.isEmpty()) {
3832 typified(ptype, relative,
true, generateType);
3838 if (generateExtra || pname.isEmpty()) {
3839 m_writer->writeStartElement(dbNamespace,
"emphasis");
3840 m_writer->writeCharacters(paramName);
3841 m_writer->writeEndElement();
3844 const QString &pvalue = parameter.defaultValue();
3845 if (generateExtra && !pvalue.isEmpty())
3846 m_writer->writeCharacters(
" = " + pvalue);
3858 const int MaxEnumValues = 6;
3860 if (generateExtra) {
3861 if (
auto extra = CodeMarker::extraSynopsis(node, style); !extra.isEmpty()) {
3862 generateExtraSynopsis(extra);
3863 m_writer->writeCharacters(u" "_s);
3868 QString namePrefix {};
3872 namePrefix = taggedNode(node->parent()) +
"::";
3877 case NodeType::Namespace:
3878 m_writer->writeCharacters(
"namespace ");
3879 m_writer->writeCharacters(namePrefix);
3880 generateSynopsisName(node, relative, generateNameLink);
3882 case NodeType::Class:
3883 m_writer->writeCharacters(
"class ");
3884 m_writer->writeCharacters(namePrefix);
3885 generateSynopsisName(node, relative, generateNameLink);
3891 if (
auto templateDecl = func->templateDecl()) {
3892 if (templateDecl->parameters.size() > QDoc::MultilineTemplateParamThreshold)
3893 m_writer->writeCharacters(templateDecl->to_qstring_multiline() + QLatin1Char(
'\n'));
3895 m_writer->writeCharacters(templateDecl->to_qstring() + QLatin1Char(
' '));
3901 if (!func->isNonvirtual())
3902 m_writer->writeCharacters(QStringLiteral(
"virtual "));
3906 if (style != Section::AllMembers && !func->returnType().isEmpty())
3907 typified(func->returnTypeString(), relative,
true, generateType);
3908 m_writer->writeCharacters(namePrefix);
3909 generateSynopsisName(node, relative, generateNameLink);
3912 m_writer->writeCharacters(QStringLiteral(
"("));
3915 for (
int i = 0; i < parameters
.count(); i++) {
3917 m_writer->writeCharacters(QStringLiteral(
", "));
3918 generateParameter(parameters
.at(i
), relative, generateExtra, generateType);
3921 m_writer->writeCharacters(QStringLiteral(
")"));
3924 if (func->isConst())
3925 m_writer->writeCharacters(QStringLiteral(
" const"));
3931 synopsis += QStringLiteral(
" final");
3933 synopsis += QStringLiteral(
" override");
3935 synopsis += QStringLiteral(
" = 0");
3937 synopsis += QStringLiteral(
" &");
3939 synopsis += QStringLiteral(
" &&");
3940 m_writer->writeCharacters(synopsis);
3942 if (!func->returnType().isEmpty() && func->returnType() !=
"void") {
3943 m_writer->writeCharacters(QStringLiteral(
" : "));
3944 typified(func->returnTypeString(), relative,
false, generateType);
3949 synopsis += QStringLiteral(
" &");
3951 synopsis += QStringLiteral(
" &&");
3952 if (
const auto &req = func->trailingRequiresClause(); req && !req->isEmpty())
3953 synopsis +=
" requires " + *req;
3954 m_writer->writeCharacters(synopsis);
3958 const auto enume =
static_cast<
const EnumNode *>(node);
3959 if (!enume->isAnonymous()) {
3960 m_writer->writeCharacters(
"enum "_L1);
3961 m_writer->writeCharacters(namePrefix);
3962 generateSynopsisName(node, relative, generateNameLink);
3963 }
else if (generateNameLink) {
3964 m_writer->writeStartElement(dbNamespace,
"emphasis");
3965 m_writer->writeAttribute(
"role",
"bold");
3966 generateSimpleLink(linkForNode(node, relative),
"enum");
3967 m_writer->writeEndElement();
3969 m_writer->writeCharacters(
"enum"_L1);
3976 QStringList documentedItems = enume->doc().enumItemNames();
3977 if (documentedItems.isEmpty()) {
3978 const auto &enumItems = enume->items();
3979 for (
const auto &item : enumItems)
3980 documentedItems << item.name();
3982 const QStringList omitItems = enume->doc().omitEnumItemNames();
3983 for (
const auto &item : omitItems)
3984 documentedItems.removeAll(item);
3986 if (documentedItems.size() > MaxEnumValues) {
3988 const QString last = documentedItems.last();
3989 documentedItems = documentedItems.mid(0, MaxEnumValues - 1);
3990 documentedItems +=
"…";
3991 documentedItems += last;
3993 synopsis += documentedItems.join(QLatin1String(
", "));
3995 if (!documentedItems.isEmpty())
3996 synopsis += QLatin1Char(
' ');
3997 synopsis += QLatin1Char(
'}');
3999 m_writer->writeCharacters(synopsis);
4003 if (
auto templateDecl = node->templateDecl()) {
4004 if (templateDecl->parameters.size() > QDoc::MultilineTemplateParamThreshold)
4005 m_writer->writeCharacters(templateDecl->to_qstring_multiline() + QLatin1Char(
'\n'));
4007 m_writer->writeCharacters(templateDecl->to_qstring() + QLatin1Char(
' '));
4010 m_writer->writeCharacters(namePrefix);
4011 generateSynopsisName(node, relative, generateNameLink);
4014 if (
static_cast<
const TypedefNode *>(node)->associatedEnum())
4015 m_writer->writeCharacters(
"flags ");
4016 m_writer->writeCharacters(namePrefix);
4017 generateSynopsisName(node, relative, generateNameLink);
4020 const auto property =
static_cast<
const PropertyNode *>(node);
4021 m_writer->writeCharacters(namePrefix);
4022 generateSynopsisName(node, relative, generateNameLink);
4023 m_writer->writeCharacters(
" : ");
4024 typified(property->qualifiedDataType(), relative,
false, generateType);
4027 const auto variable =
static_cast<
const VariableNode *>(node);
4029 generateSynopsisName(node, relative, generateNameLink);
4030 m_writer->writeCharacters(
" : ");
4031 typified(variable->dataType(), relative,
false, generateType);
4033 typified(variable->leftType(), relative,
false, generateType);
4034 m_writer->writeCharacters(
" ");
4035 m_writer->writeCharacters(namePrefix);
4036 generateSynopsisName(node, relative, generateNameLink);
4037 m_writer->writeCharacters(variable->rightType());
4041 m_writer->writeCharacters(namePrefix);
4042 generateSynopsisName(node, relative, generateNameLink);
4057 if (nativeEnum && nativeEnum
->enumNode() && !enumValue.startsWith(
"%1."_L1.arg(nativeEnum->prefix()))) {
4058 m_writer->writeCharacters(
"%1.%2"_L1.arg(nativeEnum->prefix(), enumValue));
4064 && enumValue.section(
' ', 0, 0).contains(
'.'_L1))) {
4065 m_writer->writeCharacters(enumValue);
4069 QList<
const Node *> parents;
4071 parents.prepend(node);
4076 if (
static_cast<
const EnumNode *>(relative)->isScoped())
4077 parents << relative;
4079 m_writer->writeStartElement(dbNamespace,
"code");
4080 for (
auto parent : parents) {
4081 generateSynopsisName(parent, relative,
true);
4082 m_writer->writeCharacters((relative->genus() == Genus::QML) ?
"."_L1 :
"::"_L1);
4085 m_writer->writeCharacters(enumValue);
4086 m_writer->writeEndElement();
4090
4091
4092
4097 Q_ASSERT(node && !node->name().isEmpty());
4103 m_writer->writeStartElement(dbNamespace,
"note");
4110 m_writer->writeStartElement(dbNamespace,
"para");
4111 m_writer->writeCharacters(
4112 "This function can be invoked via the meta-object system and from QML. See ");
4113 generateSimpleLink(node->url(),
"Q_INVOKABLE");
4114 m_writer->writeCharacters(
".");
4115 m_writer->writeEndElement();
4119 m_writer->writeTextElement(
4120 dbNamespace,
"para",
4121 "This is a private signal. It can be used in signal connections but "
4122 "cannot be emitted by the user.");
4126 QString handler(node->name());
4127 int prefixLocation = handler.lastIndexOf(
'.', -2) + 1;
4128 handler[prefixLocation] = handler[prefixLocation].toTitleCase();
4129 handler.insert(prefixLocation, QLatin1String(
"on"));
4130 m_writer->writeStartElement(dbNamespace,
"para");
4131 m_writer->writeCharacters(
"The corresponding handler is ");
4132 m_writer->writeTextElement(dbNamespace,
"code", handler);
4133 m_writer->writeCharacters(
".");
4134 m_writer->writeEndElement();
4142 const auto *fn =
static_cast<
const FunctionNode *>(node);
4143 auto nodes = fn->associatedProperties();
4144 if (nodes.isEmpty())
4149 QMap<PropertyNode::FunctionRole, QList<
const PropertyNode *>> roleGroups;
4150 for (
const auto *n : std::as_const(nodes)) {
4151 const auto *pn =
static_cast<
const PropertyNode *>(n);
4152 PropertyNode::FunctionRole role = pn->role(fn);
4153 roleGroups[role].append(pn);
4165 for (
auto role : roleOrder) {
4166 const auto it = roleGroups.constFind(role);
4167 if (it == roleGroups.cend())
4170 const auto &properties = it.value();
4175 msg = QStringLiteral(
"Getter function");
4178 msg = QStringLiteral(
"Setter function");
4181 msg = QStringLiteral(
"Resetter function");
4184 msg = QStringLiteral(
"Notifier signal");
4187 msg = QStringLiteral(
"Bindable function");
4193 m_writer->writeStartElement(dbNamespace,
"para");
4194 if (properties.size() == 1) {
4195 const auto *pn = properties.first();
4196 m_writer->writeCharacters(msg +
" for property ");
4197 generateSimpleLink(linkForNode(pn,
nullptr), pn->name());
4198 m_writer->writeCharacters(
". ");
4200 m_writer->writeCharacters(msg +
" for properties ");
4201 for (qsizetype i = 0; i < properties.size(); ++i) {
4202 const auto *pn = properties.at(i);
4203 generateSimpleLink(linkForNode(pn,
nullptr), pn->name());
4204 m_writer->writeCharacters(Utilities::separator(i, properties.size()));
4206 m_writer->writeCharacters(
" ");
4208 m_writer->writeEndElement();
4215 const Node *linkNode;
4217 QString link = getAutoLink(&linkAtom, node, &linkNode);
4218 m_writer->writeStartElement(dbNamespace,
"para");
4219 m_writer->writeCharacters(
"This property supports ");
4220 generateSimpleLink(link,
"QProperty");
4221 m_writer->writeCharacters(
" bindings.");
4222 m_writer->writeEndElement();
4227 const auto *func =
static_cast<
const FunctionNode *>(node);
4230 if (func->isPrimaryOverload())
4233 m_writer->writeStartElement(dbNamespace,
"para");
4235 if (func->isSignal() || func->isSlot()) {
4236 auto writeDocBookLink = [&](
const QString &target,
const QString &label) {
4237 const Node *linkNode =
nullptr;
4239 const QString &link = getAutoLink(&linkAtom, node, &linkNode);
4241 m_writer->writeStartElement(dbNamespace,
"link");
4242 if (!link.isEmpty() && linkNode) {
4243 m_writer->writeAttribute(xlinkNamespace,
"href", link);
4245 m_writer->writeAttribute(dbNamespace,
"linkend", target);
4247 m_writer->writeCharacters(label);
4248 m_writer->writeEndElement();
4251 const QString &functionType = func->isSignal() ?
"signal" :
"slot";
4252 const QString &configKey = func->isSignal() ?
"overloadedsignalstarget" :
"overloadedslotstarget";
4253 const QString &defaultTarget = func->isSignal() ?
"connecting-overloaded-signals" :
"connecting-overloaded-slots";
4254 const QString &linkTarget = Config::instance().get(configKey).asString(defaultTarget);
4256 m_writer->writeCharacters(
"This " + functionType +
" is overloaded. ");
4258 QString snippet = generateOverloadSnippet(func);
4259 if (!snippet.isEmpty()) {
4260 m_writer->writeCharacters(
"To connect to this " + functionType +
":");
4261 m_writer->writeEndElement();
4263 m_writer->writeStartElement(dbNamespace,
"programlisting");
4264 m_writer->writeCharacters(snippet);
4265 m_writer->writeEndElement();
4270 m_writer->writeStartElement(dbNamespace,
"para");
4271 if (!linkTarget.isEmpty()) {
4272 m_writer->writeCharacters(
"For more examples and approaches, see ");
4273 writeDocBookLink(linkTarget,
"connecting to overloaded " + functionType +
"s");
4274 m_writer->writeCharacters(
".");
4276 }
else if (!linkTarget.isEmpty()) {
4277 m_writer->writeCharacters(
"For more examples and approaches, see ");
4278 writeDocBookLink(linkTarget,
"connecting to overloaded " + functionType +
"s");
4279 m_writer->writeCharacters(
".");
4283 const auto &args = node
->doc().overloadList();
4284 if (args.first().first.isEmpty()) {
4285 m_writer->writeCharacters(
"This is an overloaded function.");
4287 QString target = args.first().first;
4290 if (!target.contains(
"::")) {
4293 target = parent->name() +
"::" + target;
4296 m_writer->writeCharacters(
"This function overloads ");
4298 const Node *linkNode =
nullptr;
4300 QString link = getAutoLink(&linkAtom, node, &linkNode);
4301 if (!link.isEmpty() && linkNode)
4302 generateSimpleLink(link, target);
4304 m_writer->writeCharacters(target);
4305 m_writer->writeCharacters(
".");
4309 m_writer->writeEndElement();
4318 m_writer->writeEndElement();
4326 bool closeSupplementarySection =
false;
4330 const QList<Node *> &collective = scn->collective();
4332 bool firstFunction =
true;
4333 for (
const auto *sharedNode : collective) {
4334 if (firstFunction) {
4335 startSectionBegin(sharedNode);
4337 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4338 m_writer->writeAttribute(
"renderas",
"sect2");
4339 writeXmlId(sharedNode);
4342 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4344 generateSynopsis(sharedNode, relative, Section::Details);
4346 if (firstFunction) {
4348 firstFunction =
false;
4350 m_writer->writeEndElement();
4356 if (node->isEnumType(Genus::CPP) && (etn =
static_cast<
const EnumNode *>(node))->flagsType()) {
4357 startSectionBegin(node);
4359 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4363 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4364 m_writer->writeAttribute(
"renderas",
"sect2");
4366 m_writer->writeEndElement();
4369 startSectionBegin(node);
4371 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4376 Q_ASSERT(m_hasSection);
4385 closeSupplementarySection =
true;
4386 startSection(
"",
"Notes");
4390 const auto *func =
static_cast<
const FunctionNode *>(node);
4391 if (func->hasOverloads() && (func->isSignal() || func->isSlot()))
4399 const auto property =
static_cast<
const PropertyNode *>(node);
4408 m_writer->writeStartElement(dbNamespace,
"para");
4410 m_writer->writeStartElement(dbNamespace,
"emphasis");
4411 m_writer->writeAttribute(
"role",
"bold");
4412 m_writer->writeCharacters(
"Access functions:");
4414 m_writer->writeEndElement();
4416 m_writer->writeEndElement();
4418 generateSectionList(section, node);
4425 m_writer->writeStartElement(dbNamespace,
"para");
4427 m_writer->writeStartElement(dbNamespace,
"emphasis");
4428 m_writer->writeAttribute(
"role",
"bold");
4429 m_writer->writeCharacters(
"Notifier signal:");
4431 m_writer->writeEndElement();
4433 m_writer->writeEndElement();
4435 generateSectionList(notifiers, node);
4439 const auto en =
static_cast<
const EnumNode *>(node);
4441 if (m_qflagsHref.isEmpty()) {
4442 Node *qflags = m_qdb->findClassNode(QStringList(
"QFlags"));
4444 m_qflagsHref = linkForNode(qflags,
nullptr);
4447 if (en->flagsType()) {
4448 m_writer->writeStartElement(dbNamespace,
"para");
4449 m_writer->writeCharacters(
"The ");
4450 m_writer->writeStartElement(dbNamespace,
"code");
4451 m_writer->writeCharacters(en->flagsType()->name());
4452 m_writer->writeEndElement();
4453 m_writer->writeCharacters(
" type is a typedef for ");
4454 m_writer->writeStartElement(dbNamespace,
"code");
4455 generateSimpleLink(m_qflagsHref,
"QFlags");
4456 m_writer->writeCharacters(
"<" + en->name() +
">. ");
4457 m_writer->writeEndElement();
4458 m_writer->writeCharacters(
"It stores an OR combination of ");
4459 m_writer->writeStartElement(dbNamespace,
"code");
4460 m_writer->writeCharacters(en->name());
4461 m_writer->writeEndElement();
4462 m_writer->writeCharacters(
" values.");
4463 m_writer->writeEndElement();
4468 if (closeSupplementarySection)
4479 bool useObsoleteMembers)
4484 if (!members.isEmpty()) {
4485 bool hasPrivateSignals =
false;
4486 bool isInvokable =
false;
4488 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
4490 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4493 NodeVector::ConstIterator m = members.constBegin();
4494 while (m != members.constEnd()) {
4500 m_writer->writeStartElement(dbNamespace,
"listitem");
4502 m_writer->writeStartElement(dbNamespace,
"para");
4505 generateSynopsis(*m, relative, section
.style());
4506 if ((*m)->isFunction()) {
4508 if (fn->isPrivateSignal())
4509 hasPrivateSignals =
true;
4510 else if (fn->isInvokable())
4514 m_writer->writeEndElement();
4516 m_writer->writeEndElement();
4522 m_writer->writeEndElement();
4525 if (hasPrivateSignals)
4532 && !section.inheritedMembers().isEmpty()) {
4533 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
4535 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4538 generateSectionInheritedList(section, relative);
4540 m_writer->writeEndElement();
4548 QList<std::pair<Aggregate *,
int>>::ConstIterator p = section.inheritedMembers().constBegin();
4549 while (p != section.inheritedMembers().constEnd()) {
4550 m_writer->writeStartElement(dbNamespace,
"listitem");
4551 m_writer->writeCharacters(QString::number((*p).second) + u' ');
4552 if ((*p).second == 1)
4553 m_writer->writeCharacters(section.singular());
4555 m_writer->writeCharacters(section.plural());
4556 m_writer->writeCharacters(
" inherited from ");
4557 generateSimpleLink(fileName((*p).first) +
'#'
4558 + Generator::cleanRef(section.title().toLower()),
4559 (*p).first->plainFullName(relative));
4565
4566
4567
4571 Q_ASSERT(m_writer ==
nullptr);
4572 m_writer = startDocument(pn);
4574 generateHeader(pn->doc().title(), pn->subtitle(), pn);
4583
4584
4589 Q_ASSERT(m_writer ==
nullptr);
4590 m_writer = startDocument(qcn);
4593 QString title = qcn->name();
4595 title.append(
" QML Value Type");
4597 title.append(
" QML Type");
4600 title.append(
" (Singleton)");
4606 generateHeader(title, qcn->subtitle(), qcn);
4611 m_writer->writeStartElement(dbNamespace,
"note");
4612 m_writer->writeStartElement(dbNamespace,
"para");
4613 m_writer->writeStartElement(dbNamespace,
"emphasis");
4614 m_writer->writeAttribute(
"role",
"bold");
4615 m_writer->writeCharacters(
"Note: ");
4616 m_writer->writeEndElement();
4617 m_writer->writeCharacters(
"This type is a QML singleton. "
4618 "There is only one instance of this type in the QML engine.");
4619 m_writer->writeEndElement();
4620 m_writer->writeEndElement();
4623 startSection(
"details",
"Detailed Description");
4631 for (
const auto §ion : sections.detailsSections()) {
4632 if (!section.isEmpty()) {
4633 startSection(section.title().toLower(), section.title());
4635 for (
const auto &member : section.members())
4636 generateDetailedQmlMember(member, qcn);
4642 generateObsoleteQmlMembers(sections);
4651
4652
4653
4660 if (!title.isEmpty())
4664 title += n->element() + QLatin1Char(
'.');
4665 title += n->name() +
" : " + n->dataType();
4670 auto generateQmlMethodTitle = [&](
Node *node) {
4675 const auto *scn =
static_cast<
const SharedCommentNode *>(node);
4678 if (!scn->name().isEmpty())
4679 heading = scn->name() +
" group";
4681 heading = node->name();
4682 startSection(scn, heading);
4687 const QList<Node *> sharedNodes = scn->collective();
4688 for (
const auto &sharedNode : sharedNodes) {
4689 if (sharedNode->isQmlProperty()) {
4690 auto *qpn =
static_cast<QmlPropertyNode *>(sharedNode);
4692 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4693 m_writer->writeAttribute(
"renderas",
"sect2");
4695 m_writer->writeCharacters(getQmlPropertyTitle(qpn));
4696 m_writer->writeEndElement();
4699 generateDocBookSynopsis(qpn);
4703 auto qpn =
static_cast<QmlPropertyNode *>(node);
4704 startSection(qpn, getQmlPropertyTitle(qpn));
4708 const QList<Node *> &sharedNodes = scn->collective();
4713 for (
const auto &sharedNode : sharedNodes) {
4715 if (!sharedNode->isFunction(Genus::QML) && !sharedNode->isQmlProperty()) {
4721 startSectionBegin(sharedNode);
4723 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4724 m_writer->writeAttribute(
"renderas",
"sect2");
4728 if (sharedNode->isFunction(Genus::QML))
4729 generateQmlMethodTitle(sharedNode);
4730 else if (sharedNode->isQmlProperty())
4731 m_writer->writeCharacters(
4732 getQmlPropertyTitle(
static_cast<QmlPropertyNode *>(sharedNode)));
4738 m_writer->writeEndElement();
4739 generateDocBookSynopsis(sharedNode);
4745 startSectionBegin(refForNode(node));
4748 generateQmlMethodTitle(node);
4749 else if (node->isQmlProperty())
4750 m_writer->writeCharacters(
4751 getQmlPropertyTitle(
static_cast<QmlPropertyNode *>(node)));
4756 startSectionBegin(node);
4760 startSectionBegin(node);
4761 generateQmlMethodTitle(node);
4775
4776
4783 if (!node->url().isNull())
4787 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815 auto cn =
static_cast<CollectionNode *>(node);
4816 if (cn->wasSeen()) {
4817 m_qdb->mergeCollections(cn);
4818 generateCollectionNode(cn);
4819 }
else if (cn->isGenericCollection()) {
4823 generateGenericCollectionPage(cn);
4826 generatePageNode(
static_cast<PageNode *>(node));
4830 generateCppReferencePage(
static_cast<Aggregate *>(node));
4832 generateQmlTypePage(
static_cast<QmlTypeNode *>(node));
4834 generateProxyPage(
static_cast<Aggregate *>(node));
4840 auto *aggregate =
static_cast<Aggregate *>(node);
4841 for (
auto c : aggregate->childNodes()) {
4842 if (node->isPageNode())
4843 generateDocumentation(c);
4854 Q_ASSERT(m_writer ==
nullptr);
4855 m_writer = startDocument(aggregate);
4858 generateHeader(aggregate->plainFullName(),
"", aggregate);
4863 if (!aggregate
->doc().isEmpty()) {
4864 startSection(
"details",
"Detailed Description");
4866 generateBody(aggregate);
4875 for (
const auto §ion : detailsSections) {
4876 if (section.isEmpty())
4879 startSection(section.title().toLower(), section.title());
4881 const QList<Node *> &members = section.members();
4882 for (
const auto &member : members) {
4883 if (!member->isClassNode()) {
4884 generateDetailedMember(member, aggregate);
4886 startSectionBegin();
4887 generateFullName(member, aggregate);
4890 generateBrief(member);
4904
4905
4910 Q_ASSERT(m_writer ==
nullptr);
4911 m_writer = startDocument(cn);
4914 generateHeader(cn->doc().title(), cn->subtitle(), cn);
4920 if (cn
->genus() != Genus::DOC && cn
->genus() != Genus::DontCare) {
4931 if (!nmm.isEmpty()) {
4932 startSection(
"namespaces",
"Namespaces");
4933 generateAnnotatedList(cn, nmm.values(),
"namespaces");
4937 if (!nmm.isEmpty()) {
4938 startSection(
"classes",
"Classes");
4939 generateAnnotatedList(cn, nmm.values(),
"classes");
4945 bool generatedTitle =
false;
4947 startSection(
"details",
"Detailed Description");
4948 generatedTitle =
true;
4953 !cn
->doc().body().isEmpty() ||
4955 !cn
->doc().alsoList().empty() ||
4958 writeAnchor(
"details");
4964 if (!cn->noAutoList() && (cn->isGroup() || cn->isQmlModule()))
4965 generateAnnotatedList(cn, cn->members(),
"members", AutoSection);
4976
4977
4978
4979
4984 QString name = cn->name().toLower();
4985 name.replace(QChar(
' '), QString(
"-"));
4986 QString filename = cn->tree()->physicalModuleName() +
"-" + name +
"." + fileExtension();
4989 Q_ASSERT(m_writer ==
nullptr);
4990 m_writer = startGenericDocument(cn, filename);
4993 generateHeader(cn->fullTitle(), cn->subtitle(), cn);
4999 m_writer->writeStartElement(dbNamespace,
"para");
5000 m_writer->writeCharacters(
"Each function or type documented here is related to a class or "
5001 "namespace that is documented in a different module. The reference "
5002 "page for that class or namespace will link to the function or type "
5004 m_writer->writeEndElement();
5008 for (
const auto &member : members)
5009 generateDetailedMember(member, cnc);
5022 m_writer->writeStartElement(dbNamespace,
"link");
5023 m_writer->writeAttribute(xlinkNamespace,
"href", fullDocumentLocation(node));
5024 m_writer->writeAttribute(xlinkNamespace,
"role", targetType(node));
5025 m_writer->writeCharacters(node->fullName(relative));
5026 m_writer->writeEndElement();
5030 const Node *actualNode)
5032 Q_ASSERT(apparentNode);
5033 Q_ASSERT(actualNode);
5036 m_writer->writeStartElement(dbNamespace,
"link");
5037 m_writer->writeAttribute(xlinkNamespace,
"href", fullDocumentLocation(actualNode));
5038 m_writer->writeAttribute(
"role", targetType(actualNode));
5039 m_writer->writeCharacters(fullName);
5040 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).
void generateExampleFilePage(const Node *en, ResolvedFile resolved_file, CodeMarker *=nullptr) override
Generate a file with the contents of a C++ or QML source file.
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)
Generate the DocBook header for the file, including the abstract.
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").
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.
Aggregate * aggregate() const
Sections(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.