Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Image Resize via Reference #723

Closed
MarkMessa opened this issue Aug 16, 2019 · 12 comments
Closed

Image Resize via Reference #723

MarkMessa opened this issue Aug 16, 2019 · 12 comments

Comments

@MarkMessa
Copy link

Parsedown provides a way to reference images:

![sometext][image]

[image]: /sample.jpg

If you wanna extend Parsedown to also resize the image, you can just append the following snippet at the end of the main code:

class MyParsedown extends Parsedown
{
    protected function inlineImage($Excerpt)
    {
        $Inline = parent::inlineImage($Excerpt);

        if (!isset($Inline['element']['attributes']['title'])) { return $Inline; }

        $size = $Inline['element']['attributes']['title'];

        if (preg_match('/^\d+x\d+$/', $size)) {
            list($width, $height) = explode('x', $size);

            if($width > 0) $Inline['element']['attributes']['width'] = $width;
            if($height > 0) $Inline['element']['attributes']['height'] = $height;

            unset ($Inline['element']['attributes']['title']);
        }

        return $Inline;
    }
}

Then you can resize images like that:

![sometext][image]

[image]: /sample.jpg '100x100'

Question
There are some situations which would also be helpful the following syntax:

![sometext][image '100x100']

[image]: /sample.jpg

Any idea how to include such feature into Parsedown?

@taufik-nurrohman
Copy link

taufik-nurrohman commented Aug 16, 2019

I would do the query string method instead. And use that queries to update the image markup before it is being removed.

$data = $Inline['element']['attributes']['src'];
$a = explode('?', $data, 2); // Result: ['.path/to/image.jpg', 'width=72&height=72']
if (isset($a[1])) {
    parse_str($a[1], $attr);
    $Inline['element']['attributes'] = array_replace($Inline['element']['attributes'], $attr);
    $Inline['element']['attributes']['src'] = $a[0];
}
return $Inline;

Or use literal attribute syntax using my extension like this:

![image](./path/to/image.jpg) {width=72 height=72}

@MarkMessa
Copy link
Author

MarkMessa commented Aug 16, 2019

// [.path/to/image.jpg, width=72&height=72]

@tovic
Currently, I'm using a modified version of Parsedown (as explained in the OP) that accepts resizing images according the following syntaxes:

1. Inline Image
![Markdown Logo](/md.png "100x100")

2. Reference Image
![Markdown Logo][image]
[image]: /md.png "100x100"

I'm looking for ways to extend such syntax of reference image, to something like:

3. Reference Image Alternative
![Markdown Logo][image "100x100"]
[image]: /md.png

However, if I understood properly, the method you've posted would create an additional syntax for inline images instead for reference images:

![Markdown Logo][/md.png, width=100&height=100]

If this is indeed the case, unfortunately it doesn't address the issue of the OP.

 

Do you agree?

@taufik-nurrohman
Copy link

taufik-nurrohman commented Aug 16, 2019

No sir. My code utilize the URL query from the image itself. So, no need to invent new syntax:

1. Inline Image
![Markdown Logo](/md.png?width=100&height=100 "You can still add title here")

2. Reference Image
![Markdown Logo][image]
[image]: /md.png?width=100&height=100 "You can still add title here too"

It also backward-compatible to other parsers. So, if you decided to use another markdown parser, the automatic width and height attribute created by the code snippet above will disappear and the URL query will still there. But it will not break the image because after all it just a query string. You could use URL hash as well:

[Test Image](./path/to/image.png#100x100)

And get the image dimension from:

$dimension = explode('#', $Inline['element']['attributes']['src'], 2)[1] ?? "";
if (preg_match('/\d+x\d+/', $dimension)) { ... }

@MarkMessa
Copy link
Author

MarkMessa commented Aug 16, 2019

@tovic

1. Inline Image
![Markdown Logo](/md.png?width=100&height=100 "You can still add title here")

2. Reference Image
![Markdown Logo][image]
[image]: /md.png?width=100&height=100 "You can still add title here too"

Ok, this syntax is fine for me too. Moreover, I agree with you that there are several advantages using it instead of the one I posted in the OP.

The only thing still not clear to me is what would be your proposal for the alternative reference image? Are you considering something like:

3. Reference Image Alternative
![Markdown Logo][image#100x100]
[image]: /md.png "You can still add title here too"

 

Correct?

@taufik-nurrohman
Copy link

The only thing still not clear to me is what would be your proposal for the alternative reference image?

I don’t know. Your style is better IMO. It just that I feel a bit wrong in adding new syntax to the existing markdown syntax. It would be better to create another syntax as a whole, something like defining new prefix for different media:

+[foo][bar "100x100"]
-[foo][bar "100x100"]
@[foo][bar "100x100"]
$[foo][bar "100x100"]
&[foo][bar "100x100"]
%[foo][bar "100x100"]
#[foo][bar "100x100"]
~[foo][bar "100x100"]
>[foo][bar "100x100"]
=[foo][bar "100x100"]

@MarkMessa
Copy link
Author

MarkMessa commented Aug 17, 2019

@tovic

Your style is better IMO.

Note: This is not my style. I just copy&paste other's idea.

Ok, in that case I'm gonna propose the following syntaxes:

1. Inline Image
![Markdown Logo](/md.png "100x100")

2. Reference Image
![Markdown Logo][image]
[image]: /md.png "100x100"

3. Reference Image Alternative
![Markdown Logo][image "100x100"]
[image]: /md.png

In my opinion, the main advantages of this proposal are:

  • syntaxes 1 and 2 are already implemented (see OP)
  • additional coding would have to focus only in syntax 3
  • these 3 syntaxes are pretty consistent among each other and still simple enough (no additional verbose)

Question
Any idea how to code that?

@MarkMessa
Copy link
Author

@tovic

The part of the code that seems to be related with this issue is (L1434 IF statement):

if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches))
{
    $definition = strlen($matches[1]) ? $matches[1] : $Element['handler']['argument'];
    $definition = strtolower($definition);
    $extent += strlen($matches[0]);
}
else
{
    $definition = strtolower($Element['handler']['argument']);
}

According to Regex Online Tester, ^\s*\[(.*?)\] matches expressions that begins with [] like:

[image]
     [image]

Therefore, the focus should be in trying to make this part also recognize patterns like [alt][name "w x h"].

 

So far, do you agree?

@taufik-nurrohman
Copy link

taufik-nurrohman commented Aug 20, 2019

So you really want to rollup your language syntax then. Let me give you a clue. The first results of the regex above (the (.*?) part) is anything that match between the square bracket. So, in the code above, $matches[1] would capture name "w x h". From there you could do something like this:

list($id, $sizes) = explode(' ', $matches[1], 2); // First part is the reference ID, second part is for the sizes
$sizes = trim(trim($sizes), '\'"'); // Remove quotes

list($width, $height) = explode('x', $sizes); // Get width and height

// Then you need to put that `$id` (the original reference ID) somewhere to maps the data back to the corresponding placement. Example:
$definition = strtolower($id);

@MarkMessa
Copy link
Author

@tovic

So you really want to rollup your language syntax then.

If you have another syntax proposal, please let me know. As long as is simple and consistent, for me is just fine. I could easily go on with something like:

1. Inline Image
![Markdown Logo]md.png?width=100&height=100 "You can still add title here")

2. Reference Image
![Markdown Logo][image]
[image]: /md.png?width=100&height=100 "You can still add title here too"

3. Reference Image Alternative
![Markdown Logo][image#100x100]
[image]: /md.png "You can still add title here too"

However, as you mentioned: "Your style is better IMO". Therefore, I just followed your advice.

@MarkMessa
Copy link
Author

MarkMessa commented Aug 20, 2019

@tovic

I've just replaced the following lines:

if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches))
{
	$definition = strlen($matches[1]) ? $matches[1] : $Element['text'];
	$definition = strtolower($definition);

	$extent += strlen($matches[0]);
}
else
{
	$definition = strtolower($Element['text']);
}

 

With:

if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches))
{
	if(preg_match('/(.*?) \"\d+x\d+\"$/', $matches[1]))
	{
		$xmatches = explode(' "', $matches[1], 2);
		if(isset($xmatches[1]))
		{
			list($id, $size) = $xmatches;
			$size = trim(trim($size), '\'"');
	
			if (preg_match('/^\d+x\d+$/', $size))
			{					
				list($width, $height) = explode('x', $size);				    
		
				if($width > 0) $Element['attributes']['width'] = $width;
				if($height > 0) $Element['attributes']['height'] = $height;
			}
	
			$definition = strtolower($id);

		}
	}
	else
	{
		$definition = strlen($matches[1]) ? $matches[1] : $Element['text'];
		$definition = strtolower($definition);
	}

	$extent += strlen($matches[0]);
}
else
{
	$definition = strtolower($Element['text']);
}

 

This way, the following syntaxes are now working:

![Markdown Logo][shortname "100x100"]
[shortname]: /md.png

![Markdown Logo][long image name "100x100"]
[long image name]: /md.png

 

Although the code seems to be working fine, it also seems to be overly complicated.
Let me know what you think.

@taufik-nurrohman
Copy link

taufik-nurrohman commented Aug 21, 2019

[...] It also seems to be overly complicated.

No it isn’t. It is good. Just maybe you can remove this line as it has been checked in the second if.

if (preg_match('/^\d+x\d+$/', $size)) { ... }

@bilogic
Copy link

bilogic commented Mar 16, 2021

Was this implemented in https://github.com/erusev/parsedown?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants