Md4qt

algo.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_ALGO_H_INCLUDED
7#define MD4QT_MD_ALGO_H_INCLUDED
8
9// md4qt include.
10#include "traits.h"
11#include "visitor.h"
12
13// C++ include.
14#include <functional>
15
16namespace MD
17{
18
19//! Function type for algorithms.
20template<class Trait>
21using ItemFunctor = std::function<void(Item<Trait> *)>;
22
23namespace details
24{
25
26//
27// AlgoVisitor
28//
29
30//! Visitor for algorithms.
31template<class Trait>
32class AlgoVisitor : public Visitor<Trait>
33{
34public:
35 AlgoVisitor(unsigned int mnl,
36 const typename Trait::template Vector<ItemType> &t,
39 , m_types(t)
40 , m_func(f)
41 {
42 }
43
44 ~AlgoVisitor() override = default;
45
46 //! Walk through the document.
47 virtual void walk(std::shared_ptr<Document<Trait>> doc)
48 {
49 this->process(doc);
50
51 onFootnotes(doc);
52 }
53
54protected:
55 void onAddLineEnding() override
56 {
57 }
58
59 //! Process user defined item type.
60 void onUserDefined(Item<Trait> *i) override
61 {
63
64 if (inc.allowed(i->type())) {
65 m_func(i);
66 }
67 }
68
69 //! Process text item.
70 void onText(Text<Trait> *t) override
71 {
73
74 if (inc.allowed(ItemType::Text)) {
75 m_func(t);
76 }
77 }
78
79 //! Process LaTeX math item.
80 void onMath(Math<Trait> *m) override
81 {
83
84 if (inc.allowed(ItemType::Math)) {
85 m_func(m);
86 }
87 }
88
89 //! Process line break.
98
99 //! Process paragraph.
100 void onParagraph(Paragraph<Trait> *p, bool) override
101 {
103
104 if (inc.allowed(ItemType::Paragraph)) {
105 m_func(p);
106 }
107
108 if (inc.nextAllowed()) {
110 }
111 }
112
113 //! Process heading.
114 void onHeading(Heading<Trait> *h) override
115 {
117
118 if (inc.allowed(ItemType::Heading)) {
119 m_func(h);
120 }
121
122 if (h->text() && !h->text()->isEmpty() && inc.nextAllowed()) {
123 onParagraph(h->text().get(), true);
124 }
125 }
126
127 //! Process code block.
128 void onCode(Code<Trait> *c) override
129 {
131
132 if (inc.allowed(ItemType::Code)) {
133 m_func(c);
134 }
135 }
136
137 //! Process inline code.
138 void onInlineCode(Code<Trait> *c) override
139 {
141
142 if (inc.allowed(ItemType::Code)) {
143 m_func(c);
144 }
145 }
146
147 //! Process blockquote.
149 {
151
152 if (inc.allowed(ItemType::Blockquote)) {
153 m_func(b);
154 }
155
156 if (inc.nextAllowed()) {
158 }
159 }
160
161 //! Process list.
162 void onList(List<Trait> *l) override
163 {
165
166 if (inc.allowed(ItemType::List)) {
167 m_func(l);
168 }
169
170 for (auto it = l->items().cbegin(), last = l->items().cend(); it != last; ++it) {
171 if ((*it)->type() == ItemType::ListItem && inc.nextAllowed()) {
172 onListItem(static_cast<ListItem<Trait> *>(it->get()), true);
173 }
174 }
175 }
176
177 //! Process table.
178 void onTable(Table<Trait> *t) override
179 {
181
182 if (inc.allowed(ItemType::Table)) {
183 m_func(t);
184 }
185
186 if (!t->isEmpty() && inc.nextAllowed()) {
187 int columns = 0;
188
189 for (auto th = (*t->rows().cbegin())->cells().cbegin(), last = (*t->rows().cbegin())->cells().cend(); th != last; ++th) {
190 this->onTableCell(th->get());
191
192 ++columns;
193 }
194
195 for (auto r = std::next(t->rows().cbegin()), rlast = t->rows().cend(); r != rlast; ++r) {
196 int i = 0;
197
198 for (auto c = (*r)->cells().cbegin(), clast = (*r)->cells().cend(); c != clast; ++c) {
199 this->onTableCell(c->get());
200
201 ++i;
202
203 if (i == columns) {
204 break;
205 }
206 }
207 }
208 }
209 }
210
211 //! Process anchor.
212 void onAnchor(Anchor<Trait> *a) override
213 {
215
216 if (inc.allowed(ItemType::Anchor)) {
217 m_func(a);
218 }
219 }
220
221 //! Process raw HTML block.
222 void onRawHtml(RawHtml<Trait> *h) override
223 {
225
226 if (inc.allowed(ItemType::RawHtml)) {
227 m_func(h);
228 }
229 }
230
231 //! Process horizontal line.
240
241 //! Process link.
242 void onLink(Link<Trait> *l) override
243 {
245
246 if (inc.allowed(ItemType::Link)) {
247 m_func(l);
248 }
249
250 if (inc.nextAllowed()) {
251 if (!l->img()->isEmpty()) {
252 onImage(l->img().get());
253 } else if (l->p() && !l->p()->isEmpty()) {
254 onParagraph(l->p().get(), false);
255 }
256 }
257 }
258
259 //! Process Image.
260 void onImage(Image<Trait> *i) override
261 {
263
264 if (inc.allowed(ItemType::Image)) {
265 m_func(i);
266 }
267 }
268
269 //! Process footnote reference.
271 {
273
275 m_func(ref);
276 }
277 }
278
279 //! Process list item.
280 void onListItem(ListItem<Trait> *i, bool) override
281 {
283
284 if (inc.allowed(ItemType::ListItem)) {
285 m_func(i);
286 }
287
288 if (inc.nextAllowed()) {
290 }
291 }
292
293 //! Process table cell.
295 {
297 }
298
299 //! Process footnote.
300 void onFootnote(Footnote<Trait> *f) override
301 {
303
304 if (inc.allowed(ItemType::Footnote)) {
305 m_func(f);
306 }
307
308 if (inc.nextAllowed()) {
310 }
311 }
312
313 //! Process all footnotes.
314 virtual void onFootnotes(std::shared_ptr<Document<Trait>> doc)
315 {
316 for (const auto &f : doc->footnotesMap()) {
317 this->onFootnote(f.second.get());
318 }
319 }
320
321protected:
322 //! Current nesting level, increments/decrements during walking through te document.
323 unsigned int m_currentNestingLevel = 0;
324 //! Maximum allowed nesting level.
325 unsigned int m_maxNestingLevel = 0;
326 //! List of types that should be processed.
327 const typename Trait::template Vector<ItemType> &m_types;
328 //! Functor that will be invoked if all circumstances will be observed.
330
331 //! Auxiliary structure to increment/decrement nesting level during walking through
332 //! the document, and checking circumstances for the algorithm.
334 IncrementNestingLevel(unsigned int &l,
335 unsigned int m,
336 const typename Trait::template Vector<ItemType> &t)
337 : m_level(l)
339 , m_types(t)
340 {
341 ++m_level;
342 }
343
345 {
346 --m_level;
347 }
348
349 //! \return Is this item type allowed at this nesting level.
350 bool allowed(ItemType t) const
351 {
352 return ((m_maxNestingLevel == 0 || m_level <= m_maxNestingLevel) &&
353 std::find(m_types.cbegin(), m_types.cend(), t) != m_types.cend());
354 }
355
356 //! \return Is next nesting level allowed.
357 bool nextAllowed() const
358 {
359 return (m_maxNestingLevel == 0 || m_level + 1 <= m_maxNestingLevel);
360 }
361
362 //! Reference to nesting level.
363 unsigned int &m_level;
364 //! Maximum allowed nesting level.
365 unsigned int m_maxNestingLevel;
366 //! Reference to list of allowed types.
367 const typename Trait::template Vector<ItemType> &m_types;
368 }; // struct IncrementNestingLevel
369}; // class HtmlVisitor
370
371} /* namespace details */
372
373//! Calls function for each item in the document with the given type.
374template<class Trait>
375inline void forEach(
376 //! Vector of item's types to be processed.
377 const typename Trait::template Vector<ItemType> &types,
378 //! Document.
379 std::shared_ptr<Document<Trait>> doc,
380 //! Functor object.
382 //! Maximun nesting level.
383 //! 0 means infinity, 1 - only top level items...
384 unsigned int maxNestingLevel = 0)
385{
386 details::AlgoVisitor<Trait> v(maxNestingLevel, types, func);
387
388 v.walk(doc);
389}
390
391} /* namespace MD */
392
393#endif // MD4QT_MD_ALGO_H_INCLUDED
Just an anchor.
Definition doc.h:397
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
ParagraphSharedPointer text() const
Definition doc.h:749
Horizontal line.
Definition doc.h:364
Image.
Definition doc.h:1183
Base class for item in Markdown document.
Definition doc.h:177
virtual ItemType type() const =0
Line break.
Definition doc.h:570
ParagraphSharedPointer p() const
Definition doc.h:1126
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
bool isEmpty() const
Definition doc.h:1645
const Rows & rows() const
Definition doc.h:1598
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 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 onParagraph(Paragraph< Trait > *p, bool wrap)
Handle paragraph.
Definition visitor.h:126
void process(std::shared_ptr< Document< Trait > > d)
Walk through the document.
Definition visitor.h:33
Visitor for algorithms.
Definition algo.h:33
void onUserDefined(Item< Trait > *i) override
Process user defined item type.
Definition algo.h:60
virtual void onFootnotes(std::shared_ptr< Document< Trait > > doc)
Process all footnotes.
Definition algo.h:314
virtual void walk(std::shared_ptr< Document< Trait > > doc)
Walk through the document.
Definition algo.h:47
void onHorizontalLine(HorizontalLine< Trait > *l) override
Process horizontal line.
Definition algo.h:232
void onBlockquote(Blockquote< Trait > *b) override
Process blockquote.
Definition algo.h:148
void onImage(Image< Trait > *i) override
Process Image.
Definition algo.h:260
void onInlineCode(Code< Trait > *c) override
Process inline code.
Definition algo.h:138
void onListItem(ListItem< Trait > *i, bool) override
Process list item.
Definition algo.h:280
void onFootnote(Footnote< Trait > *f) override
Process footnote.
Definition algo.h:300
ItemFunctor< Trait > m_func
Functor that will be invoked if all circumstances will be observed.
Definition algo.h:329
const Trait::template Vector< ItemType > & m_types
List of types that should be processed.
Definition algo.h:327
void onList(List< Trait > *l) override
Process list.
Definition algo.h:162
AlgoVisitor(unsigned int mnl, const typename Trait::template Vector< ItemType > &t, ItemFunctor< Trait > f)
Definition algo.h:35
void onLineBreak(LineBreak< Trait > *l) override
Process line break.
Definition algo.h:90
void onMath(Math< Trait > *m) override
Process LaTeX math item.
Definition algo.h:80
void onRawHtml(RawHtml< Trait > *h) override
Process raw HTML block.
Definition algo.h:222
void onText(Text< Trait > *t) override
Process text item.
Definition algo.h:70
void onTable(Table< Trait > *t) override
Process table.
Definition algo.h:178
unsigned int m_maxNestingLevel
Maximum allowed nesting level.
Definition algo.h:325
void onCode(Code< Trait > *c) override
Process code block.
Definition algo.h:128
void onFootnoteRef(FootnoteRef< Trait > *ref) override
Process footnote reference.
Definition algo.h:270
void onAddLineEnding() override
For some generator it's important to keep line endings like they were in Markdown.
Definition algo.h:55
void onLink(Link< Trait > *l) override
Process link.
Definition algo.h:242
void onAnchor(Anchor< Trait > *a) override
Process anchor.
Definition algo.h:212
unsigned int m_currentNestingLevel
Current nesting level, increments/decrements during walking through te document.
Definition algo.h:323
void onParagraph(Paragraph< Trait > *p, bool) override
Process paragraph.
Definition algo.h:100
~AlgoVisitor() override=default
void onTableCell(TableCell< Trait > *c) override
Process table cell.
Definition algo.h:294
void onHeading(Heading< Trait > *h) override
Process heading.
Definition algo.h:114
Definition algo.h:17
std::function< void(Item< Trait > *)> ItemFunctor
Function type for algorithms.
Definition algo.h:21
ItemType
Enumeration of item types.
Definition doc.h:23
@ Heading
Heading.
@ Blockquote
Blockquote.
@ FootnoteRef
Footnote ref.
@ Table
Table.
@ Footnote
Footnote.
@ Anchor
Anchor.
@ Math
Math expression.
@ ListItem
List item.
@ Image
Image.
@ RawHtml
Raw HTML.
@ HorizontalLine
Horizontal line.
@ LineBreak
Line break.
@ Paragraph
Paragraph.
void forEach(const typename Trait::template Vector< ItemType > &types, std::shared_ptr< Document< Trait > > doc, ItemFunctor< Trait > func, unsigned int maxNestingLevel=0)
Calls function for each item in the document with the given type.
Definition algo.h:375
Auxiliary structure to increment/decrement nesting level during walking through the document,...
Definition algo.h:333
unsigned int m_maxNestingLevel
Maximum allowed nesting level.
Definition algo.h:365
unsigned int & m_level
Reference to nesting level.
Definition algo.h:363
IncrementNestingLevel(unsigned int &l, unsigned int m, const typename Trait::template Vector< ItemType > &t)
Definition algo.h:334
const Trait::template Vector< ItemType > & m_types
Reference to list of allowed types.
Definition algo.h:367
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:19:15 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.