View source
<?php
namespace Drupal\geshifilter\Plugin\Filter;
use Drupal\filter\Plugin\FilterBase;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Render\Markup;
use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormStateInterface;
use Drupal\filter\FilterProcessResult;
use Drupal\Core\Url;
use Drupal\geshifilter\GeshiFilter;
use Drupal\geshifilter\GeshiFilterProcess;
class GeshiFilterFilter extends FilterBase {
protected $config;
protected $configEditable;
public function __construct(array $configuration, $plugin_id, array $plugin_definition) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->config = \Drupal::config('geshifilter.settings');
$this->configEditable = \Drupal::configFactory()
->getEditable('geshifilter.settings');
}
public function process($text, $langcode) {
$result = new FilterProcessResult($text);
try {
$geshi_library = GeshiFilter::loadGeshi();
if (!$geshi_library['loaded']) {
throw new \Exception($geshi_library['error message']);
}
list($generic_code_tags, $language_tags, $tag_to_lang) = $this
->getTags();
if (in_array(GeshiFilter::BRACKETS_PHPBLOCK, array_filter($this
->tagStyles()))) {
$language_tags[] = 'questionmarkphp';
$tag_to_lang['questionmarkphp'] = 'php';
}
$tags = array_merge($generic_code_tags, $language_tags);
$tags = preg_replace('#(\\+|\\#)#', '\\\\$1', $tags);
$tags_string = implode('|', $tags);
$pattern = '#\\[geshifilter-(' . $tags_string . ')([^\\]]*)\\](.*?)(\\[/geshifilter-\\1\\])#s';
$text = preg_replace_callback($pattern, [
$this,
'replaceCallback',
], $text);
$result = new FilterProcessResult($text);
if (in_array($this->config
->get('css_mode'), [
GeshiFilter::CSS_CLASSES_AUTOMATIC,
GeshiFilter::CSS_INLINE,
])) {
$result
->setAttachments([
'library' => [
'geshifilter/geshifilter',
],
]);
}
$cache_tags = [
'geshifilter',
];
$result
->addCacheTags($cache_tags);
} catch (\Exception $e) {
watchdog_exception('geshifilter', $e);
drupal_set_message($geshi_library['error message'], 'error');
}
return $result;
}
public function prepare($text, $langcode) {
list($generic_code_tags, $language_tags, $tag_to_lang) = $this
->getTags();
$tags = array_merge($generic_code_tags, $language_tags);
$tags = preg_replace('#(\\+|\\#)#', '\\\\$1', $tags);
$tags_string = implode('|', $tags);
$tag_styles = array_filter($this
->tagStyles());
if (in_array(GeshiFilter::BRACKETS_ANGLE, $tag_styles)) {
$pattern = '#(<)(' . $tags_string . ')((\\s+[^>]*)*)(>)(.*?)(</\\2\\s*>|$)#s';
$text = preg_replace_callback($pattern, [
$this,
'prepareCallback',
], $text);
}
if (in_array(GeshiFilter::BRACKETS_SQUARE, $tag_styles)) {
$pattern = '#((?<!\\[)\\[)(' . $tags_string . ')((\\s+[^\\]]*)*)(\\])(.*?)((?<!\\[)\\[/\\2\\s*\\]|$)#s';
$text = preg_replace_callback($pattern, [
$this,
'prepareCallback',
], $text);
}
if (in_array(GeshiFilter::BRACKETS_DOUBLESQUARE, $tag_styles)) {
$pattern = '#(\\[\\[)(' . $tags_string . ')((\\s+[^\\]]*)*)(\\]\\])(.*?)(\\[\\[/\\2\\s*\\]\\]|$)#s';
$text = preg_replace_callback($pattern, [
$this,
'prepareCallback',
], $text);
}
if (in_array(GeshiFilter::BRACKETS_PHPBLOCK, $tag_styles)) {
$pattern = '#[\\[<](\\?php|\\?PHP|%)(.+?)((\\?|%)[\\]>]|$)#s';
$text = preg_replace_callback($pattern, [
$this,
'preparePhpCallback',
], $text);
}
if (in_array(GeshiFilter::BRACKETS_MARKDOWNBLOCK, $tag_styles)) {
$pattern = '#(```([a-z]*)\\n([\\s\\S]*?)\\n```)#s';
$text = preg_replace_callback($pattern, [
$this,
'prepareMarkdownCallback',
], $text);
}
return $text;
}
public function tips($long = FALSE) {
$tag_styles = array_filter($this
->tagStyles());
$tag_style_examples = [];
$bracket_open = NULL;
$bracket_close = NULL;
if (in_array(GeshiFilter::BRACKETS_ANGLE, $tag_styles)) {
if (!$bracket_open) {
$bracket_open = SafeMarkup::checkPlain('<');
$bracket_close = SafeMarkup::checkPlain('>');
}
$tag_style_examples[] = '<code>' . SafeMarkup::checkPlain('<foo>') . '</code>';
}
if (in_array(GeshiFilter::BRACKETS_SQUARE, $tag_styles)) {
if (!$bracket_open) {
$bracket_open = SafeMarkup::checkPlain('[');
$bracket_close = SafeMarkup::checkPlain(']');
}
$tag_style_examples[] = '<code>' . SafeMarkup::checkPlain('[foo]') . '</code>';
}
if (in_array(GeshiFilter::BRACKETS_DOUBLESQUARE, $tag_styles)) {
if (!$bracket_open) {
$bracket_open = SafeMarkup::checkPlain('[[');
$bracket_close = SafeMarkup::checkPlain(']]');
}
$tag_style_examples[] = '<code>' . SafeMarkup::checkPlain('[[foo]]') . '</code>';
}
if (in_array(GeshiFilter::BRACKETS_MARKDOWNBLOCK, $tag_styles)) {
if (!$bracket_open) {
$bracket_open = SafeMarkup::checkPlain('```');
$bracket_close = SafeMarkup::checkPlain('```');
}
$tag_style_examples[] = '<code>' . SafeMarkup::checkPlain('```foo ```') . '</code>';
}
if (!$bracket_open) {
drupal_set_message($this
->t('Could not determine a valid tag style for GeSHi filtering.'), 'error');
$bracket_open = SafeMarkup::checkPlain('<');
$bracket_close = SafeMarkup::checkPlain('>');
}
if ($long) {
list($generic_code_tags, $language_tags, $tag_to_lang) = $this
->getTags();
$languages = GeshiFilter::getEnabledLanguages();
$lang_attributes = GeshiFilter::whitespaceExplode(GeshiFilter::ATTRIBUTES_LANGUAGE);
$output = '<p>' . $this
->t('Syntax highlighting of source code can be enabled with the following tags:') . '</p>';
$items = [];
$tags = [];
foreach ($generic_code_tags as $tag) {
$tags[] = $bracket_open . $tag . $bracket_close;
}
$items[] = $this
->t('Generic syntax highlighting tags: <code>@tags</code>.', [
'@tags' => Markup::create(implode(', ', $tags)),
]);
$tags = [];
foreach ($language_tags as $tag) {
$tags[] = $this
->t('<code>@tag</code> for @lang source code', [
'@tag' => Markup::create($bracket_open . $tag . $bracket_close),
'@lang' => $languages[$tag_to_lang[$tag]],
]);
}
$items[] = '<li>' . $this
->t('Language specific syntax highlighting tags:') . implode(', ', $tags) . '</li>';
if (in_array(GeshiFilter::BRACKETS_PHPBLOCK, $tag_styles)) {
$items[] = $this
->t('PHP source code can also be enclosed in <?php ... ?> or <% ... %>, but additional options like line numbering are not possible here.');
}
$output .= '<ul>' . implode('', $items) . '</ul>';
$output .= '<p>' . $this
->t('Options and tips:') . '</p>';
$items = [];
$att_to_full = [];
foreach ($languages as $langcode => $fullname) {
$att_to_full[$langcode] = $fullname;
}
foreach ($tag_to_lang as $tag => $lang) {
$att_to_full[$tag] = $languages[$lang];
}
ksort($att_to_full);
$att_for_full = [];
foreach ($att_to_full as $att => $fullname) {
$att_for_full[] = $this
->t('"<code>@langcode</code>" (for @fullname)', [
'@langcode' => $att,
'@fullname' => $fullname,
]);
}
$items[] = $this
->t('The language for the generic syntax highlighting tags can be
specified with one of the attribute(s): %attributes. The possible values
are: @languages.', [
'%attributes' => implode(', ', $lang_attributes),
'@languages' => Markup::create(implode(', ', $att_for_full)),
]);
if (count($tag_style_examples) > 1) {
$items[] = $this
->t('The supported tag styles are: @tag_styles.', [
'@tag_styles' => Markup::create(implode(', ', $tag_style_examples)),
]);
}
$items[] = $this
->t('<em>Line numbering</em> can be enabled/disabled with the
attribute "%linenumbers". Possible values are: "%off" for no line
numbers, "%normal" for normal line numbers and "%fancy" for fancy line
numbers (every n<sup>th</sup> line number highlighted). The start line
number can be specified with the attribute "%start", which implicitly
enables normal line numbering. For fancy line numbering the interval
for the highlighted line numbers can be specified with the attribute
"%interval", which implicitly enables fancy line numbering.', [
'%linenumbers' => GeshiFilter::ATTRIBUTE_LINE_NUMBERING,
'%off' => 'off',
'%normal' => 'normal',
'%fancy' => 'fancy',
'%start' => GeshiFilter::ATTRIBUTE_LINE_NUMBERING_START,
'%interval' => GeshiFilter::ATTRIBUTE_FANCY_N,
]);
$items[] = $this
->t('If the source code between the tags contains a newline (e.g.
immediatly after the opening tag), the highlighted source code will be
displayed as a code block. Otherwise it will be displayed inline.');
$items[] = $this
->t('A title can be added to a code block with the attribute "%title".', [
'%title' => GeshiFilter::ATTRIBUTE_TITLE,
]);
$render = [
'#theme' => 'item_list',
'#items' => $items,
'#type' => 'ul',
];
$output .= render($render);
$output .= '<p>' . $this
->t('Defaults:') . '</p>';
$items = [];
$default_highlighting = $this->config
->get('default_highlighting');
switch ($default_highlighting) {
case GeshiFilter::DEFAULT_DONOTHING:
$description = $this
->t("when no language attribute is specified the code\n block won't be processed by the GeSHi filter");
break;
case GeshiFilter::DEFAULT_PLAINTEXT:
$description = $this
->t('when no language attribute is specified, no syntax
highlighting will be done');
break;
default:
$description = $this
->t('the default language used for syntax highlighting is
"%default_lang"', [
'%default_lang' => $default_highlighting,
]);
break;
}
$items[] = $this
->t('Default highlighting mode for generic syntax highlighting
tags: @description.', [
'@description' => $description,
]);
$default_line_numbering = $this->config
->get('default_line_numbering');
switch ($default_line_numbering) {
case GeshiFilter::LINE_NUMBERS_DEFAULT_NONE:
$description = $this
->t('no line numbers');
break;
case GeshiFilter::LINE_NUMBERS_DEFAULT_NORMAL:
$description = $this
->t('normal line numbers');
break;
default:
$description = $this
->t('fancy line numbers (every @n lines)', [
'@n' => $default_line_numbering,
]);
break;
}
$items[] = $this
->t('Default line numbering: @description.', [
'@description' => $description,
]);
$render = [
'#theme' => 'item_list',
'#items' => $items,
'#type' => 'ul',
];
$output .= render($render);
}
else {
list($generic_code_tags, $language_tags, $tag_to_lang) = $this
->getTags();
$tags = [];
foreach ($generic_code_tags as $tag) {
$tags[] = '<code>' . $bracket_open . SafeMarkup::checkPlain($tag) . $bracket_close . '</code>';
}
foreach ($language_tags as $tag) {
$tags[] = '<code>' . $bracket_open . SafeMarkup::checkPlain($tag) . $bracket_close . '</code>';
}
$output = $this
->t('You can enable syntax highlighting of source code with the following tags: @tags.', [
'@tags' => Markup::create(implode(', ', $tags)),
]);
if (count($tag_style_examples) > 1) {
$output .= ' ' . $this
->t('The supported tag styles are: @tag_styles.', [
'@tag_styles' => Markup::create(implode(', ', $tag_style_examples)),
]);
}
if (in_array(GeshiFilter::BRACKETS_PHPBLOCK, $tag_styles)) {
$output .= ' ' . $this
->t('PHP source code can also be enclosed in <?php ... ?> or <% ... %>.');
}
}
return $output;
}
public function settingsForm(array $form, FormStateInterface $form_state) {
if ($this->configEditable
->get('use_format_specific_options')) {
$form['general_tags'] = $this
->generalHighlightTagsSettings();
$form['per_language_settings'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Per language tags'),
'#collapsible' => TRUE,
'table' => $this
->perLanguageSettings('enabled', FALSE, TRUE),
];
}
else {
$form['info'] = [
'#markup' => '<p>' . $this
->t('GeSHi filter is configured to use global tag
settings. For separate settings per text format, enable this option in
the <a href=":geshi_admin_url">general GeSHi filter settings</a>.', [
':geshi_admin_url' => Url::fromRoute('geshifilter.settings')
->toString(),
]) . '</p>',
];
}
return $form;
}
protected function tags() {
if (!$this->config
->get('use_format_specific_options')) {
return $this->config
->get('tags');
}
else {
if (isset($this->settings['general_tags']['tags'])) {
return $this->settings['general_tags']['tags'];
}
else {
return $this->config
->get('tags');
}
}
}
protected function getTags() {
$generic_code_tags = GeshiFilter::tagSplit($this
->tags());
$language_tags = [];
$tag_to_lang = [];
$enabled_languages = GeshiFilter::getEnabledLanguages();
foreach ($enabled_languages as $language => $fullname) {
$lang_tags = GeshiFilter::tagSplit($this
->languageTags($language));
foreach ($lang_tags as $lang_tag) {
$language_tags[] = $lang_tag;
$tag_to_lang[$lang_tag] = $language;
}
}
return [
$generic_code_tags,
$language_tags,
$tag_to_lang,
];
}
protected function generalHighlightTagsSettings() {
$form = [];
$form["tags"] = [
'#type' => 'textfield',
'#title' => $this
->t('Generic syntax highlighting tags'),
'#default_value' => $this
->tags(),
'#description' => $this
->t('Tags that should activate the GeSHi syntax highlighting. Specify a space-separated list of tagnames.'),
];
$form["tag_styles"] = [
'#type' => 'checkboxes',
'#title' => $this
->t('Container tag style'),
'#options' => [
GeshiFilter::BRACKETS_ANGLE => '<code>' . htmlentities('<foo> ... </foo>') . '</code>',
GeshiFilter::BRACKETS_SQUARE => '<code>' . htmlentities('[foo] ... [/foo]') . '</code>',
GeshiFilter::BRACKETS_DOUBLESQUARE => '<code>' . htmlentities('[[foo]] ... [[/foo]]') . '</code>',
GeshiFilter::BRACKETS_PHPBLOCK => $this
->t('PHP style source code blocks: <code>@php</code> and <code>@percent</code>', [
'@php' => '<?php ... ?>',
'@percent' => '<% ... %>',
]),
GeshiFilter::BRACKETS_MARKDOWNBLOCK => '<code>' . htmlentities('```foo ... ```') . '</code>',
],
'#default_value' => $this
->tagStyles(),
'#description' => $this
->t('Select the container tag styles that should trigger GeSHi syntax highlighting.'),
];
$form["decode_entities"] = [
'#type' => 'checkbox',
'#title' => $this
->t('Decode entities'),
'#default_value' => $this->settings['general_tags']['decode_entities'],
'#description' => $this
->t('Decode entities, for example, if the code has been typed in a WYSIWYG editor.'),
];
return $form;
}
protected function perLanguageSettings($view, $add_checkbox, $add_tag_option) {
$form = [];
$header = [
$this
->t('Language'),
$this
->t('GeSHi language code'),
];
if ($add_tag_option) {
$header[] = $this
->t('Tag/language attribute value');
}
$form['language'] = [
'#type' => 'table',
'#header' => $header,
'#empty' => $this
->t('Nome language is available.'),
];
$languages = GeshiFilter::getAvailableLanguages();
foreach ($languages as $language => $language_data) {
$enabled = $this->config
->get("language.{$language}.enabled", FALSE);
if ($view == 'enabled' && !$enabled || $view == 'disabled' && $enabled) {
continue;
}
$form['language'][$language] = [];
if ($add_checkbox) {
$form['language'][$language]['enabled'] = [
'#type' => 'checkbox',
'#default_value' => $enabled,
'#title' => $language_data['fullname'],
];
}
else {
$form['language'][$language]['fullname'] = [
'#type' => 'markup',
'#markup' => $language_data['fullname'],
];
}
$form['language'][$language]['name'] = [
'#type' => 'markup',
'#markup' => $language,
];
if ($add_tag_option) {
$form['language'][$language]['tags'] = [
'#type' => 'textfield',
'#default_value' => $this->settings['per_language_settings']['table']['language'][$language]['tags'],
'#size' => 20,
];
}
}
return $form;
}
private function languageTags($language) {
if (!$this->config
->get('use_format_specific_options')) {
return $this->config
->get("language.{$language}.tags");
}
else {
$settings = $this->settings["per_language_settings"]['table']['language'];
if (isset($settings[$language]["tags"])) {
return $settings[$language]["tags"];
}
else {
return $this->config
->get("language.{$language}.tags");
}
}
}
protected function tagStyles() {
if ($this->config
->get('use_format_specific_options') == FALSE) {
$styles = $this->config
->get('tag_styles');
}
else {
if (isset($this->settings['general_tags']["tag_styles"])) {
$styles = $this->settings['general_tags']["tag_styles"];
}
else {
$styles = $this->config
->get('tag_styles');
}
}
return $styles;
}
protected function replaceCallback(array $match) {
$complete_match = $match[0];
$tag_name = $match[1];
$tag_attributes = $match[2];
$source_code = $match[3];
$source_code = Html::decodeEntities($source_code);
$lang = $this->config
->get('default_highlighting');
$line_numbering = $this->config
->get('default_line_numbering');
$linenumbers_start = 1;
$title = NULL;
list($generic_code_tags, $language_tags, $tag_to_lang) = $this
->getTags();
if (in_array(GeshiFilter::BRACKETS_PHPBLOCK, array_filter($this
->tagStyles()))) {
$language_tags[] = 'questionmarkphp';
$tag_to_lang['questionmarkphp'] = 'php';
}
if (isset($tag_to_lang[$tag_name])) {
$lang = $tag_to_lang[$tag_name];
}
$settings = $this
->parseAttributes($tag_attributes);
if (isset($settings['language'])) {
$lang = $settings['language'];
}
if (isset($settings['line_numbering'])) {
$line_numbering = $settings['line_numbering'];
}
if (isset($settings['linenumbers_start'])) {
$linenumbers_start = $settings['linenumbers_start'];
}
if (isset($settings['title'])) {
$title = $settings['title'];
}
if (isset($settings['special_lines'])) {
$special_lines = $settings['special_lines'];
}
if ($lang == GeshiFilter::DEFAULT_DONOTHING) {
return $complete_match;
}
if ($lang == GeshiFilter::DEFAULT_PLAINTEXT) {
$lang = 'text';
}
$inline_mode = strpos($source_code, "\n") === FALSE;
return GeshiFilterProcess::processSourceCode($source_code, $lang, $line_numbering, $linenumbers_start, $inline_mode, $title, $special_lines);
}
public function parseAttributes($attributes) {
$lang = NULL;
$line_numbering = NULL;
$linenumbers_start = NULL;
$title = NULL;
$special_lines = [];
$class_to_lang = NULL;
list($generic_code_tags, $language_tags, $tag_to_lang) = $this
->getTags();
$language_attributes = GeshiFilter::whitespaceExplode(GeshiFilter::ATTRIBUTES_LANGUAGE);
$attributes_preg_string = implode('|', array_merge($language_attributes, [
GeshiFilter::ATTRIBUTE_LINE_NUMBERING,
GeshiFilter::ATTRIBUTE_LINE_NUMBERING_START,
GeshiFilter::ATTRIBUTE_FANCY_N,
GeshiFilter::ATTRIBUTE_TITLE,
GeshiFilter::ATTRIBUTE_SPECIAL_LINES,
]));
$enabled_languages = GeshiFilter::getEnabledLanguages();
preg_match_all('#(' . $attributes_preg_string . ')="?([^"]*)"?#', $attributes, $attribute_matches);
foreach ($attribute_matches[1] as $a_key => $att_name) {
$att_value = $attribute_matches[2][$a_key];
$class_to_lang = str_replace('language-', '', $att_value);
if (in_array($att_name, $language_attributes)) {
if (in_array($att_value, $language_tags)) {
$att_value = $tag_to_lang[$att_value];
}
if (array_key_exists($att_value, $enabled_languages)) {
$lang = $att_value;
}
elseif ($att_name == 'class' && array_key_exists($class_to_lang, $enabled_languages)) {
$lang = $class_to_lang;
}
}
elseif ($att_name == GeshiFilter::ATTRIBUTE_LINE_NUMBERING) {
switch (strtolower($att_value)) {
case "off":
$line_numbering = 0;
break;
case "normal":
$line_numbering = 1;
break;
case "fancy":
$line_numbering = 5;
break;
}
}
elseif ($att_name == GeshiFilter::ATTRIBUTE_FANCY_N) {
$att_value = (int) $att_value;
if ($att_value >= 2) {
$line_numbering = $att_value;
}
}
elseif ($att_name == GeshiFilter::ATTRIBUTE_LINE_NUMBERING_START) {
if ($line_numbering < 1) {
$line_numbering = 1;
}
$linenumbers_start = (int) $att_value;
}
elseif ($att_name == GeshiFilter::ATTRIBUTE_TITLE) {
$title = $att_value;
}
elseif ($att_name == GeshiFilter::ATTRIBUTE_SPECIAL_LINES) {
$special_lines = explode(',', $att_value);
}
}
return [
'language' => $lang,
'line_numbering' => $line_numbering,
'linenumbers_start' => $linenumbers_start,
'title' => $title,
'special_lines' => $special_lines,
];
}
public function prepareCallback(array $match) {
$tag_name = $match[2];
$tag_attributes = $match[3];
$content = $match[6];
$lang = $this->config
->get('default_highlighting');
if ($lang == GeshiFilter::DEFAULT_DONOTHING) {
$enabled_languages = GeshiFilter::getEnabledLanguages();
list($generic_code_tags, $language_tags, $tag_to_lang) = $this
->getTags();
if (isset($tag_to_lang[$tag_name]) && isset($enabled_languages[$tag_to_lang[$tag_name]])) {
$lang = $tag_to_lang[$tag_name];
}
else {
$settings = $this
->parseAttributes($tag_attributes);
if ($settings['language'] && isset($enabled_languages[$settings['language']])) {
$lang = $settings['language'];
}
}
if ($lang == GeshiFilter::DEFAULT_DONOTHING) {
return $match[0];
}
}
if ($this
->decodeEntities()) {
$content = $this
->unencode($content);
}
return '[geshifilter-' . $tag_name . $tag_attributes . ']' . str_replace([
"\r",
"\n",
], [
'',
' ',
], SafeMarkup::checkPlain($content)) . '[/geshifilter-' . $tag_name . ']';
}
public function preparePhpCallback(array $match) {
if ($this
->decodeEntities()) {
$match[2] = $this
->unencode($match[2]);
}
return '[geshifilter-questionmarkphp]' . str_replace([
"\r",
"\n",
], [
'',
' ',
], SafeMarkup::checkPlain($match[2])) . '[/geshifilter-questionmarkphp]';
}
public function prepareMarkdownCallback(array $match) {
$tag_name = $match[2];
$tag_attributes = '';
$content = $match[3];
$lang = $this->config
->get('default_highlighting');
if ($lang == GeshiFilter::DEFAULT_DONOTHING) {
$enabled_languages = GeshiFilter::getEnabledLanguages();
list($generic_code_tags, $language_tags, $tag_to_lang) = $this
->getTags();
if (isset($tag_to_lang[$tag_name]) && isset($enabled_languages[$tag_to_lang[$tag_name]])) {
$lang = $tag_to_lang[$tag_name];
}
if ($lang == GeshiFilter::DEFAULT_DONOTHING) {
return $match[0];
}
}
if ($this
->decodeEntities()) {
$content = $this
->unencode($content);
}
return '[geshifilter-' . $tag_name . $tag_attributes . ']' . str_replace([
"\r",
"\n",
], [
'',
' ',
], SafeMarkup::checkPlain($content)) . '[/geshifilter-' . $tag_name . ']';
}
public function unencode($text) {
$text = html_entity_decode($text, ENT_QUOTES);
return $text;
}
protected function decodeEntities() {
if (!$this->config
->get('use_format_specific_options')) {
return $this->config
->get('decode_entities');
}
return $this->settings['general_tags']['decode_entities'];
}
}