Md4qt

visitor.h
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2022-2024 Igor Mironchik <igor.mironchik@gmail.com>
3 SPDX-License-Identifier: MIT
4*/
5
6#ifndef MD4QT_MD_VISITOR_HPP_INCLUDED
7#define MD4QT_MD_VISITOR_HPP_INCLUDED
8
9// md4qt include.
10#include "doc.h"
11#include "utils.h"
12
13// C++ include.
14#include <string>
15#include <utility>
16
17namespace MD
18{
19
20//
21// Visitor
22//
23
24//! Visitor interface to walk through Document.
25template<class Trait>
27{
28public:
29 Visitor() = default;
30 virtual ~Visitor() = default;
31
32 //! Walk through the document.
33 void process(std::shared_ptr<Document<Trait>> d)
34 {
35 m_anchors.clear();
36 m_doc = d;
37
38 for (auto it = m_doc->items().cbegin(), last = m_doc->items().cend(); it != last; ++it) {
39 switch ((*it)->type()) {
41 m_anchors.push_back(static_cast<Anchor<Trait> *>(it->get())->label());
42 break;
43
44 default:
45 break;
46 }
47 }
48
49 for (auto it = m_doc->items().cbegin(), last = m_doc->items().cend(); it != last; ++it) {
50 if (static_cast<int>((*it)->type()) >= static_cast<int>(ItemType::UserDefined)) {
51 onUserDefined(it->get());
52 } else {
53 switch ((*it)->type()) {
55 onHeading(static_cast<Heading<Trait> *>(it->get()));
56 break;
57
59 onParagraph(static_cast<Paragraph<Trait> *>(it->get()), true);
60 break;
61
62 case ItemType::Code:
63 onCode(static_cast<Code<Trait> *>(it->get()));
64 break;
65
67 onBlockquote(static_cast<Blockquote<Trait> *>(it->get()));
68 break;
69
70 case ItemType::List:
71 onList(static_cast<List<Trait> *>(it->get()));
72 break;
73
74 case ItemType::Table:
75 onTable(static_cast<Table<Trait> *>(it->get()));
76 break;
77
79 onAnchor(static_cast<Anchor<Trait> *>(it->get()));
80 break;
81
83 onRawHtml(static_cast<RawHtml<Trait> *>(it->get()));
84 break;
85
87 onHorizontalLine(static_cast<HorizontalLine<Trait> *>(it->get()));
88 break;
89
90 default:
91 break;
92 }
93 }
94 }
95 }
96
97protected:
98 //! For some generator it's important to keep line endings like they were in Markdown.
99 //! So onParagraph() method invokes this method when necessary to add line ending.
100 virtual void onAddLineEnding() = 0;
101
102 //! Handle user-defined item.
103 virtual void onUserDefined(
104 //! Item.
105 Item<Trait> *item)
106 {
107 MD_UNUSED(item)
108 }
109
110 //! Handle text item.
111 virtual void onText(
112 //! Text.
113 Text<Trait> *t) = 0;
114
115 //! Handle LaTeX math expression.
116 virtual void onMath(
117 //! Math.
118 Math<Trait> *m) = 0;
119
120 //! Handle line break.
121 virtual void onLineBreak(
122 //! Linebreak.
123 LineBreak<Trait> *b) = 0;
124
125 //! Handle paragraph.
126 virtual void onParagraph(
127 //! Paragraph.
129 //! Wrap this paragraph with something or no? It's useful to not wrap standalone
130 //! paragraph in list item, for example.
131 bool wrap)
132 {
133 MD_UNUSED(wrap)
134
135 long long int l = (!p->items().empty() ? p->items().at(0)->startLine() : -1);
136
137 for (auto it = p->items().begin(), last = p->items().end(); it != last; ++it) {
138 if ((*it)->startLine() != l) {
140 }
141
142 l = (*it)->endLine();
143
144 if (static_cast<int>((*it)->type()) >= static_cast<int>(ItemType::UserDefined)) {
145 onUserDefined(it->get());
146 } else {
147 switch ((*it)->type()) {
148 case ItemType::Text:
149 onText(static_cast<Text<Trait> *>(it->get()));
150 break;
151
152 case ItemType::Code:
153 onInlineCode(static_cast<Code<Trait> *>(it->get()));
154 break;
155
156 case ItemType::Link:
157 onLink(static_cast<Link<Trait> *>(it->get()));
158 break;
159
160 case ItemType::Image:
161 onImage(static_cast<Image<Trait> *>(it->get()));
162 break;
163
164 case ItemType::Math:
165 onMath(static_cast<Math<Trait> *>(it->get()));
166 break;
167
169 onLineBreak(static_cast<LineBreak<Trait> *>(it->get()));
170 break;
171
173 onFootnoteRef(static_cast<FootnoteRef<Trait> *>(it->get()));
174 break;
175
177 onRawHtml(static_cast<RawHtml<Trait> *>(it->get()));
178 break;
179
180 default:
181 break;
182 }
183 }
184 }
185 }
186
187 //! Handle heading.
188 virtual void onHeading(
189 //! Heading.
190 Heading<Trait> *h) = 0;
191
192 //! Handle code.
193 virtual void onCode(
194 //! Code.
195 Code<Trait> *c) = 0;
196
197 //! Handle inline code.
198 virtual void onInlineCode(
199 //! Code.
200 Code<Trait> *c) = 0;
201
202 //! Handle blockquote.
203 virtual void onBlockquote(
204 //! Blockquote.
206 {
207 for (auto it = b->items().cbegin(), last = b->items().cend(); it != last; ++it) {
208 if (static_cast<int>((*it)->type()) >= static_cast<int>(ItemType::UserDefined)) {
209 onUserDefined(it->get());
210 } else {
211 switch ((*it)->type()) {
213 onHeading(static_cast<Heading<Trait> *>(it->get()));
214 break;
215
217 onParagraph(static_cast<Paragraph<Trait> *>(it->get()), true);
218 break;
219
220 case ItemType::Code:
221 onCode(static_cast<Code<Trait> *>(it->get()));
222 break;
223
225 onBlockquote(static_cast<Blockquote<Trait> *>(it->get()));
226 break;
227
228 case ItemType::List:
229 onList(static_cast<List<Trait> *>(it->get()));
230 break;
231
232 case ItemType::Table:
233 onTable(static_cast<Table<Trait> *>(it->get()));
234 break;
235
237 onHorizontalLine(static_cast<HorizontalLine<Trait> *>(it->get()));
238 break;
239
241 onRawHtml(static_cast<RawHtml<Trait> *>(it->get()));
242 break;
243
244 default:
245 break;
246 }
247 }
248 }
249 }
250
251 //! Handle list.
252 virtual void onList(
253 //! List.
254 List<Trait> *l) = 0;
255
256 //! Handle table.
257 virtual void onTable(
258 //! Table.
259 Table<Trait> *t) = 0;
260
261 //! Handle anchor.
262 virtual void onAnchor(
263 //! Anchor.
264 Anchor<Trait> *a) = 0;
265
266 //! Handle raw HTML.
267 virtual void onRawHtml(
268 //! Raw HTML.
269 RawHtml<Trait> *h) = 0;
270
271 //! Handle horizontal line.
272 virtual void onHorizontalLine(
273 //! Horizontal line.
274 HorizontalLine<Trait> *l) = 0;
275
276 //! Handle link.
277 virtual void onLink(
278 //! Link.
279 Link<Trait> *l) = 0;
280
281 //! Handle image.
282 virtual void onImage(
283 //! Image.
284 Image<Trait> *i) = 0;
285
286 //! Handle footnote reference.
287 virtual void onFootnoteRef(
288 //! Footnote reference.
289 FootnoteRef<Trait> *ref) = 0;
290
291 //! Handle list item.
292 virtual void onListItem(
293 //! List item.
295 //! Is this item first in the list?
296 bool first)
297 {
298 MD_UNUSED(first)
299
300 for (auto it = i->items().cbegin(), last = i->items().cend(); it != last; ++it) {
301 if (static_cast<int>((*it)->type()) >= static_cast<int>(ItemType::UserDefined)) {
302 onUserDefined(it->get());
303 } else {
304 switch ((*it)->type()) {
306 onHeading(static_cast<Heading<Trait> *>(it->get()));
307 break;
308
310 onParagraph(static_cast<Paragraph<Trait> *>(it->get()), (i->items().size() > 1 && i->items().at(1)->type() != ItemType::List));
311 break;
312
313 case ItemType::Code:
314 onCode(static_cast<Code<Trait> *>(it->get()));
315 break;
316
318 onBlockquote(static_cast<Blockquote<Trait> *>(it->get()));
319 break;
320
321 case ItemType::List:
322 onList(static_cast<List<Trait> *>(it->get()));
323 break;
324
325 case ItemType::Table:
326 onTable(static_cast<Table<Trait> *>(it->get()));
327 break;
328
330 onRawHtml(static_cast<RawHtml<Trait> *>(it->get()));
331 break;
332
334 onHorizontalLine(static_cast<HorizontalLine<Trait> *>(it->get()));
335 break;
336
337 default:
338 break;
339 }
340 }
341 }
342 }
343
344 //! Handle table cell.
345 virtual void onTableCell(
346 //! Table cell.
348 {
349 for (auto it = c->items().cbegin(), last = c->items().cend(); it != last; ++it) {
350 if (static_cast<int>((*it)->type()) >= static_cast<int>(ItemType::UserDefined)) {
351 onUserDefined(it->get());
352 } else {
353 switch ((*it)->type()) {
354 case ItemType::Text:
355 onText(static_cast<Text<Trait> *>(it->get()));
356 break;
357
358 case ItemType::Code:
359 onInlineCode(static_cast<Code<Trait> *>(it->get()));
360 break;
361
362 case ItemType::Link:
363 onLink(static_cast<Link<Trait> *>(it->get()));
364 break;
365
366 case ItemType::Image:
367 onImage(static_cast<Image<Trait> *>(it->get()));
368 break;
369
371 onFootnoteRef(static_cast<FootnoteRef<Trait> *>(it->get()));
372 break;
373
375 onRawHtml(static_cast<RawHtml<Trait> *>(it->get()));
376 break;
377
378 case ItemType::Math:
379 onMath(static_cast<Math<Trait> *>(it->get()));
380
381 default:
382 break;
383 }
384 }
385 }
386 }
387
388 //! Handle footnote.
389 virtual void onFootnote(
390 //! Footnote.
392 {
393 for (auto it = f->items().cbegin(), last = f->items().cend(); it != last; ++it) {
394 if (static_cast<int>((*it)->type()) >= static_cast<int>(ItemType::UserDefined)) {
395 onUserDefined(it->get());
396 } else {
397 switch ((*it)->type()) {
399 onHeading(static_cast<Heading<Trait> *>(it->get()));
400 break;
401
403 onParagraph(static_cast<Paragraph<Trait> *>(it->get()), true);
404 break;
405
406 case ItemType::Code:
407 onCode(static_cast<Code<Trait> *>(it->get()));
408 break;
409
411 onBlockquote(static_cast<Blockquote<Trait> *>(it->get()));
412 break;
413
414 case ItemType::List:
415 onList(static_cast<List<Trait> *>(it->get()));
416 break;
417
418 case ItemType::Table:
419 onTable(static_cast<Table<Trait> *>(it->get()));
420 break;
421
423 onRawHtml(static_cast<RawHtml<Trait> *>(it->get()));
424 break;
425
427 onHorizontalLine(static_cast<HorizontalLine<Trait> *>(it->get()));
428 break;
429
430 default:
431 break;
432 }
433 }
434 }
435 }
436
437protected:
438 //! All available m_anchors in the document.
439 typename Trait::template Vector<typename Trait::String> m_anchors;
440 //! Document.
441 std::shared_ptr<Document<Trait>> m_doc;
442}; // class Visitor
443
444} /* namespace MD */
445
446#endif // MD4QT_MD_VISITOR_HPP_INCLUDED
Just an anchor.
Definition doc.h:397
const Trait::String & label() const
Definition doc.h:421
const Items & items() const
Definition doc.h:629
Blockquote.
Definition doc.h:836
Code.
Definition doc.h:1269
Document.
Definition doc.h:1774
Footnote reference.
Definition doc.h:1666
Footnote.
Definition doc.h:1727
Heading.
Definition doc.h:710
Horizontal line.
Definition doc.h:364
Image.
Definition doc.h:1183
Base class for item in Markdown document.
Definition doc.h:177
Line break.
Definition doc.h:570
List item in a list.
Definition doc.h:886
List.
Definition doc.h:1039
LaTeX math expression.
Definition doc.h:1423
Paragraph.
Definition doc.h:679
Raw HTML.
Definition doc.h:440
Table cell.
Definition doc.h:1472
Table.
Definition doc.h:1564
Text item in Paragraph.
Definition doc.h:513
Visitor interface to walk through Document.
Definition visitor.h:27
virtual void onFootnote(Footnote< Trait > *f)
Handle footnote.
Definition visitor.h:389
virtual void onRawHtml(RawHtml< Trait > *h)=0
Handle raw HTML.
virtual void onList(List< Trait > *l)=0
Handle list.
virtual void onListItem(ListItem< Trait > *i, bool first)
Handle list item.
Definition visitor.h:292
virtual void onBlockquote(Blockquote< Trait > *b)
Handle blockquote.
Definition visitor.h:203
virtual void onTableCell(TableCell< Trait > *c)
Handle table cell.
Definition visitor.h:345
virtual void onText(Text< Trait > *t)=0
Handle text item.
virtual void onHorizontalLine(HorizontalLine< Trait > *l)=0
Handle horizontal line.
virtual void onAnchor(Anchor< Trait > *a)=0
Handle anchor.
Trait::template Vector< typename Trait::String > m_anchors
All available m_anchors in the document.
Definition visitor.h:439
virtual ~Visitor()=default
virtual void onMath(Math< Trait > *m)=0
Handle LaTeX math expression.
std::shared_ptr< Document< Trait > > m_doc
Document.
Definition visitor.h:441
virtual void onLineBreak(LineBreak< Trait > *b)=0
Handle line break.
Visitor()=default
virtual void onLink(Link< Trait > *l)=0
Handle link.
virtual void onParagraph(Paragraph< Trait > *p, bool wrap)
Handle paragraph.
Definition visitor.h:126
virtual void onUserDefined(Item< Trait > *item)
Handle user-defined item.
Definition visitor.h:103
virtual void onHeading(Heading< Trait > *h)=0
Handle heading.
virtual void onInlineCode(Code< Trait > *c)=0
Handle inline code.
virtual void onTable(Table< Trait > *t)=0
Handle table.
virtual void onFootnoteRef(FootnoteRef< Trait > *ref)=0
Handle footnote reference.
virtual void onAddLineEnding()=0
For some generator it's important to keep line endings like they were in Markdown.
virtual void onImage(Image< Trait > *i)=0
Handle image.
void process(std::shared_ptr< Document< Trait > > d)
Walk through the document.
Definition visitor.h:33
virtual void onCode(Code< Trait > *c)=0
Handle code.
Definition algo.h:17
@ Heading
Heading.
@ Blockquote
Blockquote.
@ FootnoteRef
Footnote ref.
@ Table
Table.
@ Anchor
Anchor.
@ Math
Math expression.
@ Image
Image.
@ UserDefined
Start item for user-defined types.
@ RawHtml
Raw HTML.
@ HorizontalLine
Horizontal line.
@ LineBreak
Line break.
@ Paragraph
Paragraph.
#define MD_UNUSED(x)
Avoid "unused parameter" warnings.
Definition utils.h:26
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Wed Nov 6 2024 12:12:28 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.