function tableofcontents_filter in Table of Contents 5.2
Same name and namespace in other branches
- 5 tableofcontents.module \tableofcontents_filter()
- 6.3 tableofcontents.module \tableofcontents_filter()
- 6.2 tableofcontents.module \tableofcontents_filter()
Implementation of hook_filter().
File
- ./
tableofcontents.module, line 74 - This is a filter module to generate a collapsible jquery enabled mediawiki style table of contents based on <h[1-6]> tags. Transforms header tags into named anchors.
Code
function tableofcontents_filter($op, $delta = 0, $format = -1, $text = '') {
if ($op == 'list') {
return array(
0 => t('Table of Contents'),
);
}
global $toc_options;
switch ($op) {
case 'description':
return t('Inserts a table of contents in the place of <!--tableofcontents--> tags.');
case 'no cache':
return FALSE;
case 'settings':
return _tableofcontents_settings($format);
case 'prepare':
// get all toc markers and options
preg_match_all('!<\\!-- ?tableofcontents(.*)-->!', $text, $options_str, PREG_PATTERN_ORDER);
// to optimize performance enclose preparation in conditional that tests for presence of ToC marker
if (!empty($options_str[0]) && $options_str[0][0] != "") {
// Set defaults.
$toc_options = array();
// We save a translate call and only translate this when we process the options.
$toc_options["title"] = variable_get('tableofcontents_title_' . $format, 'Table of Contents');
$toc_options["list"] = variable_get('tableofcontents_list_type_' . $format, 'ol');
$toc_options["minlevel"] = variable_get('tableofcontents_minlevel_' . $format, 2);
$toc_options["maxlevel"] = variable_get('tableofcontents_maxlevel_' . $format, 3);
$toc_options["attachments"] = variable_get('tableofcontents_attachments_' . $format, FALSE);
// Only process options if user arguments were specified and are allowed.
if (variable_get('tableofcontents_allow_override_' . $format, TRUE) && count($options_str, 1) > 2) {
// parse separate options
preg_match_all('/([A-z]+): ?([A-z0-9 ]+);/', $options_str[1][0], $options, PREG_PATTERN_ORDER);
// make sure arguments contain valid option identifiers
$allowed_options = array_keys($toc_options);
for ($i = 0; $i < sizeof($options[1]); $i++) {
if (!in_array($options[1][$i], $allowed_options)) {
form_set_error("Table of Contents", t("Table of Contents Error: " . $options[1][$i] . " is an invalid option."));
}
else {
$toc_options[$options[1][$i]] = $options[2][$i];
}
}
// validate option values, use defaults for invalid values, build & display error message
$error_status = false;
if ($toc_options["list"] != "ol" && $toc_options["list"] != "ul") {
$error_message[] = $toc_options["list"] . " is an invalid list type. The only valid values for list are 'ol' or 'ul'. Using default value of ol.\n";
$error_status = true;
$toc_options["list"] = "ol";
}
if (!($toc_options["minlevel"] >= 1 && $toc_options["minlevel"] < 6)) {
$error_message[] = $toc_options["minlevel"] . " is an invalid minimum level option. You must use a number between 1 and 4. Using default value of 1.\n";
$error_status = true;
$toc_options["minlevel"] = 1;
}
if (!($toc_options["maxlevel"] >= $toc_options["minlevel"] && $toc_options["maxlevel"] <= 6)) {
$error_message[] = $toc_options["maxlevel"] . " is an invalid maximum depth option. You must use a number between " . $toc_options["minlevel"] . " and 5. Using default value of 3.";
$error_status = true;
$toc_options["maxlevel"] = 3;
}
if (!($toc_options["attachments"] == 1 || $toc_options["attachments"] == 0)) {
$error_message[] = t("!attachments is an invalid attachments option. Attachments option must be set to '1' to display or '0' to hide.", array(
'!attachments' => $toc_options["attachments"],
));
$error_status = true;
}
if ($error_status) {
// According to IRC, there can be issues with translations when you use dynamic variables
// As well, t() should only be on single paragraphs with no newlines.
// within t().
foreach ($error_message as $message) {
form_set_error("Table of Contents", t('%error', array(
'%error' => $message,
)));
}
}
}
// Translate title.
$toc_options["title"] = t($toc_options["title"]);
}
return $text;
case 'process':
// to optimize performance enclose processing in conditional that tests for the presence of the toc marker options
if (isset($toc_options)) {
//build the toc
// toc(array('level' => 1, 'heading' => $text))
$toc = array();
// $i = index of header level being processed
// $matches[0][$i] -> Whole string matched
// $matches[1][$i] -> First heading level
// $matches[2][$i] -> Whole string of attributes
// $matches[3][$i] -> id attibute, used for anchor
// $matches[4][$i] -> Text of id attribute
// $matches[5][$i] -> Text inside of h tag
// $matches[6][$i] -> Close heading level, should be equal to open level
$matches = array();
//get all headers of current level, case insensitive
$pattern = '/<h([' . $toc_options["minlevel"] . '-' . $toc_options["maxlevel"] . '])( .*?(id="([^"]+)" ?.*?))?>(.*?)<\\/h([' . $toc_options["minlevel"] . '-' . $toc_options["maxlevel"] . '])>/is';
preg_match('!<\\!-- ?tableofcontents(.*)-->!', $text, $matches, PREG_OFFSET_CAPTURE);
$heading_search_text = substr($text, $matches[0][1]);
$matches = array();
preg_match_all($pattern, $heading_search_text, $matches, PREG_PATTERN_ORDER);
$anchors = array();
for ($i = 0; $i < sizeof($matches[0]); $i++) {
// Strip HTML and non alphanumerics
$level = $matches[1][$i];
$heading = strip_tags($matches[5][$i]);
$anchor = $matches[4][$i];
array_push($toc, array(
'level' => $level,
'heading' => $heading,
'anchor' => $anchor,
));
}
// If attachments are enabled, prepare the $files variable
if ($toc_options["attachments"]) {
$nid = explode('/', $_GET['q']);
if (isset($nid[0]) && $nid[0] == 'node' && isset($nid[1]) && is_numeric($nid[1])) {
$nid = $nid[1];
$node = node_load($nid);
}
if (!empty($node->files)) {
$files = $node->files;
}
}
// Build HTML for the Table of Contents.
$toc_html = theme('tableofcontents_toc', $toc, $toc_options, $files);
// replace all tableofcontents markers with generated ToC html
return preg_replace('!<\\!-- ?tableofcontents(.*)-->!', $toc_html, $text);
}
else {
return $text;
}
}
}