Skip to content

Tutorial: Create Extensions

Benjamin Beaumont edited this page Apr 10, 2018 · 11 revisions

Contents


Disable Element

This example disables Header elements. That is, both Atx Header and Setext Header elements.

class Extension extends Parsedown
{

    protected function blockHeader($Line)
    {
        return;
    }

    protected function blockSetextHeader($Line, array $Block = null)
    {
        return;
    }

}

You can use the same approach for other elements types. This includes inline element types. For example, to disable Image elements you should override inlineImage.

Note that to disable all headers you should also disable support for HTML. You can do that by setting the MarkupEscaped option to true.

Change Element Markup

This example prepends a base path to the src of Image elements.

class Extension extends Parsedown
{

    private $baseImagePath = 'http://cdn.example.com/';

    protected function inlineImage($excerpt)
    {
        $image = parent::inlineImage($excerpt);

        if ( ! isset($image))
        {
            return null;
        }

        $image['element']['attributes']['src'] = $this->baseImagePath . $image['element']['attributes']['src'];

        return $image;
    }

}

You can use the same approach for other element types.

Add Inline Element

This example adds a ColoredText element. You can find a description of this element at https://github.com/erusev/parsedown/issues/262.

class Extension extends Parsedown
{

    function __construct()
    {
        $this->InlineTypes['{'][]= 'ColoredText';

        $this->inlineMarkerList .= '{';
    }

    protected function inlineColoredText($excerpt)
    {
        if (preg_match('/^{c:([#\w]\w+)}(.*?){\/c}/', $excerpt['text'], $matches))
        {
            return array(

                // How many characters to advance the Parsedown's
                // cursor after being done processing this tag.
                'extent' => strlen($matches[0]), 
                'element' => array(
                    'name' => 'span',
                    'text' => $matches[2],
                    'attributes' => array(
                        'style' => 'color: ' . $matches[1],
                    ),
                ),

            );
        }
    }

}

You can use the same approach for other element types.

Add Multi-Line Element

This example extends the bold element (**) to work on multiple lines.

class Extension extends Parsedown
{

    /**
     * The array index is the first character of the pattern to match.
     * It is not possible to define patterns longer than one character directly here, as only the first
     * character of the line will be checked. (eg. Setting $this->BlockTypes['{tag'] won't work.)
     *
     * The second array is a list of all functions that should be called when the character is found.
     *
     * Leave out the 'block' or 'inline' part of the function name, as it will be prepended automatically.
     */
    function __construct()
    {
        $this->BlockTypes['*'][] = 'BoldText'; 
    }

    protected function blockBoldText($line, $block)
    {
        if (preg_match('/^\*\*/', $line['text'], $matches))
        {
            return array(
                'char' => $line['text'][0],
                'element' => array(
                    'name' => 'strong',
                ),
                'text' => ''
            );
        }
    } 

    /**
     * Appending the word `continue` to the function name will cause this function to be
     * called to process any following lines, until $block['complete'] is set to be 'true'.
     */
    protected function blockBoldTextContinue($line, $block)
    {
        if (isset($block['complete']))
        {
            return;
        }

        // A blank newline has occurred.
        if (isset($block['interrupted']))
        {
            $block['element']['text'] .= "\n";
            unset($block['interrupted']);
        }

        // Check for end of the block. 
        if (preg_match('/\*\*/', $line['text']))
        {
            $block['element']['text'] = substr($block['element']['text'], 1);

            // This will flag the block as 'complete':
            // 1. The 'continue' function will not be called again.
            // 2. The 'complete' function will be called instead.
            $block['complete'] = true;
            return $block;
        }
        
        $block['element']['text'] .= "\n" . $line['body'];
        
        return $block;
    }

    /**
     * Appending the word `complete` to the function name will cause this function to be
     * called when the block is marked as *complete* (see the previous method).
     */
    protected function blockBoldTextComplete($block)
    {
        return $block;
    }

}
Clone this wiki locally