33#include <QtCore/qlist.h>
34#include <QtCore/qmap.h>
35#include <QtCore/quuid.h>
36#include <QtCore/qurl.h>
37#include <QtCore/qregularexpression.h>
38#include <QtCore/qversionnumber.h>
44using namespace Qt::StringLiterals;
46static const char dbNamespace[] =
"http://docbook.org/ns/docbook";
54 m_writer->writeCharacters(
"\n");
62 m_writer->writeAttribute(
"xml:id", registerRef(id,
true));
75 QString id = Generator::cleanRef(refForNode(node),
true);
77 m_writer->writeAttribute(
"xml:id", id);
84 m_writer->writeStartElement(dbNamespace,
"section");
87 m_writer->writeStartElement(dbNamespace,
"title");
92 m_writer->writeStartElement(dbNamespace,
"section");
95 m_writer->writeStartElement(dbNamespace,
"title");
100 m_writer->writeEndElement();
106 startSectionBegin(id);
107 m_writer->writeCharacters(title);
113 startSectionBegin(node);
114 m_writer->writeCharacters(title);
121 startSection(
"", title);
126 m_writer->writeEndElement();
135 m_writer->writeEmptyElement(dbNamespace,
"anchor");
141
142
143
148 m_config = &Config::instance();
154 if (m_projectDescription.isEmpty() && !m_project.isEmpty())
155 m_projectDescription = m_project + QLatin1String(
" Reference Documentation");
158 if (m_naturalLanguage.isEmpty())
159 m_naturalLanguage = QLatin1String(
"en");
163 m_config->get(format() + Config::dot +
"usedocbookextensions").asBool();
164 m_useITS = m_config->get(format() + Config::dot +
"its").asBool();
173
174
181
182
183
184
199 QString rewritten = code;
200 static const QRegularExpression re(
"(<@[^>&]*>)|(<\\/@[^&>]*>)");
201 rewritten.replace(re,
"");
206
207
213 qsizetype skipAhead = 0;
214 Genus genus = Genus::DontCare;
222 if (!m_inLink && !m_inContents && !m_inSectionHeading) {
223 const Node *node =
nullptr;
224 QString link = getAutoLink(atom, relative, &node, genus);
229 if (link.isEmpty()) {
230 m_writer->writeCharacters(atom->string());
232 beginLink(link, node, relative);
237 m_writer->writeCharacters(atom->string());
247 m_writer->writeStartElement(dbNamespace,
"para");
253 m_writer->writeEndElement();
263 m_writer->writeCharacters(plainCode(atom->string()));
265 m_writer->writeTextElement(dbNamespace,
"code", plainCode(atom->string()));
267 case Atom::CaptionLeft:
268 m_writer->writeStartElement(dbNamespace,
"title");
272 m_writer->writeEndElement();
276 m_writer->writeStartElement(dbNamespace,
"programlisting");
277 m_writer->writeAttribute(
"language",
"qml");
279 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
280 m_writer->writeCharacters(plainCode(removeCodeMarkers(atom->string())));
281 m_writer->writeEndElement();
285 m_writer->writeStartElement(dbNamespace,
"programlisting");
287 if (atom->strings().count() == 2)
288 m_writer->writeAttribute(
"language", atom->string(1));
290 m_writer->writeAttribute(
"language",
"cpp");
292 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
293 m_writer->writeCharacters(plainCode(removeCodeMarkers(atom->string())));
294 m_writer->writeEndElement();
298 m_writer->writeStartElement(dbNamespace,
"programlisting");
299 m_writer->writeAttribute(
"language",
"cpp");
300 m_writer->writeAttribute(
"role",
"bad");
302 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
303 m_writer->writeCharacters(plainCode(removeCodeMarkers(atom->string())));
304 m_writer->writeEndElement();
311 qsizetype offset{ 0 };
320 case Atom::FootnoteLeft:
321 m_writer->writeStartElement(dbNamespace,
"footnote");
323 m_writer->writeStartElement(dbNamespace,
"para");
326 case Atom::FootnoteRight:
327 m_writer->writeEndElement();
330 m_writer->writeEndElement();
338 m_writer->writeStartElement(dbNamespace,
"emphasis");
339 m_writer->writeAttribute(
"role",
"bold");
341 m_writer->writeStartElement(dbNamespace,
"emphasis");
343 m_writer->writeStartElement(dbNamespace,
"emphasis");
344 m_writer->writeAttribute(
"role",
"underline");
346 m_writer->writeStartElement(dbNamespace,
"subscript");
348 m_writer->writeStartElement(dbNamespace,
"superscript");
351 m_writer->writeStartElement(dbNamespace,
"code");
353 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
356 m_writer->writeAttribute(
"role",
"parameter");
360 m_writer->writeStartElement(dbNamespace,
"guilabel");
362 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
364 m_writer->writeStartElement(dbNamespace,
365 appendTrademark(atom->find(Atom::FormattingRight)) ?
366 "trademark" :
"phrase");
368 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
370 m_writer->writeStartElement(dbNamespace,
"phrase");
372 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
374 relative
->location().warning(QStringLiteral(
"Unsupported formatting: %1").arg(atom->string()));
387 m_writer->writeEndElement();
390 m_inTeletype =
false;
393 relative
->location().warning(QStringLiteral(
"Unsupported formatting: %1").arg(atom->string()));
397 if (
const CollectionNode *cn = m_qdb->getCollectionNode(atom->string(), NodeType::Group))
398 generateList(cn, atom->string(), Generator::sortOrder(atom->strings().last()));
401 const auto sortOrder{Generator::sortOrder(atom->strings().last())};
402 bool hasGeneratedSomething =
false;
403 if (atom->string() == QLatin1String(
"annotatedclasses")
404 || atom->string() == QLatin1String(
"attributions")
405 || atom->string() == QLatin1String(
"namespaces")) {
406 const NodeMultiMap things = atom->string() == QLatin1String(
"annotatedclasses")
407 ? m_qdb->getCppClasses()
408 : atom->string() == QLatin1String(
"attributions") ? m_qdb->getAttributions()
409 : m_qdb->getNamespaces();
410 generateAnnotatedList(relative, things.values(), atom->string(), Auto, sortOrder);
411 hasGeneratedSomething = !things.isEmpty();
412 }
else if (atom->string() == QLatin1String(
"annotatedexamples")
413 || atom->string() == QLatin1String(
"annotatedattributions")) {
414 const NodeMultiMap things = atom->string() == QLatin1String(
"annotatedexamples")
415 ? m_qdb->getAttributions()
416 : m_qdb->getExamples();
417 generateAnnotatedLists(relative, things, atom->string());
418 hasGeneratedSomething = !things.isEmpty();
419 }
else if (atom->string() == QLatin1String(
"classes")
420 || atom->string() == QLatin1String(
"qmlbasictypes")
421 || atom->string() == QLatin1String(
"qmlvaluetypes")
422 || atom->string() == QLatin1String(
"qmltypes")) {
423 const NodeMultiMap things = atom->string() == QLatin1String(
"classes")
424 ? m_qdb->getCppClasses()
425 : (atom->string() == QLatin1String(
"qmlvaluetypes")
426 || atom->string() == QLatin1String(
"qmlbasictypes"))
427 ? m_qdb->getQmlValueTypes()
428 : m_qdb->getQmlTypes();
429 generateCompactList(relative, things,
true, QString(), atom->string());
430 hasGeneratedSomething = !things.isEmpty();
431 }
else if (atom->string().contains(
"classes ")) {
432 QString rootName = atom->string().mid(atom->string().indexOf(
"classes") + 7).trimmed();
435 hasGeneratedSomething = !things.isEmpty();
436 generateCompactList(relative, things,
true, rootName, atom->string());
437 }
else if ((idx = atom->string().indexOf(QStringLiteral(
"bymodule"))) != -1) {
438 QString moduleName = atom->string().mid(idx + 8).trimmed();
441 if (
const CollectionNode *cn = qdb->getCollectionNode(moduleName, moduleType)) {
443 switch (moduleType) {
449 if (atom->string().contains(QLatin1String(
"qmlvaluetypes")))
455 generateAnnotatedList(relative, cn->members(), atom->string(), Auto, sortOrder);
459 if (!map.isEmpty()) {
460 generateAnnotatedList(relative, map.values(), atom->string(), Auto, sortOrder);
461 hasGeneratedSomething =
true;
464 }
else if (atom->string() == QLatin1String(
"classhierarchy")) {
465 generateClassHierarchy(relative, m_qdb->getCppClasses());
466 hasGeneratedSomething = !m_qdb->getCppClasses().isEmpty();
467 }
else if (atom->string().startsWith(
"obsolete")) {
468 QString prefix = atom->string().contains(
"cpp") ? QStringLiteral(
"Q") : QString();
469 const NodeMultiMap &things = atom->string() == QLatin1String(
"obsoleteclasses")
470 ? m_qdb->getObsoleteClasses()
471 : atom->string() == QLatin1String(
"obsoleteqmltypes")
472 ? m_qdb->getObsoleteQmlTypes()
473 : atom->string() == QLatin1String(
"obsoletecppmembers")
474 ? m_qdb->getClassesWithObsoleteMembers()
475 : m_qdb->getQmlTypesWithObsoleteMembers();
476 generateCompactList(relative, things,
false, prefix, atom->string());
477 hasGeneratedSomething = !things.isEmpty();
478 }
else if (atom->string() == QLatin1String(
"functionindex")) {
479 generateFunctionIndex(relative);
480 hasGeneratedSomething = !m_qdb->getFunctionIndex().isEmpty();
481 }
else if (atom->string() == QLatin1String(
"legalese")) {
482 generateLegaleseList(relative);
483 hasGeneratedSomething = !m_qdb->getLegaleseTexts().isEmpty();
484 }
else if (atom->string() == QLatin1String(
"overviews")
485 || atom->string() == QLatin1String(
"cpp-modules")
486 || atom->string() == QLatin1String(
"qml-modules")
487 || atom->string() == QLatin1String(
"related")) {
488 generateList(relative, atom->string());
489 hasGeneratedSomething =
true;
491 }
else if (
const auto *cn = m_qdb->getCollectionNode(atom->string(), NodeType::Group); cn) {
492 generateAnnotatedList(cn, cn->members(), atom->string(), ItemizedList, sortOrder);
493 hasGeneratedSomething =
true;
498 if (!hasGeneratedSomething && !m_inPara) {
499 m_writer->writeEmptyElement(dbNamespace,
"para");
531 m_writer->writeStartElement(dbNamespace,
"figure");
538 generateAtom(current, relative,
nullptr);
543 generateAtom(current, relative,
nullptr);
549 generateAtom(current, relative,
nullptr);
553 m_closeFigureWrapper =
true;
564 m_writer->writeStartElement(dbNamespace,
"figure");
571 generateAtom(current, relative,
nullptr);
576 generateAtom(current, relative,
nullptr);
582 generateAtom(current, relative,
nullptr);
586 m_closeFigureWrapper =
true;
609 m_writer->writeStartElement(dbNamespace, tag);
612 auto maybe_resolved_file{file_resolver.resolve(atom->string())};
613 if (!maybe_resolved_file) {
615 relative
->location().warning(QStringLiteral(
"Missing image: %1").arg(atom->string()));
617 m_writer->writeStartElement(dbNamespace,
"textobject");
619 m_writer->writeStartElement(dbNamespace,
"para");
620 m_writer->writeTextElement(dbNamespace,
"emphasis",
621 "[Missing image " + atom->string() +
"]");
622 m_writer->writeEndElement();
624 m_writer->writeEndElement();
628 QString file_name{QFileInfo{file.get_path()}.fileName()};
632 "%1/%2"_L1.arg(outputDir(), imagesOutputDir()));
636 m_writer->writeTextElement(dbNamespace,
"alt", atom->next()->string());
640 m_writer->writeStartElement(dbNamespace,
"imageobject");
642 m_writer->writeEmptyElement(dbNamespace,
"imagedata");
643 const auto &imgPath =
"%1/%2"_L1.arg(imagesOutputDir(), file_name);
645 m_writer->writeAttribute(
"fileref", imgPath);
647 m_writer->writeEndElement();
651 setImageFileName(relative, imgPath);
654 m_writer->writeEndElement();
658 if (m_closeFigureWrapper) {
659 m_writer->writeEndElement();
661 m_closeFigureWrapper =
false;
669 QString admonType = atom->typeString().toLower();
672 m_writer->writeStartElement(dbNamespace, admonType);
674 m_writer->writeStartElement(dbNamespace,
"para");
677 case Atom::ImportantRight:
678 case Atom::NoteRight:
679 case Atom::WarningRight:
680 m_writer->writeEndElement();
683 m_writer->writeEndElement();
691 const Node *node =
nullptr;
692 QString link = getLink(atom, relative, &node);
693 beginLink(link, node, relative);
697 const Node *node =
static_cast<
const Node*>(Utilities::nodeForString(atom->string()));
698 beginLink(linkForNode(node, relative), node, relative);
708 m_writer->writeEndElement();
714 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
717 m_writer->writeStartElement(dbNamespace,
"variablelist");
720 m_writer->writeStartElement(dbNamespace,
"informaltable");
722 m_writer->writeStartElement(dbNamespace,
"thead");
724 m_writer->writeStartElement(dbNamespace,
"tr");
726 m_writer->writeTextElement(dbNamespace,
"th",
"Constant");
729 m_threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
730 if (m_threeColumnEnumValueTable && relative->isEnumType(Genus::CPP)) {
732 m_writer->writeTextElement(dbNamespace,
"th",
"Value");
737 m_writer->writeTextElement(dbNamespace,
"th",
"Description");
741 m_writer->writeEndElement();
743 m_writer->writeEndElement();
746 m_writer->writeStartElement(dbNamespace,
"orderedlist");
748 if (atom->next() !=
nullptr && atom->next()->string().toInt() != 1)
749 m_writer->writeAttribute(
"startingnumber", atom->next()->string());
752 m_writer->writeAttribute(
"numeration",
"upperalpha");
754 m_writer->writeAttribute(
"numeration",
"loweralpha");
756 m_writer->writeAttribute(
"numeration",
"upperroman");
758 m_writer->writeAttribute(
"numeration",
"lowerroman");
760 m_writer->writeAttribute(
"numeration",
"arabic");
770 m_writer->writeStartElement(dbNamespace,
"varlistentry");
772 m_writer->writeStartElement(dbNamespace,
"item");
774 std::pair<QString,
int> pair = getAtomListValue(atom);
775 skipAhead = pair.second;
777 m_writer->writeStartElement(dbNamespace,
"tr");
779 m_writer->writeStartElement(dbNamespace,
"td");
781 m_writer->writeStartElement(dbNamespace,
"para");
783 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
784 generateEnumValue(pair.first, relative);
785 m_writer->writeEndElement();
787 m_writer->writeEndElement();
791 const auto enume =
static_cast<
const EnumNode *>(relative);
792 QString itemValue = enume->itemValue(atom
->next()->string());
794 m_writer->writeStartElement(dbNamespace,
"td");
795 if (itemValue.isEmpty())
796 m_writer->writeCharacters(
"?");
798 m_writer->writeStartElement(dbNamespace,
"code");
800 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
801 m_writer->writeCharacters(itemValue);
802 m_writer->writeEndElement();
804 m_writer->writeEndElement();
812 m_writer->writeEndElement();
818 m_writer->writeEndElement();
825 m_inListItemLineOpen =
false;
827 m_writer->writeStartElement(dbNamespace,
"listitem");
829 m_writer->writeStartElement(dbNamespace,
"para");
832 if (m_threeColumnEnumValueTable) {
834 m_writer->writeEmptyElement(dbNamespace,
"td");
836 m_inListItemLineOpen =
false;
838 m_writer->writeStartElement(dbNamespace,
"td");
840 m_inListItemLineOpen =
true;
844 m_writer->writeStartElement(dbNamespace,
"listitem");
853 m_writer->writeEndElement();
856 m_writer->writeEndElement();
858 m_writer->writeEndElement();
861 if (m_inListItemLineOpen) {
862 m_writer->writeEndElement();
864 m_inListItemLineOpen =
false;
866 m_writer->writeEndElement();
869 m_writer->writeEndElement();
874 case Atom::ListRight:
880 m_writer->writeEndElement();
887 m_writer->writeStartElement(dbNamespace,
"para");
893 m_writer->writeEndElement();
898 case Atom::QuotationLeft:
899 m_writer->writeStartElement(dbNamespace,
"blockquote");
900 m_inBlockquote =
true;
902 case Atom::QuotationRight:
903 m_writer->writeEndElement();
905 m_inBlockquote =
false;
908 m_writer->device()->write(atom->string().toUtf8());
914 currentSectionLevel = atom->string().toInt() +
hOffset(relative
);
916 if (currentSectionLevel > 1) {
919 while (!sectionLevels.empty() && sectionLevels.top() >= currentSectionLevel) {
921 m_writer->writeEndElement();
925 sectionLevels.push(currentSectionLevel);
927 m_writer->writeStartElement(dbNamespace,
"section");
928 writeXmlId(Tree::refForAtom(atom));
941 generateAtom(atom->next(), relative,
nullptr);
942 generateAtom(atom->next()->next(), relative,
nullptr);
943 generateAtom(atom->next()->next()->next(), relative,
nullptr);
945 m_closeSectionAfterGeneratedList =
true;
952 m_writer->writeTextElement(dbNamespace,
"title",
"");
961 if (currentSectionLevel > 1) {
962 m_writer->writeStartElement(dbNamespace,
"title");
963 m_inSectionHeading =
true;
968 if (currentSectionLevel > 1) {
969 m_writer->writeEndElement();
971 m_inSectionHeading =
false;
974 case Atom::SidebarLeft:
975 m_writer->writeStartElement(dbNamespace,
"sidebar");
977 case Atom::SidebarRight:
978 m_writer->writeEndElement();
982 if (m_inLink && !m_inContents && !m_inSectionHeading)
985 m_writer->writeCharacters(atom->string());
988 std::pair<QString, QString> pair = getTableWidthAttr(atom);
989 QString attr = pair.second;
990 QString width = pair.first;
993 m_writer->writeEndElement();
998 m_tableHeaderAlreadyOutput =
false;
1000 m_writer->writeStartElement(dbNamespace,
"informaltable");
1001 m_writer->writeAttribute(
"style", attr);
1002 if (!width.isEmpty())
1003 m_writer->writeAttribute(
"width", width);
1006 case Atom::TableRight:
1007 m_tableWidthAttr = {
"",
""};
1008 m_writer->writeEndElement();
1017 if (m_tableHeaderAlreadyOutput) {
1020 m_writer->writeEndElement();
1023 const QString &attr = m_tableWidthAttr.second;
1024 const QString &width = m_tableWidthAttr.first;
1026 m_writer->writeStartElement(dbNamespace,
"informaltable");
1027 m_writer->writeAttribute(
"style", attr);
1028 if (!width.isEmpty())
1029 m_writer->writeAttribute(
"width", width);
1032 m_tableHeaderAlreadyOutput =
true;
1038 id = TextUtils::asAsciiPrintable(next->string());
1043 m_writer->writeStartElement(dbNamespace,
"thead");
1045 m_writer->writeStartElement(dbNamespace,
"tr");
1048 m_inTableHeader =
true;
1051 m_closeTableCell =
true;
1052 m_writer->writeStartElement(dbNamespace,
"td");
1058 if (m_closeTableCell) {
1059 m_closeTableCell =
false;
1060 m_writer->writeEndElement();
1064 m_writer->writeEndElement();
1068 m_writer->writeStartElement(dbNamespace,
"tr");
1071 m_writer->writeEndElement();
1073 m_inTableHeader =
false;
1083 bool hasTarget {
false};
1085 id = TextUtils::asAsciiPrintable(atom
->next()->string());
1090 m_writer->writeStartElement(dbNamespace,
"tr");
1093 if (atom->string().isEmpty()) {
1094 m_writer->writeAttribute(
"valign",
"top");
1099 QStringList args = atom->string().split(
"\"", Qt::SkipEmptyParts);
1102 const int nArgs = args.size();
1107 QStringLiteral(
"Error when parsing attributes for the table: got \"%1\"")
1108 .arg(atom->string()));
1110 for (
int i = 0; i + 1 < nArgs; i += 2) {
1113 const QString &attr = args.at(i).chopped(1);
1116 writeXmlId(args.at(i + 1));
1118 m_writer->writeAttribute(attr, args.at(i + 1));
1134 m_closeTableRow =
true;
1135 m_writer->writeEndElement();
1141 if (m_closeTableRow) {
1142 m_closeTableRow =
false;
1143 m_writer->writeEndElement();
1147 m_writer->writeEndElement();
1150 case Atom::TableItemLeft:
1151 m_writer->writeStartElement(dbNamespace, m_inTableHeader ?
"th" :
"td");
1153 for (
int i = 0; i < atom->count(); ++i) {
1154 const QString &p = atom->string(i);
1155 if (p.contains(
'=')) {
1156 QStringList lp = p.split(QLatin1Char(
'='));
1157 m_writer->writeAttribute(lp.at(0), lp.at(1));
1159 QStringList spans = p.split(QLatin1Char(
','));
1160 if (spans.size() == 2) {
1161 if (spans.at(0) !=
"1")
1162 m_writer->writeAttribute(
"colspan", spans.at(0).trimmed());
1163 if (spans.at(1) !=
"1")
1164 m_writer->writeAttribute(
"rowspan", spans.at(1).trimmed());
1171 case Atom::TableItemRight:
1172 m_writer->writeEndElement();
1184 QString nextId = TextUtils::asAsciiPrintable(
1186 QString ownId = TextUtils::asAsciiPrintable(atom->string());
1187 if (nextId == ownId)
1191 writeAnchor(TextUtils::asAsciiPrintable(atom->string()));
1193 case Atom::UnhandledFormat:
1194 m_writer->writeStartElement(dbNamespace,
"emphasis");
1195 m_writer->writeAttribute(
"role",
"bold");
1196 m_writer->writeCharacters(
"<Missing DocBook>");
1197 m_writer->writeEndElement();
1199 case Atom::UnknownCommand:
1200 m_writer->writeStartElement(dbNamespace,
"emphasis");
1201 m_writer->writeAttribute(
"role",
"bold");
1203 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
1204 m_writer->writeCharacters(
"<Unknown command>");
1205 m_writer->writeStartElement(dbNamespace,
"code");
1206 m_writer->writeCharacters(atom->string());
1207 m_writer->writeEndElement();
1208 m_writer->writeEndElement();
1228 if (classMap.isEmpty())
1231 std::function<
void(
ClassNode *)> generateClassAndChildren
1232 = [
this, &relative, &generateClassAndChildren](ClassNode * classe) {
1233 m_writer->writeStartElement(dbNamespace,
"listitem");
1237 m_writer->writeStartElement(dbNamespace,
"para");
1238 generateFullName(classe, relative);
1239 m_writer->writeEndElement();
1243 bool hasChild =
false;
1244 for (
const RelatedClass &relatedClass : classe->derivedClasses()) {
1245 if (relatedClass.m_node && relatedClass.m_node->isInAPI()) {
1252 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
1255 for (
const RelatedClass &relatedClass: classe->derivedClasses()) {
1256 if (relatedClass.m_node && relatedClass.m_node->isInAPI()) {
1257 generateClassAndChildren(relatedClass.m_node);
1261 m_writer->writeEndElement();
1266 m_writer->writeEndElement();
1270 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
1273 for (
const auto &it : classMap) {
1274 auto *classe =
static_cast<ClassNode *>(it);
1275 if (classe->baseClasses().isEmpty())
1276 generateClassAndChildren(classe);
1279 m_writer->writeEndElement();
1288 if (m_linkNode && m_linkNode->isFunction()) {
1290 if (match.hasMatch()) {
1292 qsizetype leftParenLoc = match.capturedStart(1);
1293 m_writer->writeCharacters(atom->string().left(leftParenLoc));
1295 m_writer->writeCharacters(atom->string().mid(leftParenLoc));
1299 m_writer->writeCharacters(atom->string());
1303
1304
1305
1309 m_writer->writeStartElement(dbNamespace,
"link");
1310 m_writer->writeAttribute(xlinkNamespace,
"href", link);
1311 if (node && !(relative && node->status() == relative->status())
1312 && node->isDeprecated())
1313 m_writer->writeAttribute(
"role",
"deprecated");
1322 m_writer->writeEndElement();
1324 m_linkNode =
nullptr;
1328 Qt::SortOrder sortOrder)
1333 if (selector == QLatin1String(
"overviews"))
1335 else if (selector == QLatin1String(
"cpp-modules"))
1337 else if (selector == QLatin1String(
"qml-modules"))
1342 m_qdb->mergeCollections(type, cnm, relative);
1343 const QList<CollectionNode *> collectionList = cnm.values();
1344 nodeList.reserve(collectionList.size());
1345 for (
auto *collectionNode : collectionList)
1346 nodeList.append(collectionNode);
1347 generateAnnotatedList(relative, nodeList, selector, Auto, sortOrder);
1350
1351
1352
1353 Node *n =
const_cast<
Node *>(relative);
1354 auto *cn =
static_cast<CollectionNode *>(n);
1355 m_qdb->mergeCollections(cn);
1356 generateAnnotatedList(cn, cn->members(), selector, Auto, sortOrder);
1361
1362
1363
1365 const QString &selector, GeneratedListType type,
1366 Qt::SortOrder sortOrder)
1368 if (nodeList.isEmpty())
1372 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
1373 if (
std::all_of(nodeList.cbegin(), nodeList.cend(), [&policy](
const Node *n) {
1375 return !InclusionFilter::isIncluded(policy, context) || n->isDeprecated();
1382 bool noItemsHaveTitle =
1383 type == ItemizedList ||
std::all_of(nodeList.begin(), nodeList.end(),
1384 [](
const Node* node) {
1385 return node->doc().briefText().toString().isEmpty();
1389 if (type == AutoSection && m_hasSection)
1390 startSection(
"",
"Contents");
1393 if (!nodeList.isEmpty()) {
1394 m_writer->writeStartElement(dbNamespace, noItemsHaveTitle ?
"itemizedlist" :
"variablelist");
1395 m_writer->writeAttribute(
"role", selector);
1399 if (sortOrder == Qt::DescendingOrder)
1403 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
1404 for (
const auto &node : std::as_const(members)) {
1405 const NodeContext context = node->createContext();
1406 if (!InclusionFilter::isIncluded(policy, context) || node->isDeprecated())
1409 if (noItemsHaveTitle) {
1410 m_writer->writeStartElement(dbNamespace,
"listitem");
1412 m_writer->writeStartElement(dbNamespace,
"para");
1414 m_writer->writeStartElement(dbNamespace,
"varlistentry");
1416 m_writer->writeStartElement(dbNamespace,
"term");
1418 generateFullName(node, relative);
1419 if (noItemsHaveTitle) {
1420 m_writer->writeEndElement();
1422 m_writer->writeEndElement();
1424 m_writer->writeEndElement();
1426 m_writer->writeStartElement(dbNamespace,
"listitem");
1428 m_writer->writeStartElement(dbNamespace,
"para");
1429 m_writer->writeCharacters(node->doc().briefText().toString());
1430 m_writer->writeEndElement();
1432 m_writer->writeEndElement();
1434 m_writer->writeEndElement();
1439 m_writer->writeEndElement();
1443 if (type == AutoSection && m_hasSection)
1448
1449
1450
1452 const QString &selector)
1455 for (
const QString &name : nmm.uniqueKeys()) {
1456 if (!name.isEmpty())
1457 startSection(name.toLower(), name);
1458 generateAnnotatedList(relative, nmm.values(name), selector);
1459 if (!name.isEmpty())
1465
1466
1467
1468
1469
1470
1471
1472
1473
1475 bool includeAlphabet,
const QString &commonPrefix,
1476 const QString &selector)
1486 const int NumParagraphs = 37;
1487 qsizetype commonPrefixLen = commonPrefix.size();
1490
1491
1492
1493
1494
1496 QString paragraphName[NumParagraphs + 1];
1497 QSet<
char> usedParagraphNames;
1499 for (
auto c = nmm.constBegin(); c != nmm.constEnd(); ++c) {
1500 QStringList pieces = c.key().split(
"::");
1501 int idx = commonPrefixLen;
1502 if (idx > 0 && !pieces.last().startsWith(commonPrefix, Qt::CaseInsensitive))
1504 QString last = pieces.last().toLower();
1505 QString key = last.mid(idx);
1507 int paragraphNr = NumParagraphs - 1;
1509 if (key[0].digitValue() != -1) {
1510 paragraphNr = key[0].digitValue();
1511 }
else if (key[0] >= QLatin1Char(
'a') && key[0] <= QLatin1Char(
'z')) {
1512 paragraphNr = 10 + key[0].unicode() -
'a';
1515 paragraphName[paragraphNr] = key[0].toUpper();
1516 usedParagraphNames.insert(key[0].toLower().cell());
1517 paragraph[paragraphNr].insert(last, c.value());
1521
1522
1523
1524
1525
1526
1527
1528 int paragraphOffset[NumParagraphs + 1];
1529 paragraphOffset[0] = 0;
1530 for (
int i = 0; i < NumParagraphs; i++)
1531 paragraphOffset[i + 1] = paragraphOffset[i] + paragraph[i].size();
1534 if (includeAlphabet && !usedParagraphNames.isEmpty()) {
1535 m_writer->writeStartElement(dbNamespace,
"simplelist");
1538 for (
int i = 0; i < 26; i++) {
1540 if (usedParagraphNames.contains(
char(
'a' + i))) {
1541 m_writer->writeStartElement(dbNamespace,
"member");
1542 generateSimpleLink(ch, ch.toUpper());
1543 m_writer->writeEndElement();
1548 m_writer->writeEndElement();
1553 QHash<QString,
int> nameOccurrences;
1554 for (
const auto &[key, node] : nmm.asKeyValueRange()) {
1555 QStringList pieces{node->fullName(relative).split(
"::"_L1)};
1556 const QString &name{pieces.last()};
1557 nameOccurrences[name]++;
1562 int curParOffset = 0;
1564 m_writer->writeStartElement(dbNamespace,
"variablelist");
1565 m_writer->writeAttribute(
"role", selector);
1568 for (
int i = 0; i < nmm.size(); i++) {
1569 while ((curParNr < NumParagraphs) && (curParOffset == paragraph[curParNr].size())) {
1576 if (curParOffset == 0) {
1578 m_writer->writeEndElement();
1580 m_writer->writeEndElement();
1582 m_writer->writeEndElement();
1586 m_writer->writeStartElement(dbNamespace,
"varlistentry");
1587 if (includeAlphabet)
1588 writeXmlId(paragraphName[curParNr][0].toLower());
1591 m_writer->writeStartElement(dbNamespace,
"term");
1592 m_writer->writeStartElement(dbNamespace,
"emphasis");
1593 m_writer->writeAttribute(
"role",
"bold");
1594 m_writer->writeCharacters(paragraphName[curParNr]);
1595 m_writer->writeEndElement();
1596 m_writer->writeEndElement();
1599 m_writer->writeStartElement(dbNamespace,
"listitem");
1601 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
1606 m_writer->writeStartElement(dbNamespace,
"listitem");
1608 m_writer->writeStartElement(dbNamespace,
"para");
1610 if ((curParNr < NumParagraphs) && !paragraphName[curParNr].isEmpty()) {
1611 NodeMultiMap::Iterator it;
1612 NodeMultiMap::Iterator next;
1613 it = paragraph[curParNr].begin();
1614 for (
int j = 0; j < curParOffset; j++)
1619 QStringList pieces{it.value()->fullName(relative).split(
"::"_L1)};
1620 const auto &name{pieces.last()};
1623 if (nameOccurrences[name] > 1) {
1624 const QString moduleName = it.value()->isQmlNode() ? it.value()->logicalModuleName()
1625 : it.value()->tree()->camelCaseModuleName();
1626 pieces.last().append(
": %1"_L1.arg(moduleName));
1630 m_writer->writeStartElement(dbNamespace,
"link");
1631 m_writer->writeAttribute(xlinkNamespace,
"href", linkForNode(*it, relative));
1632 if (
const QString type = targetType(it.value()); !type.isEmpty())
1633 m_writer->writeAttribute(
"role", type);
1634 m_writer->writeCharacters(pieces.last());
1635 m_writer->writeEndElement();
1638 if (pieces.size() > 1) {
1639 m_writer->writeCharacters(
" (");
1640 generateFullName(it.value()->parent(), relative);
1641 m_writer->writeCharacters(
")");
1645 m_writer->writeEndElement();
1647 m_writer->writeEndElement();
1652 m_writer->writeEndElement();
1654 m_writer->writeEndElement();
1656 m_writer->writeEndElement();
1659 m_writer->writeEndElement();
1668 m_writer->writeStartElement(dbNamespace,
"simplelist");
1669 m_writer->writeAttribute(
"role",
"functionIndex");
1671 for (
int i = 0; i < 26; i++) {
1673 m_writer->writeStartElement(dbNamespace,
"member");
1674 m_writer->writeAttribute(xlinkNamespace,
"href", QString(
"#") + ch);
1675 m_writer->writeCharacters(ch.toUpper());
1676 m_writer->writeEndElement();
1679 m_writer->writeEndElement();
1684 if (m_qdb->getFunctionIndex().isEmpty())
1686 char nextLetter =
'a';
1689 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
1692 NodeMapMap &funcIndex = m_qdb->getFunctionIndex();
1693 QMap<QString, NodeMap>::ConstIterator f = funcIndex.constBegin();
1694 while (f != funcIndex.constEnd()) {
1695 m_writer->writeStartElement(dbNamespace,
"listitem");
1697 m_writer->writeStartElement(dbNamespace,
"para");
1698 m_writer->writeCharacters(f.key() +
": ");
1700 currentLetter = f.key()[0].unicode();
1701 while (islower(currentLetter) && currentLetter >= nextLetter) {
1702 writeAnchor(QString(nextLetter));
1706 NodeMap::ConstIterator s = (*f).constBegin();
1707 while (s != (*f).constEnd()) {
1708 m_writer->writeCharacters(
" ");
1709 generateFullName((*s)->parent(), relative);
1713 m_writer->writeEndElement();
1715 m_writer->writeEndElement();
1719 m_writer->writeEndElement();
1727 for (
auto it = legaleseTexts.cbegin(), end = legaleseTexts.cend(); it != end; ++it) {
1728 Text text = it.key();
1730 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
1733 m_writer->writeStartElement(dbNamespace,
"listitem");
1735 m_writer->writeStartElement(dbNamespace,
"para");
1736 generateFullName(it.value(), relative);
1737 m_writer->writeEndElement();
1739 m_writer->writeEndElement();
1742 }
while (it != legaleseTexts.constEnd() && it.key() == text);
1743 m_writer->writeEndElement();
1758 m_writer->writeStartElement(dbNamespace,
"para");
1760 m_writer->writeEndElement();
1768 if (!node->since().isEmpty()) {
1769 m_writer->writeStartElement(dbNamespace,
"para");
1771 const auto &collective =
static_cast<
const SharedCommentNode *>(node)->collective();
1772 QString typeStr = collective.size() > 1 ? typeString(collective.first()) +
"s" : typeString(node);
1773 m_writer->writeCharacters(
"These " + typeStr +
" were introduced in ");
1775 m_writer->writeCharacters(
"This " + typeString(node) +
" was introduced in ");
1777 m_writer->writeCharacters(formatSince(node) +
".");
1778 m_writer->writeEndElement();
1788
1789
1790
1797 m_writer->writeStartElement(dbNamespace,
"info");
1799 m_writer->writeStartElement(dbNamespace,
"title");
1800 if (isApiGenus(node->genus()) && m_useITS)
1801 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
1803 m_writer->writeEndElement();
1806 if (!subTitle.isEmpty()) {
1807 m_writer->writeStartElement(dbNamespace,
"subtitle");
1808 if (isApiGenus(node->genus()) && m_useITS)
1809 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
1810 m_writer->writeCharacters(subTitle);
1811 m_writer->writeEndElement();
1815 if (!m_productName.isEmpty() || !m_project.isEmpty()) {
1816 m_writer->writeTextElement(dbNamespace,
"productname", m_productName.isEmpty() ?
1817 m_project : m_productName);
1821 if (!m_buildVersion.isEmpty()) {
1822 m_writer->writeTextElement(dbNamespace,
"edition", m_buildVersion);
1826 if (!m_projectDescription.isEmpty()) {
1827 m_writer->writeTextElement(dbNamespace,
"titleabbrev", m_projectDescription);
1835 if (node && !node->links().empty()) {
1836 std::pair<QString, QString> linkPair;
1837 std::pair<QString, QString> anchorPair;
1838 const Node *linkNode;
1840 if (node->links().contains(Node::PreviousLink)) {
1841 linkPair = node->links()[Node::PreviousLink];
1842 linkNode = m_qdb->findNodeForTarget(linkPair.first, node);
1843 if (!linkNode || linkNode == node)
1844 anchorPair = linkPair;
1846 anchorPair = anchorForNode(linkNode);
1848 m_writer->writeStartElement(dbNamespace,
"extendedlink");
1849 m_writer->writeAttribute(xlinkNamespace,
"type",
"extended");
1850 m_writer->writeEmptyElement(dbNamespace,
"link");
1851 m_writer->writeAttribute(xlinkNamespace,
"to", anchorPair.first);
1852 m_writer->writeAttribute(xlinkNamespace,
"type",
"arc");
1853 m_writer->writeAttribute(xlinkNamespace,
"arcrole",
"prev");
1854 if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
1855 m_writer->writeAttribute(xlinkNamespace,
"title", anchorPair.second);
1857 m_writer->writeAttribute(xlinkNamespace,
"title", linkPair.second);
1858 m_writer->writeEndElement();
1861 if (node->links().contains(Node::NextLink)) {
1862 linkPair = node->links()[Node::NextLink];
1863 linkNode = m_qdb->findNodeForTarget(linkPair.first, node);
1864 if (!linkNode || linkNode == node)
1865 anchorPair = linkPair;
1867 anchorPair = anchorForNode(linkNode);
1869 m_writer->writeStartElement(dbNamespace,
"extendedlink");
1870 m_writer->writeAttribute(xlinkNamespace,
"type",
"extended");
1871 m_writer->writeEmptyElement(dbNamespace,
"link");
1872 m_writer->writeAttribute(xlinkNamespace,
"to", anchorPair.first);
1873 m_writer->writeAttribute(xlinkNamespace,
"type",
"arc");
1874 m_writer->writeAttribute(xlinkNamespace,
"arcrole",
"next");
1875 if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
1876 m_writer->writeAttribute(xlinkNamespace,
"title", anchorPair.second);
1878 m_writer->writeAttribute(xlinkNamespace,
"title", linkPair.second);
1879 m_writer->writeEndElement();
1882 if (node->links().contains(Node::StartLink)) {
1883 linkPair = node->links()[Node::StartLink];
1884 linkNode = m_qdb->findNodeForTarget(linkPair.first, node);
1885 if (!linkNode || linkNode == node)
1886 anchorPair = linkPair;
1888 anchorPair = anchorForNode(linkNode);
1890 m_writer->writeStartElement(dbNamespace,
"extendedlink");
1891 m_writer->writeAttribute(xlinkNamespace,
"type",
"extended");
1892 m_writer->writeEmptyElement(dbNamespace,
"link");
1893 m_writer->writeAttribute(xlinkNamespace,
"to", anchorPair.first);
1894 m_writer->writeAttribute(xlinkNamespace,
"type",
"arc");
1895 m_writer->writeAttribute(xlinkNamespace,
"arcrole",
"start");
1896 if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
1897 m_writer->writeAttribute(xlinkNamespace,
"title", anchorPair.second);
1899 m_writer->writeAttribute(xlinkNamespace,
"title", linkPair.second);
1900 m_writer->writeEndElement();
1912 m_writer->writeStartElement(dbNamespace,
"abstract");
1915 bool generatedSomething =
false;
1919 node->isNamespace() ?
static_cast<
const NamespaceNode *>(node) :
nullptr;
1922 brief <<
"The " << ns->name()
1923 <<
" namespace includes the following elements from module "
1924 << ns
->tree()->camelCaseModuleName() <<
". The full namespace is "
1925 <<
"documented in module " << NS
->tree()->camelCaseModuleName();
1926 addNodeLink(brief, fullDocumentLocation(NS),
" here.");
1935 m_writer->writeStartElement(dbNamespace,
"para");
1937 m_writer->writeEndElement();
1940 generatedSomething =
true;
1950 if (!generatedSomething)
1951 m_writer->writeTextElement(dbNamespace,
"para", m_projectDescription +
".");
1953 m_writer->writeEndElement();
1958 m_writer->writeEndElement();
1964 while (!sectionLevels.isEmpty()) {
1965 sectionLevels.pop();
1972 if (m_closeSectionAfterGeneratedList) {
1973 m_closeSectionAfterGeneratedList =
false;
1976 if (m_closeSectionAfterRawTitle) {
1977 m_closeSectionAfterRawTitle =
false;
1982 m_writer->writeEndElement();
1985void DocBookGenerator::generateSimpleLink(
const QString &href,
const QString &text)
1987 m_writer->writeStartElement(dbNamespace,
"link");
1988 m_writer->writeAttribute(xlinkNamespace,
"href", href);
1989 m_writer->writeCharacters(text);
1990 m_writer->writeEndElement();
1994
1995
1996
1999 static const QHash<QString, QString> extrefUrls = {
2000 {u"cpp-explicitly-defaulted"_s,
2001 u"https://en.cppreference.com/w/cpp/language/function#Defaulted_functions"_s},
2002 {u"cpp-deleted-functions"_s,
2003 u"https://en.cppreference.com/w/cpp/language/function#Deleted_functions"_s},
2006 static const QRegularExpression extrefRegex(
2007 u"<@extref target=\"([^\"]+)\">([^<]*)</@extref>"_s);
2010 auto it = extrefRegex.globalMatch(extra);
2011 while (it.hasNext()) {
2012 auto match = it.next();
2013 if (match.capturedStart() > pos)
2014 m_writer->writeCharacters(extra.mid(pos, match.capturedStart() - pos));
2016 QString target = match.captured(1);
2017 QString text = match.captured(2);
2018 QString url = extrefUrls.value(target);
2020 generateSimpleLink(url, text);
2022 m_writer->writeCharacters(text);
2024 pos = match.capturedEnd();
2026 if (pos < extra.size())
2027 m_writer->writeCharacters(extra.mid(pos));
2039 startSection(
"obsolete",
"Obsolete Members for " + aggregate->plainFullName());
2041 m_writer->writeStartElement(dbNamespace,
"para");
2042 m_writer->writeStartElement(dbNamespace,
"emphasis");
2043 m_writer->writeAttribute(
"role",
"bold");
2044 m_writer->writeCharacters(
"The following members of class ");
2045 generateSimpleLink(linkForNode(aggregate,
nullptr), aggregate->name());
2046 m_writer->writeCharacters(
" are deprecated.");
2047 m_writer->writeEndElement();
2048 m_writer->writeCharacters(
" We strongly advise against using them in new code.");
2049 m_writer->writeEndElement();
2052 for (
const Section *section : details_spv) {
2053 const QString &title =
"Obsolete " + section->title();
2054 startSection(title.toLower(), title);
2056 const NodeVector &members = section->obsoleteMembers();
2057 NodeVector::ConstIterator m = members.constBegin();
2058 while (m != members.constEnd()) {
2059 if ((*m)->access() != Access::Private)
2060 generateDetailedMember(*m, aggregate);
2071
2072
2073
2074
2075
2076
2077
2087 startSection(
"obsolete",
"Obsolete Members for " + aggregate->name());
2089 m_writer->writeStartElement(dbNamespace,
"para");
2090 m_writer->writeStartElement(dbNamespace,
"emphasis");
2091 m_writer->writeAttribute(
"role",
"bold");
2092 m_writer->writeCharacters(
"The following members of QML type ");
2093 generateSimpleLink(linkForNode(aggregate,
nullptr), aggregate->name());
2094 m_writer->writeCharacters(
" are deprecated.");
2095 m_writer->writeEndElement();
2096 m_writer->writeCharacters(
" We strongly advise against using them in new code.");
2097 m_writer->writeEndElement();
2100 for (
const auto *section : details_spv) {
2101 const QString &title =
"Obsolete " + section->title();
2102 startSection(title.toLower(), title);
2104 const NodeVector &members = section->obsoleteMembers();
2105 NodeVector::ConstIterator m = members.constBegin();
2106 while (m != members.constEnd()) {
2107 if ((*m)->access() != Access::Private)
2108 generateDetailedQmlMember(*m, aggregate);
2122 return QStringLiteral(
"classsynopsis");
2124 return QStringLiteral(
"packagesynopsis");
2130 return QStringLiteral(
"enumsynopsis");
2132 return QStringLiteral(
"typedefsynopsis");
2135 const auto fn =
static_cast<
const FunctionNode *>(node);
2136 if (fn->isCtor() || fn->isCCtor() || fn->isMCtor())
2137 return QStringLiteral(
"constructorsynopsis");
2139 return QStringLiteral(
"destructorsynopsis");
2140 return QStringLiteral(
"methodsynopsis");
2143 return QStringLiteral(
"fieldsynopsis");
2145 node
->doc().location().warning(QString(
"Unknown node tag %1").arg(node->nodeTypeString()));
2146 return QStringLiteral(
"synopsis");
2151 m_writer->writeStartElement(dbNamespace,
"varlistentry");
2153 m_writer->writeTextElement(dbNamespace,
"term", description);
2155 m_writer->writeStartElement(dbNamespace,
"listitem");
2157 m_writer->writeStartElement(dbNamespace,
"para");
2163 m_writer->writeEndElement();
2166 m_writer->writeEndElement();
2168 m_writer->writeEndElement();
2172void DocBookGenerator::generateRequisite(
const QString &description,
const QString &value)
2174 generateStartRequisite(description);
2175 m_writer->writeCharacters(value);
2176 generateEndRequisite();
2180
2181
2182
2183void DocBookGenerator::generateCMakeRequisite(
const QString &findPackage,
const QString &linkLibraries)
2185 const QString description(
"CMake");
2186 generateStartRequisite(description);
2187 m_writer->writeCharacters(findPackage);
2188 m_writer->writeEndElement();
2191 m_writer->writeStartElement(dbNamespace,
"para");
2192 m_writer->writeCharacters(linkLibraries);
2193 generateEndRequisite();
2199 QMap<QString, ClassNode *> classMap;
2200 QList<RelatedClass>::ConstIterator r = rc.constBegin();
2201 while (r != rc.constEnd()) {
2204 && !rcn
->doc().isEmpty()) {
2205 classMap[rcn->plainFullName(cn).toLower()] = rcn;
2210 QStringList classNames = classMap.keys();
2214 for (
const QString &className : classNames) {
2215 generateFullName(classMap.value(className), cn);
2216 m_writer->writeCharacters(TextUtils::comma(index++, classNames.size()));
2224 QMap<QString, Node *> classMap;
2225 QStringList typeNames(knownTypes);
2226 for (
const auto sub : subs)
2227 typeNames << sub->name();
2229 for (
auto sub : subs) {
2230 QString key{sub->plainFullName(base).toLower()};
2232 if (typeNames.count(sub->name()) > 1)
2233 key.append(
": (%1)"_L1.arg(sub->logicalModuleName()));
2234 classMap[key] = sub;
2237 QStringList names = classMap.keys();
2241 for (
const QString &name : names) {
2242 generateFullName(classMap.value(name), base);
2243 if (name.contains(
':'))
2244 m_writer->writeCharacters(name.section(
':', 1));
2245 m_writer->writeCharacters(TextUtils::comma(index++, names.size()));
2250
2251
2260 QXmlStreamWriter* oldWriter = m_writer;
2262 m_writer =
new QXmlStreamWriter(&output);
2265 if (aggregate->includeFile()) generateRequisite(
"Header", *aggregate->includeFile());
2268 if (!aggregate->since().isEmpty())
2269 generateRequisite(
"Since", formatSince(aggregate));
2274 m_qdb->getCollectionNode(aggregate->physicalModuleName(), NodeType::Module);
2276 if (
const auto result = cmakeRequisite(cn)) {
2277 generateCMakeRequisite(result->first, result->second);
2280 if (cn && !cn->qtVariable().isEmpty())
2281 generateRequisite(
"qmake",
"QT += " + cn->qtVariable());
2286 auto *classe =
const_cast<ClassNode *>(
static_cast<
const ClassNode *>(aggregate));
2287 if (classe && classe->isQmlNativeType() && !classe->isInternal()) {
2288 generateStartRequisite(
"In QML");
2291 QList<QmlTypeNode *> nativeTypes { classe->qmlNativeTypes().cbegin(), classe->qmlNativeTypes().cend()};
2294 for (
const auto &item : std::as_const(nativeTypes)) {
2295 generateFullName(item, classe);
2296 m_writer->writeCharacters(
2297 TextUtils::comma(idx++, nativeTypes.size()));
2299 generateEndRequisite();
2303 QList<RelatedClass>::ConstIterator r;
2304 const auto *metaTags = classe ? classe->doc().metaTagMap() :
nullptr;
2305 bool suppressInherits = metaTags && metaTags->contains(u"qdoc-suppress-inheritance"_s);
2306 if (classe && !suppressInherits && !classe->baseClasses().isEmpty()) {
2307 generateStartRequisite(
"Inherits");
2309 r = classe->baseClasses().constBegin();
2311 while (r != classe->baseClasses().constEnd()) {
2313 generateFullName((*r).m_node, classe);
2315 if ((*r).m_access == Access::Protected)
2316 m_writer->writeCharacters(
" (protected)");
2317 else if ((*r).m_access == Access::Private)
2318 m_writer->writeCharacters(
" (private)");
2319 m_writer->writeCharacters(
2320 TextUtils::comma(index++, classe->baseClasses().size()));
2325 generateEndRequisite();
2329 if (!classe->derivedClasses().isEmpty()) {
2330 generateStartRequisite(
"Inherited By");
2331 generateSortedNames(classe, classe->derivedClasses());
2332 generateEndRequisite();
2337 if (!aggregate->groupNames().empty()) {
2338 generateStartRequisite(
"Group");
2340 generateEndRequisite();
2344 if (
auto status = formatStatus(aggregate, m_qdb); status)
2345 generateRequisite(
"Status", status.value());
2349 m_writer = oldWriter;
2351 if (!output.isEmpty()) {
2354 static const QRegularExpression xmlTag(R"(<(/?)n\d+:)");
2355 static const QRegularExpression xmlnsDocBookDefinition(R"( xmlns:n\d+=")" + QString{dbNamespace} +
"\"");
2356 static const QRegularExpression xmlnsXLinkDefinition(R"( xmlns:n\d+=")" + QString{xlinkNamespace} +
"\"");
2357 static const QRegularExpression xmlAttr(R"( n\d+:)");
2359 const QString cleanOutput = output.replace(xmlTag, R"(<\1db:)")
2360 .replace(xmlnsDocBookDefinition,
"")
2361 .replace(xmlnsXLinkDefinition,
"")
2362 .replace(xmlAttr,
" xlink:");
2364 m_writer->writeStartElement(dbNamespace,
"variablelist");
2366 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
2369 m_writer->device()->write(cleanOutput.toUtf8());
2371 m_writer->writeEndElement();
2377
2378
2386 const QString importText =
"Import Statement";
2387 const QString sinceText =
"Since";
2388 const QString inheritedByText =
"Inherited By";
2389 const QString inheritsText =
"Inherits";
2390 const QString nativeTypeText =
"In C++";
2391 const QString groupText =
"Group";
2392 const QString statusText =
"Status";
2400 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
2409 bool generate_import_statement = !qcn->logicalModuleName().isEmpty();
2410 if (generate_import_statement && collection) {
2415 const bool generates_something = generate_import_statement || !qcn->since().isEmpty() || !subs.isEmpty() || base;
2417 if (!generates_something)
2420 QStringList knownTypeNames{qcn->name()};
2422 knownTypeNames << base->name();
2425 m_writer->writeStartElement(dbNamespace,
"variablelist");
2427 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
2430 if (generate_import_statement) {
2431 QStringList parts = QStringList() <<
"import" << qcn->logicalModuleName() << qcn->logicalModuleVersion();
2432 generateRequisite(importText, parts.join(
' ').trimmed());
2436 if (!qcn->since().isEmpty())
2437 generateRequisite(sinceText, formatSince(qcn));
2442 generateStartRequisite(nativeTypeText);
2443 generateSimpleLink(fullDocumentLocation(cn), cn->name());
2444 generateEndRequisite();
2449 generateStartRequisite(inheritsText);
2450 generateSimpleLink(fullDocumentLocation(base), base->name());
2452 for (
const auto sub : std::as_const(subs)) {
2453 if (knownTypeNames.contains(sub->name())) {
2454 m_writer->writeCharacters(
" (%1)"_L1.arg(base->logicalModuleName()));
2458 generateEndRequisite();
2462 if (!subs.isEmpty()) {
2463 generateStartRequisite(inheritedByText);
2464 generateSortedQmlNames(qcn, knownTypeNames, subs);
2465 generateEndRequisite();
2469 if (!qcn->groupNames().empty()) {
2470 generateStartRequisite(groupText);
2472 generateEndRequisite();
2476 if (
auto status = formatStatus(qcn, m_qdb); status)
2477 generateRequisite(statusText, status.value());
2479 m_writer->writeEndElement();
2490 const QString &state =
static_cast<
const CollectionNode*>(node)->state();
2491 if (!state.isEmpty()) {
2492 m_writer->writeStartElement(dbNamespace,
"para");
2493 m_writer->writeCharacters(
"This " + typeString(node) +
" is in ");
2494 m_writer->writeStartElement(dbNamespace,
"emphasis");
2495 m_writer->writeCharacters(state);
2496 m_writer->writeEndElement();
2497 m_writer->writeCharacters(
" state.");
2498 m_writer->writeEndElement();
2503 if (
const auto &version = node->deprecatedSince(); !version.isEmpty()) {
2504 m_writer->writeStartElement(dbNamespace,
"para");
2505 m_writer->writeCharacters(
"This " + typeString(node)
2506 +
" is scheduled for deprecation in version "
2508 m_writer->writeEndElement();
2513 case Status::Preliminary:
2514 m_writer->writeStartElement(dbNamespace,
"para");
2515 m_writer->writeStartElement(dbNamespace,
"emphasis");
2516 m_writer->writeAttribute(
"role",
"bold");
2517 m_writer->writeCharacters(
2521 .replace(
'\1'_L1, typeString(node)));
2522 m_writer->writeEndElement();
2523 m_writer->writeEndElement();
2526 case Status::Deprecated:
2527 m_writer->writeStartElement(dbNamespace,
"para");
2529 m_writer->writeStartElement(dbNamespace,
"emphasis");
2530 m_writer->writeAttribute(
"role",
"bold");
2532 m_writer->writeCharacters(
"This " + typeString(node) +
" is deprecated");
2533 if (
const QString &version = node->deprecatedSince(); !version.isEmpty()) {
2534 m_writer->writeCharacters(
" since ");
2535 if (node->isQmlNode() && !node->logicalModuleName().isEmpty())
2536 m_writer->writeCharacters(node->logicalModuleName() +
" ");
2537 m_writer->writeCharacters(version);
2539 m_writer->writeCharacters(
". We strongly advise against using it in new code.");
2540 if (node->isAggregate())
2541 m_writer->writeEndElement();
2542 m_writer->writeEndElement();
2553
2554
2555
2559 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
2562 NodeList::ConstIterator n = nodes.constBegin();
2563 while (n != nodes.constEnd()) {
2564 m_writer->writeStartElement(dbNamespace,
"listitem");
2566 m_writer->writeStartElement(dbNamespace,
"para");
2568 generateSimpleLink(currentGenerator()->fullDocumentLocation(*n),
2569 (*n)->signature(Node::SignaturePlain));
2571 m_writer->writeEndElement();
2573 m_writer->writeEndElement();
2578 m_writer->writeEndElement();
2583
2584
2585
2592 const auto aggregate =
static_cast<
const Aggregate *>(node);
2594 const QStringList &groups_names{aggregate->groupNames()};
2595 if (!groups_names.empty()) {
2596 m_writer->writeCharacters(aggregate->name() +
" is part of ");
2597 m_writer->writeStartElement(dbNamespace,
"simplelist");
2599 for (qsizetype index{0}; index < groups_names.size(); ++index) {
2601 m_qdb->mergeCollections(group);
2603 m_writer->writeStartElement(dbNamespace,
"member");
2604 if (QString target{linkForNode(group,
nullptr)}; !target.isEmpty())
2605 generateSimpleLink(target, group->fullTitle());
2607 m_writer->writeCharacters(group->name());
2608 m_writer->writeEndElement();
2611 m_writer->writeEndElement();
2617
2618
2619
2625 const Node *reentrantNode;
2627 QString linkReentrant = getAutoLink(&reentrantAtom, node, &reentrantNode);
2628 const Node *threadSafeNode;
2630 QString linkThreadSafe = getAutoLink(&threadSafeAtom, node, &threadSafeNode);
2633 m_writer->writeStartElement(dbNamespace,
"warning");
2635 m_writer->writeStartElement(dbNamespace,
"para");
2636 m_writer->writeCharacters(
"This " + typeString(node) +
" is not ");
2637 generateSimpleLink(linkReentrant,
"reentrant");
2638 m_writer->writeCharacters(
".");
2639 m_writer->writeEndElement();
2641 m_writer->writeEndElement();
2645 m_writer->writeStartElement(dbNamespace,
"note");
2647 m_writer->writeStartElement(dbNamespace,
"para");
2650 m_writer->writeCharacters(
"All functions in this " + typeString(node) +
" are ");
2651 if (ts == Node::ThreadSafe)
2652 generateSimpleLink(linkThreadSafe,
"thread-safe");
2654 generateSimpleLink(linkReentrant,
"reentrant");
2659 bool exceptions = hasExceptions(node, reentrant, threadsafe, nonreentrant);
2660 if (!exceptions || (ts ==
Node::Reentrant && !threadsafe.isEmpty())) {
2661 m_writer->writeCharacters(
".");
2662 m_writer->writeEndElement();
2665 m_writer->writeCharacters(
" with the following exceptions:");
2666 m_writer->writeEndElement();
2668 m_writer->writeStartElement(dbNamespace,
"para");
2671 if (!nonreentrant.isEmpty()) {
2672 m_writer->writeCharacters(
"These functions are not ");
2673 generateSimpleLink(linkReentrant,
"reentrant");
2674 m_writer->writeCharacters(
":");
2675 m_writer->writeEndElement();
2677 generateSignatureList(nonreentrant);
2679 if (!threadsafe.isEmpty()) {
2680 m_writer->writeCharacters(
"These functions are also ");
2681 generateSimpleLink(linkThreadSafe,
"thread-safe");
2682 m_writer->writeCharacters(
":");
2683 m_writer->writeEndElement();
2685 generateSignatureList(threadsafe);
2688 if (!reentrant.isEmpty()) {
2689 m_writer->writeCharacters(
"These functions are only ");
2690 generateSimpleLink(linkReentrant,
"reentrant");
2691 m_writer->writeCharacters(
":");
2692 m_writer->writeEndElement();
2694 generateSignatureList(reentrant);
2696 if (!nonreentrant.isEmpty()) {
2697 m_writer->writeCharacters(
"These functions are not ");
2698 generateSimpleLink(linkReentrant,
"reentrant");
2699 m_writer->writeCharacters(
":");
2700 m_writer->writeEndElement();
2702 generateSignatureList(nonreentrant);
2707 m_writer->writeCharacters(
"This " + typeString(node) +
" is ");
2708 if (ts == Node::ThreadSafe)
2709 generateSimpleLink(linkThreadSafe,
"thread-safe");
2711 generateSimpleLink(linkReentrant,
"reentrant");
2712 m_writer->writeCharacters(
".");
2713 m_writer->writeEndElement();
2716 m_writer->writeEndElement();
2726
2727
2728
2732 const FunctionNode *fn = node->isFunction() ?
static_cast<
const FunctionNode *>(node) :
nullptr;
2736
2737
2738
2742 t =
"Destroys the instance of " + fn
->parent()->name() +
".";
2744 t +=
" The destructor is virtual.";
2746 t =
"Default constructs an instance of " + fn
->parent()->name() +
".";
2748 t =
"Copy constructor.";
2750 t =
"Move-copy constructor.";
2752 t =
"Copy-assignment constructor.";
2754 t =
"Move-assignment constructor.";
2758 m_writer->writeTextElement(dbNamespace,
"para", t);
2762 if (fn && !fn->overridesThis().isEmpty())
2763 generateReimplementsClause(fn);
2765 if (
static_cast<
const PropertyNode *>(node)->propertyType() != PropertyNode::PropertyType::StandardProperty)
2794 generateRequiredLinks(node);
2798
2799
2800
2801
2802
2809 const auto en =
static_cast<
const ExampleNode *>(node);
2812 if (exampleUrl.isEmpty()) {
2813 if (!en->noAutoList()) {
2814 generateFileList(en,
false);
2815 generateFileList(en,
true);
2818 generateLinkToExample(en, exampleUrl);
2823
2824
2825
2826
2827
2831 QString exampleUrl(baseUrl);
2833#ifndef QT_BOOTSTRAPPED
2834 link = QUrl(exampleUrl).host();
2836 if (!link.isEmpty())
2837 link.prepend(
" @ ");
2838 link.prepend(
"Example project");
2840 const QLatin1Char separator(
'/');
2841 const QLatin1Char placeholder(
'\1');
2842 if (!exampleUrl.contains(placeholder)) {
2843 if (!exampleUrl.endsWith(separator))
2844 exampleUrl += separator;
2845 exampleUrl += placeholder;
2849 QStringList path = QStringList()
2851 path.removeAll(QString());
2855 startSection(
"Example project");
2857 m_writer->writeStartElement(dbNamespace,
"para");
2858 generateSimpleLink(exampleUrl.replace(placeholder, path.join(separator)), link);
2859 m_writer->writeEndElement();
2868
2869
2870
2871
2872
2873
2889 paths = en->images();
2892 paths = en->files();
2895 std::sort(paths.begin(), paths.end(), Generator::comparePaths);
2897 if (paths.isEmpty())
2900 startSection(
"",
"List of Files");
2902 m_writer->writeStartElement(dbNamespace,
"para");
2903 m_writer->writeCharacters(tag);
2904 m_writer->writeEndElement();
2907 startSection(
"List of Files");
2909 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
2912 for (
const auto &path : std::as_const(paths)) {
2913 auto maybe_resolved_file{file_resolver.resolve(path)};
2914 if (!maybe_resolved_file) {
2916 QString details = std::transform_reduce(
2917 file_resolver.get_search_directories().cbegin(),
2918 file_resolver.get_search_directories().cend(),
2919 u"Searched directories:"_s,
2921 [](
const DirectoryPath &directory_path) -> QString {
return u' ' + directory_path.value(); }
2924 en->location().warning(u"Cannot find file to quote from: %1"_s.arg(path), details);
2929 const auto &file{*maybe_resolved_file};
2930 if (images) addImageToCopy(en, file);
2931 else generateExampleFilePage(en, file);
2933 m_writer->writeStartElement(dbNamespace,
"listitem");
2935 m_writer->writeStartElement(dbNamespace,
"para");
2936 generateSimpleLink(file.get_query(), file.get_query());
2937 m_writer->writeEndElement();
2938 m_writer->writeEndElement();
2942 m_writer->writeEndElement();
2949
2950
2960 const auto en =
static_cast<
const ExampleNode *>(node);
2963 QXmlStreamWriter *currentWriter = m_writer;
2964 m_writer = startDocument(en, resolved_file.get_query());
2965 generateHeader(en->doc().title(), en->subtitle(), en);
2970 QString code = quoter.quoteTo(en->location(), QString(), QString());
2971 CodeMarker *codeMarker = CodeMarker::markerForFileName(resolved_file.get_path());
2977 m_writer = currentWriter;
2983 if (fn->overridesThis().isEmpty() || !fn
->parent()->isClassNode())
2988 if (
const FunctionNode *overrides = cn->findOverriddenFunction(fn);
2991 m_writer->writeStartElement(dbNamespace,
"para");
2992 m_writer->writeCharacters(
"Reimplements: ");
2995 generateFullName(overrides
->parent(), fullName, overrides);
2996 m_writer->writeCharacters(
".");
2997 m_writer->writeEndElement();
3003 if (
const PropertyNode *sameName = cn->findOverriddenProperty(fn); sameName && sameName
->hasDoc()) {
3004 m_writer->writeStartElement(dbNamespace,
"para");
3005 m_writer->writeCharacters(
"Reimplements an access function for property: ");
3006 QString fullName = sameName
->parent()->name() +
"::" + sameName->name();
3007 generateFullName(sameName
->parent(), fullName, sameName);
3008 m_writer->writeCharacters(
".");
3009 m_writer->writeEndElement();
3018 QList<Text> alsoList = node
->doc().alsoList();
3019 supplementAlsoList(node, alsoList);
3021 if (!alsoList.isEmpty()) {
3022 startSection(
"See Also");
3024 m_writer->writeStartElement(dbNamespace,
"para");
3025 m_writer->writeStartElement(dbNamespace,
"emphasis");
3026 m_writer->writeCharacters(
"See also ");
3027 m_writer->writeEndElement();
3030 m_writer->writeStartElement(dbNamespace,
"simplelist");
3031 m_writer->writeAttribute(
"type",
"vert");
3032 m_writer->writeAttribute(
"role",
"see-also");
3035 for (
const Text &text : alsoList) {
3036 m_writer->writeStartElement(dbNamespace,
"member");
3037 generateText(text, node);
3038 m_writer->writeEndElement();
3042 m_writer->writeEndElement();
3045 m_writer->writeEndElement();
3053
3054
3055
3056QXmlStreamWriter *
DocBookGenerator::startGenericDocument(
const Node *node,
const QString &fileName)
3059 QFile *outFile = openSubPageFile(
static_cast<
const PageNode*>(node), fileName);
3060 m_writer =
new QXmlStreamWriter(outFile);
3061 m_writer->setAutoFormatting(
false);
3063 m_writer->writeStartDocument();
3065 m_writer->writeNamespace(dbNamespace,
"db");
3066 m_writer->writeNamespace(xlinkNamespace,
"xlink");
3068 m_writer->writeNamespace(itsNamespace,
"its");
3069 m_writer->writeStartElement(dbNamespace,
"article");
3070 m_writer->writeAttribute(
"version",
"5.2");
3071 if (!m_naturalLanguage.isEmpty())
3072 m_writer->writeAttribute(
"xml:lang", m_naturalLanguage);
3076 sectionLevels.resize(0);
3085 m_hasSection =
false;
3088 QString fileName = Generator::fileName(node, fileExtension());
3089 return startGenericDocument(node, fileName);
3094 m_hasSection =
false;
3096 QString fileName = linkForExampleFile(file);
3097 return startGenericDocument(en, fileName);
3102 m_writer->writeEndElement();
3103 m_writer->writeEndDocument();
3105 m_writer->device()->close();
3106 delete m_writer->device();
3112
3113
3114
3119 const auto aggregate =
static_cast<
const Aggregate *>(node);
3123 QString subtitleText;
3124 const QString typeWord{aggregate->typeWord(
true)};
3125 if (aggregate->isNamespace()) {
3126 title =
"%1 %2"_L1.arg(aggregate->plainFullName(), typeWord);
3127 }
else if (aggregate->isClass()) {
3128 auto templateDecl = node->templateDecl();
3130 subtitleText =
"%1 %2 %3"_L1.arg((*templateDecl).to_qstring(),
3131 aggregate->typeWord(
false),
3132 aggregate->plainFullName());
3133 title =
"%1 %2"_L1.arg(aggregate->plainFullName(), typeWord);
3134 }
else if (aggregate->isHeader()) {
3135 title = aggregate->fullTitle();
3136 if (!aggregate->doc().title().isEmpty())
3137 titleText << aggregate->name() <<
" - "_L1 << aggregate->doc().title();
3141 m_writer = startDocument(node);
3144 if (!titleText.isEmpty())
3145 generateHeader(titleText, subtitleText, aggregate);
3147 generateHeader(title, subtitleText, aggregate);
3156 if (!aggregate->doc().isEmpty()) {
3157 startSection(
"details",
"Detailed Description");
3159 generateBody(aggregate);
3167 for (
const Section §ion : sectionVector) {
3168 if (section.members().isEmpty())
3171 startSection(section.title().toLower(), section.title());
3173 for (
const Node *member : section.members()) {
3174 if (member->nodeType() != NodeType::Class) {
3176 generateDetailedMember(member, aggregate);
3178 startSectionBegin();
3179 m_writer->writeCharacters(
"class ");
3180 generateFullName(member, aggregate);
3183 generateBrief(member);
3192 generateObsoleteMembers(sections);
3197void DocBookGenerator::generateSynopsisInfo(
const QString &key,
const QString &value)
3199 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3200 m_writer->writeAttribute(
"role", key);
3201 m_writer->writeCharacters(value);
3202 m_writer->writeEndElement();
3208 m_writer->writeTextElement(dbNamespace,
"modifier", value);
3213
3214
3224 if (!m_useDocBook52)
3234 node->isAggregate() ?
static_cast<
const Aggregate *>(node) :
nullptr;
3235 const ClassNode *classNode = node->isClass() ?
static_cast<
const ClassNode *>(node) :
nullptr;
3237 node->isFunction() ?
static_cast<
const FunctionNode *>(node) :
nullptr;
3239 node->isProperty() ?
static_cast<
const PropertyNode *>(node) :
nullptr;
3241 node->isVariable() ?
static_cast<
const VariableNode *>(node) :
nullptr;
3242 const EnumNode *enumNode = node->isEnumType() ?
static_cast<
const EnumNode *>(node) :
nullptr;
3244 node->isQmlProperty() ?
static_cast<
const QmlPropertyNode *>(node) :
nullptr;
3245 const QmlTypeNode *qcn = node->isQmlType() ?
static_cast<
const QmlTypeNode *>(node) :
nullptr;
3251 QString synopsisTag = nodeToSynopsisTag(node);
3252 m_writer->writeStartElement(dbNamespace, synopsisTag);
3257 m_writer->writeStartElement(dbNamespace,
"ooclass");
3258 m_writer->writeTextElement(dbNamespace,
"classname", node->plainName());
3259 m_writer->writeEndElement();
3262 m_writer->writeTextElement(dbNamespace,
"namespacename", node->plainName());
3265 m_writer->writeStartElement(dbNamespace,
"ooclass");
3266 m_writer->writeTextElement(dbNamespace,
"classname", node->plainName());
3267 m_writer->writeEndElement();
3269 if (!qcn->groupNames().isEmpty())
3270 m_writer->writeAttribute(
"groups", qcn->groupNames().join(QLatin1Char(
',')));
3272 m_writer->writeTextElement(dbNamespace,
"modifier",
"(Qt property)");
3274 m_writer->writeTextElement(dbNamespace,
"type", propertyNode->dataType());
3276 m_writer->writeTextElement(dbNamespace,
"varname", node->plainName());
3280 m_writer->writeTextElement(dbNamespace,
"modifier",
"static");
3283 m_writer->writeTextElement(dbNamespace,
"type", variableNode->dataType());
3285 m_writer->writeTextElement(dbNamespace,
"varname", node->plainName());
3289 m_writer->writeTextElement(dbNamespace,
"enumname", node->plainName());
3293 QString name = node->name();
3295 name.prepend(qpn->element() + QLatin1Char(
'.'));
3297 m_writer->writeTextElement(dbNamespace,
"type", qpn->dataType());
3299 m_writer->writeTextElement(dbNamespace,
"varname", name);
3307 m_writer->writeTextElement(dbNamespace,
"modifier",
"attached");
3311 m_writer->writeTextElement(dbNamespace,
"modifier",
"writable");
3315 m_writer->writeTextElement(dbNamespace,
"modifier",
"required");
3320 generateModifier(
"[read-only]");
3324 generateModifier(
"[default]");
3328 if (functionNode->virtualness() !=
"non")
3329 generateModifier(
"virtual");
3330 if (functionNode->isConst())
3331 generateModifier(
"const");
3332 if (functionNode->isStatic())
3333 generateModifier(
"static");
3338 if (functionNode->returnType() ==
"void")
3339 m_writer->writeEmptyElement(dbNamespace,
"void");
3341 m_writer->writeTextElement(dbNamespace,
"type", functionNode->returnTypeString());
3346 QString name = node->plainName();
3347 if (name.endsWith(
"()"))
3349 m_writer->writeTextElement(dbNamespace,
"methodname", name);
3353 m_writer->writeEmptyElement(dbNamespace,
"void");
3358 for (
int i = 0; i < lp
.count(); ++i) {
3360 m_writer->writeStartElement(dbNamespace,
"methodparam");
3362 m_writer->writeTextElement(dbNamespace,
"type", parameter.type());
3364 m_writer->writeTextElement(dbNamespace,
"parameter", parameter.name());
3366 if (!parameter.defaultValue().isEmpty()) {
3367 m_writer->writeTextElement(dbNamespace,
"initializer", parameter.defaultValue());
3370 m_writer->writeEndElement();
3374 if (functionNode->isImplicitlyGenerated())
3375 generateModifier(
"implicit");
3376 else if (functionNode->isExplicitlyDefaulted())
3377 generateModifier(
"default");
3378 else if (functionNode->isDeletedAsWritten())
3379 generateModifier(
"delete");
3380 if (functionNode->isFinal())
3381 generateModifier(
"final");
3382 if (functionNode->isOverride())
3383 generateModifier(
"override");
3385 m_writer->writeTextElement(dbNamespace,
"typedefname", node->plainName());
3389 QStringLiteral(
"Unexpected node type in generateDocBookSynopsis: %1")
3390 .arg(node->nodeTypeString()));
3396 for (
const EnumItem &item : enumNode->items()) {
3397 m_writer->writeStartElement(dbNamespace,
"enumitem");
3399 m_writer->writeTextElement(dbNamespace,
"enumidentifier", item.name());
3401 m_writer->writeTextElement(dbNamespace,
"enumvalue", item.value());
3403 m_writer->writeEndElement();
3407 if (enumNode->items().isEmpty()) {
3410 m_writer->writeStartElement(dbNamespace,
"enumitem");
3412 m_writer->writeEmptyElement(dbNamespace,
"enumidentifier");
3414 m_writer->writeEndElement();
3425 generateSynopsisInfo(
"meta", functionNode->metanessString());
3428 generateSynopsisInfo(
"overload",
"overload");
3429 generateSynopsisInfo(
"overload-number",
3430 QString::number(functionNode->overloadNumber()));
3433 if (functionNode->isRef())
3434 generateSynopsisInfo(
"refness", QString::number(1));
3435 else if (functionNode->isRefRef())
3436 generateSynopsisInfo(
"refness", QString::number(2));
3439 QStringList associatedProperties;
3440 const auto &nodes = functionNode->associatedProperties();
3441 for (
const Node *n : nodes) {
3442 const auto pn =
static_cast<
const PropertyNode *>(n);
3443 associatedProperties << pn->name();
3445 associatedProperties.sort();
3446 generateSynopsisInfo(
"associated-property",
3447 associatedProperties.join(QLatin1Char(
',')));
3453 signature +=
" final";
3455 signature +=
" override";
3457 signature +=
" = 0";
3459 signature +=
" = default";
3461 signature +=
" = delete";
3462 if (
const auto &req = functionNode->trailingRequiresClause(); req && !req->isEmpty())
3463 signature +=
" requires " + *req;
3464 generateSynopsisInfo(
"signature", signature);
3470 case Access::Public:
3471 generateSynopsisInfo(
"access",
"public");
3473 case Access::Protected:
3474 generateSynopsisInfo(
"access",
"protected");
3476 case Access::Private:
3477 generateSynopsisInfo(
"access",
"private");
3482 if (node->isAbstract())
3483 generateSynopsisInfo(
"abstract",
"true");
3488 case Status::Active:
3489 generateSynopsisInfo(
"status",
"active");
3491 case Status::Preliminary:
3492 generateSynopsisInfo(
"status",
3495 case Status::Deprecated:
3496 generateSynopsisInfo(
"status",
"deprecated");
3498 case Status::Internal:
3499 case Status::InternalAuto:
3500 generateSynopsisInfo(
"status",
"internal");
3503 generateSynopsisInfo(
"status",
"main");
3510 if (aggregate->includeFile()) generateSynopsisInfo(
"headers", *aggregate->includeFile());
3513 if (!aggregate->since().isEmpty())
3514 generateSynopsisInfo(
"since", formatSince(aggregate));
3518 if (!aggregate->physicalModuleName().isEmpty()) {
3520 m_qdb->getCollectionNode(aggregate->physicalModuleName(), NodeType::Module);
3522 if (
const auto result = cmakeRequisite(cn)) {
3523 generateSynopsisInfo(
"cmake-find-package", result->first);
3524 generateSynopsisInfo(
"cmake-target-link-libraries", result->second);
3527 if (cn && !cn->qtVariable().isEmpty())
3528 generateSynopsisInfo(
"qmake",
"QT += " + cn->qtVariable());
3534 auto *classe =
const_cast<ClassNode *>(
static_cast<
const ClassNode *>(aggregate));
3535 if (classe && classe->isQmlNativeType() && !classe->isInternal()) {
3536 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3537 m_writer->writeAttribute(
"role",
"nativeTypeFor");
3539 QList<QmlTypeNode *> nativeTypes { classe->qmlNativeTypes().cbegin(), classe->qmlNativeTypes().cend()};
3542 for (
auto item : std::as_const(nativeTypes)) {
3543 const Node *otherNode{
nullptr};
3544 Atom a = Atom(Atom::LinkNode, Utilities::stringForNode(item));
3545 const QString &link = getAutoLink(&a, aggregate, &otherNode);
3546 generateSimpleLink(link, item->name());
3549 m_writer->writeEndElement();
3553 QList<RelatedClass>::ConstIterator r;
3554 if (!classe->baseClasses().isEmpty()) {
3555 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3556 m_writer->writeAttribute(
"role",
"inherits");
3558 r = classe->baseClasses().constBegin();
3560 while (r != classe->baseClasses().constEnd()) {
3562 generateFullName((*r).m_node, classe);
3564 if ((*r).m_access == Access::Protected) {
3565 m_writer->writeCharacters(
" (protected)");
3566 }
else if ((*r).m_access == Access::Private) {
3567 m_writer->writeCharacters(
" (private)");
3569 m_writer->writeCharacters(
3570 TextUtils::comma(index++, classe->baseClasses().size()));
3575 m_writer->writeEndElement();
3580 if (!classe->derivedClasses().isEmpty()) {
3581 m_writer->writeStartElement(dbNamespace,
"synopsisinfo");
3582 m_writer->writeAttribute(
"role",
"inheritedBy");
3583 generateSortedNames(classe, classe->derivedClasses());
3584 m_writer->writeEndElement();
3593 QString logicalModuleVersion;
3595 m_qdb->getCollectionNode(qcn->logicalModuleName(), qcn->nodeType());
3597 logicalModuleVersion = collection->logicalModuleVersion();
3599 logicalModuleVersion = qcn->logicalModuleVersion();
3601 QStringList importText;
3602 importText <<
"import " + qcn->logicalModuleName();
3603 if (!logicalModuleVersion.isEmpty())
3604 importText << logicalModuleVersion;
3605 generateSynopsisInfo(
"import", importText.join(
' '));
3608 if (!qcn->since().isEmpty())
3609 generateSynopsisInfo(
"since", formatSince(qcn));
3612 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
3620 QStringList knownTypeNames{qcn->name()};
3622 knownTypeNames << base->name();
3627 if (!subs.isEmpty()) {
3628 m_writer->writeTextElement(dbNamespace,
"synopsisinfo");
3629 m_writer->writeAttribute(
"role",
"inheritedBy");
3630 generateSortedQmlNames(qcn, knownTypeNames, subs);
3631 m_writer->writeEndElement();
3637 const Node *otherNode =
nullptr;
3639 QString link = getAutoLink(&a, base, &otherNode);
3641 m_writer->writeTextElement(dbNamespace,
"synopsisinfo");
3642 m_writer->writeAttribute(
"role",
"inherits");
3643 generateSimpleLink(link, base->name());
3645 for (
const auto sub : std::as_const(subs)) {
3646 if (knownTypeNames.contains(sub->name())) {
3647 m_writer->writeCharacters(
" (%1)"_L1.arg(base->logicalModuleName()));
3651 m_writer->writeEndElement();
3659 const Node *otherNode =
nullptr;
3661 QString link = getAutoLink(&a, cn, &otherNode);
3663 m_writer->writeTextElement(dbNamespace,
"synopsisinfo");
3664 m_writer->writeAttribute(
"role",
"nativeType");
3665 generateSimpleLink(link, cn->name());
3666 m_writer->writeEndElement();
3673 case Node::UnspecifiedSafeness:
3674 generateSynopsisInfo(
"threadsafeness",
"unspecified");
3676 case Node::NonReentrant:
3677 generateSynopsisInfo(
"threadsafeness",
"non-reentrant");
3679 case Node::Reentrant:
3680 generateSynopsisInfo(
"threadsafeness",
"reentrant");
3682 case Node::ThreadSafe:
3683 generateSynopsisInfo(
"threadsafeness",
"thread safe");
3686 generateSynopsisInfo(
"threadsafeness",
"unspecified");
3691 if (!node->physicalModuleName().isEmpty())
3692 generateSynopsisInfo(
"module", node->physicalModuleName());
3695 if (classNode && !classNode->groupNames().isEmpty()) {
3696 generateSynopsisInfo(
"groups", classNode->groupNames().join(QLatin1Char(
',')));
3697 }
else if (qcn && !qcn->groupNames().isEmpty()) {
3698 generateSynopsisInfo(
"groups", qcn->groupNames().join(QLatin1Char(
',')));
3703 for (
const Node *fnNode : propertyNode->getters()) {
3705 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3706 generateSynopsisInfo(
"getter", funcNode->name());
3709 for (
const Node *fnNode : propertyNode->setters()) {
3711 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3712 generateSynopsisInfo(
"setter", funcNode->name());
3715 for (
const Node *fnNode : propertyNode->resetters()) {
3717 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3718 generateSynopsisInfo(
"resetter", funcNode->name());
3721 for (
const Node *fnNode : propertyNode->notifiers()) {
3723 const auto funcNode =
static_cast<
const FunctionNode *>(fnNode);
3724 generateSynopsisInfo(
"notifier", funcNode->name());
3729 m_writer->writeEndElement();
3735 m_writer->writeStartElement(dbNamespace,
"typedefsynopsis");
3738 m_writer->writeTextElement(dbNamespace,
"typedefname",
3739 enumNode->flagsType()->fullDocumentName());
3742 m_writer->writeEndElement();
3753 return node->name().mid(4);
3754 return node->name();
3758
3759
3760
3761void DocBookGenerator::typified(
const QString &string,
const Node *relative,
bool trailingSpace,
3766 QString pendingWord;
3768 for (
int i = 0; i <= string.size(); ++i) {
3770 if (i != string.size())
3773 QChar lower = ch.toLower();
3774 if ((lower >= QLatin1Char(
'a') && lower <= QLatin1Char(
'z')) || ch.digitValue() >= 0
3775 || ch == QLatin1Char(
'_') || ch == QLatin1Char(
':')) {
3778 if (!pendingWord.isEmpty()) {
3779 bool isProbablyType = (pendingWord != QLatin1String(
"const"));
3780 if (generateType && isProbablyType) {
3782 m_writer->writeCharacters(result);
3786 const Node *n = m_qdb->findTypeNode(pendingWord, relative, Genus::DontCare);
3791 href = linkForNode(n, relative);
3794 m_writer->writeStartElement(dbNamespace,
"type");
3796 m_writer->writeCharacters(pendingWord);
3798 generateSimpleLink(href, pendingWord);
3799 m_writer->writeEndElement();
3801 result += pendingWord;
3804 pendingWord.clear();
3806 if (ch.unicode() !=
'\0')
3811 if (trailingSpace && string.size()) {
3812 if (!string.endsWith(QLatin1Char(
'*')) && !string.endsWith(QLatin1Char(
'&')))
3813 result += QLatin1Char(
' ');
3816 m_writer->writeCharacters(result);
3820 bool generateNameLink)
3824 QString name = taggedNode(node);
3826 if (!generateNameLink) {
3827 m_writer->writeCharacters(name);
3831 m_writer->writeStartElement(dbNamespace,
"emphasis");
3832 m_writer->writeAttribute(
"role",
"bold");
3833 generateSimpleLink(linkForNode(node, relative), name);
3834 m_writer->writeEndElement();
3838 bool generateExtra,
bool generateType)
3840 const QString &pname = parameter.name();
3841 const QString &ptype = parameter.type();
3843 qsizetype insertPos = !pname.isEmpty() ? parameter.nameInsertionPoint() : -1;
3844 if (!pname.isEmpty()) {
3845 if (insertPos >= 0) {
3847 typified(ptype.left(insertPos), relative,
false, generateType);
3849 typified(ptype, relative,
true, generateType);
3856 if (generateExtra || pname.isEmpty()) {
3857 m_writer->writeStartElement(dbNamespace,
"emphasis");
3858 m_writer->writeCharacters(paramName);
3859 m_writer->writeEndElement();
3863 typified(ptype.mid(insertPos), relative,
false, generateType);
3865 const QString &pvalue = parameter.defaultValue();
3866 if (generateExtra && !pvalue.isEmpty())
3867 m_writer->writeCharacters(
" = " + pvalue);
3879 const int MaxEnumValues = 6;
3881 if (generateExtra) {
3882 if (
auto extra = CodeMarker::extraSynopsis(node, style); !extra.isEmpty()) {
3883 generateExtraSynopsis(extra);
3884 m_writer->writeCharacters(u" "_s);
3889 QString namePrefix {};
3893 namePrefix = taggedNode(node->parent()) +
"::";
3898 case NodeType::Namespace:
3899 m_writer->writeCharacters(
"namespace ");
3900 m_writer->writeCharacters(namePrefix);
3901 generateSynopsisName(node, relative, generateNameLink);
3903 case NodeType::Class:
3904 m_writer->writeCharacters(
"class ");
3905 m_writer->writeCharacters(namePrefix);
3906 generateSynopsisName(node, relative, generateNameLink);
3912 if (
auto templateDecl = func->templateDecl()) {
3913 if (templateDecl->visibleParameterCount() > QDoc::MultilineTemplateParamThreshold)
3914 m_writer->writeCharacters(templateDecl->to_qstring_multiline() + QLatin1Char(
'\n'));
3916 m_writer->writeCharacters(templateDecl->to_qstring() + QLatin1Char(
' '));
3922 if (!func->isNonvirtual())
3923 m_writer->writeCharacters(QStringLiteral(
"virtual "));
3927 if (style != Section::AllMembers && !func->returnType().isEmpty())
3928 typified(func->returnTypeString(), relative,
true, generateType);
3929 m_writer->writeCharacters(namePrefix);
3930 generateSynopsisName(node, relative, generateNameLink);
3933 m_writer->writeCharacters(QStringLiteral(
"("));
3936 for (
int i = 0; i < parameters
.count(); i++) {
3938 m_writer->writeCharacters(QStringLiteral(
", "));
3939 generateParameter(parameters
.at(i
), relative, generateExtra, generateType);
3942 m_writer->writeCharacters(QStringLiteral(
")"));
3945 if (func->isConst())
3946 m_writer->writeCharacters(QStringLiteral(
" const"));
3952 synopsis += QStringLiteral(
" final");
3954 synopsis += QStringLiteral(
" override");
3956 synopsis += QStringLiteral(
" = 0");
3958 synopsis += QStringLiteral(
" &");
3960 synopsis += QStringLiteral(
" &&");
3961 m_writer->writeCharacters(synopsis);
3963 if (!func->returnType().isEmpty() && func->returnType() !=
"void") {
3964 m_writer->writeCharacters(QStringLiteral(
" : "));
3965 typified(func->returnTypeString(), relative,
false, generateType);
3970 synopsis += QStringLiteral(
" &");
3972 synopsis += QStringLiteral(
" &&");
3973 if (
const auto &req = func->trailingRequiresClause(); req && !req->isEmpty())
3974 synopsis +=
" requires " + *req;
3975 m_writer->writeCharacters(synopsis);
3979 const auto enume =
static_cast<
const EnumNode *>(node);
3980 if (!enume->isAnonymous()) {
3981 m_writer->writeCharacters(
"enum "_L1);
3982 m_writer->writeCharacters(namePrefix);
3983 generateSynopsisName(node, relative, generateNameLink);
3984 }
else if (generateNameLink) {
3985 m_writer->writeStartElement(dbNamespace,
"emphasis");
3986 m_writer->writeAttribute(
"role",
"bold");
3987 generateSimpleLink(linkForNode(node, relative),
"enum");
3988 m_writer->writeEndElement();
3990 m_writer->writeCharacters(
"enum"_L1);
3997 QStringList documentedItems = enume->doc().enumItemNames();
3998 if (documentedItems.isEmpty()) {
3999 const auto &enumItems = enume->items();
4000 for (
const auto &item : enumItems)
4001 documentedItems << item.name();
4003 const QStringList omitItems = enume->doc().omitEnumItemNames();
4004 for (
const auto &item : omitItems)
4005 documentedItems.removeAll(item);
4007 if (documentedItems.size() > MaxEnumValues) {
4009 const QString last = documentedItems.last();
4010 documentedItems = documentedItems.mid(0, MaxEnumValues - 1);
4011 documentedItems +=
"…";
4012 documentedItems += last;
4014 synopsis += documentedItems.join(QLatin1String(
", "));
4016 if (!documentedItems.isEmpty())
4017 synopsis += QLatin1Char(
' ');
4018 synopsis += QLatin1Char(
'}');
4020 m_writer->writeCharacters(synopsis);
4024 if (
auto templateDecl = node->templateDecl()) {
4025 if (templateDecl->visibleParameterCount() > QDoc::MultilineTemplateParamThreshold)
4026 m_writer->writeCharacters(templateDecl->to_qstring_multiline() + QLatin1Char(
'\n'));
4028 m_writer->writeCharacters(templateDecl->to_qstring() + QLatin1Char(
' '));
4031 m_writer->writeCharacters(namePrefix);
4032 generateSynopsisName(node, relative, generateNameLink);
4035 if (
static_cast<
const TypedefNode *>(node)->associatedEnum())
4036 m_writer->writeCharacters(
"flags ");
4037 m_writer->writeCharacters(namePrefix);
4038 generateSynopsisName(node, relative, generateNameLink);
4041 const auto property =
static_cast<
const PropertyNode *>(node);
4042 m_writer->writeCharacters(namePrefix);
4043 generateSynopsisName(node, relative, generateNameLink);
4044 m_writer->writeCharacters(
" : ");
4045 typified(property->qualifiedDataType(), relative,
false, generateType);
4048 const auto variable =
static_cast<
const VariableNode *>(node);
4050 generateSynopsisName(node, relative, generateNameLink);
4051 m_writer->writeCharacters(
" : ");
4052 typified(variable->dataType(), relative,
false, generateType);
4054 typified(variable->leftType(), relative,
false, generateType);
4055 m_writer->writeCharacters(
" ");
4056 m_writer->writeCharacters(namePrefix);
4057 generateSynopsisName(node, relative, generateNameLink);
4058 m_writer->writeCharacters(variable->rightType());
4062 m_writer->writeCharacters(namePrefix);
4063 generateSynopsisName(node, relative, generateNameLink);
4078 if (nativeEnum && nativeEnum
->enumNode() && !enumValue.startsWith(
"%1."_L1.arg(nativeEnum->prefix()))) {
4079 m_writer->writeCharacters(
"%1.%2"_L1.arg(nativeEnum->prefix(), enumValue));
4085 && enumValue.section(
' ', 0, 0).contains(
'.'_L1))) {
4086 m_writer->writeCharacters(enumValue);
4090 QList<
const Node *> parents;
4092 parents.prepend(node);
4097 if (
static_cast<
const EnumNode *>(relative)->isScoped())
4098 parents << relative;
4100 m_writer->writeStartElement(dbNamespace,
"code");
4101 for (
auto parent : parents) {
4102 generateSynopsisName(parent, relative,
true);
4103 m_writer->writeCharacters((relative->genus() == Genus::QML) ?
"."_L1 :
"::"_L1);
4106 m_writer->writeCharacters(enumValue);
4107 m_writer->writeEndElement();
4111
4112
4113
4118 Q_ASSERT(node && !node->name().isEmpty());
4124 m_writer->writeStartElement(dbNamespace,
"note");
4131 m_writer->writeStartElement(dbNamespace,
"para");
4132 m_writer->writeCharacters(
4133 "This function can be invoked via the meta-object system and from QML. See ");
4134 generateSimpleLink(node->url(),
"Q_INVOKABLE");
4135 m_writer->writeCharacters(
".");
4136 m_writer->writeEndElement();
4140 m_writer->writeTextElement(
4141 dbNamespace,
"para",
4142 "This is a private signal. It can be used in signal connections but "
4143 "cannot be emitted by the user.");
4147 QString handler(node->name());
4148 int prefixLocation = handler.lastIndexOf(
'.', -2) + 1;
4149 handler[prefixLocation] = handler[prefixLocation].toTitleCase();
4150 handler.insert(prefixLocation, QLatin1String(
"on"));
4151 m_writer->writeStartElement(dbNamespace,
"para");
4152 m_writer->writeCharacters(
"The corresponding handler is ");
4153 m_writer->writeTextElement(dbNamespace,
"code", handler);
4154 m_writer->writeCharacters(
".");
4155 m_writer->writeEndElement();
4163 const auto *fn =
static_cast<
const FunctionNode *>(node);
4164 auto nodes = fn->associatedProperties();
4165 if (nodes.isEmpty())
4170 QMap<PropertyNode::FunctionRole, QList<
const PropertyNode *>> roleGroups;
4171 for (
const auto *n : std::as_const(nodes)) {
4172 const auto *pn =
static_cast<
const PropertyNode *>(n);
4173 PropertyNode::FunctionRole role = pn->role(fn);
4174 roleGroups[role].append(pn);
4186 for (
auto role : roleOrder) {
4187 const auto it = roleGroups.constFind(role);
4188 if (it == roleGroups.cend())
4191 const auto &properties = it.value();
4196 msg = QStringLiteral(
"Getter function");
4199 msg = QStringLiteral(
"Setter function");
4202 msg = QStringLiteral(
"Resetter function");
4205 msg = QStringLiteral(
"Notifier signal");
4208 msg = QStringLiteral(
"Bindable function");
4214 m_writer->writeStartElement(dbNamespace,
"para");
4215 if (properties.size() == 1) {
4216 const auto *pn = properties.first();
4217 m_writer->writeCharacters(msg +
" for property ");
4218 generateSimpleLink(linkForNode(pn,
nullptr), pn->name());
4219 m_writer->writeCharacters(
". ");
4221 m_writer->writeCharacters(msg +
" for properties ");
4222 for (qsizetype i = 0; i < properties.size(); ++i) {
4223 const auto *pn = properties.at(i);
4224 generateSimpleLink(linkForNode(pn,
nullptr), pn->name());
4225 m_writer->writeCharacters(TextUtils::separator(i, properties.size()));
4227 m_writer->writeCharacters(
" ");
4229 m_writer->writeEndElement();
4236 const Node *linkNode;
4238 QString link = getAutoLink(&linkAtom, node, &linkNode);
4239 m_writer->writeStartElement(dbNamespace,
"para");
4240 m_writer->writeCharacters(
"This property supports ");
4241 generateSimpleLink(link,
"QProperty");
4242 m_writer->writeCharacters(
" bindings.");
4243 m_writer->writeEndElement();
4248 const auto *func =
static_cast<
const FunctionNode *>(node);
4251 if (func->isPrimaryOverload())
4254 m_writer->writeStartElement(dbNamespace,
"para");
4256 if (func->isSignal() || func->isSlot()) {
4257 auto writeDocBookLink = [&](
const QString &target,
const QString &label) {
4258 const Node *linkNode =
nullptr;
4260 const QString &link = getAutoLink(&linkAtom, node, &linkNode);
4262 m_writer->writeStartElement(dbNamespace,
"link");
4263 if (!link.isEmpty() && linkNode) {
4264 m_writer->writeAttribute(xlinkNamespace,
"href", link);
4266 m_writer->writeAttribute(dbNamespace,
"linkend", target);
4268 m_writer->writeCharacters(label);
4269 m_writer->writeEndElement();
4272 const QString &functionType = func->isSignal() ?
"signal" :
"slot";
4273 const QString &configKey = func->isSignal() ?
"overloadedsignalstarget" :
"overloadedslotstarget";
4274 const QString &defaultTarget = func->isSignal() ?
"connecting-overloaded-signals" :
"connecting-overloaded-slots";
4275 const QString &linkTarget = Config::instance().get(configKey).asString(defaultTarget);
4277 m_writer->writeCharacters(
"This " + functionType +
" is overloaded. ");
4279 QString snippet = generateOverloadSnippet(func);
4280 if (!snippet.isEmpty()) {
4281 m_writer->writeCharacters(
"To connect to this " + functionType +
":");
4282 m_writer->writeEndElement();
4284 m_writer->writeStartElement(dbNamespace,
"programlisting");
4285 m_writer->writeCharacters(snippet);
4286 m_writer->writeEndElement();
4291 m_writer->writeStartElement(dbNamespace,
"para");
4292 if (!linkTarget.isEmpty()) {
4293 m_writer->writeCharacters(
"For more examples and approaches, see ");
4294 writeDocBookLink(linkTarget,
"connecting to overloaded " + functionType +
"s");
4295 m_writer->writeCharacters(
".");
4297 }
else if (!linkTarget.isEmpty()) {
4298 m_writer->writeCharacters(
"For more examples and approaches, see ");
4299 writeDocBookLink(linkTarget,
"connecting to overloaded " + functionType +
"s");
4300 m_writer->writeCharacters(
".");
4304 const auto &args = node
->doc().overloadList();
4305 if (args.first().first.isEmpty()) {
4306 m_writer->writeCharacters(
"This is an overloaded function.");
4308 QString target = args.first().first;
4311 if (!target.contains(
"::")) {
4314 target = parent->name() +
"::" + target;
4317 m_writer->writeCharacters(
"This function overloads ");
4319 const Node *linkNode =
nullptr;
4321 QString link = getAutoLink(&linkAtom, node, &linkNode);
4322 if (!link.isEmpty() && linkNode)
4323 generateSimpleLink(link, target);
4325 m_writer->writeCharacters(target);
4326 m_writer->writeCharacters(
".");
4330 m_writer->writeEndElement();
4339 m_writer->writeEndElement();
4347 bool closeSupplementarySection =
false;
4351 const QList<Node *> &collective = scn->collective();
4353 bool firstFunction =
true;
4354 for (
const auto *sharedNode : collective) {
4355 if (firstFunction) {
4356 startSectionBegin(sharedNode);
4358 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4359 m_writer->writeAttribute(
"renderas",
"sect2");
4360 writeXmlId(sharedNode);
4363 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4365 generateSynopsis(sharedNode, relative, Section::Details);
4367 if (firstFunction) {
4369 firstFunction =
false;
4371 m_writer->writeEndElement();
4377 if (node->isEnumType(Genus::CPP) && (etn =
static_cast<
const EnumNode *>(node))->flagsType()) {
4378 startSectionBegin(node);
4380 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4384 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4385 m_writer->writeAttribute(
"renderas",
"sect2");
4387 m_writer->writeEndElement();
4390 startSectionBegin(node);
4392 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4397 Q_ASSERT(m_hasSection);
4406 closeSupplementarySection =
true;
4407 startSection(
"",
"Notes");
4411 const auto *func =
static_cast<
const FunctionNode *>(node);
4412 if (func->hasOverloads() && (func->isSignal() || func->isSlot()))
4420 const auto property =
static_cast<
const PropertyNode *>(node);
4429 m_writer->writeStartElement(dbNamespace,
"para");
4431 m_writer->writeStartElement(dbNamespace,
"emphasis");
4432 m_writer->writeAttribute(
"role",
"bold");
4433 m_writer->writeCharacters(
"Access functions:");
4435 m_writer->writeEndElement();
4437 m_writer->writeEndElement();
4439 generateSectionList(section, node);
4446 m_writer->writeStartElement(dbNamespace,
"para");
4448 m_writer->writeStartElement(dbNamespace,
"emphasis");
4449 m_writer->writeAttribute(
"role",
"bold");
4450 m_writer->writeCharacters(
"Notifier signal:");
4452 m_writer->writeEndElement();
4454 m_writer->writeEndElement();
4456 generateSectionList(notifiers, node);
4460 const auto en =
static_cast<
const EnumNode *>(node);
4462 if (m_qflagsHref.isEmpty()) {
4463 Node *qflags = m_qdb->findClassNode(QStringList(
"QFlags"));
4465 m_qflagsHref = linkForNode(qflags,
nullptr);
4468 if (en->flagsType()) {
4469 m_writer->writeStartElement(dbNamespace,
"para");
4470 m_writer->writeCharacters(
"The ");
4471 m_writer->writeStartElement(dbNamespace,
"code");
4472 m_writer->writeCharacters(en->flagsType()->name());
4473 m_writer->writeEndElement();
4474 m_writer->writeCharacters(
" type is a typedef for ");
4475 m_writer->writeStartElement(dbNamespace,
"code");
4476 generateSimpleLink(m_qflagsHref,
"QFlags");
4477 m_writer->writeCharacters(
"<" + en->name() +
">. ");
4478 m_writer->writeEndElement();
4479 m_writer->writeCharacters(
"It stores an OR combination of ");
4480 m_writer->writeStartElement(dbNamespace,
"code");
4481 m_writer->writeCharacters(en->name());
4482 m_writer->writeEndElement();
4483 m_writer->writeCharacters(
" values.");
4484 m_writer->writeEndElement();
4489 if (closeSupplementarySection)
4500 bool useObsoleteMembers)
4505 if (!members.isEmpty()) {
4506 bool hasPrivateSignals =
false;
4507 bool isInvokable =
false;
4509 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
4511 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4514 NodeVector::ConstIterator m = members.constBegin();
4515 while (m != members.constEnd()) {
4516 if ((*m)->access() == Access::Private) {
4521 m_writer->writeStartElement(dbNamespace,
"listitem");
4523 m_writer->writeStartElement(dbNamespace,
"para");
4526 generateSynopsis(*m, relative, section
.style());
4527 if ((*m)->isFunction()) {
4529 if (fn->isPrivateSignal())
4530 hasPrivateSignals =
true;
4531 else if (fn->isInvokable())
4535 m_writer->writeEndElement();
4537 m_writer->writeEndElement();
4543 m_writer->writeEndElement();
4546 if (hasPrivateSignals)
4553 && !section.inheritedMembers().isEmpty()) {
4554 m_writer->writeStartElement(dbNamespace,
"itemizedlist");
4556 m_writer->writeAttribute(itsNamespace,
"translate",
"no");
4559 generateSectionInheritedList(section, relative);
4561 m_writer->writeEndElement();
4569 QList<std::pair<
const Aggregate *,
int>>::ConstIterator p = section.inheritedMembers().constBegin();
4570 while (p != section.inheritedMembers().constEnd()) {
4571 m_writer->writeStartElement(dbNamespace,
"listitem");
4572 m_writer->writeCharacters(QString::number((*p).second) + u' ');
4573 if ((*p).second == 1)
4574 m_writer->writeCharacters(section.singular());
4576 m_writer->writeCharacters(section.plural());
4577 m_writer->writeCharacters(
" inherited from ");
4578 generateSimpleLink(fileName((*p).first) +
'#'
4579 + Generator::cleanRef(section.title().toLower()),
4580 (*p).first->plainFullName(relative));
4586
4587
4588
4592 Q_ASSERT(m_writer ==
nullptr);
4593 m_writer = startDocument(pn);
4595 generateHeader(pn->doc().title(), pn->subtitle(), pn);
4604
4605
4610 Q_ASSERT(m_writer ==
nullptr);
4611 m_writer = startDocument(qcn);
4614 QString title = qcn->name();
4616 title.append(
" QML Value Type");
4618 title.append(
" QML Type");
4621 title.append(
" (Singleton)");
4623 title.append(
" (Uncreatable)");
4629 generateHeader(title, qcn->subtitle(), qcn);
4634 m_writer->writeStartElement(dbNamespace,
"note");
4635 m_writer->writeStartElement(dbNamespace,
"para");
4636 m_writer->writeStartElement(dbNamespace,
"emphasis");
4637 m_writer->writeAttribute(
"role",
"bold");
4638 m_writer->writeCharacters(
"Note: ");
4639 m_writer->writeEndElement();
4640 if (qcn->isSingleton())
4641 m_writer->writeCharacters(
"This type is a QML singleton. "
4642 "There is only one instance of this type in the QML engine.");
4644 m_writer->writeCharacters(
"This is an uncreatable type. "
4645 "It cannot be instantiated in QML.");
4646 m_writer->writeEndElement();
4647 m_writer->writeEndElement();
4650 startSection(
"details",
"Detailed Description");
4658 for (
const auto §ion : sections.detailsSections()) {
4659 if (!section.isEmpty()) {
4660 startSection(section.title().toLower(), section.title());
4662 for (
const auto &member : section.members())
4663 generateDetailedQmlMember(member, qcn);
4669 generateObsoleteQmlMembers(sections);
4678
4679
4680
4687 if (!title.isEmpty())
4691 title += n->element() + QLatin1Char(
'.');
4692 title += n->name() +
" : " + n->dataType();
4697 auto generateQmlMethodTitle = [&](
Node *node) {
4702 const auto *scn =
static_cast<
const SharedCommentNode *>(node);
4705 if (!scn->name().isEmpty())
4706 heading = scn->name() +
" group";
4708 heading = node->name();
4709 startSection(scn, heading);
4714 const QList<Node *> sharedNodes = scn->collective();
4715 for (
const auto &sharedNode : sharedNodes) {
4716 if (sharedNode->isQmlProperty()) {
4717 auto *qpn =
static_cast<QmlPropertyNode *>(sharedNode);
4719 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4720 m_writer->writeAttribute(
"renderas",
"sect2");
4722 m_writer->writeCharacters(getQmlPropertyTitle(qpn));
4723 m_writer->writeEndElement();
4726 generateDocBookSynopsis(qpn);
4730 auto qpn =
static_cast<QmlPropertyNode *>(node);
4731 startSection(qpn, getQmlPropertyTitle(qpn));
4735 const QList<Node *> &sharedNodes = scn->collective();
4740 for (
const auto &sharedNode : sharedNodes) {
4742 if (!sharedNode->isFunction(Genus::QML) && !sharedNode->isQmlProperty()) {
4748 startSectionBegin(sharedNode);
4750 m_writer->writeStartElement(dbNamespace,
"bridgehead");
4751 m_writer->writeAttribute(
"renderas",
"sect2");
4755 if (sharedNode->isFunction(Genus::QML))
4756 generateQmlMethodTitle(sharedNode);
4757 else if (sharedNode->isQmlProperty())
4758 m_writer->writeCharacters(
4759 getQmlPropertyTitle(
static_cast<QmlPropertyNode *>(sharedNode)));
4765 m_writer->writeEndElement();
4766 generateDocBookSynopsis(sharedNode);
4772 startSectionBegin(refForNode(node));
4775 generateQmlMethodTitle(node);
4776 else if (node->isQmlProperty())
4777 m_writer->writeCharacters(
4778 getQmlPropertyTitle(
static_cast<QmlPropertyNode *>(node)));
4783 startSectionBegin(node);
4787 startSectionBegin(node);
4788 generateQmlMethodTitle(node);
4802
4803
4810 if (!node->url().isNull())
4814 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842 auto cn =
static_cast<CollectionNode *>(node);
4843 if (cn->wasSeen()) {
4844 m_qdb->mergeCollections(cn);
4845 generateCollectionNode(cn);
4846 }
else if (cn->isGenericCollection()) {
4850 generateGenericCollectionPage(cn);
4853 generatePageNode(
static_cast<PageNode *>(node));
4857 generateCppReferencePage(
static_cast<Aggregate *>(node));
4859 generateQmlTypePage(
static_cast<QmlTypeNode *>(node));
4861 generateProxyPage(
static_cast<Aggregate *>(node));
4867 auto *aggregate =
static_cast<Aggregate *>(node);
4868 for (
auto c : aggregate->childNodes()) {
4869 if (node->isPageNode())
4870 generateDocumentation(c);
4881 Q_ASSERT(m_writer ==
nullptr);
4882 m_writer = startDocument(aggregate);
4885 generateHeader(aggregate->plainFullName(),
"", aggregate);
4890 if (!aggregate
->doc().isEmpty()) {
4891 startSection(
"details",
"Detailed Description");
4893 generateBody(aggregate);
4902 for (
const auto §ion : detailsSections) {
4903 if (section.isEmpty())
4906 startSection(section.title().toLower(), section.title());
4908 const QList<Node *> &members = section.members();
4909 for (
const auto &member : members) {
4910 if (!member->isClassNode()) {
4911 generateDetailedMember(member, aggregate);
4913 startSectionBegin();
4914 generateFullName(member, aggregate);
4917 generateBrief(member);
4931
4932
4937 Q_ASSERT(m_writer ==
nullptr);
4938 m_writer = startDocument(cn);
4941 generateHeader(cn->doc().title(), cn->subtitle(), cn);
4947 if (cn
->genus() != Genus::DOC && cn
->genus() != Genus::DontCare) {
4958 if (!nmm.isEmpty()) {
4959 startSection(
"namespaces",
"Namespaces");
4960 generateAnnotatedList(cn, nmm.values(),
"namespaces");
4964 if (!nmm.isEmpty()) {
4965 startSection(
"classes",
"Classes");
4966 generateAnnotatedList(cn, nmm.values(),
"classes");
4972 bool generatedTitle =
false;
4974 startSection(
"details",
"Detailed Description");
4975 generatedTitle =
true;
4980 !cn
->doc().body().isEmpty() ||
4982 !cn
->doc().alsoList().empty() ||
4985 writeAnchor(
"details");
4991 if (!cn->noAutoList() && (cn->isGroup() || cn->isQmlModule()))
4992 generateAnnotatedList(cn, cn->members(),
"members", AutoSection);
5003
5004
5005
5006
5011 QString name = cn->name().toLower();
5012 name.replace(QChar(
' '), QString(
"-"));
5013 QString filename = cn->tree()->physicalModuleName() +
"-" + name +
"." + fileExtension();
5016 Q_ASSERT(m_writer ==
nullptr);
5017 m_writer = startGenericDocument(cn, filename);
5020 generateHeader(cn->fullTitle(), cn->subtitle(), cn);
5026 m_writer->writeStartElement(dbNamespace,
"para");
5027 m_writer->writeCharacters(
"Each function or type documented here is related to a class or "
5028 "namespace that is documented in a different module. The reference "
5029 "page for that class or namespace will link to the function or type "
5031 m_writer->writeEndElement();
5035 for (
const auto &member : members)
5036 generateDetailedMember(member, cnc);
5049 m_writer->writeStartElement(dbNamespace,
"link");
5050 m_writer->writeAttribute(xlinkNamespace,
"href", fullDocumentLocation(node));
5051 m_writer->writeAttribute(xlinkNamespace,
"role", targetType(node));
5052 m_writer->writeCharacters(node->fullName(relative));
5053 m_writer->writeEndElement();
5057 const Node *actualNode)
5059 Q_ASSERT(apparentNode);
5060 Q_ASSERT(actualNode);
5063 m_writer->writeStartElement(dbNamespace,
"link");
5064 m_writer->writeAttribute(xlinkNamespace,
"href", fullDocumentLocation(actualNode));
5065 m_writer->writeAttribute(
"role", targetType(actualNode));
5066 m_writer->writeCharacters(fullName);
5067 m_writer->writeEndElement();
#define ATOM_FORMATTING_TELETYPE
#define ATOM_LIST_LOWERALPHA
#define ATOM_FORMATTING_UNDERLINE
#define ATOM_LIST_UPPERALPHA
#define ATOM_FORMATTING_NOTRANSLATE
#define ATOM_LIST_LOWERROMAN
#define ATOM_FORMATTING_SUBSCRIPT
#define ATOM_FORMATTING_BOLD
#define ATOM_FORMATTING_TRADEMARK
#define ATOM_FORMATTING_ITALIC
#define ATOM_LIST_UPPERROMAN
#define ATOM_FORMATTING_LINK
#define ATOM_FORMATTING_SUPERSCRIPT
#define ATOM_FORMATTING_UICONTROL
#define ATOM_FORMATTING_PARAMETER
The Atom class is the fundamental unit for representing documents internally.
AtomType type() const
Return the type of this atom.
const Atom * next() const
Return the next atom in the atom list.
The ClassNode represents a C++ class.
virtual Atom::AtomType atomType() const
A class for holding the members of a collection of doc pages.
const NodeList & members() const
NodeMap getMembers(NodeType type) const
void generatePageNode(PageNode *pn)
Generate the DocBook page for an entity that doesn't map to any underlying parsable C++ or QML elemen...
void generateQmlTypePage(QmlTypeNode *qcn)
Generate the DocBook page for a QML type.
void generateAlsoList(const Node *node) override
void generateQmlRequisites(const QmlTypeNode *qcn)
Lists the required imports and includes.
void generateAddendum(const Node *node, Generator::Addendum type, CodeMarker *marker, AdmonitionPrefix prefix) override
Generates an addendum note of type type for node.
void initializeGenerator() override
Initializes the DocBook output generator's data structures from the configuration (Config).
bool generateText(const Text &text, const Node *relative) override
Generate the documentation for relative.
void generateCppReferencePage(Node *node)
Generate a reference page for the C++ class, namespace, or header file documented in node.
void generateSortedQmlNames(const Node *base, const QStringList &knownTypes, const NodeList &subs)
DocBookGenerator(FileResolver &file_resolver)
bool generateThreadSafeness(const Node *node)
Generates text that explains how threadsafe and/or reentrant node is.
void generateCollectionNode(CollectionNode *cn)
Generate the HTML page for a group, module, or QML module.
void generateHeader(const Text &title, const QString &subtitle, const Node *node)
void generateDocBookSynopsis(const Node *node)
Generate the metadata for the given node in DocBook.
void generateGenericCollectionPage(CollectionNode *cn)
Generate the HTML page for a generic collection.
void generateList(const Node *relative, const QString &selector, Qt::SortOrder sortOrder=Qt::AscendingOrder)
void generateBody(const Node *node)
Generate the body of the documentation from the qdoc comment found with the entity represented by the...
qsizetype generateAtom(const Atom *atom, const Node *relative, CodeMarker *) override
Generate DocBook from an instance of Atom.
void generateProxyPage(Aggregate *aggregate)
bool generateStatus(const Node *node)
void generateRequisites(const Aggregate *inner)
Lists the required imports and includes.
void generateSortedNames(const ClassNode *cn, const QList< RelatedClass > &rc)
void generateDocumentation(Node *node) override
Recursive writing of DocBook files from the root node.
void generateGroupReferenceText(const Node *node)
Return a string representing a text that exposes information about the groups that the node is part o...
QString format() const override
Returns the format identifier for this producer (e.g., "HTML", "DocBook", "template").
void generateExampleFilePage(const PageNode *en, ResolvedFile resolved_file, CodeMarker *=nullptr) override
Generate a file with the contents of a C++ or QML source file.
QString fileExtension() const override
Returns "xml" for this subclass of Generator.
bool generateSince(const Node *node)
const Location & location() const
Returns the starting location of a qdoc comment.
static void quoteFromFile(const Location &location, Quoter "er, ResolvedFile resolved_file, CodeMarker *marker=nullptr)
const Text & body() const
Text briefText(bool inclusive=false) const
const TypedefNode * flagsType() const
Encapsulate the logic that QDoc uses to find files whose path is provided by the user and that are re...
This node is used to represent any kind of function being documented.
bool isMacroWithoutParams() const
bool isPrivateSignal() const
const Parameters & parameters() const
bool isPureVirtual() const override
bool hasOverloads() const
Returns true if this function has overloads.
bool isMacro() const override
returns true if either FunctionNode::isMacroWithParams() or FunctionNode::isMacroWithoutParams() retu...
bool isDeletedAsWritten() const
bool isExplicitlyDefaulted() const
bool hasAssociatedProperties() const
bool generateComparisonCategory(const Node *node, CodeMarker *marker=nullptr)
static void setQmlTypeContext(QmlTypeNode *t)
const Atom * generateAtomList(const Atom *atom, const Node *relative, CodeMarker *marker, bool generate, int &numGeneratedAtoms)
void unknownAtom(const Atom *atom)
static bool matchAhead(const Atom *atom, Atom::AtomType expectedAtomType)
void generateEnumValuesForQmlReference(const Node *node, CodeMarker *marker)
virtual int skipAtoms(const Atom *atom, Atom::AtomType type) const
bool generateComparisonTable(const Node *node)
Generates a table of comparison categories for node, combining both self-comparison (from \compares) ...
virtual void initializeGenerator()
No-op base implementation.
void initializeTextOutput()
Resets the variables used during text output.
static bool isIncluded(const InclusionPolicy &policy, const NodeContext &context)
This class represents a C++ namespace.
NamespaceNode * docNode() const
Returns a pointer to the NamespaceNode that represents where the namespace documentation is actually ...
Tree * tree() const override
Returns a pointer to the Tree that contains this NamespaceNode.
Interface implemented by Node subclasses that can refer to a C++ enum.
virtual const NativeEnum * nativeEnum() const =0
Encapsulates information about native (C++) enum values.
const EnumNode * enumNode() const
A PageNode is a Node that generates a documentation page.
bool noAutoList() const
Returns the value of the no auto-list flag.
The Parameter class describes one function parameter.
This class describes one instance of using the Q_PROPERTY macro.
This class provides exclusive access to the qdoc database, which consists of a forrest of trees and a...
static QDocDatabase * qdocDB()
Creates the singleton.
Status
Specifies the status of the QQmlIncubator.
bool isDefault() const override
Returns true if the QML property node is marked as default.
bool isReadOnly() const
Returns true if this QML property node is marked as a read-only property.
bool isRequired() const
Const overloads that delegate to the resolving non-const versions when the attribute hasn't been cach...
bool isAttached() const override
Returns true if the QML property or QML method node is marked as attached.
ClassNode * classNode() const override
If this is a QmlTypeNode, this function returns the pointer to the C++ ClassNode that this QML type r...
bool isUncreatable() const
static void subclasses(const Node *base, NodeList &subs, bool recurse=false)
Loads the list subs with the nodes of all the subclasses of base.
QmlTypeNode * qmlBaseNode() const override
If this Aggregate is a QmlTypeNode, this function returns a pointer to the QmlTypeNode that is its ba...
CollectionNode * logicalModule() const override
If this is a QmlTypeNode, a pointer to its QML module is returned, which is a pointer to a Collection...
A class for containing the elements of one documentation section.
const NodeVector & obsoleteMembers() const
void appendMembers(const NodeVector &nv)
const NodeVector & members() const
A class for creating vectors of collections for documentation.
const Aggregate * aggregate() const
Sections(const Aggregate *aggregate)
This constructor builds the section vectors based on the type of the aggregate node.
bool hasObsoleteMembers(SectionPtrVector *summary_spv, SectionPtrVector *details_spv) const
Returns true if any sections in this object contain obsolete members.
SectionVector & detailsSections()
static Text sectionHeading(const Atom *sectionBegin)
const Atom * firstAtom() const
Text & operator=(const Text &text)
const Atom * lastAtom() const
bool isStatic() const override
Returns true if the FunctionNode represents a static function.
static bool isOneColumnValueTable(const Atom *atom)
Determines whether the list atom should be shown with just one column (value).
static void rewritePropertyBrief(const Atom *atom, const Node *relative)
Rewrites the brief of this node depending on its first word.
static int hOffset(const Node *node)
Header offset depending on the type of the node.
static bool hasBrief(const Node *node)
Do not display.
XmlGenerator(FileResolver &file_resolver)
static const QRegularExpression m_funcLeftParen
static NodeType typeFromString(const Atom *atom)
Returns the type of this atom as an enumeration.
#define CONFIG_DOCBOOKEXTENSIONS
#define CONFIG_PRELIMINARY
#define CONFIG_DESCRIPTION
#define CONFIG_EXAMPLESINSTALLPATH
#define CONFIG_NATURALLANGUAGE
#define CONFIG_PRODUCTNAME
#define CONFIG_BUILDVERSION
static const char xlinkNamespace[]
static QString nodeToSynopsisTag(const Node *node)
QString removeCodeMarkers(const QString &code)
static const char dbNamespace[]
QString taggedNode(const Node *node)
static const char itsNamespace[]
Combined button and popup list for selecting options.
QList< Node * > NodeVector
QMap< QString, Node * > NodeMap
QMap< QString, NodeMap > NodeMapMap
QMap< QString, CollectionNode * > CNMap
QT_BEGIN_NAMESPACE typedef QMultiMap< Text, const Node * > TextToNodeMap
QList< const Section * > SectionPtrVector
QList< Section > SectionVector
The Node class is the base class for all the nodes in QDoc's parse tree.
bool isExternalPage() const
Returns true if the node type is ExternalPage.
const Doc & doc() const
Returns a reference to the node's Doc data member.
bool isQmlNode() const
Returns true if this node's Genus value is QML.
bool isEnumType(Genus g) const
bool isGroup() const
Returns true if the node type is Group.
virtual bool docMustBeGenerated() const
This function is called to perform a test to decide if the node must have documentation generated.
bool isPrivate() const
Returns true if this node's access is Private.
bool isNamespace() const
Returns true if the node type is Namespace.
bool isTypedef() const
Returns true if the node type is Typedef.
bool isQmlBasicType() const
Returns true if the node type is QmlBasicType.
bool isQmlType() const
Returns true if the node type is QmlType or QmlValueType.
bool isSharedCommentNode() const
Returns true if the node type is SharedComment.
virtual bool isInternal() const
Returns true if the node's status is Internal, or if its parent is a class with Internal status.
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.