diff --git a/Userland/Libraries/LibMarkdown/CMakeLists.txt b/Userland/Libraries/LibMarkdown/CMakeLists.txt index 01cd4882b90..7a060acebed 100644 --- a/Userland/Libraries/LibMarkdown/CMakeLists.txt +++ b/Userland/Libraries/LibMarkdown/CMakeLists.txt @@ -1,6 +1,7 @@ set(SOURCES BlockQuote.cpp CodeBlock.cpp + CommentBlock.cpp ContainerBlock.cpp Document.cpp Heading.cpp diff --git a/Userland/Libraries/LibMarkdown/CommentBlock.cpp b/Userland/Libraries/LibMarkdown/CommentBlock.cpp new file mode 100644 index 00000000000..7b4f892100c --- /dev/null +++ b/Userland/Libraries/LibMarkdown/CommentBlock.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021, Ben Wiederhake + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Markdown { + +String CommentBlock::render_to_html(bool) const +{ + StringBuilder builder; + + builder.append("\n"); + + return builder.build(); +} + +String CommentBlock::render_for_terminal(size_t) const +{ + return ""; +} + +RecursionDecision CommentBlock::walk(Visitor& visitor) const +{ + RecursionDecision rd = visitor.visit(*this); + if (rd != RecursionDecision::Recurse) + return rd; + + // Normalize return value. + return RecursionDecision::Continue; +} + +OwnPtr CommentBlock::parse(LineIterator& lines) +{ + if (lines.is_end()) + return {}; + + constexpr auto comment_start = ""sv; + + StringView line = *lines; + if (!line.starts_with(comment_start)) + return {}; + line = line.substring_view(comment_start.length()); + + StringBuilder builder; + + while (true) { + // Invariant: At the beginning of the loop, `line` is valid and should be added the the builder. + bool ends_here = line.ends_with(comment_end); + if (ends_here) + line = line.substring_view(0, line.length() - comment_end.length()); + builder.append(line); + if (!ends_here) + builder.append('\n'); + + ++lines; + if (lines.is_end() || ends_here) { + break; + } + line = *lines; + } + + return make(builder.build()); +} + +} diff --git a/Userland/Libraries/LibMarkdown/CommentBlock.h b/Userland/Libraries/LibMarkdown/CommentBlock.h new file mode 100644 index 00000000000..e557efd7cfd --- /dev/null +++ b/Userland/Libraries/LibMarkdown/CommentBlock.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021, Ben Wiederhake + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include + +namespace Markdown { + +class CommentBlock final : public Block { +public: + CommentBlock(String const& comment) + : m_comment(comment) + { + } + virtual ~CommentBlock() override { } + + virtual String render_to_html(bool tight = false) const override; + virtual String render_for_terminal(size_t view_width = 0) const override; + virtual RecursionDecision walk(Visitor&) const override; + static OwnPtr parse(LineIterator& lines); + +private: + String m_comment; +}; + +} diff --git a/Userland/Libraries/LibMarkdown/ContainerBlock.cpp b/Userland/Libraries/LibMarkdown/ContainerBlock.cpp index 0682bc89b01..acb0f4db59b 100644 --- a/Userland/Libraries/LibMarkdown/ContainerBlock.cpp +++ b/Userland/Libraries/LibMarkdown/ContainerBlock.cpp @@ -107,8 +107,12 @@ OwnPtr ContainerBlock::parse(LineIterator& lines) has_blank_lines = has_blank_lines || has_trailing_blank_lines; } - bool any = try_parse_block(lines, blocks) || try_parse_block(lines, blocks) || try_parse_block(lines, blocks) - || try_parse_block(lines, blocks) || try_parse_block(lines, blocks) + bool any = try_parse_block
(lines, blocks) + || try_parse_block(lines, blocks) + || try_parse_block(lines, blocks) + || try_parse_block(lines, blocks) + || try_parse_block(lines, blocks) + || try_parse_block(lines, blocks) || try_parse_block
(lines, blocks); if (any) { diff --git a/Userland/Libraries/LibMarkdown/Visitor.h b/Userland/Libraries/LibMarkdown/Visitor.h index d2035811a93..7341b404f37 100644 --- a/Userland/Libraries/LibMarkdown/Visitor.h +++ b/Userland/Libraries/LibMarkdown/Visitor.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ public: virtual RecursionDecision visit(BlockQuote const&) { return RecursionDecision::Recurse; } virtual RecursionDecision visit(CodeBlock const&) { return RecursionDecision::Recurse; } + virtual RecursionDecision visit(CommentBlock const&) { return RecursionDecision::Recurse; } virtual RecursionDecision visit(ContainerBlock const&) { return RecursionDecision::Recurse; } virtual RecursionDecision visit(Heading const&) { return RecursionDecision::Recurse; } virtual RecursionDecision visit(HorizontalRule const&) { return RecursionDecision::Recurse; }