function _collapse_text_process_recurse_levels in Collapse Text 7.2
Same name and namespace in other branches
- 6.2 collapse_text.module \_collapse_text_process_recurse_levels()
translate the flat levels array into a tree.
this function is recursive.
1 call to _collapse_text_process_recurse_levels()
- _collapse_text_filter_process in ./
collapse_text.module - Implements hook_filter_FILTER_process().
File
- ./
collapse_text.module, line 346 - collapse_text is an input filter that allows text to be collapsible
Code
function _collapse_text_process_recurse_levels($string, $string_start, $string_end, $elements, $options) {
$text_start = $string_start;
$text_length = $string_end - $string_start;
$child_start = $string_start;
$child_end = $string_end;
$slice_start = -1;
$slice_end = count($elements);
// find the first start element
$elt_start_found = FALSE;
$elt_start = 0;
while (!$elt_start_found and $elt_start < count($elements)) {
if ($elements[$elt_start]['type'] == 'start') {
$elt_start_found = TRUE;
}
else {
$elt_start++;
}
}
if ($elt_start_found) {
// if there is an opening element, set the text length to everything up to it
$text_length = $elements[$elt_start]['start'] - $string_start;
$child_start = $elements[$elt_start]['end'];
$slice_start = $elt_start + 1;
}
else {
// otherwise, return everything in this segment as a string
return array(
array(
'type' => 'text',
'value' => substr($string, $text_start, $text_length),
),
);
}
// find the next end element at the same level
$elt_end_found = FALSE;
$elt_end = $elt_start;
while (!$elt_end_found and $elt_end < count($elements)) {
if ($elements[$elt_end]['type'] == 'end' and $elements[$elt_end]['level'] == $elements[$elt_start]['level']) {
$elt_end_found = TRUE;
}
else {
$elt_end++;
}
}
if ($elt_end_found) {
$child_end = $elements[$elt_end]['start'];
$slice_length = $elt_end - $slice_start;
}
else {
// there is a matching failure
// try skipping the start element...
if ($elt_start + 1 < count($elements)) {
return _collapse_text_process_recurse_levels($string, $string_start, $string_end, array_slice($elements, $elt_start + 1), $options);
}
else {
// fall back to just returning the string...
$text_length = $string_end - $text_start;
// reset the text length
return array(
array(
'type' => 'text',
'value' => substr($string, $text_start, $text_length),
),
);
}
}
$parts = array();
// add the text before the opening element
$parts[] = array(
'type' => 'text',
'value' => substr($string, $text_start, $text_length),
);
// add the child element
$parts[] = array(
'type' => 'child',
'tag' => $elements[$elt_start]['tag'],
'value' => _collapse_text_process_recurse_levels($string, $child_start, $child_end, array_slice($elements, $slice_start, $slice_length), $options),
);
// tail recurse (which ideally could be optimized away, although it won't be...) to handle
// any siblings
$parts = array_merge($parts, _collapse_text_process_recurse_levels($string, $elements[$elt_end]['end'], $string_end, array_slice($elements, $elt_end), $options));
// return the result
return $parts;
}