__NAMESPACE__ . '\\render_callback'
]);
}
add_action( 'init', 'register_simpletoc_block' );
/**
* Filter to add plugins to the TOC list for Rank Math plugin
*
* @param array TOC plugins.
*/
add_filter('rank_math/researches/toc_plugins', function ($toc_plugins) {
$toc_plugins['simpletoc/plugin.php'] = 'SimpleTOC';
return $toc_plugins;
});
/**
* Render block output
*
*/
function render_callback( $attributes )
{
//add only if block is used in this post.
add_filter('render_block', __NAMESPACE__ . '\\filter_block', 10, 2);
$alignclass = '';
if ( isset ($attributes['align']) ) {
$align = $attributes['align'];
$alignclass = 'align' . $align;
}
$className = '';
if ( isset( $attributes['className'] ) ) {
$className = strip_tags(htmlspecialchars($attributes['className']));
}
$post = get_post();
$blocks = parse_blocks($post->post_content);
if (empty($blocks)) {
$html = '';
if ($attributes['no_title'] == false) {
$html = '
' . __('Table of Contents2', 'simpletoc') . '
';
}
$html .= '' . __('No blocks found.', 'simpletoc') . ' ' . __('Save or update post first.', 'simpletoc') . '
';
return $html;
}
$headings = array_reverse(filter_headings_recursive($blocks));
$headings_clean = array_map('trim', $headings);
if (empty($headings_clean)) {
$html = '';
if ($attributes['no_title'] == false) {
$html = '' . __('Table of Contents', 'simpletoc') . '
';
}
$html .= '' . __('No headings found.', 'simpletoc') . ' ' . __('Save or update post first.', 'simpletoc') . '
';
return $html;
}
$output = generateToc($headings_clean, $attributes);
$pre_html = '';
$post_html = '
';
$output = $pre_html . $output . $post_html;
return $output;
}
/**
* Return all headings with a recursive walk through all blocks.
* This includes groups and reusable block with groups within reusable blocks.
*/
function filter_headings_recursive($blocks)
{
$arr = array();
foreach ($blocks as $block => $innerBlock) {
if (is_array($innerBlock)) {
if (isset($innerBlock['attrs']['ref'])) {
// search in reusable blocks
$e_arr = parse_blocks(get_post($innerBlock['attrs']['ref'])->post_content);
$arr = array_merge(filter_headings_recursive($e_arr), $arr);
} else {
// search in groups
$arr = array_merge(filter_headings_recursive($innerBlock), $arr);
}
} else {
if (isset($blocks['blockName']) && $blocks['blockName'] === 'core/heading' && $innerBlock !== 'core/heading') {
// make sure its a headline.
if (preg_match("/(' . __('Support', 'simpletoc') . ''));
$links = array_merge($links, array('' . __('Donate', 'simpletoc') . ''));
$links = array_merge($links, array('' . __('Write a review', 'simpletoc') . ' ⭐️⭐️⭐️⭐️⭐️'));
}
return $links;
}
function addAnchorAttribute($html)
{
// remove non-breaking space entites from input HTML
$html_wo_nbs = str_replace(" ", " ", $html);
// Thank you Nick Diego
if (!$html_wo_nbs) {
return $html;
}
libxml_use_internal_errors(TRUE);
$dom = new \DOMDocument();
@$dom->loadHTML($html_wo_nbs, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
// use xpath to select the Heading html tags.
$xpath = new \DOMXPath($dom);
$tags = $xpath->evaluate("//*[self::h1 or self::h2 or self::h3 or self::h4 or self::h5 or self::h6]");
// Loop through all the found tags
foreach ($tags as $tag) {
// Set id attribute
$heading_text = strip_tags($html);
$anchor = simpletoc_sanitize_string($heading_text);
$tag->setAttribute("id", $anchor);
}
// Save the HTML changes
$content = utf8_decode($dom->saveHTML($dom->documentElement));
return $content;
}
function filter_block($block_content, $block)
{
$className = '';
if ($block['blockName'] !== 'core/heading') {
return $block_content;
}
$block_content = addAnchorAttribute($block_content);
return $block_content;
}
function generateToc($headings, $attributes)
{
$list = '';
$html = '';
$min_depth = 6;
$listtype = 'ul';
$absolute_url = '';
$inital_depth = 6;
$link_class = '';
$styles = '';
if ($attributes['remove_indent'] == true) {
$styles = 'style="padding-left:0;list-style:none;"';
}
if ($attributes['add_smooth'] == true) {
$link_class = 'class="smooth-scroll"';
}
if ($attributes['use_ol'] == true) {
$listtype = 'ol';
}
if ($attributes['use_absolute_urls'] == true) {
$absolute_url = get_permalink();
}
foreach ($headings as $line => $headline) {
if ($min_depth > $headings[$line][2]) {
// search for lowest level
$min_depth = (int) $headings[$line][2];
$inital_depth = $min_depth;
}
}
foreach ($headings as $line => $headline) {
$title = strip_tags($headline);
$link = simpletoc_sanitize_string($title);
$this_depth = (int) $headings[$line][2];
if (isset($headings[$line + 1][2])) {
$next_depth = (int) $headings[$line + 1][2];
} else {
$next_depth = '';
}
// skip this heading because a max depth is set.
if ($this_depth > $attributes['max_level'] or strpos($headline, 'class="simpletoc-hidden') > 0) {
goto closelist;
}
// start list
if ($this_depth == $min_depth) {
$list .= "
\n";
} else {
// we are not as base level. Start opening levels until base is reached.
for ($min_depth; $min_depth < $this_depth; $min_depth++) {
$list .= "\n\t\t<" . $listtype . ">\n";
}
}
$list .= "" . $title . "";
closelist:
// close lists
// check if this is not the last heading
if ($line != count($headings) - 1) {
// do we need to close the door behind us?
if ($min_depth > $next_depth) {
// If yes, how many times?
for ($min_depth; $min_depth > $next_depth; $min_depth--) {
$list .= "" . $listtype . ">\n";
}
}
if ($min_depth == $next_depth) {
$list .= "";
}
// last heading
} else {
for ($inital_depth; $inital_depth < $this_depth; $inital_depth++) {
$list .= "" . $listtype . ">\n";
}
}
}
if ($attributes['no_title'] == false) {
$html = "" . __("Table of Contents", "simpletoc") . "
";
}
$html .= "<" . $listtype . " class=\"simpletoc-list\" " . $styles .">\n" . $list . "" . $listtype . ">";
return $html;
}