From 55b7f8ab27b94af0a7daa49063c4d5db8271e61e Mon Sep 17 00:00:00 2001 From: demostanis Date: Sun, 31 Jul 2022 21:53:25 +0200 Subject: [PATCH] LibMarkdown: Indent code blocks --- Userland/Libraries/LibMarkdown/CodeBlock.cpp | 16 +++++++++----- Userland/Libraries/LibMarkdown/CodeBlock.h | 9 +++++--- .../Libraries/LibMarkdown/ContainerBlock.cpp | 22 ++++++++++++++++--- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/Userland/Libraries/LibMarkdown/CodeBlock.cpp b/Userland/Libraries/LibMarkdown/CodeBlock.cpp index c22aae97b7..87a82b24bb 100644 --- a/Userland/Libraries/LibMarkdown/CodeBlock.cpp +++ b/Userland/Libraries/LibMarkdown/CodeBlock.cpp @@ -51,9 +51,13 @@ String CodeBlock::render_for_terminal(size_t) const StringBuilder builder; for (auto line : m_code.split('\n')) { + // Do not indent too much if we are in the synopsis + if (!(m_current_section && m_current_section->render_for_terminal().contains("SYNOPSIS"sv))) + builder.append(" "sv); + builder.append(" "sv); builder.append(line); - builder.append("\n"sv); + builder.append("\x1b[0m\n"sv); } return builder.build(); @@ -104,14 +108,14 @@ static Optional line_block_prefix(StringView const& line) return {}; } -OwnPtr CodeBlock::parse(LineIterator& lines) +OwnPtr CodeBlock::parse(LineIterator& lines, Heading* current_section) { if (lines.is_end()) return {}; StringView line = *lines; if (open_fence_re.match(line).success) - return parse_backticks(lines); + return parse_backticks(lines, current_section); if (line_block_prefix(line).has_value()) return parse_indent(lines); @@ -119,7 +123,7 @@ OwnPtr CodeBlock::parse(LineIterator& lines) return {}; } -OwnPtr CodeBlock::parse_backticks(LineIterator& lines) +OwnPtr CodeBlock::parse_backticks(LineIterator& lines, Heading* current_section) { StringView line = *lines; @@ -160,7 +164,7 @@ OwnPtr CodeBlock::parse_backticks(LineIterator& lines) builder.append('\n'); } - return make(language, style, builder.build()); + return make(language, style, builder.build(), current_section); } OwnPtr CodeBlock::parse_indent(LineIterator& lines) @@ -183,6 +187,6 @@ OwnPtr CodeBlock::parse_indent(LineIterator& lines) builder.append('\n'); } - return make("", "", builder.build()); + return make("", "", builder.build(), nullptr); } } diff --git a/Userland/Libraries/LibMarkdown/CodeBlock.h b/Userland/Libraries/LibMarkdown/CodeBlock.h index 3a9ddc2b35..83dcb9a030 100644 --- a/Userland/Libraries/LibMarkdown/CodeBlock.h +++ b/Userland/Libraries/LibMarkdown/CodeBlock.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -16,10 +17,11 @@ namespace Markdown { class CodeBlock final : public Block { public: - CodeBlock(String const& language, String const& style, String const& code) + CodeBlock(String const& language, String const& style, String const& code, Heading* current_section) : m_code(move(code)) , m_language(language) , m_style(style) + , m_current_section(current_section) { } virtual ~CodeBlock() override = default; @@ -27,14 +29,15 @@ public: 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); + static OwnPtr parse(LineIterator& lines, Heading* current_section); private: String m_code; String m_language; String m_style; + Heading* m_current_section; - static OwnPtr parse_backticks(LineIterator& lines); + static OwnPtr parse_backticks(LineIterator& lines, Heading* current_section); static OwnPtr parse_indent(LineIterator& lines); }; diff --git a/Userland/Libraries/LibMarkdown/ContainerBlock.cpp b/Userland/Libraries/LibMarkdown/ContainerBlock.cpp index fef3ec15c3..6cee5150d0 100644 --- a/Userland/Libraries/LibMarkdown/ContainerBlock.cpp +++ b/Userland/Libraries/LibMarkdown/ContainerBlock.cpp @@ -66,6 +66,16 @@ RecursionDecision ContainerBlock::walk(Visitor& visitor) const return RecursionDecision::Continue; } +template +static bool try_parse_block(LineIterator& lines, NonnullOwnPtrVector& blocks, Heading* current_section) +{ + OwnPtr block = CodeBlock::parse(lines, current_section); + if (!block) + return false; + blocks.append(block.release_nonnull()); + return true; +} + template static bool try_parse_block(LineIterator& lines, NonnullOwnPtrVector& blocks) { @@ -81,6 +91,7 @@ OwnPtr ContainerBlock::parse(LineIterator& lines) NonnullOwnPtrVector blocks; StringBuilder paragraph_text; + Heading* current_section; auto flush_paragraph = [&] { if (paragraph_text.is_empty()) @@ -107,12 +118,17 @@ OwnPtr ContainerBlock::parse(LineIterator& lines) has_blank_lines = has_blank_lines || has_trailing_blank_lines; } - bool any = try_parse_block(lines, blocks) + bool heading = false; + if ((heading = try_parse_block(lines, blocks))) + current_section = dynamic_cast(&blocks.last()); + + bool any = heading + || try_parse_block
(lines, blocks) || try_parse_block(lines, blocks) || try_parse_block(lines, blocks) - || try_parse_block(lines, blocks) + // CodeBlock needs to know the current section's name for proper indentation + || try_parse_block(lines, blocks, current_section) || try_parse_block(lines, blocks) - || try_parse_block(lines, blocks) || try_parse_block
(lines, blocks); if (any) {