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 (aggregate->isNamespace() || aggregate->isHeader()) ?
3159 for (
const Section §ion : sectionVector) {
3160 if (section.members().isEmpty())
3163 startSection(section.title().toLower(), section.title());
3165 for (
const Node *member : section.members()) {
3166 if (member->nodeType() != NodeType::Class) {
3168 generateDetailedMember(member, aggregate);
3170 startSectionBegin();
3171 m_writer->writeCharacters(
"class ");
3172 generateFullName(member, aggregate);
3175 generateBrief(member);
3184 generateObsoleteMembers(sections);
3189void DocBookGenerator::generateSynopsisInfo(
const QString &key,
const QString &value)
3191 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3192 m_writer->writeAttribute(
"role", key);
3193 m_writer->writeCharacters(value);
3194 m_writer->writeEndElement();
3200 m_writer->writeTextElement(dbNamespace,
"modifier", value);
3205
3206
3216 if (!m_useDocBook52)
3226 node->isAggregate() ?
static_cast<
const Aggregate *>(node) :
nullptr;
3227 const ClassNode *classNode = node->isClass() ?
static_cast<
const ClassNode *>(node) :
nullptr;
3229 node->isFunction() ?
static_cast<
const FunctionNode *>(node) :
nullptr;
3231 node->isProperty() ?
static_cast<
const PropertyNode *>(node) :
nullptr;
3233 node->isVariable() ?
static_cast<
const VariableNode *>(node) :
nullptr;
3234 const EnumNode *enumNode = node->isEnumType() ?
static_cast<
const EnumNode *>(node) :
nullptr;
3236 node->isQmlProperty() ?
static_cast<
const QmlPropertyNode *>(node) :
nullptr;
3237 const QmlTypeNode *qcn = node->isQmlType() ?
static_cast<
const QmlTypeNode *>(node) :
nullptr;
3243 QString synopsisTag = nodeToSynopsisTag(node);
3244 m_writer->writeStartElement(dbNamespace, synopsisTag);
3249 m_writer->writeStartElement(dbNamespace,
"ooclass");
3250 m_writer->writeTextElement(dbNamespace,
"classname", node->plainName());
3251 m_writer->writeEndElement();
3254 m_writer->writeTextElement(dbNamespace,
"namespacename", node->plainName());
3257 m_writer->writeStartElement(dbNamespace,
"ooclass");
3258 m_writer->writeTextElement(dbNamespace,
"classname", node->plainName());
3259 m_writer->writeEndElement();
3261 if (!qcn->groupNames().isEmpty())
3262 m_writer->writeAttribute(
"groups", qcn->groupNames().join(QLatin1Char(
',')));
3264 m_writer->writeTextElement(dbNamespace,
"modifier",
"(Qt property)");
3266 m_writer->writeTextElement(dbNamespace,
"type", propertyNode->dataType());
3268 m_writer->writeTextElement(dbNamespace,
"varname", node->plainName());
3272 m_writer->writeTextElement(dbNamespace,
"modifier",
"static");
3275 m_writer->writeTextElement(dbNamespace,
"type", variableNode->dataType());
3277 m_writer->writeTextElement(dbNamespace,
"varname", node->plainName());
3281 m_writer->writeTextElement(dbNamespace,
"enumname", node->plainName());
3285 QString name = node->name();
3287 name.prepend(qpn->element() + QLatin1Char(
'.'));
3289 m_writer->writeTextElement(dbNamespace,
"type", qpn->dataType());
3291 m_writer->writeTextElement(dbNamespace,
"varname", name);
3299 m_writer->writeTextElement(dbNamespace,
"modifier",
"attached");
3303 m_writer->writeTextElement(dbNamespace,
"modifier",
"writable");
3307 m_writer->writeTextElement(dbNamespace,
"modifier",
"required");
3312 generateModifier(
"[read-only]");
3316 generateModifier(
"[default]");
3320 if (functionNode->virtualness() !=
"non")
3321 generateModifier(
"virtual");
3322 if (functionNode->isConst())
3323 generateModifier(
"const");
3324 if (functionNode->isStatic())
3325 generateModifier(
"static");
3330 if (functionNode->returnType() ==
"void")
3331 m_writer->writeEmptyElement(dbNamespace,
"void");
3333 m_writer->writeTextElement(dbNamespace,
"type", functionNode->returnTypeString());
3338 QString name = node->plainName();
3339 if (name.endsWith(
"()"))
3341 m_writer->writeTextElement(dbNamespace,
"methodname", name);
3345 m_writer->writeEmptyElement(dbNamespace,
"void");
3350 for (
int i = 0; i < lp
.count(); ++i) {
3352 m_writer->writeStartElement(dbNamespace,
"methodparam");
3354 m_writer->writeTextElement(dbNamespace,
"type", parameter.type());
3356 m_writer->writeTextElement(dbNamespace,
"parameter", parameter.name());
3358 if (!parameter.defaultValue().isEmpty()) {
3359 m_writer->writeTextElement(dbNamespace,
"initializer", parameter.defaultValue());
3362 m_writer->writeEndElement();
3366 if (functionNode->isImplicitlyGenerated())
3367 generateModifier(
"implicit");
3368 else if (functionNode->isExplicitlyDefaulted())
3369 generateModifier(
"default");
3370 else if (functionNode->isDeletedAsWritten())
3371 generateModifier(
"delete");
3372 if (functionNode->isFinal())
3373 generateModifier(
"final");
3374 if (functionNode->isOverride())
3375 generateModifier(
"override");
3377 m_writer->writeTextElement(dbNamespace,
"typedefname", node->plainName());
3381 QStringLiteral(
"Unexpected node type in generateDocBookSynopsis: %1")
3382 .arg(node->nodeTypeString()));
3388 for (
const EnumItem &item : enumNode->items()) {
3389 m_writer->writeStartElement(dbNamespace,
"enumitem");
3391 m_writer->writeTextElement(dbNamespace,
"enumidentifier", item.name());
3393 m_writer->writeTextElement(dbNamespace,
"enumvalue", item.value());
3395 m_writer->writeEndElement();
3399 if (enumNode->items().isEmpty()) {
3402 m_writer->writeStartElement(dbNamespace,
"enumitem");
3404 m_writer->writeEmptyElement(dbNamespace,
"enumidentifier");
3406 m_writer->writeEndElement();
3417 generateSynopsisInfo(
"meta", functionNode->metanessString());
3420 generateSynopsisInfo(
"overload",
"overload");
3421 generateSynopsisInfo(
"overload-number",
3422 QString::number(functionNode->overloadNumber()));
3425 if (functionNode->isRef())
3426 generateSynopsisInfo(
"refness", QString::number(1));
3427 else if (functionNode->isRefRef())
3428 generateSynopsisInfo(
"refness", QString::number(2));
3431 QStringList associatedProperties;
3432 const auto &nodes = functionNode->associatedProperties();
3433 for (
const Node *n : nodes) {
3434 const auto pn =
static_cast<
const PropertyNode *>(n);
3435 associatedProperties << pn->name();
3437 associatedProperties.sort();
3438 generateSynopsisInfo(
"associated-property",
3439 associatedProperties.join(QLatin1Char(
',')));
3445 signature +=
" final";
3447 signature +=
" override";
3449 signature +=
" = 0";
3451 signature +=
" = default";
3453 signature +=
" = delete";
3454 if (
const auto &req = functionNode->trailingRequiresClause(); req && !req->isEmpty())
3455 signature +=
" requires " + *req;
3456 generateSynopsisInfo(
"signature", signature);
3462 case Access::Public:
3463 generateSynopsisInfo(
"access",
"public");
3465 case Access::Protected:
3466 generateSynopsisInfo(
"access",
"protected");
3468 case Access::Private:
3469 generateSynopsisInfo(
"access",
"private");
3474 if (node->isAbstract())
3475 generateSynopsisInfo(
"abstract",
"true");
3480 case Status::Active:
3481 generateSynopsisInfo(
"status",
"active");
3483 case Status::Preliminary:
3484 generateSynopsisInfo(
"status",
3487 case Status::Deprecated:
3488 generateSynopsisInfo(
"status",
"deprecated");
3490 case Status::Internal:
3491 generateSynopsisInfo(
"status",
"internal");
3494 generateSynopsisInfo(
"status",
"main");
3501 if (aggregate->includeFile()) generateSynopsisInfo(
"headers", *aggregate->includeFile());
3504 if (!aggregate->since().isEmpty())
3505 generateSynopsisInfo(
"since", formatSince(aggregate));
3509 if (!aggregate->physicalModuleName().isEmpty()) {
3511 m_qdb->getCollectionNode(aggregate->physicalModuleName(), NodeType::Module);
3513 if (
const auto result = cmakeRequisite(cn)) {
3514 generateSynopsisInfo(
"cmake-find-package", result->first);
3515 generateSynopsisInfo(
"cmake-target-link-libraries", result->second);
3518 if (cn && !cn->qtVariable().isEmpty())
3519 generateSynopsisInfo(
"qmake",
"QT += " + cn->qtVariable());
3525 auto *classe =
const_cast<ClassNode *>(
static_cast<
const ClassNode *>(aggregate));
3526 if (classe && classe->isQmlNativeType() && classe->status() !=
Status::Internal) {
3527 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3528 m_writer->writeAttribute(
"role",
"nativeTypeFor");
3530 QList<QmlTypeNode *> nativeTypes { classe->qmlNativeTypes().cbegin(), classe->qmlNativeTypes().cend()};
3533 for (
auto item : std::as_const(nativeTypes)) {
3534 const Node *otherNode{
nullptr};
3535 Atom a = Atom(Atom::LinkNode, Utilities::stringForNode(item));
3536 const QString &link = getAutoLink(&a, aggregate, &otherNode);
3537 generateSimpleLink(link, item->name());
3540 m_writer->writeEndElement();
3544 QList<RelatedClass>::ConstIterator r;
3545 if (!classe->baseClasses().isEmpty()) {
3546 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3547 m_writer->writeAttribute(
"role",
"inherits");
3549 r = classe->baseClasses().constBegin();
3551 while (r != classe->baseClasses().constEnd()) {
3553 generateFullName((*r).m_node, classe);
3556 m_writer->writeCharacters(
" (protected)");
3558 m_writer->writeCharacters(
" (private)");
3560 m_writer->writeCharacters(
3561 Utilities::comma(index++, classe->baseClasses().size()));
3566 m_writer->writeEndElement();
3571 if (!classe->derivedClasses().isEmpty()) {
3572 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3573 m_writer->writeAttribute(
"role",
"inheritedBy");
3574 generateSortedNames(classe, classe->derivedClasses());
3575 m_writer->writeEndElement();
3584 QString logicalModuleVersion;
3586 m_qdb->getCollectionNode(qcn->logicalModuleName(), qcn->nodeType());
3588 logicalModuleVersion = collection->logicalModuleVersion();
3590 logicalModuleVersion = qcn->logicalModuleVersion();
3592 QStringList importText;
3593 importText <<
"import " + qcn->logicalModuleName();
3594 if (!logicalModuleVersion.isEmpty())
3595 importText << logicalModuleVersion;
3596 generateSynopsisInfo(
"import", importText.join(
' '));
3599 if (!qcn->since().isEmpty())
3600 generateSynopsisInfo(
"since", formatSince(qcn));
3603 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
3611 QStringList knownTypeNames{qcn->name()};
3613 knownTypeNames << base->name();
3618 if (!subs.isEmpty()) {
3619 m_writer->writeTextElement(dbNamespace,
"synopsisinfo");
3620 m_writer->writeAttribute(
"role",
"inheritedBy");
3621 generateSortedQmlNames(qcn, knownTypeNames, subs);
3622 m_writer->writeEndElement();
3628 const Node *otherNode =
nullptr;
3630 QString link = getAutoLink(&a, base, &otherNode);
3632 m_writer->writeTextElement(dbNamespace,
"synopsisinfo");
3633 m_writer->writeAttribute(
"role",
"inherits");
3634 generateSimpleLink(link, base->name());
3636 for (
const auto sub : std::as_const(subs)) {
3637 if (knownTypeNames.contains(sub->name())) {
3638 m_writer->writeCharacters(
" (%1)"_L1.arg(base->logicalModuleName()));
3642 m_writer->writeEndElement();
3650 const Node *otherNode =
nullptr;
3652 QString link = getAutoLink(&a, cn, &otherNode);
3654 m_writer->writeTextElement(dbNamespace,
"synopsisinfo");
3655 m_writer->writeAttribute(
"role",
"nativeType");
3656 generateSimpleLink(link, cn->name());
3657 m_writer->writeEndElement();
3664 case Node::UnspecifiedSafeness:
3665 generateSynopsisInfo(
"threadsafeness",
"unspecified");
3667 case Node::NonReentrant:
3668 generateSynopsisInfo(
"threadsafeness",
"non-reentrant");
3670 case Node::Reentrant:
3671 generateSynopsisInfo(
"threadsafeness",
"reentrant");
3673 case Node::ThreadSafe:
3674 generateSynopsisInfo(
"threadsafeness",
"thread safe");
3677 generateSynopsisInfo(
"threadsafeness",
"unspecified");
3682 if (!node->physicalModuleName().isEmpty())
3683 generateSynopsisInfo(
"module", node->physicalModuleName());
3686 if (classNode && !classNode->groupNames().isEmpty()) {
3687 generateSynopsisInfo(
"groups", classNode->groupNames().join(QLatin1Char(
',')));
3688 }
else if (qcn && !qcn->groupNames().isEmpty()) {
3689 generateSynopsisInfo(
"groups", qcn->groupNames().join(QLatin1Char(
',')));
3694 for (
const Node *fnNode : propertyNode->getters()) {
3696 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3697 generateSynopsisInfo(
"getter", funcNode->name());
3700 for (
const Node *fnNode : propertyNode->setters()) {
3702 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3703 generateSynopsisInfo(
"setter", funcNode->name());
3706 for (
const Node *fnNode : propertyNode->resetters()) {
3708 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3709 generateSynopsisInfo(
"resetter", funcNode->name());
3712 for (
const Node *fnNode : propertyNode->notifiers()) {
3714 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3715 generateSynopsisInfo(
"notifier", funcNode->name());
3720 m_writer->writeEndElement();
3726 m_writer->writeStartElement(dbNamespace,
"typedefsynopsis");
3729 m_writer->writeTextElement(dbNamespace,
"typedefname",
3730 enumNode->flagsType()->fullDocumentName());
3733 m_writer->writeEndElement();
3744 return node->name().mid(4);
3745 return node->name();
3749
3750
3751
3752void DocBookGenerator::typified(
const QString &string,
const Node *relative,
bool trailingSpace,
3757 QString pendingWord;
3759 for (
int i = 0; i <= string.size(); ++i) {
3761 if (i != string.size())
3764 QChar lower = ch.toLower();
3765 if ((lower >= QLatin1Char(
'a') && lower <= QLatin1Char(
'z')) || ch.digitValue() >= 0
3766 || ch == QLatin1Char(
'_') || ch == QLatin1Char(
':')) {
3769 if (!pendingWord.isEmpty()) {
3770 bool isProbablyType = (pendingWord != QLatin1String(
"const"));
3771 if (generateType && isProbablyType) {
3773 m_writer->writeCharacters(result);
3777 const Node *n = m_qdb->findTypeNode(pendingWord, relative, Genus::DontCare);
3782 href = linkForNode(n, relative);
3785 m_writer->writeStartElement(dbNamespace,
"type");
3787 m_writer->writeCharacters(pendingWord);
3789 generateSimpleLink(href, pendingWord);
3790 m_writer->writeEndElement();
3792 result += pendingWord;
3795 pendingWord.clear();
3797 if (ch.unicode() !=
'\0')
3802 if (trailingSpace && string.size()) {
3803 if (!string.endsWith(QLatin1Char(
'*')) && !string.endsWith(QLatin1Char(
'&')))
3804 result += QLatin1Char(
' ');
3807 m_writer->writeCharacters(result);
3811 bool generateNameLink)
3815 QString name = taggedNode(node);
3817 if (!generateNameLink) {
3818 m_writer->writeCharacters(name);
3822 m_writer->writeStartElement(dbNamespace,
"emphasis");
3823 m_writer->writeAttribute(
"role",
"bold");
3824 generateSimpleLink(linkForNode(node, relative), name);
3825 m_writer->writeEndElement();
3829 bool generateExtra,
bool generateType)
3831 const QString &pname = parameter.name();
3832 const QString &ptype = parameter.type();
3834 if (!pname.isEmpty()) {
3835 typified(ptype, relative,
true, generateType);
3841 if (generateExtra || pname.isEmpty()) {
3842 m_writer->writeStartElement(dbNamespace,
"emphasis");
3843 m_writer->writeCharacters(paramName);
3844 m_writer->writeEndElement();
3847 const QString &pvalue = parameter.defaultValue();
3848 if (generateExtra && !pvalue.isEmpty())
3849 m_writer->writeCharacters(
" = " + pvalue);
3861 const int MaxEnumValues = 6;
3863 if (generateExtra) {
3864 if (
auto extra = CodeMarker::extraSynopsis(node, style); !extra.isEmpty()) {
3865 generateExtraSynopsis(extra);
3866 m_writer->writeCharacters(u" "_s);
3871 QString namePrefix {};
3875 namePrefix = taggedNode(node->parent()) +
"::";
3880 case NodeType::Namespace:
3881 m_writer->writeCharacters(
"namespace ");
3882 m_writer->writeCharacters(namePrefix);
3883 generateSynopsisName(node, relative, generateNameLink);
3885 case NodeType::Class:
3886 m_writer->writeCharacters(
"class ");
3887 m_writer->writeCharacters(namePrefix);
3888 generateSynopsisName(node, relative, generateNameLink);
3894 if (
auto templateDecl = func->templateDecl()) {
3895 if (templateDecl->parameters.size() > QDoc::MultilineTemplateParamThreshold)
3896 m_writer->writeCharacters(templateDecl->to_qstring_multiline() + QLatin1Char(
'\n'));
3898 m_writer->writeCharacters(templateDecl->to_qstring() + QLatin1Char(
' '));
3904 if (!func->isNonvirtual())
3905 m_writer->writeCharacters(QStringLiteral(
"virtual "));
3909 if (style != Section::AllMembers && !func->returnType().isEmpty())
3910 typified(func->returnTypeString(), relative,
true, generateType);
3911 m_writer->writeCharacters(namePrefix);
3912 generateSynopsisName(node, relative, generateNameLink);
3915 m_writer->writeCharacters(QStringLiteral(
"("));
3918 for (
int i = 0; i < parameters
.count(); i++) {
3920 m_writer->writeCharacters(QStringLiteral(
", "));
3921 generateParameter(parameters
.at(i
), relative, generateExtra, generateType);
3924 m_writer->writeCharacters(QStringLiteral(
")"));
3927 if (func->isConst())
3928 m_writer->writeCharacters(QStringLiteral(
" const"));
3934 synopsis += QStringLiteral(
" final");
3936 synopsis += QStringLiteral(
" override");
3938 synopsis += QStringLiteral(
" = 0");
3940 synopsis += QStringLiteral(
" &");
3942 synopsis += QStringLiteral(
" &&");
3943 m_writer->writeCharacters(synopsis);
3945 if (!func->returnType().isEmpty() && func->returnType() !=
"void") {
3946 m_writer->writeCharacters(QStringLiteral(
" : "));
3947 typified(func->returnTypeString(), relative,
false, generateType);
3952 synopsis += QStringLiteral(
" &");
3954 synopsis += QStringLiteral(
" &&");
3955 if (
const auto &req = func->trailingRequiresClause(); req && !req->isEmpty())
3956 synopsis +=
" requires " + *req;
3957 m_writer->writeCharacters(synopsis);
3961 const auto enume =
static_cast<
const EnumNode *>(node);
3962 if (!enume->isAnonymous()) {
3963 m_writer->writeCharacters(
"enum "_L1);
3964 m_writer->writeCharacters(namePrefix);
3965 generateSynopsisName(node, relative, generateNameLink);
3966 }
else if (generateNameLink) {
3967 m_writer->writeStartElement(dbNamespace,
"emphasis");
3968 m_writer->writeAttribute(
"role",
"bold");
3969 generateSimpleLink(linkForNode(node, relative),
"enum");
3970 m_writer->writeEndElement();
3972 m_writer->writeCharacters(
"enum"_L1);
3979 QStringList documentedItems = enume->doc().enumItemNames();
3980 if (documentedItems.isEmpty()) {
3981 const auto &enumItems = enume->items();
3982 for (
const auto &item : enumItems)
3983 documentedItems << item.name();
3985 const QStringList omitItems = enume->doc().omitEnumItemNames();
3986 for (
const auto &item : omitItems)
3987 documentedItems.removeAll(item);
3989 if (documentedItems.size() > MaxEnumValues) {
3991 const QString last = documentedItems.last();
3992 documentedItems = documentedItems.mid(0, MaxEnumValues - 1);
3993 documentedItems +=
"…";
3994 documentedItems += last;
3996 synopsis += documentedItems.join(QLatin1String(
", "));
3998 if (!documentedItems.isEmpty())
3999 synopsis += QLatin1Char(
' ');
4000 synopsis += QLatin1Char(
'}');
4002 m_writer->writeCharacters(synopsis);
4006 if (
auto templateDecl = node->templateDecl()) {
4007 if (templateDecl->parameters.size() > QDoc::MultilineTemplateParamThreshold)
4008 m_writer->writeCharacters(templateDecl->to_qstring_multiline() + QLatin1Char(
'\n'));
4010 m_writer->writeCharacters(templateDecl->to_qstring() + QLatin1Char(
' '));
4013 m_writer->writeCharacters(namePrefix);
4014 generateSynopsisName(node, relative, generateNameLink);
4017 if (
static_cast<
const TypedefNode *>(node)->associatedEnum())
4018 m_writer->writeCharacters(
"flags ");
4019 m_writer->writeCharacters(namePrefix);
4020 generateSynopsisName(node, relative, generateNameLink);
4023 const auto property =
static_cast<
const PropertyNode *>(node);
4024 m_writer->writeCharacters(namePrefix);
4025 generateSynopsisName(node, relative, generateNameLink);
4026 m_writer->writeCharacters(
" : ");
4027 typified(property->qualifiedDataType(), relative,
false, generateType);
4030 const auto variable =
static_cast<
const VariableNode *>(node);
4032 generateSynopsisName(node, relative, generateNameLink);
4033 m_writer->writeCharacters(
" : ");
4034 typified(variable->dataType(), relative,
false, generateType);
4036 typified(variable->leftType(), relative,
false, generateType);
4037 m_writer->writeCharacters(
" ");
4038 m_writer->writeCharacters(namePrefix);
4039 generateSynopsisName(node, relative, generateNameLink);
4040 m_writer->writeCharacters(variable->rightType());
4044 m_writer->writeCharacters(namePrefix);
4045 generateSynopsisName(node, relative, generateNameLink);
4060 if (nativeEnum && nativeEnum
->enumNode() && !enumValue.startsWith(
"%1."_L1.arg(nativeEnum->prefix()))) {
4061 m_writer->writeCharacters(
"%1.%2"_L1.arg(nativeEnum->prefix(), enumValue));
4067 && enumValue.section(
' ', 0, 0).contains(
'.'_L1))) {
4068 m_writer->writeCharacters(enumValue);
4072 QList<
const Node *> parents;
4074 parents.prepend(node);
4079 if (
static_cast<
const EnumNode *>(relative)->isScoped())
4080 parents << relative;
4082 m_writer->writeStartElement(dbNamespace,
"code");
4083 for (
auto parent : parents) {
4084 generateSynopsisName(parent, relative,
true);
4085 m_writer->writeCharacters((relative->genus() == Genus::QML) ?
"."_L1 :
"::"_L1);
4088 m_writer->writeCharacters(enumValue);
4089 m_writer->writeEndElement();
4093
4094
4095
4100 Q_ASSERT(node && !node->name().isEmpty());
4106 m_writer->writeStartElement(dbNamespace,
"note");
4113 m_writer->writeStartElement(dbNamespace,
"para");
4114 m_writer->writeCharacters(
4115 "This function can be invoked via the meta-object system and from QML. See ");
4116 generateSimpleLink(node->url(),
"Q_INVOKABLE");
4117 m_writer->writeCharacters(
".");
4118 m_writer->writeEndElement();
4122 m_writer->writeTextElement(
4123 dbNamespace,
"para",
4124 "This is a private signal. It can be used in signal connections but "
4125 "cannot be emitted by the user.");
4129 QString handler(node->name());
4130 int prefixLocation = handler.lastIndexOf(
'.', -2) + 1;
4131 handler[prefixLocation] = handler[prefixLocation].toTitleCase();
4132 handler.insert(prefixLocation, QLatin1String(
"on"));
4133 m_writer->writeStartElement(dbNamespace,
"para");
4134 m_writer->writeCharacters(
"The corresponding handler is ");
4135 m_writer->writeTextElement(dbNamespace,
"code", handler);
4136 m_writer->writeCharacters(
".");
4137 m_writer->writeEndElement();
4145 const auto *fn =
static_cast<
const FunctionNode *>(node);
4146 auto nodes = fn->associatedProperties();
4147 if (nodes.isEmpty())
4152 QMap<PropertyNode::FunctionRole, QList<
const PropertyNode *>> roleGroups;
4153 for (
const auto *n : std::as_const(nodes)) {
4154 const auto *pn =
static_cast<
const PropertyNode *>(n);
4155 PropertyNode::FunctionRole role = pn->role(fn);
4156 roleGroups[role].append(pn);
4168 for (
auto role : roleOrder) {
4169 const auto it = roleGroups.constFind(role);
4170 if (it == roleGroups.cend())
4173 const auto &properties = it.value();
4178 msg = QStringLiteral(
"Getter function");
4181 msg = QStringLiteral(
"Setter function");
4184 msg = QStringLiteral(
"Resetter function");
4187 msg = QStringLiteral(
"Notifier signal");
4190 msg = QStringLiteral(
"Bindable function");
4196 m_writer->writeStartElement(dbNamespace,
"para");
4197 if (properties.size() == 1) {
4198 const auto *pn = properties.first();
4199 m_writer->writeCharacters(msg +
" for property ");
4200 generateSimpleLink(linkForNode(pn,
nullptr), pn->name());
4201 m_writer->writeCharacters(
". ");
4203 m_writer->writeCharacters(msg +
" for properties ");
4204 for (qsizetype i = 0; i < properties.size(); ++i) {
4205 const auto *pn = properties.at(i);
4206 generateSimpleLink(linkForNode(pn,
nullptr), pn->name());
4207 m_writer->writeCharacters(Utilities::separator(i, properties.size()));
4209 m_writer->writeCharacters(
" ");
4211 m_writer->writeEndElement();
4218 const Node *linkNode;
4220 QString link = getAutoLink(&linkAtom, node, &linkNode);
4221 m_writer->writeStartElement(dbNamespace,
"para");
4222 m_writer->writeCharacters(
"This property supports ");
4223 generateSimpleLink(link,
"QProperty");
4224 m_writer->writeCharacters(
" bindings.");
4225 m_writer->writeEndElement();
4230 const auto *func =
static_cast<
const FunctionNode *>(node);
4233 if (func->isPrimaryOverload())
4236 m_writer->writeStartElement(dbNamespace,
"para");
4238 if (func->isSignal() || func->isSlot()) {
4239 auto writeDocBookLink = [&](
const QString &target,
const QString &label) {
4240 const Node *linkNode =
nullptr;
4242 const QString &link = getAutoLink(&linkAtom, node, &linkNode);
4244 m_writer->writeStartElement(dbNamespace,
"link");
4245 if (!link.isEmpty() && linkNode) {
4246 m_writer->writeAttribute(xlinkNamespace,
"href", link);
4248 m_writer->writeAttribute(dbNamespace,
"linkend", target);
4250 m_writer->writeCharacters(label);
4251 m_writer->writeEndElement();
4254 const QString &functionType = func->isSignal() ?
"signal" :
"slot";
4255 const QString &configKey = func->isSignal() ?
"overloadedsignalstarget" :
"overloadedslotstarget";
4256 const QString &defaultTarget = func->isSignal() ?
"connecting-overloaded-signals" :
"connecting-overloaded-slots";
4257 const QString &linkTarget = Config::instance().get(configKey).asString(defaultTarget);
4259 m_writer->writeCharacters(
"This " + functionType +
" is overloaded. ");
4261 QString snippet = generateOverloadSnippet(func);
4262 if (!snippet.isEmpty()) {
4263 m_writer->writeCharacters(
"To connect to this " + functionType +
":");
4264 m_writer->writeEndElement();
4266 m_writer->writeStartElement(dbNamespace,
"programlisting");
4267 m_writer->writeCharacters(snippet);
4268 m_writer->writeEndElement();
4273 m_writer->writeStartElement(dbNamespace,
"para");
4274 if (!linkTarget.isEmpty()) {
4275 m_writer->writeCharacters(
"For more examples and approaches, see ");
4276 writeDocBookLink(linkTarget,
"connecting to overloaded " + functionType +
"s");
4277 m_writer->writeCharacters(
".");
4279 }
else if (!linkTarget.isEmpty()) {
4280 m_writer->writeCharacters(
"For more examples and approaches, see ");
4281 writeDocBookLink(linkTarget,
"connecting to overloaded " + functionType +
"s");
4282 m_writer->writeCharacters(
".");
4286 const auto &args = node
->doc().overloadList();
4287 if (args.first().first.isEmpty()) {
4288 m_writer->writeCharacters(
"This is an overloaded function.");
4290 QString target = args.first().first;
4293 if (!target.contains(
"::")) {
4296 target = parent->name() +
"::" + target;
4299 m_writer->writeCharacters(
"This function overloads ");
4301 const Node *linkNode =
nullptr;
4303 QString link = getAutoLink(&linkAtom, node, &linkNode);
4304 if (!link.isEmpty() && linkNode)
4305 generateSimpleLink(link, target);
4307 m_writer->writeCharacters(target);
4308 m_writer->writeCharacters(
".");
4312 m_writer->writeEndElement();
4321 m_writer->writeEndElement();
4329 bool closeSupplementarySection =
false;
4333 const QList<Node *> &collective = scn->collective();
4335 bool firstFunction =
true;
4336 for (
const auto *sharedNode : collective) {
4337 if (firstFunction) {
4338 startSectionBegin(sharedNode);
4340 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4341 m_writer->writeAttribute(
"renderas",
"sect2");
4342 writeXmlId(sharedNode);
4345 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4347 generateSynopsis(sharedNode, relative, Section::Details);
4349 if (firstFunction) {
4351 firstFunction =
false;
4353 m_writer->writeEndElement();
4359 if (node->isEnumType(Genus::CPP) && (etn =
static_cast<
const EnumNode *>(node))->flagsType()) {
4360 startSectionBegin(node);
4362 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4366 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4367 m_writer->writeAttribute(
"renderas",
"sect2");
4369 m_writer->writeEndElement();
4372 startSectionBegin(node);
4374 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4379 Q_ASSERT(m_hasSection);
4388 closeSupplementarySection =
true;
4389 startSection(
"",
"Notes");
4393 const auto *func =
static_cast<
const FunctionNode *>(node);
4394 if (func->hasOverloads() && (func->isSignal() || func->isSlot()))
4402 const auto property =
static_cast<
const PropertyNode *>(node);
4411 m_writer->writeStartElement(dbNamespace,
"para");
4413 m_writer->writeStartElement(dbNamespace,
"emphasis");
4414 m_writer->writeAttribute(
"role",
"bold");
4415 m_writer->writeCharacters(
"Access functions:");
4417 m_writer->writeEndElement();
4419 m_writer->writeEndElement();
4421 generateSectionList(section, node);
4428 m_writer->writeStartElement(dbNamespace,
"para");
4430 m_writer->writeStartElement(dbNamespace,
"emphasis");
4431 m_writer->writeAttribute(
"role",
"bold");
4432 m_writer->writeCharacters(
"Notifier signal:");
4434 m_writer->writeEndElement();
4436 m_writer->writeEndElement();
4438 generateSectionList(notifiers, node);
4442 const auto en =
static_cast<
const EnumNode *>(node);
4444 if (m_qflagsHref.isEmpty()) {
4445 Node *qflags = m_qdb->findClassNode(QStringList(
"QFlags"));
4447 m_qflagsHref = linkForNode(qflags,
nullptr);
4450 if (en->flagsType()) {
4451 m_writer->writeStartElement(dbNamespace,
"para");
4452 m_writer->writeCharacters(
"The ");
4453 m_writer->writeStartElement(dbNamespace,
"code");
4454 m_writer->writeCharacters(en->flagsType()->name());
4455 m_writer->writeEndElement();
4456 m_writer->writeCharacters(
" type is a typedef for ");
4457 m_writer->writeStartElement(dbNamespace,
"code");
4458 generateSimpleLink(m_qflagsHref,
"QFlags");
4459 m_writer->writeCharacters(
"<" + en->name() +
">. ");
4460 m_writer->writeEndElement();
4461 m_writer->writeCharacters(
"It stores an OR combination of ");
4462 m_writer->writeStartElement(dbNamespace,
"code");
4463 m_writer->writeCharacters(en->name());
4464 m_writer->writeEndElement();
4465 m_writer->writeCharacters(
" values.");
4466 m_writer->writeEndElement();
4471 if (closeSupplementarySection)
4482 bool useObsoleteMembers)
4487 if (!members.isEmpty()) {
4488 bool hasPrivateSignals =
false;
4489 bool isInvokable =
false;
4491 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
4493 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4496 NodeVector::ConstIterator m = members.constBegin();
4497 while (m != members.constEnd()) {
4503 m_writer->writeStartElement(dbNamespace,
"listitem");
4505 m_writer->writeStartElement(dbNamespace,
"para");
4508 generateSynopsis(*m, relative, section
.style());
4509 if ((*m)->isFunction()) {
4511 if (fn->isPrivateSignal())
4512 hasPrivateSignals =
true;
4513 else if (fn->isInvokable())
4517 m_writer->writeEndElement();
4519 m_writer->writeEndElement();
4525 m_writer->writeEndElement();
4528 if (hasPrivateSignals)
4535 && !section.inheritedMembers().isEmpty()) {
4536 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
4538 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4541 generateSectionInheritedList(section, relative);
4543 m_writer->writeEndElement();
4551 QList<std::pair<Aggregate *,
int>>::ConstIterator p = section.inheritedMembers().constBegin();
4552 while (p != section.inheritedMembers().constEnd()) {
4553 m_writer->writeStartElement(dbNamespace,
"listitem");
4554 m_writer->writeCharacters(QString::number((*p).second) + u' ');
4555 if ((*p).second == 1)
4556 m_writer->writeCharacters(section.singular());
4558 m_writer->writeCharacters(section.plural());
4559 m_writer->writeCharacters(
" inherited from ");
4560 generateSimpleLink(fileName((*p).first) +
'#'
4561 + Generator::cleanRef(section.title().toLower()),
4562 (*p).first->plainFullName(relative));
4568
4569
4570
4574 Q_ASSERT(m_writer ==
nullptr);
4575 m_writer = startDocument(pn);
4577 generateHeader(pn->doc().title(), pn->subtitle(), pn);
4586
4587
4592 Q_ASSERT(m_writer ==
nullptr);
4593 m_writer = startDocument(qcn);
4596 QString title = qcn->name();
4598 title.append(
" QML Value Type");
4600 title.append(
" QML Type");
4603 title.append(
" (Singleton)");
4609 generateHeader(title, qcn->subtitle(), qcn);
4614 m_writer->writeStartElement(dbNamespace,
"note");
4615 m_writer->writeStartElement(dbNamespace,
"para");
4616 m_writer->writeStartElement(dbNamespace,
"emphasis");
4617 m_writer->writeAttribute(
"role",
"bold");
4618 m_writer->writeCharacters(
"Note: ");
4619 m_writer->writeEndElement();
4620 m_writer->writeCharacters(
"This type is a QML singleton. "
4621 "There is only one instance of this type in the QML engine.");
4622 m_writer->writeEndElement();
4623 m_writer->writeEndElement();
4626 startSection(
"details",
"Detailed Description");
4634 for (
const auto §ion : sections.stdQmlTypeDetailsSections()) {
4635 if (!section.isEmpty()) {
4636 startSection(section.title().toLower(), section.title());
4638 for (
const auto &member : section.members())
4639 generateDetailedQmlMember(member, qcn);
4645 generateObsoleteQmlMembers(sections);
4654
4655
4656
4663 if (!title.isEmpty())
4667 title += n->element() + QLatin1Char(
'.');
4668 title += n->name() +
" : " + n->dataType();
4673 auto generateQmlMethodTitle = [&](
Node *node) {
4678 const auto *scn =
static_cast<
const SharedCommentNode *>(node);
4681 if (!scn->name().isEmpty())
4682 heading = scn->name() +
" group";
4684 heading = node->name();
4685 startSection(scn, heading);
4690 const QList<Node *> sharedNodes = scn->collective();
4691 for (
const auto &sharedNode : sharedNodes) {
4692 if (sharedNode->isQmlProperty()) {
4693 auto *qpn =
static_cast<QmlPropertyNode *>(sharedNode);
4695 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4696 m_writer->writeAttribute(
"renderas",
"sect2");
4698 m_writer->writeCharacters(getQmlPropertyTitle(qpn));
4699 m_writer->writeEndElement();
4702 generateDocBookSynopsis(qpn);
4706 auto qpn =
static_cast<QmlPropertyNode *>(node);
4707 startSection(qpn, getQmlPropertyTitle(qpn));
4711 const QList<Node *> &sharedNodes = scn->collective();
4716 for (
const auto &sharedNode : sharedNodes) {
4718 if (!sharedNode->isFunction(Genus::QML) && !sharedNode->isQmlProperty()) {
4724 startSectionBegin(sharedNode);
4726 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4727 m_writer->writeAttribute(
"renderas",
"sect2");
4731 if (sharedNode->isFunction(Genus::QML))
4732 generateQmlMethodTitle(sharedNode);
4733 else if (sharedNode->isQmlProperty())
4734 m_writer->writeCharacters(
4735 getQmlPropertyTitle(
static_cast<QmlPropertyNode *>(sharedNode)));
4741 m_writer->writeEndElement();
4742 generateDocBookSynopsis(sharedNode);
4748 startSectionBegin(refForNode(node));
4751 generateQmlMethodTitle(node);
4752 else if (node->isQmlProperty())
4753 m_writer->writeCharacters(
4754 getQmlPropertyTitle(
static_cast<QmlPropertyNode *>(node)));
4759 startSectionBegin(node);
4763 startSectionBegin(node);
4764 generateQmlMethodTitle(node);
4778
4779
4786 if (!node->url().isNull())
4790 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818 auto cn =
static_cast<CollectionNode *>(node);
4819 if (cn->wasSeen()) {
4820 m_qdb->mergeCollections(cn);
4821 generateCollectionNode(cn);
4822 }
else if (cn->isGenericCollection()) {
4826 generateGenericCollectionPage(cn);
4829 generatePageNode(
static_cast<PageNode *>(node));
4833 generateCppReferencePage(
static_cast<Aggregate *>(node));
4835 generateQmlTypePage(
static_cast<QmlTypeNode *>(node));
4837 generateProxyPage(
static_cast<Aggregate *>(node));
4843 auto *aggregate =
static_cast<Aggregate *>(node);
4844 for (
auto c : aggregate->childNodes()) {
4845 if (node->isPageNode())
4846 generateDocumentation(c);
4857 Q_ASSERT(m_writer ==
nullptr);
4858 m_writer = startDocument(aggregate);
4861 generateHeader(aggregate->plainFullName(),
"", aggregate);
4866 if (!aggregate
->doc().isEmpty()) {
4867 startSection(
"details",
"Detailed Description");
4869 generateBody(aggregate);
4878 for (
const auto §ion : std::as_const(*detailsSections)) {
4879 if (section.isEmpty())
4882 startSection(section.title().toLower(), section.title());
4884 const QList<Node *> &members = section.members();
4885 for (
const auto &member : members) {
4886 if (!member->isClassNode()) {
4887 generateDetailedMember(member, aggregate);
4889 startSectionBegin();
4890 generateFullName(member, aggregate);
4893 generateBrief(member);
4907
4908
4913 Q_ASSERT(m_writer ==
nullptr);
4914 m_writer = startDocument(cn);
4917 generateHeader(cn->doc().title(), cn->subtitle(), cn);
4923 if (cn
->genus() != Genus::DOC && cn
->genus() != Genus::DontCare) {
4934 if (!nmm.isEmpty()) {
4935 startSection(
"namespaces",
"Namespaces");
4936 generateAnnotatedList(cn, nmm.values(),
"namespaces");
4940 if (!nmm.isEmpty()) {
4941 startSection(
"classes",
"Classes");
4942 generateAnnotatedList(cn, nmm.values(),
"classes");
4948 bool generatedTitle =
false;
4950 startSection(
"details",
"Detailed Description");
4951 generatedTitle =
true;
4956 !cn
->doc().body().isEmpty() ||
4958 !cn
->doc().alsoList().empty() ||
4961 writeAnchor(
"details");
4967 if (!cn->noAutoList() && (cn->isGroup() || cn->isQmlModule()))
4968 generateAnnotatedList(cn, cn->members(),
"members", AutoSection);
4979
4980
4981
4982
4987 QString name = cn->name().toLower();
4988 name.replace(QChar(
' '), QString(
"-"));
4989 QString filename = cn->tree()->physicalModuleName() +
"-" + name +
"." + fileExtension();
4992 Q_ASSERT(m_writer ==
nullptr);
4993 m_writer = startGenericDocument(cn, filename);
4996 generateHeader(cn->fullTitle(), cn->subtitle(), cn);
5002 m_writer->writeStartElement(dbNamespace,
"para");
5003 m_writer->writeCharacters(
"Each function or type documented here is related to a class or "
5004 "namespace that is documented in a different module. The reference "
5005 "page for that class or namespace will link to the function or type "
5007 m_writer->writeEndElement();
5011 for (
const auto &member : members)
5012 generateDetailedMember(member, cnc);
5025 m_writer->writeStartElement(dbNamespace,
"link");
5026 m_writer->writeAttribute(xlinkNamespace,
"href", fullDocumentLocation(node));
5027 m_writer->writeAttribute(xlinkNamespace,
"role", targetType(node));
5028 m_writer->writeCharacters(node->fullName(relative));
5029 m_writer->writeEndElement();
5033 const Node *actualNode)
5035 Q_ASSERT(apparentNode);
5036 Q_ASSERT(actualNode);
5039 m_writer->writeStartElement(dbNamespace,
"link");
5040 m_writer->writeAttribute(xlinkNamespace,
"href", fullDocumentLocation(actualNode));
5041 m_writer->writeAttribute(
"role", targetType(actualNode));
5042 m_writer->writeCharacters(fullName);
5043 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)
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() 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 vectors of sections based on the type of the aggregate node.
SectionVector & stdDetailsSections()
SectionVector & stdCppClassDetailsSections()
bool hasObsoleteMembers(SectionPtrVector *summary_spv, SectionPtrVector *details_spv) const
Returns true if any sections in this object contain obsolete members.
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.