src/Ciconia/Extension/Core/ImageExtension.php
public function processInlineImage(Text $text, array $options = array())
    {
        if (!$text->contains('![')) {
            return;
        }

        /** @noinspection PhpUnusedParameterInspection */
        $text->replace(
            '{
                (               # wrap whole match in $1
                  !\[
                    (.*?)       # alt text = $2
                  \]
                  \(            # literal paren
                    [ \t]*
                    <?(\S+?)>?  # src url = $3
                    [ \t]*
                    (           # $4
                      ([\'"])   # quote char = $5
                      (.*?)     # title = $6
                      \5        # matching quote
                      [ \t]*
                    )?          # title is optional
                  \)
                )
            }xs',
            function (
                Text $w,
                Text $whole,
                Text $alt,
                Text $url,
                Text $a = null,
                Text $q = null,
                Text $title = null
            ) use ($options) {
                $this->markdown->emit('escape.special_chars', [$alt->replace('/(?<!\\\\)_/', '\\\\_')]);

                $attr = array(
                    'alt' => $alt->replace('/"/', '&quot;')
                );

                $this->markdown->emit('escape.special_chars', [$url->replace('/(?<!\\\\)_/', '\\\\_')]);
                $url->escapeHtml();

                if ($title) {
                    $attr['title'] = $title->replace('/"/', '&quot;')->escapeHtml();
                }

                return $this->getRenderer()->renderImage($url,  array('attr' => $attr));
            }
        );
    }
public function processInlineImage(Text $text, array $options = array())
    {
        if (!$text->contains('![')) {
            return;
        }

        /** @noinspection PhpUnusedParameterInspection */
        $text->replace(
            '{
                (               # wrap whole match in $1
                  !\[
                    (.*?)       # alt text = $2
                  \]
                  \(            # literal paren
                    [ \t]*
                    <?(\S+?)>?  # src url = $3
                    [ \t]*
                    (           # $4
                      ([\'"])   # quote char = $5
                      (.*?)     # title = $6
                      \5        # matching quote
                      [ \t]*
                    )?          # title is optional
                  \)
                )
            }xs',
            function (
                Text $w,
                Text $whole,
                Text $alt,
                Text $url,
                Text $a = null,
                Text $q = null,
                Text $title = null
            ) use ($options) {
                $this->markdown->emit('escape.special_chars', [$alt->replace('/(?<!\\\\)_/', '\\\\_')]);

                $attr = array(
                    'alt' => $alt->replace('/"/', '&quot;')
                );

                $this->markdown->emit('escape.special_chars', [$url->replace('/(?<!\\\\)_/', '\\\\_')]);
                $url->escapeHtml();

                if ($title) {
                    $attr['title'] = $title->replace('/"/', '&quot;')->escapeHtml();
                }

                return $this->getRenderer()->renderImage($url,  array('attr' => $attr));
            }
        );
    }
handle inline images:  ![alt text](url "optional title")

@param Text  $text
@param array $options