|
|
@ -4,7 +4,9 @@ namespace Drupal\bibcite_footnotes\Plugin\Filter; |
|
|
|
|
|
|
|
|
|
|
|
use Drupal\Component\Utility\Xss; |
|
|
|
use Drupal\Component\Utility\Xss; |
|
|
|
use Drupal\Core\Form\FormStateInterface; |
|
|
|
use Drupal\Core\Form\FormStateInterface; |
|
|
|
use Drupal\footnotes\Plugin\Filter\FootnotesFilter; |
|
|
|
use Drupal\filter\FilterProcessResult; |
|
|
|
|
|
|
|
use Drupal\filter\Plugin\FilterBase; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Reference Footnotes filter. |
|
|
|
* Reference Footnotes filter. |
|
|
@ -24,7 +26,7 @@ use Drupal\footnotes\Plugin\Filter\FootnotesFilter; |
|
|
|
* weight = 0 |
|
|
|
* weight = 0 |
|
|
|
* ) |
|
|
|
* ) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
class ReferenceFootnotesFilter extends FootnotesFilter { |
|
|
|
class ReferenceFootnotesFilter extends FilterBase { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Object with configuration for reference footnotes. |
|
|
|
* Object with configuration for reference footnotes. |
|
|
@ -46,6 +48,7 @@ class ReferenceFootnotesFilter extends FootnotesFilter { |
|
|
|
public function __construct(array $configuration, $plugin_id, array $plugin_definition) { |
|
|
|
public function __construct(array $configuration, $plugin_id, array $plugin_definition) { |
|
|
|
parent::__construct($configuration, $plugin_id, $plugin_definition); |
|
|
|
parent::__construct($configuration, $plugin_id, $plugin_definition); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$this->renderer = \Drupal::service('renderer'); |
|
|
|
$this->config = \Drupal::config('reference_footnotes.settings'); |
|
|
|
$this->config = \Drupal::config('reference_footnotes.settings'); |
|
|
|
$this->configEditable = \Drupal::configFactory() |
|
|
|
$this->configEditable = \Drupal::configFactory() |
|
|
|
->getEditable('reference_footnotes.settings'); |
|
|
|
->getEditable('reference_footnotes.settings'); |
|
|
@ -310,4 +313,89 @@ class ReferenceFootnotesFilter extends FootnotesFilter { |
|
|
|
$prev_reference_id = $fn['reference']; |
|
|
|
$prev_reference_id = $fn['reference']; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* {@inheritdoc} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public function process($text, $langcode) { |
|
|
|
|
|
|
|
// Supporting both [fn] and <fn> now. Thanks to fletchgqc |
|
|
|
|
|
|
|
// http://drupal.org/node/268026. |
|
|
|
|
|
|
|
// Convert all square brackets to angle brackets. This way all further code |
|
|
|
|
|
|
|
// just manipulates angle brackets. (Angle brackets are preferred here for |
|
|
|
|
|
|
|
// the simple reason that square brackets are more tedious to use in |
|
|
|
|
|
|
|
// regexps). |
|
|
|
|
|
|
|
if (is_array($text)) { |
|
|
|
|
|
|
|
implode($text); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
$text = preg_replace('|\[fn([^\]]*)\]|', '<fn$1>', $text); |
|
|
|
|
|
|
|
$text = preg_replace('|\[/fn\]|', '</fn>', $text); |
|
|
|
|
|
|
|
$text = preg_replace('|\[footnotes([^\]]*)\]|', '<footnotes$1>', $text); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check that there are an even number of open and closing tags. |
|
|
|
|
|
|
|
// If there is one closing tag missing, append this to the end. |
|
|
|
|
|
|
|
// If there is more disparity, throw a warning and continue. |
|
|
|
|
|
|
|
// A closing tag may sometimes be missing when we are processing a teaser |
|
|
|
|
|
|
|
// and it has been cut in the middle of the footnote. |
|
|
|
|
|
|
|
// See http://drupal.org/node/253326 |
|
|
|
|
|
|
|
$foo = []; |
|
|
|
|
|
|
|
$open_tags = preg_match_all("|<fn([^>]*)>|", $text, $foo); |
|
|
|
|
|
|
|
$close_tags = preg_match_all("|</fn>|", $text, $foo); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ($open_tags == $close_tags + 1) { |
|
|
|
|
|
|
|
$text = $text . '</fn>'; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
elseif ($open_tags > $close_tags + 1) { |
|
|
|
|
|
|
|
trigger_error($this->t("You have unclosed fn tags. This is invalid and will |
|
|
|
|
|
|
|
produce unpredictable results.")); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Before doing the replacement, the callback function needs to know which |
|
|
|
|
|
|
|
// options to use. |
|
|
|
|
|
|
|
$this->replaceCallback($this->settings, 'prepare'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$pattern = '|<fn([^>]*)>(.*?)</fn>|s'; |
|
|
|
|
|
|
|
$text = preg_replace_callback($pattern, [ |
|
|
|
|
|
|
|
$this, |
|
|
|
|
|
|
|
'replaceCallback', |
|
|
|
|
|
|
|
], $text); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Replace tag <footnotes> with the list of footnotes. |
|
|
|
|
|
|
|
// If tag is not present, by default add the footnotes at the end. |
|
|
|
|
|
|
|
// Thanks to acp on drupal.org for this idea. see |
|
|
|
|
|
|
|
// http://drupal.org/node/87226. |
|
|
|
|
|
|
|
$footer = $this->replaceCallback(NULL, 'output footer'); |
|
|
|
|
|
|
|
$pattern = '|(<footnotes([^\]]*)>)|'; |
|
|
|
|
|
|
|
if (preg_match($pattern, $text) > 0) { |
|
|
|
|
|
|
|
$text = preg_replace($pattern, $footer, $text, 1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
elseif (!empty($footer)) { |
|
|
|
|
|
|
|
$text .= "\n\n" . $footer; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
$result = new FilterProcessResult($text); |
|
|
|
|
|
|
|
$result->setAttachments([ |
|
|
|
|
|
|
|
'library' => [ |
|
|
|
|
|
|
|
'footnotes/footnotes', |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
]); |
|
|
|
|
|
|
|
return $result; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Helper function to return a random text string. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @return string |
|
|
|
|
|
|
|
* Random (lowercase) alphanumeric string. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public function randstr() { |
|
|
|
|
|
|
|
$chars = "abcdefghijklmnopqrstuwxyz1234567890"; |
|
|
|
|
|
|
|
$str = ""; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Seeding with srand() not necessary in modern PHP versions. |
|
|
|
|
|
|
|
for ($i = 0; $i < 7; $i++) { |
|
|
|
|
|
|
|
$n = rand(0, strlen($chars) - 1); |
|
|
|
|
|
|
|
$str .= substr($chars, $n, 1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return $str; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|