4#ifdef QDOC_TEMPLATE_GENERATOR_ENABLED
6#include "listexpander.h"
8#include "contentblock.h"
9#include "listplaceholder.h"
16using namespace Qt::Literals::StringLiterals;
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
45
46
47
48
49
50
51
52
53
54
55
56
57
63ContentBlock makeSectionHeading(
int level,
const QString &text,
64 const QString &anchorId)
67 heading.type = BlockType::SectionHeading;
68 heading.attributes[
"level"_L1] = level;
69 if (!anchorId.isEmpty())
70 heading.attributes[
"id"_L1] = anchorId;
71 InlineContent textInline;
72 textInline.type = InlineType::Text;
73 textInline.text = text;
74 heading.inlineContent.append(textInline);
78InlineContent makeLink(
const QString &name,
const QString &href)
81 link.type = InlineType::Link;
87 link.link = InlineContent::LinkData{ LinkOrigin::Explicit, LinkState::Resolved };
88 InlineContent nameInline;
89 nameInline.type = InlineType::Text;
90 nameInline.text = name;
91 link.children.append(nameInline);
95InlineContent makeText(
const QString &text)
98 t.type = InlineType::Text;
103ContentBlock makeCell(QList<InlineContent> inlines)
106 cell.type = BlockType::TableCell;
107 cell.inlineContent = std::move(inlines);
111ContentBlock makeRow(QList<ContentBlock> cells)
114 row.type = BlockType::TableRow;
115 row.children = std::move(cells);
119ContentBlock makeAnnotatedTable(
const QList<CatalogEntry> &entries)
122 table.type = BlockType::Table;
123 table.attributes[
"style"_L1] = u"annotated"_s;
125 for (
const CatalogEntry &e : entries) {
126 QList<InlineContent> nameInlines;
127 if (!e.href.isEmpty())
128 nameInlines.append(makeLink(e.name, e.href));
130 nameInlines.append(makeText(e.name));
132 QList<InlineContent> briefInlines;
133 briefInlines.append(makeText(e.brief));
135 QList<ContentBlock> cells;
136 cells.append(makeCell(std::move(nameInlines)));
137 cells.append(makeCell(std::move(briefInlines)));
139 ContentBlock row = makeRow(std::move(cells));
144 if (!e.since.isEmpty())
145 row.attributes[
"since"_L1] = e.since;
147 row.attributes[
"deprecated"_L1] =
true;
148 table.children.append(std::move(row));
161ContentBlock makeCompactList(
const QList<CatalogEntry> &entries)
164 list.type = BlockType::List;
165 list.attributes[
"style"_L1] = u"bullet"_s;
167 for (
const CatalogEntry &e : entries) {
169 item.type = BlockType::ListItem;
170 if (!e.href.isEmpty())
171 item.inlineContent.append(makeLink(e.name, e.href));
173 item.inlineContent.append(makeText(e.name));
174 list.children.append(std::move(item));
179ContentBlock makeCatalog(ListPlaceholderVariant variant)
181 ContentBlock catalog;
182 catalog.type = BlockType::Catalog;
183 catalog.attributes[
"variant"_L1] = toString(variant);
187Qt::SortOrder readSortOrder(
const ContentBlock &placeholder)
189 return placeholder.attributes.value(
"sort"_L1).toString() == u"descending"_s
190 ? Qt::DescendingOrder : Qt::AscendingOrder;
193void notifyEmpty(
const ListExpanderCallbacks &cb,
const QString &argument,
194 ListPlaceholderVariant variant)
197 cb.onEmpty(argument, variant);
200std::optional<ContentBlock> expandAnnotatedClasses(
201 const ListExpanderCallbacks &cb,
const ContentBlock &placeholder,
202 const Node *relative)
204 const QString argument = placeholder.attributes.value(
"argument"_L1).toString();
205 QList<CatalogEntry> entries = cb.collectCppClasses
206 ? cb.collectCppClasses(relative, readSortOrder(placeholder))
207 : QList<CatalogEntry>{};
209 if (entries.isEmpty()) {
210 notifyEmpty(cb, argument, ListPlaceholderVariant::AnnotatedClasses);
214 ContentBlock catalog = makeCatalog(ListPlaceholderVariant::AnnotatedClasses);
215 catalog.children.append(makeAnnotatedTable(entries));
219std::optional<ContentBlock> expandAnnotatedExamples(
220 const ListExpanderCallbacks &cb,
const ContentBlock &placeholder,
221 const Node *relative)
223 const QString argument = placeholder.attributes.value(
"argument"_L1).toString();
224 QList<CatalogEntryGroup> groups = cb.collectExamplesGrouped
225 ? cb.collectExamplesGrouped(relative)
226 : QList<CatalogEntryGroup>{};
228 ContentBlock catalog = makeCatalog(ListPlaceholderVariant::AnnotatedExamples);
229 for (
const CatalogEntryGroup &g : groups) {
234 if (g.entries.isEmpty())
242 if (!g.label.isEmpty())
243 catalog.children.append(makeSectionHeading(2, g.label, g.anchorId));
244 catalog.children.append(makeAnnotatedTable(g.entries));
247 if (catalog.children.isEmpty()) {
248 notifyEmpty(cb, argument, ListPlaceholderVariant::AnnotatedExamples);
254std::optional<ContentBlock> expandCompactClasses(
255 const ListExpanderCallbacks &cb,
const ContentBlock &placeholder,
256 const Node *relative)
258 const QString argument = placeholder.attributes.value(
"argument"_L1).toString();
259 const QString rootName = placeholder.attributes.value(
"rootName"_L1).toString();
261 QList<CatalogEntry> entries = cb.collectCompactClasses
262 ? cb.collectCompactClasses(relative, rootName)
263 : QList<CatalogEntry>{};
265 if (entries.isEmpty()) {
266 notifyEmpty(cb, argument, ListPlaceholderVariant::CompactClasses);
270 ContentBlock catalog = makeCatalog(ListPlaceholderVariant::CompactClasses);
271 if (!rootName.isEmpty())
272 catalog.attributes[
"rootName"_L1] = rootName;
273 catalog.children.append(makeCompactList(entries));
277std::optional<ContentBlock> expandAnnotatedGroup(
278 const ListExpanderCallbacks &cb,
const ContentBlock &placeholder,
279 const Node *relative)
281 const QString argument = placeholder.attributes.value(
"argument"_L1).toString();
282 QList<CatalogEntry> entries = cb.collectGroupMembers
283 ? cb.collectGroupMembers(relative, argument, readSortOrder(placeholder))
284 : QList<CatalogEntry>{};
286 if (entries.isEmpty()) {
287 notifyEmpty(cb, argument, ListPlaceholderVariant::AnnotatedGroup);
291 ContentBlock catalog = makeCatalog(ListPlaceholderVariant::AnnotatedGroup);
292 catalog.attributes[
"argument"_L1] = argument;
293 catalog.children.append(makeAnnotatedTable(entries));
297std::optional<ContentBlock> expandPlaceholder(
298 const ListExpanderCallbacks &cb,
const ContentBlock &placeholder,
299 const Node *relative)
301 const auto variant = parseListPlaceholderVariant(
302 placeholder.attributes.value(
"variant"_L1).toString());
307 case ListPlaceholderVariant::AnnotatedClasses:
308 return expandAnnotatedClasses(cb, placeholder, relative);
309 case ListPlaceholderVariant::AnnotatedExamples:
310 return expandAnnotatedExamples(cb, placeholder, relative);
311 case ListPlaceholderVariant::CompactClasses:
312 return expandCompactClasses(cb, placeholder, relative);
313 case ListPlaceholderVariant::AnnotatedGroup:
314 return expandAnnotatedGroup(cb, placeholder, relative);
316 Q_UNREACHABLE_RETURN(std::nullopt);
321ListExpander::ListExpander(ListExpanderCallbacks callbacks)
322 : m_callbacks(std::move(callbacks))
327
328
329
330
331
332
333
334
335
336
337
338void ListExpander::expand(QList<ContentBlock> &blocks,
const Node *relative)
340 for (qsizetype i = 0; i < blocks.size(); ) {
341 if (blocks[i].type == BlockType::ListPlaceholder) {
342 auto expanded = expandPlaceholder(m_callbacks, blocks[i], relative);
344 blocks.replace(i, std::move(*expanded));
350 expand(blocks[i].children, relative);