You are here

function _footnotes_replace_callback in Footnotes 5.2

Same name and namespace in other branches
  1. 5 footnotes.module \_footnotes_replace_callback()
  2. 6.2 footnotes.module \_footnotes_replace_callback()
  3. 6 footnotes.module \_footnotes_replace_callback()
  4. 7.3 footnotes.module \_footnotes_replace_callback()
  5. 7.2 footnotes.module \_footnotes_replace_callback()

Helper function called from preg_replace_callback() above

Uses static vars to temporarily store footnotes found. In my understanding, this is not threadsafe?!

1 call to _footnotes_replace_callback()
footnotes_filter in ./footnotes.module
Implementation of hook_filter().
1 string reference to '_footnotes_replace_callback'
footnotes_filter in ./footnotes.module
Implementation of hook_filter().

File

./footnotes.module, line 211
The Footnotes module is a filter that can be used to insert automatically numbered footnotes into Drupal texts.

Code

function _footnotes_replace_callback($matches, $op = '') {
  static $n = 0;
  static $store_matches = array();
  $str = '';
  if ($op == 'output footer') {
    if (count($store_matches) > 0) {

      // Only if there are stored fn matches, pass the array of fns to be themed
      // as a list
      $str = theme('footnote_list', $store_matches);
    }
    $n = 0;
    $store_matches = array();
    return $str;
  }

  // Default op: act as called by preg_replace_callback()
  // Random string used to ensure footnote id's are unique, even
  // when contents of multiple nodes reside on same page. (fixes http://drupal.org/node/194558)
  $randstr = _footnotes_helper_randstr();
  $value = '';

  // Did the pattern match anything in the <fn> tag?
  if ($matches[1]) {

    // See if value attribute can parsed, either well-formed in quotes eg <fn value="3">
    if (preg_match('|value=["\'](.*?)["\']|', $matches[1], $value_match)) {
      $value = $value_match[1];

      // Or without quotes eg <fn value=8>
    }
    elseif (preg_match('|value=(\\S*)|', $matches[1], $value_match)) {
      $value = $value_match[1];
    }
  }
  if ($value) {

    // A value label was found. If it is numeric, record it in $n so further notes
    // can increment from there.
    if (is_numeric($value)) {
      $n = $value;
    }
  }
  else {

    // No value label, either a plain <fn> or unparsable attributes. Increment the
    // footnote counter, set label equal to it.
    $n++;
    $value = $n;
  }

  // Remove illegal characters from $value so it can be used as an HTML id attribute.
  $value_id = preg_replace('|[^\\w\\-]|', '', $value);

  // Create a sanitized version of $text that is suitable for using as HTML attribute
  // value. (In particular, as the title attribute to the footnote link.)
  $allowed_tags = array();
  $text_clean = filter_xss($matches['2'], $allowed_tags);

  // HTML attribute cannot contain quotes
  $text_clean = str_replace('"', "&quot;", $text_clean);

  // Remove newlines. Browsers don't support them anyway and they'll confuse line break converter in filter.module
  $text_clean = str_replace("\n", " ", $text_clean);
  $text_clean = str_replace("\r", "", $text_clean);

  // Create a footnote item as an array.
  $fn = array(
    'value' => $value,
    'text' => $matches[2],
    'text_clean' => $text_clean,
    'fn_id' => 'footnote' . $value_id . '_' . $randstr,
    'ref_id' => 'footnoteref' . $value_id . '_' . $randstr,
  );

  // Store the footnote item.
  array_push($store_matches, $fn);

  // Return the item themed into a footnote link.
  return theme('footnote_link', $fn);
}