|
ferencd@0
|
1 /*
|
|
ferencd@0
|
2 * This project is licensed under the MIT license. For more information see the
|
|
ferencd@0
|
3 * LICENSE file.
|
|
ferencd@0
|
4 */
|
|
ferencd@0
|
5 #pragma once
|
|
ferencd@0
|
6
|
|
ferencd@0
|
7 // -----------------------------------------------------------------------------
|
|
ferencd@0
|
8
|
|
ferencd@0
|
9 #include <functional>
|
|
ferencd@0
|
10 #include <regex>
|
|
ferencd@0
|
11 #include <string>
|
|
ferencd@0
|
12
|
|
ferencd@0
|
13 #include "maddy/blockparser.h"
|
|
ferencd@0
|
14
|
|
ferencd@0
|
15 // -----------------------------------------------------------------------------
|
|
ferencd@0
|
16
|
|
ferencd@0
|
17 namespace maddy {
|
|
ferencd@0
|
18
|
|
ferencd@0
|
19 // -----------------------------------------------------------------------------
|
|
ferencd@0
|
20
|
|
ferencd@0
|
21 /**
|
|
ferencd@0
|
22 * UnorderedListParser
|
|
ferencd@0
|
23 *
|
|
ferencd@0
|
24 * @class
|
|
ferencd@0
|
25 */
|
|
ferencd@0
|
26 class UnorderedListParser : public BlockParser
|
|
ferencd@0
|
27 {
|
|
ferencd@0
|
28 public:
|
|
ferencd@0
|
29 /**
|
|
ferencd@0
|
30 * ctor
|
|
ferencd@0
|
31 *
|
|
ferencd@0
|
32 * @method
|
|
ferencd@0
|
33 * @param {std::function<void(std::string&)>} parseLineCallback
|
|
ferencd@0
|
34 * @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
|
ferencd@0
|
35 */
|
|
ferencd@0
|
36 UnorderedListParser(
|
|
ferencd@0
|
37 std::function<void(std::string&)> parseLineCallback,
|
|
ferencd@0
|
38 std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
|
ferencd@0
|
39 )
|
|
ferencd@0
|
40 : BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
|
ferencd@0
|
41 , isStarted(false)
|
|
ferencd@0
|
42 , isFinished(false)
|
|
ferencd@0
|
43 {}
|
|
ferencd@0
|
44
|
|
ferencd@0
|
45 /**
|
|
ferencd@0
|
46 * IsStartingLine
|
|
ferencd@0
|
47 *
|
|
ferencd@0
|
48 * An unordered list starts with `* `.
|
|
ferencd@0
|
49 *
|
|
ferencd@0
|
50 * @method
|
|
ferencd@0
|
51 * @param {const std::string&} line
|
|
ferencd@0
|
52 * @return {bool}
|
|
ferencd@0
|
53 */
|
|
ferencd@0
|
54 static bool
|
|
ferencd@0
|
55 IsStartingLine(const std::string& line)
|
|
ferencd@0
|
56 {
|
|
ferencd@0
|
57 static std::regex re("^[+*-] .*");
|
|
ferencd@0
|
58 return std::regex_match(line, re);
|
|
ferencd@0
|
59 }
|
|
ferencd@0
|
60
|
|
ferencd@0
|
61 /**
|
|
ferencd@0
|
62 * IsFinished
|
|
ferencd@0
|
63 *
|
|
ferencd@0
|
64 * @method
|
|
ferencd@0
|
65 * @return {bool}
|
|
ferencd@0
|
66 */
|
|
ferencd@0
|
67 bool
|
|
ferencd@0
|
68 IsFinished() const override
|
|
ferencd@0
|
69 {
|
|
ferencd@0
|
70 return this->isFinished;
|
|
ferencd@0
|
71 }
|
|
ferencd@0
|
72
|
|
ferencd@0
|
73 protected:
|
|
ferencd@0
|
74 bool
|
|
ferencd@0
|
75 isInlineBlockAllowed() const override
|
|
ferencd@0
|
76 {
|
|
ferencd@0
|
77 return true;
|
|
ferencd@0
|
78 }
|
|
ferencd@0
|
79
|
|
ferencd@0
|
80 bool
|
|
ferencd@0
|
81 isLineParserAllowed() const override
|
|
ferencd@0
|
82 {
|
|
ferencd@0
|
83 return true;
|
|
ferencd@0
|
84 }
|
|
ferencd@0
|
85
|
|
ferencd@0
|
86 void
|
|
ferencd@0
|
87 parseBlock(std::string& line) override
|
|
ferencd@0
|
88 {
|
|
ferencd@0
|
89 bool isStartOfNewListItem = IsStartingLine(line);
|
|
ferencd@0
|
90 uint32_t indentation = getIndentationWidth(line);
|
|
ferencd@0
|
91
|
|
ferencd@0
|
92 static std::regex lineRegex("^([+*-] )");
|
|
ferencd@0
|
93 line = std::regex_replace(line, lineRegex, "");
|
|
ferencd@0
|
94
|
|
ferencd@0
|
95 if (!this->isStarted)
|
|
ferencd@0
|
96 {
|
|
ferencd@0
|
97 line = "<ul><li>" + line;
|
|
ferencd@0
|
98 this->isStarted = true;
|
|
ferencd@0
|
99 return;
|
|
ferencd@0
|
100 }
|
|
ferencd@0
|
101
|
|
ferencd@0
|
102 if (indentation >= 2)
|
|
ferencd@0
|
103 {
|
|
ferencd@0
|
104 line = line.substr(2);
|
|
ferencd@0
|
105 return;
|
|
ferencd@0
|
106 }
|
|
ferencd@0
|
107
|
|
ferencd@0
|
108 if (
|
|
ferencd@0
|
109 line.empty() ||
|
|
ferencd@0
|
110 line.find("</li><li>") != std::string::npos ||
|
|
ferencd@0
|
111 line.find("</li></ol>") != std::string::npos ||
|
|
ferencd@0
|
112 line.find("</li></ul>") != std::string::npos
|
|
ferencd@0
|
113 )
|
|
ferencd@0
|
114 {
|
|
ferencd@0
|
115 line = "</li></ul>" + line;
|
|
ferencd@0
|
116 this->isFinished = true;
|
|
ferencd@0
|
117 return;
|
|
ferencd@0
|
118 }
|
|
ferencd@0
|
119
|
|
ferencd@0
|
120 if (isStartOfNewListItem)
|
|
ferencd@0
|
121 {
|
|
ferencd@0
|
122 line = "</li><li>" + line;
|
|
ferencd@0
|
123 }
|
|
ferencd@0
|
124 }
|
|
ferencd@0
|
125
|
|
ferencd@0
|
126 private:
|
|
ferencd@0
|
127 bool isStarted;
|
|
ferencd@0
|
128 bool isFinished;
|
|
ferencd@0
|
129 }; // class UnorderedListParser
|
|
ferencd@0
|
130
|
|
ferencd@0
|
131 // -----------------------------------------------------------------------------
|
|
ferencd@0
|
132
|
|
ferencd@0
|
133 } // namespace maddy
|