/* * Copyright (c) 2019-2020, Sergey Bugaev * Copyright (c) 2021, Peter Elliott * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include #include #include namespace Markdown { String Document::render_to_html() const { StringBuilder builder; builder.append("\n"); builder.append("\n"); builder.append("\n"); builder.append("\n"); builder.append("\n"); builder.append("\n"); builder.append(render_to_inline_html()); builder.append("\n"); builder.append("\n"); return builder.build(); } String Document::render_to_inline_html() const { StringBuilder builder; for (auto& block : m_blocks) { auto s = block.render_to_html(); builder.append(s); } return builder.build(); } String Document::render_for_terminal(size_t view_width) const { StringBuilder builder; for (auto& block : m_blocks) { auto s = block.render_for_terminal(view_width); builder.append(s); } return builder.build(); } template static bool helper(Vector::ConstIterator& lines, NonnullOwnPtrVector& blocks) { OwnPtr block = BlockType::parse(lines); if (!block) return false; blocks.append(block.release_nonnull()); return true; } OwnPtr Document::parse(const StringView& str) { const Vector lines_vec = str.lines(); auto lines = lines_vec.begin(); auto document = make(); auto& blocks = document->m_blocks; StringBuilder paragraph_text; auto flush_paragraph = [&] { if (paragraph_text.is_empty()) return; auto paragraph = make(Text::parse(paragraph_text.build())); document->m_blocks.append(move(paragraph)); paragraph_text.clear(); }; while (true) { if (lines.is_end()) break; if ((*lines).is_empty()) { ++lines; flush_paragraph(); continue; } bool any = helper(lines, blocks) || helper(lines, blocks) || helper(lines, blocks) || helper(lines, blocks) || helper(lines, blocks); if (any) { if (!paragraph_text.is_empty()) { auto last_block = document->m_blocks.take_last(); flush_paragraph(); document->m_blocks.append(move(last_block)); } continue; } if (!paragraph_text.is_empty()) paragraph_text.append("\n"); paragraph_text.append(*lines++); } flush_paragraph(); return document; } }