From 5bb87c630c5599309f29977512d7719ff6cae2eb Mon Sep 17 00:00:00 2001 From: Peter Elliott Date: Sun, 26 Sep 2021 20:14:58 -0600 Subject: LibMarkdown: Allow non-text items in Lists --- Userland/Libraries/LibMarkdown/List.cpp | 70 ++++++++++++--------------------- Userland/Libraries/LibMarkdown/List.h | 10 ++--- 2 files changed, 30 insertions(+), 50 deletions(-) (limited to 'Userland/Libraries/LibMarkdown') diff --git a/Userland/Libraries/LibMarkdown/List.cpp b/Userland/Libraries/LibMarkdown/List.cpp index 4da8e18ba7..393ff2899c 100644 --- a/Userland/Libraries/LibMarkdown/List.cpp +++ b/Userland/Libraries/LibMarkdown/List.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2019-2020, Sergey Bugaev + * Copyright (c) 2021, Peter Elliott * * SPDX-License-Identifier: BSD-2-Clause */ @@ -17,8 +18,8 @@ String List::render_to_html() const builder.appendff("<{}>\n", tag); for (auto& item : m_items) { - builder.append("
  • "); - builder.append(item.render_to_html()); + builder.append("
  • \n"); + builder.append(item->render_to_html()); builder.append("
  • \n"); } @@ -38,7 +39,7 @@ String List::render_for_terminal(size_t) const builder.appendff("{}. ", ++i); else builder.append("* "); - builder.append(item.render_for_terminal()); + builder.append(item->render_for_terminal()); builder.append("\n"); } builder.append("\n"); @@ -48,26 +49,13 @@ String List::render_for_terminal(size_t) const OwnPtr List::parse(LineIterator& lines) { - Vector items; - bool is_ordered = false; + Vector> items; bool first = true; - size_t offset = 0; - StringBuilder item_builder; - auto flush_item_if_needed = [&] { - if (first) - return true; - - auto text = Text::parse(item_builder.string_view()); - items.append(move(text)); - - item_builder.clear(); - return true; - }; + bool is_ordered = false; + while (!lines.is_end()) { + size_t offset = 0; - while (true) { - if (lines.is_end()) - break; const StringView& line = *lines; if (line.is_empty()) break; @@ -76,7 +64,7 @@ OwnPtr List::parse(LineIterator& lines) if (line.length() > 2) { if (line[1] == ' ' && (line[0] == '*' || line[0] == '-')) { appears_unordered = true; - offset = 2; + offset = 1; } } @@ -94,39 +82,33 @@ OwnPtr List::parse(LineIterator& lines) } VERIFY(!(appears_unordered && appears_ordered)); - - if (appears_unordered || appears_ordered) { + if (!appears_unordered && !appears_ordered) { if (first) - is_ordered = appears_ordered; - else if (is_ordered != appears_ordered) return {}; - if (!flush_item_if_needed()) - return {}; + break; + } - while (offset + 1 < line.length() && line[offset + 1] == ' ') - offset++; + while (offset < line.length() && line[offset] == ' ') + offset++; - } else { - if (first) - return {}; - for (size_t i = 0; i < offset; i++) { - if (line[i] != ' ') - return {}; - } + if (first) { + is_ordered = appears_ordered; + } else if (appears_ordered != is_ordered) { + break; } + size_t saved_indent = lines.indent(); + lines.set_indent(saved_indent + offset); + lines.ignore_next_prefix(); + + items.append(ContainerBlock::parse(lines)); + + lines.set_indent(saved_indent); + first = false; - if (!item_builder.is_empty()) - item_builder.append(' '); - VERIFY(offset <= line.length()); - item_builder.append(line.substring_view(offset, line.length() - offset)); - ++lines; - offset = 0; } - if (!flush_item_if_needed() || first) - return {}; return make(move(items), is_ordered); } diff --git a/Userland/Libraries/LibMarkdown/List.h b/Userland/Libraries/LibMarkdown/List.h index 10271403fd..ee484c50e8 100644 --- a/Userland/Libraries/LibMarkdown/List.h +++ b/Userland/Libraries/LibMarkdown/List.h @@ -7,17 +7,16 @@ #pragma once #include -#include #include +#include #include -#include namespace Markdown { class List final : public Block { public: - List(Vector&& text, bool is_ordered) - : m_items(move(text)) + List(Vector> items, bool is_ordered) + : m_items(move(items)) , m_is_ordered(is_ordered) { } @@ -29,8 +28,7 @@ public: static OwnPtr parse(LineIterator& lines); private: - // TODO: List items should be considered blocks of their own kind. - Vector m_items; + Vector> m_items; bool m_is_ordered { false }; }; -- cgit v1.2.3