diff options
author | Peter Elliott <pelliott@ualberta.ca> | 2021-10-03 21:45:10 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-10-06 12:35:46 +0200 |
commit | 2227a80f34d0a5fa02b4d7d782710d7845932e49 (patch) | |
tree | 83e9ffc118bfcc4fad27a82729b703ac96854708 /Userland/Libraries/LibMarkdown/LineIterator.cpp | |
parent | 4b091a7cc27ef07ba5c0d46a02454ecbb16f6575 (diff) | |
download | serenity-2227a80f34d0a5fa02b4d7d782710d7845932e49.zip |
LibMarkdown: Add blockquote support to LineIterator
This patch adds contexts to line iterator for nesting list items and
blockquotes. It also incidentally makes the api for LineIterator
simpler, and will make it easier to add other containers in the future.
Diffstat (limited to 'Userland/Libraries/LibMarkdown/LineIterator.cpp')
-rw-r--r-- | Userland/Libraries/LibMarkdown/LineIterator.cpp | 56 |
1 files changed, 40 insertions, 16 deletions
diff --git a/Userland/Libraries/LibMarkdown/LineIterator.cpp b/Userland/Libraries/LibMarkdown/LineIterator.cpp index 6966112be8..ec77ca1642 100644 --- a/Userland/Libraries/LibMarkdown/LineIterator.cpp +++ b/Userland/Libraries/LibMarkdown/LineIterator.cpp @@ -4,38 +4,62 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <AK/Format.h> #include <LibMarkdown/LineIterator.h> namespace Markdown { -bool LineIterator::is_indented(StringView const& line) const +void LineIterator::reset_ignore_prefix() { - if (line.is_whitespace()) - return true; + for (auto& context : m_context_stack) { + context.ignore_prefix = false; + } +} - if (line.length() < m_indent) - return false; +Optional<StringView> LineIterator::match_context(StringView const& line) const +{ + bool is_ws = line.is_whitespace(); + size_t offset = 0; + for (auto& context : m_context_stack) { + switch (context.type) { + case Context::Type::ListItem: + if (is_ws) + break; - for (size_t i = 0; i < m_indent; ++i) { - if (line[i] != ' ') - return false; - } + if (offset + context.indent > line.length()) + return {}; + + if (!context.ignore_prefix && !line.substring_view(offset, context.indent).is_whitespace()) + return {}; - return true; + offset += context.indent; + + break; + case Context::Type::BlockQuote: + for (; offset < line.length() && line[offset] == ' '; ++offset) { } + if (offset >= line.length() || line[offset] != '>') { + return {}; + } + ++offset; + break; + } + + if (offset > line.length()) + return {}; + } + return line.substring_view(offset); } bool LineIterator::is_end() const { - return m_iterator.is_end() || (!m_ignore_prefix_mode && !is_indented(*m_iterator)); + return m_iterator.is_end() || !match_context(*m_iterator).has_value(); } StringView LineIterator::operator*() const { - VERIFY(m_ignore_prefix_mode || is_indented(*m_iterator)); - if (m_iterator->is_whitespace()) - return *m_iterator; - - return m_iterator->substring_view(m_indent); + auto line = match_context(*m_iterator); + VERIFY(line.has_value()); + return line.value(); } } |