You are here

function headinganchors_filter in Table of Contents 6.2

Same name and namespace in other branches
  1. 5.2 headinganchors.module \headinganchors_filter()
  2. 5 headinganchors.module \headinganchors_filter()

Implementation of hook_filter().

The bulk of filtering work is done here.

File

./headinganchors.module, line 50
This is a module which takes headings and adds id attributes to them to allow them to be linked to in a URL. The following rules are used to create an attribute:

Code

function headinganchors_filter($op, $delta = 0, $format = -1, $text = '') {
  if ($op == 'list') {
    return array(
      0 => t('Headings to Anchors'),
    );
  }

  // We currently only define one filter, so we don't need to switch on $delta
  switch ($op) {

    // Admin interface description
    case 'description':
      return t('Inserts named anchors for heading tags automatically.');
    case 'no cache':
      return FALSE;

    // Need to find out if this is required
    case 'prepare':
      return $text;

    // Here, we pull out the required information and add the anchor
    case 'process':

      // transform headers into anchors, max <h6>, case insensitive
      $matches = array();
      preg_match_all("/<h([1-6])([^>]*)>(.*?)<\\/h[1-6]>/is", $text, $matches, PREG_PATTERN_ORDER);
      $count = 0;
      $anchors = array();
      foreach ($matches[0] as $match) {

        // get level and heading
        $level = $matches[1][$count];
        $attributes = $matches[2][$count];
        $heading = $matches[3][$count];

        // check for existing id and use that if found
        if (preg_match('/id="(.*?)"/i', $attributes, $existing_id)) {
          $anchor = $existing_id[1];

          // remove the existing id, it will be added back later
          $attributes = preg_replace('/\\s*id="(.*?)"\\s*/i', '', $attributes);

          // if no id found, create one
        }
        else {

          // sanitize ID text & remove leading digits (invalid on IDs)
          $anchor = preg_replace("/&amp;/", "", strip_tags($matches[3][$count]));
          $anchor = preg_replace("/[^A-Za-z0-9]/", "", $anchor);
          $anchor = preg_replace("/^[0-9]+/", "", $anchor);
        }

        // Look for duplicate ID's, and add -number to make them unique
        if (array_key_exists($anchor, $anchors)) {
          $anchors[$anchor]++;
        }
        else {
          $anchors[$anchor] = 1;
        }
        if ($anchors[$anchor] > 1) {
          $anchor .= "-" . $anchors[$anchor];
        }
        $pattern = "/<h" . $level . preg_quote($attributes, '/') . ">" . preg_quote($heading, '/') . "<\\/h" . $level . ">/i";

        // append everything together to create the new heading
        $replacement = "<h" . $level . $attributes . " id=\"" . $anchor . "\">" . str_replace('$', '\\$', $heading) . "</h" . $level . ">";

        // replace the header in the text
        // Limit of one so that identical headers are only replaced one at a time
        $text = preg_replace($pattern, $replacement, $text, 1);
        $count++;
      }
      return $text;
  }
}