diff options
author | Peter Elliott <pelliott@ualberta.ca> | 2021-09-26 20:14:58 -0600 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2021-10-05 13:27:25 +0330 |
commit | 5bb87c630c5599309f29977512d7719ff6cae2eb (patch) | |
tree | 97564c0d5d91677fada3a4fc3e297360972a95e2 /Userland/Libraries | |
parent | 10f6f6a723b2cec608d9499e27c28b7343d6e51f (diff) | |
download | serenity-5bb87c630c5599309f29977512d7719ff6cae2eb.zip |
LibMarkdown: Allow non-text items in Lists
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibMarkdown/List.cpp | 70 | ||||
-rw-r--r-- | Userland/Libraries/LibMarkdown/List.h | 10 |
2 files changed, 30 insertions, 50 deletions
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 <bugaevc@serenityos.org> + * Copyright (c) 2021, Peter Elliott <pelliott@serenityos.org> * * 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("<li>"); - builder.append(item.render_to_html()); + builder.append("<li>\n"); + builder.append(item->render_to_html()); builder.append("</li>\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> List::parse(LineIterator& lines) { - Vector<Text> items; - bool is_ordered = false; + Vector<OwnPtr<ContainerBlock>> 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> 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> 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<List>(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 <AK/OwnPtr.h> -#include <AK/Vector.h> #include <LibMarkdown/Block.h> +#include <LibMarkdown/ContainerBlock.h> #include <LibMarkdown/LineIterator.h> -#include <LibMarkdown/Text.h> namespace Markdown { class List final : public Block { public: - List(Vector<Text>&& text, bool is_ordered) - : m_items(move(text)) + List(Vector<OwnPtr<ContainerBlock>> items, bool is_ordered) + : m_items(move(items)) , m_is_ordered(is_ordered) { } @@ -29,8 +28,7 @@ public: static OwnPtr<List> parse(LineIterator& lines); private: - // TODO: List items should be considered blocks of their own kind. - Vector<Text> m_items; + Vector<OwnPtr<ContainerBlock>> m_items; bool m_is_ordered { false }; }; |