53bool XmlGenerator::isOneColumnValueTable(
const Atom *atom)
55 if (atom->type() != Atom::ListLeft || atom->string() !=
ATOM_LIST_VALUE)
58 while (atom && atom->type() != Atom::ListTagRight)
62 if (!matchAhead(atom, Atom::ListItemLeft))
66 return matchAhead(atom->next(), Atom::ListItemRight);
103void XmlGenerator::rewritePropertyBrief(
const Atom *atom,
const Node *relative)
105 if (relative->nodeType() != NodeType::Property && relative->nodeType() != NodeType::Variable)
108 if (!atom || atom->type() != Atom::String)
111 const QString firstWord =
112 atom->string().toLower().section(
' ', 0, 0, QString::SectionSkipEmpty);
113 const QStringList words{
"the",
"a",
"an",
"whether",
"which" };
114 if (words.contains(firstWord)) {
115 QString str = QLatin1String(
"This ")
116 + QLatin1String(relative->nodeType() == NodeType::Property ?
"property" :
"variable")
117 + QLatin1String(
" holds ") + atom->string().left(1).toLower()
118 + atom->string().mid(1);
119 const_cast<Atom *>(atom)->setString(str);
141void XmlGenerator::setImageFileName(
const Node *relative,
const QString &fileName)
143 if (relative->isExample()) {
144 const auto cen =
static_cast<
const ExampleNode *>(relative);
145 if (cen->imageFileName().isEmpty()) {
146 auto *en =
const_cast<ExampleNode *>(cen);
147 en->setImageFileName(fileName);
157std::pair<QString,
int> XmlGenerator::getAtomListValue(
const Atom *atom)
159 const Atom *lookAhead = atom->next();
161 return std::pair<QString,
int>(QString(), 1);
163 QString t = lookAhead->string();
164 lookAhead = lookAhead->next();
165 if (!lookAhead || lookAhead->type() != Atom::ListTagRight)
166 return std::pair<QString,
int>(QString(), 1);
168 lookAhead = lookAhead->next();
170 if (lookAhead && lookAhead->type() == Atom::SinceTagLeft) {
171 lookAhead = lookAhead->next();
172 Q_ASSERT(lookAhead && lookAhead->type() == Atom::String);
173 t += QLatin1String(
" (since ");
174 const QString sinceString = lookAhead->string();
175 if (sinceString.at(0).isDigit()) {
177 t += productName.isEmpty() ? sinceString : productName +
" " + sinceString;
181 t += QLatin1String(
")");
186 return std::pair<QString,
int>(t, skipAhead);
195std::pair<QString, QString> XmlGenerator::getTableWidthAttr(
const Atom *atom)
198 QString attr =
"generic";
200 if (atom->count() > 0) {
201 p0 = atom->string(0);
202 if (atom->count() > 1)
203 p1 = atom->string(1);
206 if (p0 == QLatin1String(
"borderless"))
208 else if (p0.contains(QLatin1Char(
'%')))
212 if (p1 == QLatin1String(
"borderless"))
213 attr = std::move(p1);
214 else if (p1.contains(QLatin1Char(
'%')))
215 width = std::move(p1);
220 if (width == QLatin1String(
"%")) {
223 int widthPercentage = p0.toInt(&ok);
225 width = QString::number(widthPercentage) +
"%";
231 return {width, attr};
284QString XmlGenerator::linkForNode(
const Node *node,
const Node *relative)
288 if (!node->url().isNull())
290 if (fileBase(node).isEmpty())
292 const InclusionPolicy policy = Config::instance().createInclusionPolicy();
293 const NodeContext context = node->createContext();
294 if (!InclusionFilter::isIncluded(policy, context))
297 QString fn = fileName(node);
298 if (node->parent() && node->parent()->isQmlType() && node->parent()->isAbstract()) {
299 if (Generator::qmlTypeContext()) {
300 if (Generator::qmlTypeContext()->inherits(node->parent())) {
301 fn = fileName(Generator::qmlTypeContext());
302 }
else if (node->parent()->isInternal() && !noLinkErrors()) {
303 node->doc().location().warning(
304 QStringLiteral(
"Cannot link to property in internal type '%1'")
305 .arg(node->parent()->name()));
313 if (!node->isPageNode() || node->isPropertyGroup()) {
314 QString ref = refForNode(node);
315 if (relative && fn == fileName(relative) && ref == refForNode(relative))
318 link += QLatin1Char(
'#');
323
324
325
326
327
328
329
330 if (relative && (node != relative)) {
331 if (useOutputSubdirs() && !node->isExternalPage() &&
332 (node->isIndexNode() || node->tree() != relative->tree()))
333 link.prepend(
"../%1/"_L1.arg(node->tree()->physicalModuleName()));
383QString XmlGenerator::getAutoLink(
const Atom *atom,
const Node *relative,
const Node **node,
392 if (genus != Genus::DontCare && relative && relative->genus() != Genus::DontCare) {
393 using GenusValue = std::underlying_type_t<Genus>;
394 const Genus common =
static_cast<Genus>(
395 static_cast<GenusValue>(genus) &
396 static_cast<GenusValue>(relative->genus())
398 if (common != Genus::DontCare)
399 *node = m_qdb->findNodeForAtom(atom, relative, ref, common);
403 *node = m_qdb->findNodeForAtom(atom, relative, ref, genus);
407 QString link = (*node)->url();
409 link = linkForNode(*node, relative);
410 }
else if (link.isEmpty()) {
413 if (!ref.isEmpty()) {
414 qsizetype hashtag = link.lastIndexOf(QChar(
'#'));
416 link.truncate(hashtag);
417 link += QLatin1Char(
'#') + ref;
422std::pair<QString, QString> XmlGenerator::anchorForNode(
const Node *node)
424 std::pair<QString, QString> anchorPair;
426 anchorPair.first = Generator::fileName(node);
427 if (node->isTextPageNode())
428 anchorPair.second = node->title();