diff options
-rw-r--r-- | Userland/Libraries/LibMarkdown/Text.cpp | 50 | ||||
-rw-r--r-- | Userland/Libraries/LibMarkdown/Text.h | 10 |
2 files changed, 58 insertions, 2 deletions
diff --git a/Userland/Libraries/LibMarkdown/Text.cpp b/Userland/Libraries/LibMarkdown/Text.cpp index ec62ff40e6..1826642342 100644 --- a/Userland/Libraries/LibMarkdown/Text.cpp +++ b/Userland/Libraries/LibMarkdown/Text.cpp @@ -140,6 +140,13 @@ void Text::LinkNode::render_to_html(StringBuilder& builder) const if (is_image) { builder.append("<img src=\""sv); builder.append(escape_html_entities(href)); + if (has_image_dimensions()) { + builder.append("\" style=\""sv); + if (image_width.has_value()) + builder.appendff("width: {}px;", *image_width); + if (image_height.has_value()) + builder.appendff("height: {}px;", *image_height); + } builder.append("\" alt=\""sv); text->render_to_html(builder); builder.append("\" >"sv); @@ -576,11 +583,52 @@ NonnullOwnPtr<Text::Node> Text::parse_link(Vector<Token>::ConstIterator& tokens) auto separator = *tokens; VERIFY(separator == "]("sv); + Optional<int> image_width; + Optional<int> image_height; + + auto parse_image_dimensions = [&](StringView dimensions) -> bool { + if (!dimensions.starts_with('=')) + return false; + + ArmedScopeGuard clear_image_dimensions = [&] { + image_width = {}; + image_height = {}; + }; + + auto dimension_seperator = dimensions.find('x', 1); + if (!dimension_seperator.has_value()) + return false; + + auto width_string = dimensions.substring_view(1, *dimension_seperator - 1); + if (!width_string.is_empty()) { + auto width = width_string.to_int(); + if (!width.has_value()) + return false; + image_width = width; + } + + auto height_start = *dimension_seperator + 1; + if (height_start < dimensions.length()) { + auto height_string = dimensions.substring_view(height_start); + auto height = height_string.to_int(); + if (!height.has_value()) + return false; + image_height = height; + } + + clear_image_dimensions.disarm(); + return true; + }; + StringBuilder address; for (auto iterator = tokens + 1; !iterator.is_end(); ++iterator) { + // FIXME: What to do if there's multiple dimension tokens? + if (is_image && !address.is_empty() && parse_image_dimensions(iterator->data)) + continue; + if (*iterator == ")"sv) { tokens = iterator; - return make<LinkNode>(is_image, move(link_text), address.build()); + return make<LinkNode>(is_image, move(link_text), address.build().trim_whitespace(), image_width, image_height); } address.append(iterator->data); diff --git a/Userland/Libraries/LibMarkdown/Text.h b/Userland/Libraries/LibMarkdown/Text.h index 3fc6c48503..2c95ac63e9 100644 --- a/Userland/Libraries/LibMarkdown/Text.h +++ b/Userland/Libraries/LibMarkdown/Text.h @@ -97,14 +97,22 @@ public: bool is_image; NonnullOwnPtr<Node> text; String href; + Optional<int> image_width; + Optional<int> image_height; - LinkNode(bool is_image, NonnullOwnPtr<Node> text, String href) + LinkNode(bool is_image, NonnullOwnPtr<Node> text, String href, Optional<int> image_width, Optional<int> image_height) : is_image(is_image) , text(move(text)) , href(move(href)) + , image_width(image_width) + , image_height(image_height) { } + bool has_image_dimensions() const + { + return image_width.has_value() || image_height.has_value(); + } virtual void render_to_html(StringBuilder& builder) const override; virtual void render_for_terminal(StringBuilder& builder) const override; virtual size_t terminal_length() const override; |