erusev / parsedown-extra

Markdown Extra Extension for Parsedown
MIT License
822 stars 124 forks source link

Idea for extension: wrap #66

Open jerry1970 opened 9 years ago

jerry1970 commented 9 years ago

I just made an extension that makes an invisible wrapper around any block. Contents are parsed as usual. It wraps any other text in a div so you have more possibilities with CSS and JS.

For example, in our CMS I want our writers to be able to add a setlist when writing a concert review:

     ...setlist
     Intro
     Song 1
     Song 2
     ...

I know this could have been done using

     ```setlist
     Intro
     Song 1
     Song 2

but the following could not. I wanted our writers to be able to add an image gallery.
 ...gallery
 * ![](some-url)
 * ![](some-url)
 * ![](some-url)
 ...

I could not have a list of images inside en fenced code block since the images would not be parsed. And having images in a list is not enough, since a list could be used someplace else as well.  
So I needed an invisible wrapper with a class. Now I can have CSS and JS targeting the `.gallery ul`.

Using a wrapper with a class I can save some time finding extra codes and extensions. That way I keep ParsedownExtra smaller and put more control into CSS and JS.

Maybe this is interesting in some way for ParsedownExtra. Most code was copied from the blockQuote and blockQuoteContinues methods.

``` php
    public function __construct()
    {
        // add a new block type: tripe period plus class name
        $this->BlockTypes['.'] = array('Wrap');
    }

    protected function blockWrap($Line)
    {
        // check for the triple period (or more) plus class name
        if (preg_match('/^\.{3,}[ ]?(.*)/', $Line['text'], $matches)) {
            $Block = array(
                'element' => array(
                    'name' => 'div',
                    'handler' => 'lines',
                    'attributes' => ['class' => $matches[1]],
                ),
            );

            return $Block;
        }
    }

    protected function blockWrapContinue($Line, array $Block)
    {
        if ($Line['text'][0] === '.' and preg_match('/^\.{3,}[ ]?(.*)/', $Line['text'], $matches)) {
            if (isset($Block['interrupted'])) {
                $Block['element']['text'] []= '';
                unset($Block['interrupted']);
            }

            $Block['element']['text'] []= $matches[1];

            return $Block;
        }

        if ( ! isset($Block['interrupted'])) {
            $Block['element']['text'] []= $Line['text'];

            return $Block;
        }
    }
jerry1970 commented 9 years ago

Just realized that this is not a fenced block. The block ends when there is a blank line. Hm, still having a problem with the wrapper, then. I'd prefer a wrapper being fenced but with the contents being parsed.

markseuffert commented 9 years ago

Similar was suggested in michelf/php-markdown#191