diff options
author | Andreas Kling <kling@serenityos.org> | 2020-04-28 21:04:25 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-04-28 21:04:25 +0200 |
commit | ea204ef05b99b65f7d7630936e891b595012f9f5 (patch) | |
tree | 54899bb6aabe6c71fae2cace16e7bff7c3c0899a /Libraries/LibMarkdown/List.cpp | |
parent | 104969a9f5c4eaacbdc89b548729a8edeada5fff (diff) | |
download | serenity-ea204ef05b99b65f7d7630936e891b595012f9f5.zip |
LibMarkdown: Drop MD prefixes and move into "Markdown" namespace :^)
Diffstat (limited to 'Libraries/LibMarkdown/List.cpp')
-rw-r--r-- | Libraries/LibMarkdown/List.cpp | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/Libraries/LibMarkdown/List.cpp b/Libraries/LibMarkdown/List.cpp new file mode 100644 index 0000000000..bf3bd14f88 --- /dev/null +++ b/Libraries/LibMarkdown/List.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <AK/StringBuilder.h> +#include <LibMarkdown/List.h> + +namespace Markdown { + +String List::render_to_html() const +{ + StringBuilder builder; + + const char* tag = m_is_ordered ? "ol" : "ul"; + builder.appendf("<%s>", tag); + + for (auto& item : m_items) { + builder.append("<li>"); + builder.append(item.render_to_html()); + builder.append("</li>\n"); + } + + builder.appendf("</%s>\n", tag); + + return builder.build(); +} + +String List::render_for_terminal() const +{ + StringBuilder builder; + + int i = 0; + for (auto& item : m_items) { + builder.append(" "); + if (m_is_ordered) + builder.appendf("%d. ", ++i); + else + builder.append("* "); + builder.append(item.render_for_terminal()); + builder.append("\n"); + } + builder.append("\n"); + + return builder.build(); +} + +bool List::parse(Vector<StringView>::ConstIterator& lines) +{ + bool first = true; + while (true) { + if (lines.is_end()) + break; + const StringView& line = *lines; + if (line.is_empty()) + break; + + bool appears_unordered = false; + size_t offset = 0; + if (line.length() > 2) + if (line[1] == ' ' && (line[0] == '*' || line[0] == '-')) { + appears_unordered = true; + offset = 2; + } + + bool appears_ordered = false; + for (size_t i = 0; i < 10 && i < line.length(); i++) { + char ch = line[i]; + if ('0' <= ch && ch <= '9') + continue; + if (ch == '.' || ch == ')') + if (i + 1 < line.length() && line[i + 1] == ' ') { + appears_ordered = true; + offset = i + 1; + } + break; + } + + ASSERT(!(appears_unordered && appears_ordered)); + if (!appears_unordered && !appears_ordered) + return false; + if (first) + m_is_ordered = appears_ordered; + else if (m_is_ordered != appears_ordered) + return false; + + first = false; + Text text; + bool success = text.parse(line.substring_view(offset, line.length() - offset)); + ASSERT(success); + m_items.append(move(text)); + ++lines; + } + + return !first; +} + +} |