View source
<?php
namespace Drupal\markdown\Plugin\Filter;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
use Drupal\markdown\Plugin\Markdown\ExtensibleMarkdownParserInterface;
use Drupal\markdown\Traits\MarkdownStatesTrait;
class Markdown extends FilterBase implements MarkdownFilterInterface {
use MarkdownStatesTrait;
protected $parser;
protected $parserManager;
public function __construct(array $configuration, $plugin_id, $plugin_definition) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->parserManager = \Drupal::service('plugin.manager.markdown.parser');
}
public function getSetting($name, $default = NULL) {
$settings = $this
->getSettings();
return isset($settings[$name]) ? $settings[$name] : $default;
}
public function getSettings() {
return $this->settings;
}
public function getParser() {
if (!isset($this->parser)) {
$this->parser = $this->parserManager
->createInstance($this
->getSetting('parser', 'thephpleague/commonmark'), [
'filter' => $this,
]);
}
return $this->parser;
}
public function getParserSetting($name, $default = NULL) {
$settings = $this
->getParserSettings();
return isset($settings[$name]) ? $settings[$name] : $default;
}
public function getParserSettings() {
return $this
->getSetting('parser_settings', []);
}
public function isEnabled() {
return !!$this->status;
}
public function settingsForm(array $form, FormStateInterface $form_state) {
$parents = $form['#parents'];
$defaultParser = $form_state
->getValue(array_merge($parents, [
'parser',
]), $this
->getParser()
->getPluginId());
if ($labels = $this->parserManager
->getLabels()) {
$id = Html::getUniqueId('markdown-parser-ajax');
$form['ajax'] = [
'#type' => 'container',
'#attributes' => [
'id' => $id,
],
'#parents' => $parents,
];
$form['ajax']['parser'] = [
'#type' => 'select',
'#title' => $this
->t('Parser'),
'#options' => $labels,
'#default_value' => $defaultParser,
'#ajax' => [
'callback' => [
$this,
'ajaxChangeParser',
],
'event' => 'change',
'wrapper' => $id,
],
];
}
else {
$form['ajax']['parser'] = [
'#type' => 'item',
'#title' => $this
->t('No Markdown Parsers Found'),
'#description' => $this
->t('Visit the <a href=":system.status">@system.status</a> page for more details.', [
'@system.status' => $this
->t('Status report'),
':system.status' => \Drupal::urlGenerator()
->generate('system.status'),
]),
];
}
if ($defaultParser && ($parser = $this->parserManager
->createInstance($defaultParser, [
'filter' => $this,
])) && $parser instanceof ExtensibleMarkdownParserInterface && ($extensions = $parser
->getExtensions())) {
$form['ajax']['parser_settings'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Extensions'),
];
$form['ajax']['parser_settings']['extensions'] = [
'#type' => 'container',
];
foreach ($extensions as $pluginId => $extension) {
$form['ajax']['parser_settings']['extensions'][$pluginId] = [
'#type' => 'details',
'#title' => ($url = $extension
->getUrl()) ? Link::fromTextAndUrl($extension
->getLabel(), $url) : $extension
->getLabel(),
'#description' => $extension
->getDescription(),
'#open' => $extension
->isEnabled(),
'#array_parents' => array_merge($parents, [
'parser_settings',
'extensions',
]),
];
$form['ajax']['parser_settings']['extensions'][$pluginId]['enabled'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Enabled'),
'#default_value' => $extension
->isEnabled(),
];
$selector = $this
->getSatesSelector(array_merge($parents, [
'parser_settings',
'extensions',
$pluginId,
]), 'enabled');
$form['ajax']['parser_settings']['extensions'][$pluginId]['settings'] = [
'#type' => 'container',
'#states' => [
'visible' => [
$selector => [
'checked' => TRUE,
],
],
],
];
$form['ajax']['parser_settings']['extensions'][$pluginId]['settings'] = $extension
->settingsForm($form['ajax']['parser_settings']['extensions'][$pluginId]['settings'], $form_state, $this);
}
}
return $form;
}
public function ajaxChangeParser(array $form, FormStateInterface $form_state) {
$parents = $form_state
->getTriggeringElement()['#array_parents'];
array_pop($parents);
return NestedArray::getValue($form, $parents);
}
public static function processTextFormat(&$element, FormStateInterface $form_state, &$complete_form) {
$formats = filter_formats();
$format = isset($formats[$element['#format']]) ? $formats[$element['#format']] : FALSE;
if ($format && ($markdown = $format
->filters('markdown')) && $markdown instanceof MarkdownFilterInterface && $markdown
->isEnabled()) {
$element['format']['help']['about'] = [
'#type' => 'link',
'#title' => t('@iconStyling with Markdown is supported', [
'@icon' => new FormattableMarkup('<svg class="octicon octicon-markdown v-align-bottom" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true" style="fill: currentColor;margin-right: 5px;vertical-align: text-bottom;"><path fill-rule="evenodd" d="M14.85 3H1.15C.52 3 0 3.52 0 4.15v7.69C0 12.48.52 13 1.15 13h13.69c.64 0 1.15-.52 1.15-1.15v-7.7C16 3.52 15.48 3 14.85 3zM9 11H7V8L5.5 9.92 4 8v3H2V5h2l1.5 2L7 5h2v6zm2.99.5L9.5 8H11V5h2v3h1.5l-2.51 3.5z"></path></svg>', []),
]),
'#url' => Url::fromRoute('filter.tips_all')
->setOptions([
'attributes' => [
'class' => [
'markdown',
],
'target' => '_blank',
],
]),
];
}
return $element;
}
public function process($text, $langcode) {
if (!empty($text)) {
$language = \Drupal::languageManager()
->getLanguage($langcode);
$markdown = $this
->getParser()
->parse($text, $language);
$text = $markdown
->setAllowedTags(TRUE)
->getHtml();
}
return new FilterProcessResult($text);
}
public function tips($long = FALSE) {
return $this
->getParser()
->tips($long);
}
}