summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibMarkdown/LineIterator.cpp
blob: 7366716e72a6dc8e0f53d8684fbe03533dfbad89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*
 * Copyright (c) 2021, Peter Elliott <pelliott@serenityos.org>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <AK/Format.h>
#include <LibMarkdown/LineIterator.h>

namespace Markdown {

void LineIterator::reset_ignore_prefix()
{
    for (auto& context : m_context_stack) {
        context.ignore_prefix = false;
    }
}

Optional<StringView> LineIterator::match_context(StringView 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;

            if (offset + context.indent > line.length())
                return {};

            if (!context.ignore_prefix && !line.substring_view(offset, context.indent).is_whitespace())
                return {};

            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() || !match_context(*m_iterator).has_value();
}

StringView LineIterator::operator*() const
{
    auto line = match_context(*m_iterator);
    VERIFY(line.has_value());
    return line.value();
}

}