You are here

tableofcontents.themes.inc in Table of Contents 7.2

Table of Contents - Versatile system for generating Tables of Contents for fields - themes.

File

tableofcontents.themes.inc
View source
<?php

/**
 * @file
 * Table of Contents - Versatile system for generating Tables of Contents for fields - themes.
 */

/**
 * Theme the output of a table of contents.
 *
 * @param $toc A TOC object with the options, table of contents, headers, and files.
 *
 * @return Rendered HTML to be displayed.
 */
function theme_tableofcontents_toc($variables) {
  $toc = $variables['toc'];

  // TODO: we should only define the id="toc" for the first TOC
  if ($toc['back_to_top']['anchor']) {
    $id = ' id="' . check_plain($toc['back_to_top']['anchor']) . '"';
  }
  else {
    $id = '';
  }
  $output = "<div{$id} class='toc'>\n";
  if ($toc['box']['title'] != '<none>') {

    // TODO: at this time, the hideshow works with all TOCs at once
    $hs = $toc['box']['hide_show'] ? '<span class="toc-toggle-message">&nbsp;</span>' : '';
    $output .= "<div class='toc-title'>" . t($toc['box']['title']) . $hs . "</div>\n";
  }
  $list = $toc['numbering']['method'] == 4 ? 'ol' : 'ul';
  $output .= "<div class='toc-list'>\n<{$list}>\n";
  $has_content = FALSE;

  // Process nested lists.
  $level = $toc['box']['minlevel'];
  if (!isset($toc['header']['h'])) {
    $toc['header']['h'] = array();
  }
  foreach ($toc['header']['h'] as $index => $h) {
    $cur_level = $h->level;
    if ($cur_level >= $toc['box']['minlevel'] && $cur_level <= $toc['box']['maxlevel']) {
      $has_content = TRUE;

      // Be sure to deal with skipping between non-adjacent h levels.
      if ($cur_level > $level) {
        do {
          $output .= "\n<" . $list . ">\n";
          ++$level;
        } while ($cur_level > $level);
      }
      elseif ($cur_level < $level) {
        do {
          $output .= "</li>\n</" . $list . ">\n";
          --$level;
        } while ($cur_level < $level);
        $output .= "</li>\n";
      }
      elseif ($index != 0) {

        // we know that $cur_level == $level here
        // Close list items at the same level (except the very first time)
        $output .= "</li>\n";
      }
      if ($h->number) {
        $number = '<span class="toc-number">' . $h->number . '</span>';
      }
      else {
        $number = '';
      }
      $list_class = 'toc-level-' . ($level - $toc['box']['minlevel'] + 1);
      $title = strip_tags($h->title, $toc['header']['allowed']);

      // insert the li element
      $output .= "\t<li class=\"{$list_class}\">";
      $output .= "<a href=\"#" . $h->ident . "\">" . $number . $title . "</a>";
    }
  }

  // Did we recurse back out? If not, close open lists.
  for (; $level > $toc['box']['minlevel']; --$level) {
    $output .= "</li>\n</" . $list . ">\n";
  }
  $output .= "</li>\n";
  if (!$has_content) {

    // this happens when all the header levels are either too small or too large
    // and if there is no attachment either
    return '';
  }
  $output .= "</" . $list . ">\n</div>\n</div>";
  return theme('tableofcontents_toc_text', array(
    'toc' => $toc,
    'output' => $output,
  ));
}

/**
 * Basic formatting of the text generated by the
 * theme_tableofcontents_toc() function. This is the
 * table of contents in the form of a string.
 *
 * @param $text The text to format
 *
 * @return The resulting text
 */
function theme_tableofcontents_toc_text($variables) {
  return $variables['output'];
}

/*****************************************************************************/

/**
 * PHP Roman Numeral Library
 *
 * Copyright (c) 2008, reusablecode.blogspot.com; some rights reserved.
 *
 * This work is licensed under the Creative Commons Attribution License. To view
 * a copy of this license, visit http://creativecommons.org/licenses/by/3.0/ or
 * send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California
 * 94305, USA.
 *
 * Roman numbers library from
 * http://snipplr.com/view/6314/roman-numerals/
 * http://reusablecode.blogspot.com/search/label/roman%20numerals
 */

// Convert Arabic numerals into Roman numerals.
function _tableofcontents_roman($arabic) {

  //static $fractions = Array("", "�", "��", "���", "����", "�����", "S", "S�", "S��", "S���", "S����", "S�����", "I");
  static $ones = array(
    "",
    "I",
    "II",
    "III",
    "IV",
    "V",
    "VI",
    "VII",
    "VIII",
    "IX",
  );
  static $tens = array(
    "",
    "X",
    "XX",
    "XXX",
    "XL",
    "L",
    "LX",
    "LXX",
    "LXXX",
    "XC",
  );
  static $hundreds = array(
    "",
    "C",
    "CC",
    "CCC",
    "CD",
    "D",
    "DC",
    "DCC",
    "DCCC",
    "CM",
  );
  static $thousands = array(
    "",
    "M",
    "MM",
    "MMM",
    "MMMM",
  );
  if ($arabic > 4999) {

    // For large numbers (five thousand and above), a bar is placed above a base numeral to indicate multiplication by 1000.
    // Since it is not possible to illustrate this in plain ASCII, this function will refuse to convert numbers above 4999.

    //die("Cannot represent numbers larger than 4999 in plain ASCII.");
    return $arabic;
  }
  elseif ($arabic == 0) {

    // About 725, Bede or one of his colleagues used the letter N, the initial of nullae,
    // in a table of epacts, all written in Roman numerals, to indicate zero.
    return "N";
  }
  else {

    // Handle fractions that will round up to 1.

    //if (round(fmod($arabic, 1) * 12) == 12) {

    //  $arabic = round($arabic);

    //}

    // With special cases out of the way, we can proceed.
    // NOTE: modulous operator (%) only supports integers, so fmod() had to be used instead to support floating point.
    $m = fmod($arabic, 1000);
    $roman = $thousands[($arabic - $m) / 1000];
    $arabic = $m;
    $m = fmod($arabic, 100);
    $roman .= $hundreds[($arabic - $m) / 100];
    $arabic = $m;
    $m = fmod($arabic, 10);
    $roman .= $tens[($arabic - $m) / 10];
    $arabic = $m;
    $m = fmod($arabic, 1);
    $roman .= $ones[($arabic - $m) / 1];

    // Handling for fractions.

    //$arabic = $m;

    //if ($arabic > 0) {

    //  $roman .= $fractions[round($arabic * 12)];

    //}
    return $roman;
  }
}

/**
 * Transform a decimal number into a set of letters
 */
function _tableofcontents_letter($number) {
  while ($number > 0) {
    $result = chr($number % 26 + 64) . $result;
    $number = (int) ($number / 26);
  }
  return $result;
}

/**
 * Transform a decimal number in one of:
 *
 * decimal number
 * Roman number
 * letters
 *
 * @param $mode The type of number to transform into
 * @param $number The number to transform
 *
 * @return The result
 */
function _tableofcontents_convert_number($mode, $number) {
  switch ($mode) {
    default:

      //case 0:
      return $number;
    case 1:
      return _tableofcontents_roman($number);
    case 2:
      return drupal_strtolower(_tableofcontents_roman($number));
    case 3:
      return _tableofcontents_letter($number);
    case 4:
      return drupal_strtolower(_tableofcontents_letter($number));
    case 5:
      return sprintf("0x%02x", $number);
  }
}

/**
 * Theme the output of the Back to Top link.
 *
 * This way users can easily add an image instead of using the CSS
 * arrow up as we have in the module.
 *
 * @param $toc A TOC object with the options and levels.
 *
 * @return Rendered HTML to be displayed.
 */
function theme_tableofcontents_back_to_top($variables) {
  $toc = $variables['toc'];
  $label = check_plain($toc['back_to_top']['label']);
  $anchor = check_plain($toc['back_to_top']['anchor']);
  return "<div class='toc-back-to-top'><a href='#{$anchor}'>{$label}</a></div>";
}

/**
 * Theme the output of a multi-level number.
 *
 * @param $toc A TOC object with the options and levels.
 *
 * @return Rendered HTML to be displayed.
 */
function theme_tableofcontents_number($variables) {
  $toc = $variables['toc'];
  $result = '';
  switch ($toc['numbering']['method']) {
    case 0:

    // no numbering
    case 4:

      // numbering by browser
      return '';
    case 1:

      // "regular" (like <ol>)
      $result = _tableofcontents_convert_number($toc['numbering']['mode'], $toc['header']['counters'][$toc['header']['level_to']]);
      break;
    case 2:
    case 3:

      // 1., 1.1, 1.2, 2., 2.1, 2.2, ...
      $mode = $toc['numbering']['mode'];
      $result = _tableofcontents_convert_number($mode, $toc['header']['counters'][$toc['header']['level_from']]);
      for ($idx = $toc['header']['level_from'] + 1; $idx <= $toc['header']['level_to']; ++$idx) {
        $result .= $toc['numbering']['separator'] . _tableofcontents_convert_number($mode, $toc['header']['counters'][$idx]);
      }
      if ($toc['numbering']['method'] == 3 && $toc['header']['level_from'] == $toc['header']['level_to']) {
        $result .= $toc['numbering']['separator'] . _tableofcontents_convert_number($mode, 0);
      }
      break;
  }

  // we add a space at the end (before the title)
  $output = $toc['numbering']['prefix'] . $result . $toc['numbering']['suffix'] . ' ';
  return theme('tableofcontents_number_text', $output);
}

/**
 * Basic formatting of the text generated by the
 * theme_tableofcontents_number() function. This is the
 * number in the form of a string.
 *
 * @param $text The text to format
 *
 * @return The resulting text
 */
function theme_tableofcontents_number_text($variables) {
  return $variables['text'];
}

Functions

Namesort descending Description
theme_tableofcontents_back_to_top Theme the output of the Back to Top link.
theme_tableofcontents_number Theme the output of a multi-level number.
theme_tableofcontents_number_text Basic formatting of the text generated by the theme_tableofcontents_number() function. This is the number in the form of a string.
theme_tableofcontents_toc Theme the output of a table of contents.
theme_tableofcontents_toc_text Basic formatting of the text generated by the theme_tableofcontents_toc() function. This is the table of contents in the form of a string.
_tableofcontents_convert_number Transform a decimal number in one of:
_tableofcontents_letter Transform a decimal number into a set of letters
_tableofcontents_roman