summaryrefslogtreecommitdiffstats
path: root/yql/essentials/utils/docs/markdown.cpp
diff options
context:
space:
mode:
authorrobot-piglet <[email protected]>2025-07-16 10:20:41 +0300
committerrobot-piglet <[email protected]>2025-07-16 10:34:35 +0300
commit620507e761ed6b11758e43a6e4ff5cc4d6c2e2cb (patch)
tree91020fe5f2d55ee0174cefad8f1f4a56aa64a190 /yql/essentials/utils/docs/markdown.cpp
parent37a359136f861e7e9de7fc1755779e731d9ff0fe (diff)
Intermediate changes
commit_hash:5aaa14131e1a44bd5ff318aaed16345258d4c42e
Diffstat (limited to 'yql/essentials/utils/docs/markdown.cpp')
-rw-r--r--yql/essentials/utils/docs/markdown.cpp74
1 files changed, 74 insertions, 0 deletions
diff --git a/yql/essentials/utils/docs/markdown.cpp b/yql/essentials/utils/docs/markdown.cpp
new file mode 100644
index 00000000000..4af1357f1fe
--- /dev/null
+++ b/yql/essentials/utils/docs/markdown.cpp
@@ -0,0 +1,74 @@
+#include "markdown.h"
+
+#include <yql/essentials/utils/yql_panic.h>
+
+#include <contrib/libs/re2/re2/re2.h>
+
+#include <util/generic/yexception.h>
+
+namespace NSQLComplete {
+
+ class TMarkdownParser {
+ public:
+ void Parse(IInputStream& markdown, TMarkdownCallback&& onSection) {
+ for (TString line; markdown.ReadLine(line) != 0;) {
+ if (IsSkipping_) {
+ if (IsSectionHeader(line)) {
+ ResetSection(std::move(line));
+ IsSkipping_ = false;
+ } else {
+ // Skip
+ }
+ } else {
+ if (IsSectionHeader(line)) {
+ onSection(std::move(Section_));
+ ResetSection(std::move(line));
+ } else {
+ Section_.Body.append(std::move(line));
+ }
+ }
+ }
+
+ if (!IsSkipping_) {
+ onSection(std::move(Section_));
+ }
+ }
+
+ private:
+ void ResetSection(TString&& line) {
+ Section_ = TMarkdownSection();
+
+ TString content;
+ std::optional<TString> dummy;
+ std::optional<TString> anchor;
+ YQL_ENSURE(
+ RE2::FullMatch(line, SectionHeaderRegex_, &content, &dummy, &anchor),
+ "line '" << line << "' does not match regex '"
+ << SectionHeaderRegex_.pattern() << "'");
+
+ Section_.Header.Content = std::move(content);
+ if (anchor) {
+ Section_.Header.Anchor = std::move(*anchor);
+ }
+ }
+
+ bool IsSectionHeader(TStringBuf line) const {
+ return HeaderDepth(line) == 2;
+ }
+
+ size_t HeaderDepth(TStringBuf line) const {
+ size_t pos = line.find_first_not_of('#');
+ return pos != TStringBuf::npos ? pos : 0;
+ }
+
+ RE2 SectionHeaderRegex_{R"re(## ([^#]+)(\s+{(#[a-z\-_]+)})?)re"};
+ bool IsSkipping_ = true;
+ TMarkdownSection Section_;
+ };
+
+ void ParseMarkdown(IInputStream& markdown, TMarkdownCallback&& onSection) {
+ TMarkdownParser parser;
+ parser.Parse(markdown, std::forward<TMarkdownCallback>(onSection));
+ }
+
+} // namespace NSQLComplete