class CollapseText in Collapse Text 8
Same name and namespace in other branches
- 2.0.x src/Plugin/Filter/CollapseText.php \Drupal\collapse_text\Plugin\Filter\CollapseText
Provides a filter to display Collapsible text blocks.
Plugin annotation
@Filter(
id = "filter_collapse_text",
title = @Translation("Collapsible text blocks"),
description = @Translation("Allows the creation of collapsing blocks of text. This filter must be after the 'Limit allowed HTML tags' filter, and should be after the 'Convert line breaks into HTML' filter."),
type = Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE,
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\filter\Plugin\FilterBase implements FilterInterface
- class \Drupal\collapse_text\Plugin\Filter\CollapseText
- class \Drupal\filter\Plugin\FilterBase implements FilterInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of CollapseText
File
- src/
Plugin/ Filter/ CollapseText.php, line 23
Namespace
Drupal\collapse_text\Plugin\FilterView source
class CollapseText extends FilterBase {
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$form['default_title'] = [
'#type' => 'textfield',
'#title' => t('Default title'),
'#description' => t('If no title is supplied for a section, use this as the default. This may not be empty. The original default title is "@default_title".', [
'@default_title' => COLLAPSE_TEXT_DEFAULT_TITLE,
]),
'#default_value' => isset($this->settings['default_title']) ? $this->settings['default_title'] : COLLAPSE_TEXT_DEFAULT_TITLE,
'#required' => TRUE,
];
$form['form'] = [
'#type' => 'checkbox',
'#title' => t('Surround text with an empty form tag'),
'#description' => t('Collapse text works by generating <details> tags. To validate as proper HTML, these need to be within a <form> tag. This option allows you to prevent the generation of the surrounding form tag. You probably do not want to change this.'),
'#default_value' => isset($this->settings['form']) ? $this->settings['form'] : 1,
];
return $form;
}
/**
* {@inheritdoc}
*/
public function prepare($text, $langcode) {
// Fix any html style (ie, '<>' delimited) tags into our '[]'
// style delimited tags.
$text = preg_replace('/(?<!\\\\) # not preceded by a backslash
< # an open bracket
( # start capture
\\/? # optional backslash
collapse # the string collapse
[^>]* # everything up to the closing angle bracket; note that you cannot use one inside the tag!
) # stop capture
> # close bracket
/ix', '[$1]', $text);
$text = preg_replace_callback('/(?<!\\\\) # not preceded by a backslash
\\[ # open bracket
collapse # the string collapse
[^\\]]* # everything up to a closing straight bracket; note that you cannot use one inside a tag!
\\] # closing bracket
/ix', [
$this,
'filterPrepareRegexCallback',
], $text);
return $text;
}
/**
* {@inheritdoc}
*/
public function process($text, $langcode) {
// Retrieve the options, then look for overrides.
$options = $this->settings;
list($text, $options) = $this
->checkOptions($text, $options);
// Find all of the collapse tags and their location in the string.
$tags = $this
->findTags($text, $options);
// Determine the level of nesting for each element.
$levels = $this
->findLevels($tags, $options);
// Process the text if there are any collapse tags...
if (count($levels)) {
// Turn the levels and the string into a structured tree.
$tree = $this
->processRecurseLevels($text, 0, strlen($text), $levels, $options);
// Take the tree, and turn it into FAPI elements, then embed
// them in a form if requested.
// Used to generate unique ids to prevent an E_NOTICE.
static $render_number = 1;
$holder = [];
if ($options['form']) {
$holder = [
'#type' => 'form',
'#theme' => 'collapse_text_form',
'#form_id' => 'collapse-text-dynamic-form-number-' . $render_number,
'#id' => 'collapse-text-dynamic-form-number-' . $render_number++,
];
}
else {
$holder = [
'#type' => 'markup',
'#prefix' => '<div id="' . 'collapse-text-dynamic-div-number-' . $render_number++ . '">',
'#suffix' => '</div>',
];
}
$holder['collapse_text_internal_text'] = $this
->processRecurseTree($tree, $options);
// Render the elements back to a string.
$text = drupal_render($holder);
}
return new FilterProcessResult($text);
}
/**
* {@inheritdoc}
*/
public function tips($long = FALSE) {
if ($long) {
return t('<p>You may surround a section of text with "[collapse]" and "[/collapse]" to it into a collapsible section.</p><p>You may use "[collapse]" tags within other "[collapse]" tags for nested collapsing sections.</p><p>If you start with "[collapsed]" or "[collapse collapsed]", the section will default to a collapsed state.</p><p>You may specify a title for the section in two ways. You may add a "title=" parameter to the opening tag, such as "[collapse title=<your title here>]". In this case, you should surround the title with double-quotes. If you need to include double-quotes in the title, use the html entity "&quot;". For example: \'[collapse title="&quot;Once upon a time&quot;"]\'. If a title is not specified in the "[collapse]" tag, the title will be taken from the first heading found inside the section. A heading is specified using the "<hX>" html tag, where X is a number from 1-6. The heading will be removed from the section in order to prevent duplication. If a title is not found using these two methods, a default title will be supplied.</p><p>For advanced uses, you may also add a "class=" option to specify CSS classes to be added to the section. The CSS classes should be surrounded by double-quotes, and separated by spaces; e.g. \'[collapse class="class1 class2"]\'.</p><p>You may combine these options in (almost) any order. The "collapsed" option should always come first; things will break if it comes after "title=" or "class=". If you need to have it come after the other options, you must specify it as \'collapsed="collapsed"\'; e.g. \'[collapse title="foo" collapsed="collapsed"]\'.</p><p>If you wish to put the string "[collapse" into the document, you will need to prefix it with a backslash ("\\"). The first backslash before any instance of "[collapse" or "[/collapse" will be removed, all others will remain. Thus, if you want to display "[collapse stuff here", you should enter "\\[collapse stuff here". If you wish to display "\\[collapse other stuff", you will need to put in "\\\\[collapse other stuff". If you prefix three backslashes, two will be displayed, etc.</p><p>If you prefer, you can use angle brackets ("<>") instead of straight brackets ("[]"). This module will find any instance of "<collapse" and change it to "[collapse" (also fixing the end of the tags and the closing tags).</p><p>You may override the settings of the filter on an individual basis using a "[collapse options ...]" tag. The possible options now are \'form="form"\' or \'form="noform"\', and \'default_title="..."\'. For example, \'[collapse options form="noform" default_title="Click me!"]\'. Only the first options tag will be looked at, and the settings apply for the entire text area, not just the "[collapse]" tags following the options tag. Note that surrounding <p> and <br> tags will be removed.</p><p>This module supports some historical variants of the tag as well. The following are <strong>not</strong> recommended for any new text, but are left in place so that old uses still work. The "class=" option used to called "style=", and "style=" will be changed into "class=". If you don\'t put a double-quote immediately after "class=", everything up to the end of the tag or the string "title=" will be interpreted as the class string. Similarly, if you don\'t have a double-quote immediately following "title=", everything up to the end of the tag will be used as the title. Note that in this format, "style=" <em>must</em> precede "title=".</p>');
}
else {
return t('Use [collapse] and [/collapse] to create collapsible text blocks. [collapse collapsed] or [collapsed] will start with the block closed.');
}
}
/**
* Callback function for the prepare replacement.
*
* Attempt to clean up poorly formatted tags.
*/
public function filterPrepareRegexCallback($matches) {
// All regexes here are running against an already extracted tag.
$tag = $matches[0];
// Allow the [collapsed] open tag.
$tag = preg_replace('/^ # start of tag
\\[ # open bracket
( # start capture
collapsed # the string collapsed
(?: |\\]) # either a space or a close bracket
) # end capture
/ix', '[collapse $1', $tag);
// Fix the collapsed element.
$tag = preg_replace('/^\\[collapse collapsed( |\\])/i', '[collapse collapsed="collapsed"$1', $tag);
// Fix the style element. going forward, we prefer "class=".
$tag = preg_replace('/ style=([^"].*?)(?= collapsed=| title=|\\])/i', ' class="$1"', $tag);
$tag = preg_replace('/ style="/i', ' class="', $tag);
// Fix the title element.
// Not sufficient if title includes double-quotes.
$tag = preg_replace('/ title=([^"].*?)(?= collapsed=| class=|\\])/i', ' title="$1"', $tag);
return $tag;
}
/**
* Helper function to take a nested tree and turn it into a string.
*
* This function is recursive.
*/
public function processRecurseTree($tree, $options) {
$parts = [];
// We use $weight to make sure elements are displayed in the correct order.
$weight = 0;
foreach ($tree as $item) {
// Iterate over the tree.
$part = NULL;
if ($item['type'] == 'text') {
$part = $this
->processTextItem($item['value'], $options);
}
elseif ($item['type'] = 'child') {
$part = $this
->processChildItem($item, $options);
}
if (isset($part)) {
$part['#weight'] = $weight++;
$parts[] = $part;
}
}
return $parts;
}
/**
* Helper function to process a text item.
*/
public function processTextItem($item, $options) {
// Remove any leftover [collapse] or [/collapse] tags,
// such as might be caused by the teaser.
// Leaving out the closing tag.
// Note that a backslash before the collapse tag will act as an escape.
$item = preg_replace('/(?<!\\\\)\\[\\/?collapse[^\\]]*\\]/', '', $item);
// Remove the first backslash before any collapse tags.
// This allows collapse tags to be escaped.
$item = str_replace([
'\\[collapse',
'\\[/collapse',
], [
'[collapse',
'[/collapse',
], $item);
// Clear out some miscellaneous tags that are
// introduced by visual editors...
// Close paragraph right at the start.
$item = preg_replace('/^<\\/p>/', '', $item);
// Open paragraph right at the end.
$item = preg_replace('/<p(?:\\s[^>]*)?>$/', '', $item);
// Clear out cruft introduced by the html line ending filter.
// These are probably more controversial,
// since they may actually be intended...
// At the very start.
$item = preg_replace('/^<br ?\\/?>/', '', $item);
// At the very end.
$item = preg_replace('/<br ?\\/?>$/', '', $item);
// Only return a value if there is something besides whitespace.
if (preg_match('/\\S/', $item)) {
return [
'#type' => 'markup',
'#markup' => $item,
'#prefix' => '<div class="collapse-text-text">',
'#suffix' => '</div>',
];
}
else {
return NULL;
}
}
/**
* Helper function to process a child item.
*/
public function processChildItem($item, $options) {
// Translate the "tag" into a proper tag,
// and then parse it as an xml tag.
$tag = preg_replace([
'/^\\[/',
'/\\]$/',
'/&/',
], [
'<',
'/>',
'&',
], $item['tag']);
// Turn HTML entities into XML entities.
// Issue #1109792 by eronte.
$tag = $this
->htmlToXmlEntities($tag);
$xmltag = simplexml_load_string($tag);
$collapsed = $xmltag['collapsed'] == 'collapsed';
$class = trim($xmltag['class']);
// Issue #1096070 by Asgardinho: issues with UTF8 text.
$title = htmlspecialchars(trim($xmltag['title']), ENT_QUOTES, 'UTF-8');
// Set up the styles array.
// We need to include the 'collapsible' and 'collapsed' classes ourself,
// because this is no longer done by the theme system.
$classes = [];
$classes[] = Html::cleanCssIdentifier('collapse-text-details');
$classes[] = 'collapsible';
if ($collapsed) {
$classes[] = 'collapsed';
}
// Change the style item into an array.
foreach (explode(' ', $class) as $c) {
if (!empty($c)) {
$classes[] = Html::cleanCssIdentifier($c);
}
}
// If a title is not supplied, look in the first child for a header tag.
if (empty($title)) {
if ($item['value'][0]['type'] == 'text') {
$h_matches = [];
if (preg_match('/(<h\\d[^>]*>(.+?)<\\/h\\d>)/smi', $item['value'][0]['value'], $h_matches)) {
$title = strip_tags($h_matches[2]);
}
// If we get the title from the first header tag,
// we should remove it from the text so that it isn't repeated.
if (!empty($title)) {
// This is a hack to only replace the first instance.
$occ = 1;
$item['value'][0]['value'] = str_replace($h_matches[0], '', $item['value'][0]['value'], $occ);
}
}
}
// If still no title, put in the default title.
if (empty($title)) {
$title = $options['default_title'];
$classes[] = Html::cleanCssIdentifier('collapse-text-default-title');
}
// Create a details element that can be themed.
$details = [
'#type' => 'details',
'#theme' => 'collapse_text_details',
'#title' => htmlspecialchars_decode($title),
'#open' => !$collapsed,
'#attributes' => [
'class' => $classes,
],
'collapse_text_contents' => $this
->processRecurseTree($item['value'], $options),
];
return $details;
}
/**
* Helper function to translate the flat levels array into a tree.
*
* This function is recursive.
*/
public function processRecurseLevels($string, $string_start, $string_end, $elements, $options) {
$text_start = $string_start;
$text_length = $string_end - $string_start;
$child_start = $string_start;
$child_end = $string_end;
$slice_start = -1;
// Find the first start element.
$elt_start_found = FALSE;
$elt_start = 0;
while (!$elt_start_found and $elt_start < count($elements)) {
if ($elements[$elt_start]['type'] == 'start') {
$elt_start_found = TRUE;
}
else {
$elt_start++;
}
}
if ($elt_start_found) {
// If there is an opening element,
// set the text length to everything up to it.
$text_length = $elements[$elt_start]['start'] - $string_start;
$child_start = $elements[$elt_start]['end'];
$slice_start = $elt_start + 1;
}
else {
// Otherwise, return everything in this segment as a string.
return [
[
'type' => 'text',
'value' => substr($string, $text_start, $text_length),
],
];
}
// Find the next end element at the same level.
$elt_end_found = FALSE;
$elt_end = $elt_start;
while (!$elt_end_found and $elt_end < count($elements)) {
if ($elements[$elt_end]['type'] == 'end' and $elements[$elt_end]['level'] == $elements[$elt_start]['level']) {
$elt_end_found = TRUE;
}
else {
$elt_end++;
}
}
if ($elt_end_found) {
$child_end = $elements[$elt_end]['start'];
$slice_length = $elt_end - $slice_start;
}
else {
// There is a matching failure.
// Try skipping the start element...
if ($elt_start + 1 < count($elements)) {
return $this
->processRecurseLevels($string, $string_start, $string_end, array_slice($elements, $elt_start + 1), $options);
}
else {
// Fall back to just returning the string...
// Reset the text length.
$text_length = $string_end - $text_start;
return [
[
'type' => 'text',
'value' => substr($string, $text_start, $text_length),
],
];
}
}
$parts = [];
// Add the text before the opening element.
$parts[] = [
'type' => 'text',
'value' => substr($string, $text_start, $text_length),
];
// Add the child element.
$parts[] = [
'type' => 'child',
'tag' => $elements[$elt_start]['tag'],
'value' => $this
->processRecurseLevels($string, $child_start, $child_end, array_slice($elements, $slice_start, $slice_length), $options),
];
// Tail recurse (which ideally could be optimized away,
// although it won't be...) to handle any siblings.
$parts = array_merge($parts, $this
->processRecurseLevels($string, $elements[$elt_end]['end'], $string_end, array_slice($elements, $elt_end), $options));
// Return the result.
return $parts;
}
/**
* Helper function to determine what the nesting structure is.
*/
public function findLevels($tags, $options) {
$levels = [];
$curr_level = 0;
foreach ($tags as $item) {
// Determine whether this is an open or close tag.
$type = 'unknown';
if (substr($item[0], 0, 9) == '[collapse') {
$type = 'start';
}
elseif (substr($item[0], 0, 10) == '[/collapse') {
$type = 'end';
}
// The level of an open tag is incremented before we save its
// information, while the level of a close tag is decremented after.
if ($type == 'start') {
$curr_level++;
}
$levels[] = [
'type' => $type,
'tag' => $item[0],
'start' => $item[1],
'end' => $item[1] + strlen($item[0]),
'level' => $curr_level,
];
if ($type == 'end') {
$curr_level--;
}
}
return $levels;
}
/**
* Helper function to find all of the [collapse...] tags location.
*/
public function findTags($text, $options) {
$matches = [];
$regex = '/
(?<!\\\\) # not proceeded by a backslash
\\[ # opening bracket
\\/? # a closing tag?
collapse # the word collapse
[^\\]]* # everything until the closing bracket
\\] # a closing bracket
/smx';
preg_match_all($regex, $text, $matches, PREG_OFFSET_CAPTURE);
return $matches[0];
}
/**
* Helper function to see if there is an options tag available.
*
* If so, remove it from the text and set the options.
*/
public function checkOptions($text, $options) {
$matches = [];
$regex_text = '
(?<!\\\\) # not proceeded by a backslash
\\[ # opening bracket
collapse # the word collapse
\\s+ # white space
options # the word options
[^\\]]* # everything until the closing bracket
\\] # a closing bracket
';
if (preg_match('/' . $regex_text . '/smx', $text, $matches)) {
$opt_tag = $matches[0];
// Remove the "collapse" from the front of the tag,
// baking in an "options" tag.
$opt_tag = preg_replace('/^\\[collapse /', '[', $opt_tag);
// Change to angle brackets, so it can be parsed as XML.
$opt_tag = preg_replace([
'/^\\[/',
'/\\]$/',
], [
'<',
'/>',
], $opt_tag);
// Turn HTML entities into XML entities.
$opt_tag = $this
->htmlToXmlEntities($opt_tag);
$opt_tag = simplexml_load_string($opt_tag);
// Form options are either 'form="form"' or 'form="noform"'.
if ($opt_tag['form'] == 'form') {
$options['form'] = 1;
}
elseif ($opt_tag['form'] == 'noform') {
$options['form'] = 0;
}
if ($opt_tag['default_title']) {
// Issue #1096070 by Asgardinho: issues with UTF8 text.
$options['default_title'] = htmlspecialchars(trim($opt_tag['default_title']), ENT_QUOTES, 'UTF-8');
}
// Remove the options tag, including any miscellaneous <p>, </p>,
// or <br> tags around it.
$text = preg_replace('/(?:<\\/?p>|<br\\s*\\/?>)*' . $regex_text . '(?:<\\/?p>|<br\\s*\\/?>)*/smx', '', $text);
}
return [
$text,
$options,
];
}
/**
* Helper function to convert html entities to xml entities.
*
* HTML entity lists from
* - http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
* - http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent
* - http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent.
*
* @todo -- rewrite to use str_replace
*/
public function htmlToXmlEntities($text) {
static $replace = [
// Latin 1.
' ' => ' ',
'¡' => '¡',
'¢' => '¢',
'£' => '£',
'¤' => '¤',
'¥' => '¥',
'¦' => '¦',
'§' => '§',
'¨' => '¨',
'©' => '©',
'ª' => 'ª',
'«' => '«',
'¬' => '¬',
'­' => '­',
'®' => '®',
'¯' => '¯',
'°' => '°',
'±' => '±',
'²' => '²',
'³' => '³',
'´' => '´',
'µ' => 'µ',
'¶' => '¶',
'·' => '·',
'¸' => '¸',
'¹' => '¹',
'º' => 'º',
'»' => '»',
'¼' => '¼',
'½' => '½',
'¾' => '¾',
'¿' => '¿',
'À' => 'À',
'Á' => 'Á',
'Â' => 'Â',
'Ã' => 'Ã',
'Ä' => 'Ä',
'Å' => 'Å',
'Æ' => 'Æ',
'Ç' => 'Ç',
'È' => 'È',
'É' => 'É',
'Ê' => 'Ê',
'Ë' => 'Ë',
'Ì' => 'Ì',
'Í' => 'Í',
'Î' => 'Î',
'Ï' => 'Ï',
'Ð' => 'Ð',
'Ñ' => 'Ñ',
'Ò' => 'Ò',
'Ó' => 'Ó',
'Ô' => 'Ô',
'Õ' => 'Õ',
'Ö' => 'Ö',
'×' => '×',
'Ø' => 'Ø',
'Ù' => 'Ù',
'Ú' => 'Ú',
'Û' => 'Û',
'Ü' => 'Ü',
'Ý' => 'Ý',
'Þ' => 'Þ',
'ß' => 'ß',
'à' => 'à',
'á' => 'á',
'â' => 'â',
'ã' => 'ã',
'ä' => 'ä',
'å' => 'å',
'æ' => 'æ',
'ç' => 'ç',
'è' => 'è',
'é' => 'é',
'ê' => 'ê',
'ë' => 'ë',
'ì' => 'ì',
'í' => 'í',
'î' => 'î',
'ï' => 'ï',
'ð' => 'ð',
'ñ' => 'ñ',
'ò' => 'ò',
'ó' => 'ó',
'ô' => 'ô',
'õ' => 'õ',
'ö' => 'ö',
'÷' => '÷',
'ø' => 'ø',
'ù' => 'ù',
'ú' => 'ú',
'û' => 'û',
'ü' => 'ü',
'ý' => 'ý',
'þ' => 'þ',
'ÿ' => 'ÿ',
// Special.
''' => ''',
'Œ' => 'Œ',
'œ' => 'œ',
'Š' => 'Š',
'š' => 'š',
'Ÿ' => 'Ÿ',
'ˆ' => 'ˆ',
'˜' => '˜',
' ' => ' ',
' ' => ' ',
' ' => ' ',
'‌' => '‌',
'‍' => '‍',
'‎' => '‎',
'‏' => '‏',
'–' => '–',
'—' => '—',
'‘' => '‘',
'’' => '’',
'‚' => '‚',
'“' => '“',
'”' => '”',
'„' => '„',
'†' => '†',
'‡' => '‡',
'‰' => '‰',
'‹' => '‹',
'›' => '›',
'€' => '€',
// Symbols.
'ƒ' => 'ƒ',
'Α' => 'Α',
'Β' => 'Β',
'Γ' => 'Γ',
'Δ' => 'Δ',
'Ε' => 'Ε',
'Ζ' => 'Ζ',
'Η' => 'Η',
'Θ' => 'Θ',
'Ι' => 'Ι',
'Κ' => 'Κ',
'Λ' => 'Λ',
'Μ' => 'Μ',
'Ν' => 'Ν',
'Ξ' => 'Ξ',
'Ο' => 'Ο',
'Π' => 'Π',
'Ρ' => 'Ρ',
'Σ' => 'Σ',
'Τ' => 'Τ',
'Υ' => 'Υ',
'Φ' => 'Φ',
'Χ' => 'Χ',
'Ψ' => 'Ψ',
'Ω' => 'Ω',
'α' => 'α',
'β' => 'β',
'γ' => 'γ',
'δ' => 'δ',
'ε' => 'ε',
'ζ' => 'ζ',
'η' => 'η',
'θ' => 'θ',
'ι' => 'ι',
'κ' => 'κ',
'λ' => 'λ',
'μ' => 'μ',
'ν' => 'ν',
'ξ' => 'ξ',
'ο' => 'ο',
'π' => 'π',
'ρ' => 'ρ',
'ς' => 'ς',
'σ' => 'σ',
'τ' => 'τ',
'υ' => 'υ',
'φ' => 'φ',
'χ' => 'χ',
'ψ' => 'ψ',
'ω' => 'ω',
'ϒ' => 'ϒ',
'ϖ' => 'ϖ',
'•' => '•',
'…' => '…',
'′' => '′',
'″' => '″',
'‾' => '‾',
'⁄' => '⁄',
'℘' => '℘',
'ℑ' => 'ℑ',
'ℜ' => 'ℜ',
'™' => '™',
'ℵ' => 'ℵ',
'←' => '←',
'↑' => '↑',
'→' => '→',
'↓' => '↓',
'↔' => '↔',
'↵' => '↵',
'⇐' => '⇐',
'⇑' => '⇑',
'⇒' => '⇒',
'⇓' => '⇓',
'⇔' => '⇔',
'∀' => '∀',
'∂' => '∂',
'∃' => '∃',
'∅' => '∅',
'∇' => '∇',
'∈' => '∈',
'∉' => '∉',
'∋' => '∋',
'∏' => '∏',
'∑' => '∑',
'−' => '−',
'∗' => '∗',
'√' => '√',
'∝' => '∝',
'∞' => '∞',
'∠' => '∠',
'∧' => '∧',
'∨' => '∨',
'∩' => '∩',
'∪' => '∪',
'∫' => '∫',
'∴' => '∴',
'∼' => '∼',
'≅' => '≅',
'≈' => '≈',
'≠' => '≠',
'≡' => '≡',
'≤' => '≤',
'≥' => '≥',
'⊂' => '⊂',
'⊃' => '⊃',
'⊄' => '⊄',
'⊆' => '⊆',
'⊇' => '⊇',
'⊕' => '⊕',
'⊗' => '⊗',
'⊥' => '⊥',
'⋅' => '⋅',
'⌈' => '⌈',
'⌉' => '⌉',
'⌊' => '⌊',
'⌋' => '⌋',
'⟨' => '〈',
'⟩' => '〉',
'◊' => '◊',
'♠' => '♠',
'♣' => '♣',
'♥' => '♥',
'♦' => '♦',
];
// Only run the substitution if there is actually an entity in the tag.
if (strpos($text, '&') !== FALSE) {
$text = strtr($text, $replace);
}
return $text;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
CollapseText:: |
public | function | Helper function to see if there is an options tag available. | |
CollapseText:: |
public | function | Callback function for the prepare replacement. | |
CollapseText:: |
public | function | Helper function to determine what the nesting structure is. | |
CollapseText:: |
public | function | Helper function to find all of the [collapse...] tags location. | |
CollapseText:: |
public | function | Helper function to convert html entities to xml entities. | |
CollapseText:: |
public | function |
Prepares the text for processing. Overrides FilterBase:: |
|
CollapseText:: |
public | function |
Performs the filter processing. Overrides FilterInterface:: |
|
CollapseText:: |
public | function | Helper function to process a child item. | |
CollapseText:: |
public | function | Helper function to translate the flat levels array into a tree. | |
CollapseText:: |
public | function | Helper function to take a nested tree and turn it into a string. | |
CollapseText:: |
public | function | Helper function to process a text item. | |
CollapseText:: |
public | function |
Generates a filter's settings form. Overrides FilterBase:: |
|
CollapseText:: |
public | function |
Generates a filter's tip. Overrides FilterBase:: |
|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
FilterBase:: |
public | property | The name of the provider that owns this filter. | |
FilterBase:: |
public | property | An associative array containing the configured settings of this filter. | |
FilterBase:: |
public | property | A Boolean indicating whether this filter is enabled. | |
FilterBase:: |
public | property | The weight of this filter compared to others in a filter collection. | |
FilterBase:: |
public | function |
Calculates dependencies for the configured plugin. Overrides DependentPluginInterface:: |
1 |
FilterBase:: |
public | function |
Gets default configuration for this plugin. Overrides ConfigurableInterface:: |
|
FilterBase:: |
public | function |
Gets this plugin's configuration. Overrides ConfigurableInterface:: |
|
FilterBase:: |
public | function |
Returns the administrative description for this filter plugin. Overrides FilterInterface:: |
|
FilterBase:: |
public | function |
Returns HTML allowed by this filter's configuration. Overrides FilterInterface:: |
4 |
FilterBase:: |
public | function |
Returns the administrative label for this filter plugin. Overrides FilterInterface:: |
|
FilterBase:: |
public | function |
Returns the processing type of this filter plugin. Overrides FilterInterface:: |
|
FilterBase:: |
public | function |
Sets the configuration for this plugin instance. Overrides ConfigurableInterface:: |
1 |
FilterBase:: |
public | function |
Constructs a \Drupal\Component\Plugin\PluginBase object. Overrides PluginBase:: |
4 |
FilterInterface:: |
constant | HTML tag and attribute restricting filters to prevent XSS attacks. | ||
FilterInterface:: |
constant | Non-HTML markup language filters that generate HTML. | ||
FilterInterface:: |
constant | Irreversible transformation filters. | ||
FilterInterface:: |
constant | Reversible transformation filters. | ||
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |