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

A way to override default Parsedown behavior #747

Conversation

maxlysenko
Copy link
Contributor

As discussed in #736 It's possible to override default Parsedown processing if the new tag for existing type will be inserted into the array in higher position then the standard tag we want to override.

As discussed in #736 It's possible to override default Parsedown processing if the new `tag` for existing `type` will be inserted into the array in higher position then the standard tag we want to override.
@rhukster
Copy link
Member

Looks like a good PR, i will test when i get home from vacation this weekend! Thanks!

@rhukster rhukster merged commit 9d2ef02 into getgrav:develop Apr 6, 2016
@rhukster
Copy link
Member

rhukster commented Apr 6, 2016

Sorry it took so long to look at this. But I tested it and found no issues. Thanks.

@flaviocopes
Copy link
Contributor

@maxlysenko can you make a short example of how to use this, so it can be documented?

@maxlysenko
Copy link
Contributor Author

@flaviocopes, @rhukster here is couple of simple examples of how to use it.
First, in the onPluginsInitialized there are following lines:

if ($this->config->get('system.pages.markdown.extra')) {
    $this->enable([
        'onMarkdownInitialized' => ['onMarkdownInitialized', 0],
    ]);
}

and then the onMarkdownInitialized contains the following:

public function onMarkdownInitialized(Event $event)
{
    $markdown = $event['markdown'];

    //Example of overriding block type (`QuoteExtended` overrides `Quote`)
    $markdown->addBlockType('>', 'QuoteExtended', true, false, 0);

    $blockQuoteExtended = function($Line) {
        $Block = parent::blockQuote($Line);

        if (preg_match('/^[ ]*{(' . $this->regexAttribute . '+)}[ ]*$/', $Block['element']['text'][0], $matches, PREG_OFFSET_CAPTURE))
        {
            $attributeString = $matches[1][0];
            $Block['element']['attributes'] = $this->parseAttributeData($attributeString);
            $Block['element']['text'][0] = substr($Block['element']['text'][0], 0, $matches[0][1]);
        }

        return $Block;
    };

    $blockQuoteExtendedContinue = function($Line, array $Block) {
        $Block = parent::blockQuoteContinue($Line, $Block);
        return $Block;
    };

    $markdown->blockQuoteExtended = $blockQuoteExtended->bindTo($markdown, $markdown);
    $markdown->blockQuoteExtendedContinue = $blockQuoteExtendedContinue->bindTo($markdown, $markdown);

    //Example of overriding inline type (`EmailTagExtended` overrides `EmailTag`)
    $markdown->addInlineType('<', 'EmailTagExtended', 1);

    $inlineEmailTagExtended = function($Excerpt) {
        if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<((mailto:)?(\S+?@\S+?))>{('.$this->regexAttribute.'+)}/i', $Excerpt['text'], $matches))
        {
            $url = $matches[1];
            $text = $matches[3];

            if (empty($matches[2])) {
                $url = 'mailto:' . $url;
            }

            $grav = \Grav\Common\Grav::instance();

            if (isset($grav['twig']->twig->getFilters()['safe_email'])) {
                $safeEmailFilter = $grav['twig']->twig->getFilters()['safe_email']->getCallable();
                $url = $safeEmailFilter($url);
                $text = $safeEmailFilter($text);
            }

            $EmailTag = [
                'extent' => strlen($matches[0]),
                'element' => [
                    'name' => 'a',
                    'text' => $text,
                    'attributes' => [
                        'href' => $url,
                    ],
                ],
            ];

            $EmailTag['element']['attributes'] += $this->parseAttributeData($matches[4]);

            return $EmailTag;
        }
    };

    $markdown->inlineEmailTagExtended = $inlineEmailTagExtended->bindTo($markdown, $markdown);
}

Then in markdown we can use:

> {#id-from-markdown .class-from-markdown }
> Blockquote with class and id set from markdown

>>> {#id-from-markdown .class-from-markdown }
>>> Grav style blockquote with class and id set from markdown

Test of the extended email link <test_email@local.dev>{#email-id-from-markdowm .email-class-from-markdown} with class and id set from markdown and `safe_email` filter applied.

Also, recently I realised that it could be more intuitive and informative to use names instead of indexes (and with no need to know the index), e.g.

$markdown->addBlockType('>', 'QuoteExtended', true, false, 'Quote');
$markdown->addInlineType('<', 'EmailTagExtended', 'EmailTag');

For this current implementation needs to be slightly changed to something like this:

public function addBlockType($type, $tag, $continuable = false, $completable = false, $override = null)
{
    if (isset($override)) {
        $index = array_search($override, $this->BlockTypes[$type]);
    }

    if (!isset($index) || $index === false) {
        $this->BlockTypes[$type] [] = $tag;
    } else {
        array_splice($this->BlockTypes[$type], $index, 0, $tag);
    }

    if ($continuable) {
        $this->continuable_blocks[] = $tag;
    }

    if ($completable) {
        $this->completable_blocks[] = $tag;
    }
}

public function addInlineType($type, $tag, $override = null)
{
    if (isset($override)) {
        $index = array_search($override, $this->InlineTypes[$type]);
    }

    if (!isset($index) || $index === false) {
        $this->InlineTypes[$type] [] = $tag;
    } else {
        array_splice($this->InlineTypes[$type], $index, 0, $tag);
    }

    if (strpos($this->inlineMarkerList, $type) === false) {
        $this->inlineMarkerList .= $type;
    }
}

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

Successfully merging this pull request may close these issues.

3 participants