-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
A way to override default Parsedown behavior #747
Conversation
As discussed in getgrav#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.
Looks like a good PR, i will test when i get home from vacation this weekend! Thanks! |
Sorry it took so long to look at this. But I tested it and found no issues. Thanks. |
@maxlysenko can you make a short example of how to use this, so it can be documented? |
@flaviocopes, @rhukster here is couple of simple examples of how to use it. if ($this->config->get('system.pages.markdown.extra')) {
$this->enable([
'onMarkdownInitialized' => ['onMarkdownInitialized', 0],
]);
} and then the 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;
}
} |
As discussed in #736 It's possible to override default Parsedown processing if the new
tag
for existingtype
will be inserted into the array in higher position then the standard tag we want to override.