Serenity Operating System
at master 82 lines 1.9 kB view raw
1/* 2 * Copyright (c) 2019-2020, Sergey Bugaev <bugaevc@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/StringBuilder.h> 8#include <LibMarkdown/Heading.h> 9#include <LibMarkdown/Visitor.h> 10 11namespace Markdown { 12 13DeprecatedString Heading::render_to_html(bool) const 14{ 15 return DeprecatedString::formatted("<h{}>{}</h{}>\n", m_level, m_text.render_to_html(), m_level); 16} 17 18Vector<DeprecatedString> Heading::render_lines_for_terminal(size_t) const 19{ 20 StringBuilder builder; 21 22 builder.append("\n\033[0;31;1m"sv); 23 switch (m_level) { 24 case 1: 25 case 2: 26 builder.append(m_text.render_for_terminal().to_uppercase()); 27 builder.append("\033[0m"sv); 28 break; 29 default: 30 builder.append(m_text.render_for_terminal()); 31 builder.append("\033[0m"sv); 32 break; 33 } 34 35 return Vector<DeprecatedString> { builder.to_deprecated_string() }; 36} 37 38RecursionDecision Heading::walk(Visitor& visitor) const 39{ 40 RecursionDecision rd = visitor.visit(*this); 41 if (rd != RecursionDecision::Recurse) 42 return rd; 43 44 return m_text.walk(visitor); 45} 46 47OwnPtr<Heading> Heading::parse(LineIterator& lines) 48{ 49 if (lines.is_end()) 50 return {}; 51 52 StringView line = *lines; 53 size_t indent = 0; 54 55 // Allow for up to 3 spaces of indentation. 56 // https://spec.commonmark.org/0.30/#example-68 57 for (size_t i = 0; i < 3; ++i) { 58 if (line[i] != ' ') 59 break; 60 61 ++indent; 62 } 63 64 size_t level; 65 66 for (level = 0; indent + level < line.length(); level++) { 67 if (line[indent + level] != '#') 68 break; 69 } 70 71 if (!level || indent + level >= line.length() || line[indent + level] != ' ' || level > 6) 72 return {}; 73 74 StringView title_view = line.substring_view(indent + level + 1); 75 auto text = Text::parse(title_view); 76 auto heading = make<Heading>(move(text), level); 77 78 ++lines; 79 return heading; 80} 81 82}