فهرست منبع

LibMarkdown: Indent code blocks

demostanis 3 سال پیش
والد
کامیت
55b7f8ab27

+ 10 - 6
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<int> line_block_prefix(StringView const& line)
     return {};
 }
 
-OwnPtr<CodeBlock> CodeBlock::parse(LineIterator& lines)
+OwnPtr<CodeBlock> 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> CodeBlock::parse(LineIterator& lines)
     return {};
 }
 
-OwnPtr<CodeBlock> CodeBlock::parse_backticks(LineIterator& lines)
+OwnPtr<CodeBlock> CodeBlock::parse_backticks(LineIterator& lines, Heading* current_section)
 {
     StringView line = *lines;
 
@@ -160,7 +164,7 @@ OwnPtr<CodeBlock> CodeBlock::parse_backticks(LineIterator& lines)
         builder.append('\n');
     }
 
-    return make<CodeBlock>(language, style, builder.build());
+    return make<CodeBlock>(language, style, builder.build(), current_section);
 }
 
 OwnPtr<CodeBlock> CodeBlock::parse_indent(LineIterator& lines)
@@ -183,6 +187,6 @@ OwnPtr<CodeBlock> CodeBlock::parse_indent(LineIterator& lines)
         builder.append('\n');
     }
 
-    return make<CodeBlock>("", "", builder.build());
+    return make<CodeBlock>("", "", builder.build(), nullptr);
 }
 }

+ 6 - 3
Userland/Libraries/LibMarkdown/CodeBlock.h

@@ -9,6 +9,7 @@
 
 #include <AK/OwnPtr.h>
 #include <LibMarkdown/Block.h>
+#include <LibMarkdown/Heading.h>
 #include <LibMarkdown/LineIterator.h>
 #include <LibMarkdown/Text.h>
 
@@ -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<CodeBlock> parse(LineIterator& lines);
+    static OwnPtr<CodeBlock> parse(LineIterator& lines, Heading* current_section);
 
 private:
     String m_code;
     String m_language;
     String m_style;
+    Heading* m_current_section;
 
-    static OwnPtr<CodeBlock> parse_backticks(LineIterator& lines);
+    static OwnPtr<CodeBlock> parse_backticks(LineIterator& lines, Heading* current_section);
     static OwnPtr<CodeBlock> parse_indent(LineIterator& lines);
 };
 

+ 19 - 3
Userland/Libraries/LibMarkdown/ContainerBlock.cpp

@@ -66,6 +66,16 @@ RecursionDecision ContainerBlock::walk(Visitor& visitor) const
     return RecursionDecision::Continue;
 }
 
+template<class CodeBlock>
+static bool try_parse_block(LineIterator& lines, NonnullOwnPtrVector<Block>& blocks, Heading* current_section)
+{
+    OwnPtr<CodeBlock> block = CodeBlock::parse(lines, current_section);
+    if (!block)
+        return false;
+    blocks.append(block.release_nonnull());
+    return true;
+}
+
 template<typename BlockType>
 static bool try_parse_block(LineIterator& lines, NonnullOwnPtrVector<Block>& blocks)
 {
@@ -81,6 +91,7 @@ OwnPtr<ContainerBlock> ContainerBlock::parse(LineIterator& lines)
     NonnullOwnPtrVector<Block> blocks;
 
     StringBuilder paragraph_text;
+    Heading* current_section;
 
     auto flush_paragraph = [&] {
         if (paragraph_text.is_empty())
@@ -107,12 +118,17 @@ OwnPtr<ContainerBlock> ContainerBlock::parse(LineIterator& lines)
             has_blank_lines = has_blank_lines || has_trailing_blank_lines;
         }
 
-        bool any = try_parse_block<Table>(lines, blocks)
+        bool heading = false;
+        if ((heading = try_parse_block<Heading>(lines, blocks)))
+            current_section = dynamic_cast<Heading*>(&blocks.last());
+
+        bool any = heading
+            || try_parse_block<Table>(lines, blocks)
             || try_parse_block<HorizontalRule>(lines, blocks)
             || try_parse_block<List>(lines, blocks)
-            || try_parse_block<CodeBlock>(lines, blocks)
+            // CodeBlock needs to know the current section's name for proper indentation
+            || try_parse_block<CodeBlock>(lines, blocks, current_section)
             || try_parse_block<CommentBlock>(lines, blocks)
-            || try_parse_block<Heading>(lines, blocks)
             || try_parse_block<BlockQuote>(lines, blocks);
 
         if (any) {