mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 19:27:45 +00:00
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:  Width only:  Height only:  The size is always in pixels (relative sizing does not seem to be spec'd anywhere).
This commit is contained in:
parent
fb47a87340
commit
8140b1fa18
2 changed files with 58 additions and 2 deletions
|
@ -140,6 +140,13 @@ void Text::LinkNode::render_to_html(StringBuilder& builder) const
|
||||||
if (is_image) {
|
if (is_image) {
|
||||||
builder.append("<img src=\""sv);
|
builder.append("<img src=\""sv);
|
||||||
builder.append(escape_html_entities(href));
|
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);
|
builder.append("\" alt=\""sv);
|
||||||
text->render_to_html(builder);
|
text->render_to_html(builder);
|
||||||
builder.append("\" >"sv);
|
builder.append("\" >"sv);
|
||||||
|
@ -576,11 +583,52 @@ NonnullOwnPtr<Text::Node> Text::parse_link(Vector<Token>::ConstIterator& tokens)
|
||||||
auto separator = *tokens;
|
auto separator = *tokens;
|
||||||
VERIFY(separator == "]("sv);
|
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;
|
StringBuilder address;
|
||||||
for (auto iterator = tokens + 1; !iterator.is_end(); ++iterator) {
|
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) {
|
if (*iterator == ")"sv) {
|
||||||
tokens = iterator;
|
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);
|
address.append(iterator->data);
|
||||||
|
|
|
@ -97,14 +97,22 @@ public:
|
||||||
bool is_image;
|
bool is_image;
|
||||||
NonnullOwnPtr<Node> text;
|
NonnullOwnPtr<Node> text;
|
||||||
String href;
|
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)
|
: is_image(is_image)
|
||||||
, text(move(text))
|
, text(move(text))
|
||||||
, href(move(href))
|
, 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_to_html(StringBuilder& builder) const override;
|
||||||
virtual void render_for_terminal(StringBuilder& builder) const override;
|
virtual void render_for_terminal(StringBuilder& builder) const override;
|
||||||
virtual size_t terminal_length() const override;
|
virtual size_t terminal_length() const override;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue