summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibMarkdown
diff options
context:
space:
mode:
authorMacDue <macdue@dueutil.tech>2022-08-03 00:11:58 +0100
committerAndreas Kling <kling@serenityos.org>2022-08-04 02:49:29 +0200
commit8140b1fa1803f0d4269b45ec1dd01e443017325a (patch)
tree4d809854851c2281af6896e74aabfdd6b9840a1b /Userland/Libraries/LibMarkdown
parentfb47a873400d7a5483abc8ffdd1939f08180bd16 (diff)
downloadserenity-8140b1fa1803f0d4269b45ec1dd01e443017325a.zip
LibMarkdown: Implement the image size extension
This implements the image size extension that's quite commonly used: https://github.com/commonmark/commonmark-spec/wiki/Deployed-Extensions#image-size This supports specifying... Both width and height: ![](foo.png =100x200) Width only: ![](foo.png =100x) Height only: ![](foo.png =x200) The size is always in pixels (relative sizing does not seem to be spec'd anywhere).
Diffstat (limited to 'Userland/Libraries/LibMarkdown')
-rw-r--r--Userland/Libraries/LibMarkdown/Text.cpp50
-rw-r--r--Userland/Libraries/LibMarkdown/Text.h10
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;