diff --git a/config/install/toc_api.toc_type.default.yml b/config/install/toc_api.toc_type.default.yml index 7affc29841229cb03d6319142d0ebe611da049c2..705ec78a9673d3aa4980ead230e8a123125db2fd 100644 --- a/config/install/toc_api.toc_type.default.yml +++ b/config/install/toc_api.toc_type.default.yml @@ -13,6 +13,7 @@ options: header_allowed_tags: '<em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub> <em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub>' header_id: title header_id_prefix: section + header_exclude_xpath: '' top_label: 'Back to top' top_min: 2 top_max: 2 diff --git a/config/install/toc_api.toc_type.full.yml b/config/install/toc_api.toc_type.full.yml index 3b43c5570ffb3b46b55cb3651b5c3f9c0a5fed72..dd671e8a53c4a23bde96b06f23637b75f61bf5a1 100644 --- a/config/install/toc_api.toc_type.full.yml +++ b/config/install/toc_api.toc_type.full.yml @@ -13,6 +13,7 @@ options: header_allowed_tags: '<em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub> <em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub>' header_id: title header_id_prefix: section + header_exclude_xpath: '' top_label: 'Back to top' top_min: 2 top_max: 2 diff --git a/config/install/toc_api.toc_type.full_numbered.yml b/config/install/toc_api.toc_type.full_numbered.yml index 0bb82d8fe33d1ac680afbcecc66de03abc917d58..61961c7f0710aa311d50bd40130d3fd58716b81a 100644 --- a/config/install/toc_api.toc_type.full_numbered.yml +++ b/config/install/toc_api.toc_type.full_numbered.yml @@ -13,6 +13,7 @@ options: header_allowed_tags: '<em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub> <em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub>' header_id: title header_id_prefix: section + header_exclude_xpath: '' top_label: 'Back to top' top_min: 2 top_max: 2 diff --git a/config/install/toc_api.toc_type.simple.yml b/config/install/toc_api.toc_type.simple.yml index 55f240378737da1925f331f64f1d7539e2f9d0cc..20bfad37967a5c1dd1a940dd4c9befc2afec32d8 100644 --- a/config/install/toc_api.toc_type.simple.yml +++ b/config/install/toc_api.toc_type.simple.yml @@ -13,6 +13,7 @@ options: header_allowed_tags: '<em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub> <em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub>' header_id: title header_id_prefix: section + header_exclude_xpath: '' top_label: 'Back to top' top_min: 2 top_max: 2 diff --git a/config/install/toc_api.toc_type.simple_numbered.yml b/config/install/toc_api.toc_type.simple_numbered.yml index bff250343722c5fa7f94c182b73e2e2da3d3b752..bcccb138e7affd3a3f8671905b0f216a9fec2d20 100644 --- a/config/install/toc_api.toc_type.simple_numbered.yml +++ b/config/install/toc_api.toc_type.simple_numbered.yml @@ -13,6 +13,7 @@ options: header_allowed_tags: '<em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub> <em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub>' header_id: title header_id_prefix: section + header_exclude_xpath: '' top_label: 'Back to top' top_min: 2 top_max: 2 diff --git a/config/schema/toc_api.toc_type.schema.yml b/config/schema/toc_api.toc_type.schema.yml index 0966dfac4f90a7e239fecc14fbd4e1bcbe4043fb..19bdb585abff3c638d8cdf9f612e99d4107ef499 100644 --- a/config/schema/toc_api.toc_type.schema.yml +++ b/config/schema/toc_api.toc_type.schema.yml @@ -42,6 +42,9 @@ toc_api.toc_type.*: header_id_prefix: type: string label: 'Header ID prefix' + header_exclude_xpath: + type: string + label: 'Header exclude XPath' top_label: type: string label: 'Back to top' diff --git a/src/Toc.php b/src/Toc.php index 545ce8b3dde1d815926e38dbf64e2b03d0bc1735..fa5eed4365d426f68ed638ea94886c5e19865c10 100644 --- a/src/Toc.php +++ b/src/Toc.php @@ -40,6 +40,7 @@ class Toc implements TocInterface { 'header_allowed_tags' => '<em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub> <em> <b> <del> <i> <mark> <s> <span> <strong> <sup> <sub>', 'header_id' => 'title', 'header_id_prefix' => 'section', + 'header_exclude_xpath' => '', 'top_label' => 'Back to top', 'top_min' => 2, 'top_max' => 2, @@ -135,6 +136,8 @@ class Toc implements TocInterface { * - 'header_id_prefix': Prefix to be prepended to header id when * 'path' or 'key' is selected. * Default value is 'section' + * - 'header_exclude_xpath': Optional XPath for any headers to exclude from + * the table of contents. * * - 'top_min': The minimum level of header to include a back to top link. * Default value is 2 @@ -203,12 +206,22 @@ class Toc implements TocInterface { $index_keys = $default_keys; $dom = Html::load($this->source); + + // If the exclude XPath option is set, retrieve those elements. + $exclude_nodes = []; + if ($this->options['header_exclude_xpath']) { + $xpath = new \DOMXPath($dom); + foreach ($xpath->query($this->options['header_exclude_xpath']) as $exclude_node) { + $exclude_nodes[] = $exclude_node; + } + } + // Loop through all the tags to ensure headers are found in the correct // order. $dom_nodes = $dom->getElementsByTagName('*'); /** @var \DOMElement $dom_node */ foreach ($dom_nodes as $dom_node) { - if (empty($this->options['headers'][$dom_node->tagName])) { + if (empty($this->options['headers'][$dom_node->tagName]) || in_array($dom_node, $exclude_nodes, TRUE)) { continue; } diff --git a/src/TocTypeForm.php b/src/TocTypeForm.php index 9f6f547e4cb3eb24ae39448859e1812f80e317e4..9c1012e867387e32b4d0bf0aea5e1fc55622c044 100644 --- a/src/TocTypeForm.php +++ b/src/TocTypeForm.php @@ -197,6 +197,12 @@ class TocTypeForm extends EntityForm { '#type' => 'textfield', '#default_value' => $options['header_id_prefix'], ]; + $form['options']['header']['header_exclude_xpath'] = [ + '#title' => $this->t('Header exclude XPath'), + '#description' => $this->t('Optional XPath for header elements to exclude from the table of contents. Example - //*[contains(@class,"toc-ignore")]'), + '#type' => 'textfield', + '#default_value' => $options['header_exclude_xpath'] ?? '', + ]; $form['options']['top'] = [ '#type' => 'details', diff --git a/toc_api.install b/toc_api.install new file mode 100644 index 0000000000000000000000000000000000000000..e41b71952a0f53729ee07c872374f9f1884ffeab --- /dev/null +++ b/toc_api.install @@ -0,0 +1,23 @@ +<?php + +/** + * @file + * Update functions for the toc_api module. + */ + +/** + * Add header_exclude_xpath to existing TOCs + */ +function toc_api_update_8001() { + $toc_types = \Drupal::entityQuery('toc_type')->execute(); + + foreach ($toc_types as $type) { + $entity = \Drupal::entityTypeManager()->getStorage('toc_type')->load($type); + $options = $entity->getOptions(); + + if (empty($options['header_exclude_xpath'])) { + $config_factory = \Drupal::configFactory(); + $config_factory->getEditable('toc_api.toc_type.' . $type)->set('options.header_exclude_xpath', '')->save(); + } + } +}