|
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 <string>
|
|
ferencd@0
|
11 #include <regex>
|
|
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 * HeadlineParser
|
|
ferencd@0
|
23 *
|
|
ferencd@0
|
24 * From Markdown:
|
|
ferencd@0
|
25 *
|
|
ferencd@0
|
26 * ```
|
|
ferencd@0
|
27 * # Headline 1
|
|
ferencd@0
|
28 * ## Headline 2
|
|
ferencd@0
|
29 * ### Headline 3
|
|
ferencd@0
|
30 * #### Headline 4
|
|
ferencd@0
|
31 * ##### Headline 5
|
|
ferencd@0
|
32 * ###### Headline 6
|
|
ferencd@0
|
33 * ```
|
|
ferencd@0
|
34 *
|
|
ferencd@0
|
35 * To HTML:
|
|
ferencd@0
|
36 *
|
|
ferencd@0
|
37 * ```
|
|
ferencd@0
|
38 * <h1>Headline 1</h1>
|
|
ferencd@0
|
39 * <h2>Headline 2</h2>
|
|
ferencd@0
|
40 * <h3>Headline 3</h3>
|
|
ferencd@0
|
41 * <h4>Headline 4</h4>
|
|
ferencd@0
|
42 * <h5>Headline 5</h5>
|
|
ferencd@0
|
43 * <h6>Headline 6</h6>
|
|
ferencd@0
|
44 * ```
|
|
ferencd@0
|
45 *
|
|
ferencd@0
|
46 * @class
|
|
ferencd@0
|
47 */
|
|
ferencd@0
|
48 class HeadlineParser : public BlockParser
|
|
ferencd@0
|
49 {
|
|
ferencd@0
|
50 public:
|
|
ferencd@0
|
51 /**
|
|
ferencd@0
|
52 * ctor
|
|
ferencd@0
|
53 *
|
|
ferencd@0
|
54 * @method
|
|
ferencd@0
|
55 * @param {std::function<void(std::string&)>} parseLineCallback
|
|
ferencd@0
|
56 * @param {std::function<std::shared_ptr<BlockParser>(const std::string& line)>} getBlockParserForLineCallback
|
|
ferencd@0
|
57 */
|
|
ferencd@0
|
58 HeadlineParser(
|
|
ferencd@0
|
59 std::function<void(std::string&)> parseLineCallback,
|
|
ferencd@0
|
60 std::function<std::shared_ptr<BlockParser>(const std::string& line)> getBlockParserForLineCallback
|
|
ferencd@0
|
61 )
|
|
ferencd@0
|
62 : BlockParser(parseLineCallback, getBlockParserForLineCallback)
|
|
ferencd@0
|
63 {}
|
|
ferencd@0
|
64
|
|
ferencd@0
|
65 /**
|
|
ferencd@0
|
66 * IsStartingLine
|
|
ferencd@0
|
67 *
|
|
ferencd@0
|
68 * If the line starts with 1 - 6 `#`, then it is a headline.
|
|
ferencd@0
|
69 *
|
|
ferencd@0
|
70 * @method
|
|
ferencd@0
|
71 * @param {const std::string&} line
|
|
ferencd@0
|
72 * @return {bool}
|
|
ferencd@0
|
73 */
|
|
ferencd@0
|
74 static bool
|
|
ferencd@0
|
75 IsStartingLine(const std::string& line)
|
|
ferencd@0
|
76 {
|
|
ferencd@0
|
77 static std::regex re("^(?:#){1,6} (.*)");
|
|
ferencd@0
|
78 return std::regex_match(line, re);
|
|
ferencd@0
|
79 }
|
|
ferencd@0
|
80
|
|
ferencd@0
|
81 /**
|
|
ferencd@0
|
82 * IsFinished
|
|
ferencd@0
|
83 *
|
|
ferencd@0
|
84 * The headline is always only one line long, so this method always returns
|
|
ferencd@0
|
85 * true.
|
|
ferencd@0
|
86 *
|
|
ferencd@0
|
87 * @method
|
|
ferencd@0
|
88 * @return {bool}
|
|
ferencd@0
|
89 */
|
|
ferencd@0
|
90 bool
|
|
ferencd@0
|
91 IsFinished() const override
|
|
ferencd@0
|
92 {
|
|
ferencd@0
|
93 return true;
|
|
ferencd@0
|
94 }
|
|
ferencd@0
|
95
|
|
ferencd@0
|
96 protected:
|
|
ferencd@0
|
97 bool
|
|
ferencd@0
|
98 isInlineBlockAllowed() const override
|
|
ferencd@0
|
99 {
|
|
ferencd@0
|
100 return false;
|
|
ferencd@0
|
101 }
|
|
ferencd@0
|
102
|
|
ferencd@0
|
103 bool
|
|
ferencd@0
|
104 isLineParserAllowed() const override
|
|
ferencd@0
|
105 {
|
|
ferencd@0
|
106 return false;
|
|
ferencd@0
|
107 }
|
|
ferencd@0
|
108
|
|
ferencd@0
|
109 void
|
|
ferencd@0
|
110 parseBlock(std::string& line) override
|
|
ferencd@0
|
111 {
|
|
ferencd@0
|
112 static std::vector<std::regex> hlRegex = {
|
|
ferencd@0
|
113 std::regex("^# (.*)")
|
|
ferencd@0
|
114 , std::regex("^(?:#){2} (.*)")
|
|
ferencd@0
|
115 , std::regex("^(?:#){3} (.*)")
|
|
ferencd@0
|
116 , std::regex("^(?:#){4} (.*)")
|
|
ferencd@0
|
117 , std::regex("^(?:#){5} (.*)")
|
|
ferencd@0
|
118 , std::regex("^(?:#){6} (.*)")
|
|
ferencd@0
|
119 };
|
|
ferencd@0
|
120 static std::vector<std::string> hlReplacement = {
|
|
ferencd@0
|
121 "<h1>$1</h1>"
|
|
ferencd@0
|
122 , "<h2>$1</h2>"
|
|
ferencd@0
|
123 , "<h3>$1</h3>"
|
|
ferencd@0
|
124 , "<h4>$1</h4>"
|
|
ferencd@0
|
125 , "<h5>$1</h5>"
|
|
ferencd@0
|
126 , "<h6>$1</h6>"
|
|
ferencd@0
|
127 };
|
|
ferencd@0
|
128
|
|
ferencd@0
|
129 for (uint8_t i = 0; i < 6; ++i)
|
|
ferencd@0
|
130 {
|
|
ferencd@0
|
131 line = std::regex_replace(line, hlRegex[i], hlReplacement[i]);
|
|
ferencd@0
|
132 }
|
|
ferencd@0
|
133 }
|
|
ferencd@0
|
134 }; // class HeadlineParser
|
|
ferencd@0
|
135
|
|
ferencd@0
|
136 // -----------------------------------------------------------------------------
|
|
ferencd@0
|
137
|
|
ferencd@0
|
138 } // namespace maddy
|