From eef794b8c645ea08fae3a9818c3a45ac5a4bccb4 Mon Sep 17 00:00:00 2001 From: AnotherTest Date: Sun, 20 Sep 2020 20:42:23 +0430 Subject: [PATCH] LibMarkdown: Parse paragraphs line-wise This gets rid of the doubled-up checks in `Paragraph::parse()`, and makes a paragraph the last possible kind of block to be parsed. --- Libraries/LibMarkdown/Document.cpp | 26 +++++++++++-- Libraries/LibMarkdown/Paragraph.cpp | 60 ++++++++--------------------- Libraries/LibMarkdown/Paragraph.h | 25 ++++++++++-- 3 files changed, 61 insertions(+), 50 deletions(-) diff --git a/Libraries/LibMarkdown/Document.cpp b/Libraries/LibMarkdown/Document.cpp index ba3d244b74..3e036dab16 100644 --- a/Libraries/LibMarkdown/Document.cpp +++ b/Libraries/LibMarkdown/Document.cpp @@ -81,6 +81,7 @@ OwnPtr Document::parse(const StringView& str) auto lines = lines_vec.begin(); auto document = make(); auto& blocks = document->m_blocks; + NonnullOwnPtrVector paragraph_lines; while (true) { if (lines.is_end()) @@ -91,11 +92,30 @@ OwnPtr Document::parse(const StringView& str) continue; } - bool any = helper(lines, blocks) || helper(lines, blocks) || helper(lines, blocks) - || helper(lines, blocks) || helper(lines, blocks); + bool any = helper
(lines, blocks) || helper(lines, blocks) || helper(lines, blocks) + || helper(lines, blocks); - if (!any) + if (any) { + if (!paragraph_lines.is_empty()) { + auto last_block = document->m_blocks.take_last(); + auto paragraph = make(move(paragraph_lines)); + document->m_blocks.append(move(paragraph)); + document->m_blocks.append(move(last_block)); + paragraph_lines.clear(); + } + continue; + } + + auto line = Paragraph::Line::parse(lines); + if (!line) return nullptr; + + paragraph_lines.append(line.release_nonnull()); + } + + if (!paragraph_lines.is_empty()) { + auto paragraph = make(move(paragraph_lines)); + document->m_blocks.append(move(paragraph)); } return document; diff --git a/Libraries/LibMarkdown/Paragraph.cpp b/Libraries/LibMarkdown/Paragraph.cpp index f44da06fbb..0e2b7f9df4 100644 --- a/Libraries/LibMarkdown/Paragraph.cpp +++ b/Libraries/LibMarkdown/Paragraph.cpp @@ -33,7 +33,13 @@ String Paragraph::render_to_html() const { StringBuilder builder; builder.appendf("

"); - builder.append(m_text.render_to_html()); + bool first = true; + for (auto& line : m_lines) { + if (!first) + builder.append(' '); + first = false; + builder.append(line.text().render_to_html()); + } builder.appendf("

\n"); return builder.build(); } @@ -41,58 +47,26 @@ String Paragraph::render_to_html() const String Paragraph::render_for_terminal(size_t) const { StringBuilder builder; - builder.append(m_text.render_for_terminal()); + bool first = true; + for (auto& line : m_lines) { + if (!first) + builder.append(' '); + first = false; + builder.append(line.text().render_for_terminal()); + } builder.appendf("\n\n"); return builder.build(); } -OwnPtr Paragraph::parse(Vector::ConstIterator& lines) +OwnPtr Paragraph::Line::parse(Vector::ConstIterator& lines) { if (lines.is_end()) return nullptr; - bool first = true; - StringBuilder builder; - - while (true) { - if (lines.is_end()) - break; - StringView line = *lines; - if (line.is_empty()) - break; - char ch = line[0]; - // See if it looks like a blockquote - // or like an indented block. - if (ch == '>' || ch == ' ') - break; - if (line.length() > 1) { - // See if it looks like a heading. - if (ch == '#' && (line[1] == '#' || line[1] == ' ')) - break; - // See if it looks like a code block. - if (ch == '`' && line[1] == '`') - break; - // See if it looks like a list. - if (ch == '*' || ch == '-') - if (line[1] == ' ') - break; - } - - if (!first) - builder.append(' '); - builder.append(line); - first = false; - ++lines; - } - - if (first) - return nullptr; - - auto text = Text::parse(builder.build()); + auto text = Text::parse(*lines++); if (!text.has_value()) return nullptr; - return make(move(text.value())); + return make(text.release_value()); } - } diff --git a/Libraries/LibMarkdown/Paragraph.h b/Libraries/LibMarkdown/Paragraph.h index d5e63a03c2..98e9dc9b9e 100644 --- a/Libraries/LibMarkdown/Paragraph.h +++ b/Libraries/LibMarkdown/Paragraph.h @@ -26,6 +26,7 @@ #pragma once +#include #include #include #include @@ -34,18 +35,34 @@ namespace Markdown { class Paragraph final : public Block { public: - explicit Paragraph(Text&& text) - : m_text(move(text)) + class Line { + public: + explicit Line(Text&& text) + : m_text(move(text)) + { + } + + static OwnPtr parse(Vector::ConstIterator& lines); + const Text& text() const { return m_text; } + + private: + Text m_text; + }; + + Paragraph(NonnullOwnPtrVector&& lines) + : m_lines(move(lines)) { } + virtual ~Paragraph() override { } virtual String render_to_html() const override; virtual String render_for_terminal(size_t view_width = 0) const override; - static OwnPtr parse(Vector::ConstIterator& lines); + + void add_line(NonnullOwnPtr&& line); private: - Text m_text; + NonnullOwnPtrVector m_lines; }; }