How to get level 3 headings in TOC extension? #544
-
Hi,
And so on... |
Beta Was this translation helpful? Give feedback.
Replies: 14 comments
-
It should be easy enough to modify the extension in order to show the headings up to a certain (configurable) level. As soon as I have some minutes I will try! |
Beta Was this translation helpful? Give feedback.
-
More or less it works, but <?php
// modified TOC extension, https://github.com/datenstrom/yellow-extensions/tree/master/source/toc
class YellowToc {
const VERSION = "0.8.5";
public $yellow; // access to API
// Handle initialisation
public function onLoad($yellow) {
$this->yellow = $yellow;
$this->yellow->system->setDefault("tocLevel", "3"); // shows headings up to nth level
$this->yellow->system->setDefault("tocNumbering", "1"); // if 0 numbers are not added before headings
}
// Handle page content in HTML format
public function onParseContentHtml($page, $text) {
$callback = function ($matches) use ($page) {
$output = "<ul class=\"toc\">\n";
$location = $page->getPage("main")->getLocation(true);
$rawData = $page->getPage("main")->parserData;
preg_match_all("/<h(\d) id=\"([^\"]+)\">(.*?)<\/h\d>/i", $rawData, $matches, PREG_SET_ORDER);
$levelNumbers = array_fill(2, 5, 0);
$compoundNumber = "";
foreach ($matches as $match) {
if ($match[1] > 1 && $match[1] <= $this->yellow->system->get("tocLevel")) {
if ($this->yellow->system->get("tocNumbering")) {
$levelNumbers[(int)$match[1]] += 1;
for ($i = $match[1]+1; $i <= 6; $i++) {
$levelNumbers[$i] = 0;
}
$compoundNumber = implode(".", array_slice($levelNumbers, 0, $match[1]-1)).". ";
}
$class = $match[1] == 2 ? "" : " class=\"".str_repeat("sub", $match[1]-2)."item\"";
$output .= "<li$class><a href=\"$location#$match[2]\">$compoundNumber$match[3]</a></li>\n";
}
}
$output .= "</ul>\n";
return $output;
};
return preg_replace_callback("/<p>\[toc\]<\/p>\n/i", $callback, $text);
}
} |
Beta Was this translation helpful? Give feedback.
-
I answer to myself: h4..h6 are intentionally not given an automatic id in lines 3927 and 3937 of markdown.php:
@markseu is there a compelling reason for this? or could this limitation be lifted? |
Beta Was this translation helpful? Give feedback.
-
TOC and Markdown work together, it's not a limitation rather that they work hand in hand. |
Beta Was this translation helpful? Give feedback.
-
If the above lines in markdown.php were |
Beta Was this translation helpful? Give feedback.
-
Thank you very much for your interest in the topic and for trying to solve it. 👍😉 In that version of the extension, I had everything classed well, and now I don't know how to keep it that nice. |
Beta Was this translation helpful? Give feedback.
-
I updated the Markdown extension for you, so that you can experiment with more headings. |
Beta Was this translation helpful? Give feedback.
-
@markseu Thank you very much! @kanbeq Now if you update your markdown.php extension and use the code that I posted as a modified toc.php extension, you should get what you wish. Remark that you have to adjust in system.ini these two new settings (if you leave the default values, the new toc should behave exactly like the old one!):
If all seems OK, in the next days I will publish this modified toc (or I will propose as a modification of the old toc, if the core developers prefer this). |
Beta Was this translation helpful? Give feedback.
-
My point is that the previous version did differentiate between the level of headers (so I could set the padding for lower levels in css), and in your version I can't do that. And I don't know why my previous comment was deleted. Edit: Thanks to markdown tweak by markseu, I was able to add a case to the old extension. And thanks to that, I have 3 TOC levels sufficient <?php
// TOC extension, https://github.com/datenstrom/yellow-extensions/tree/master/source/toc
class YellowToc {
const VERSION = "0.8.5";
public $yellow; // access to API
// Handle initialisation
public function onLoad($yellow) {
$this->yellow = $yellow;
}
// Handle page content in HTML format
public function onParseContentHtml($page, $text) {
$callback = function ($matches) use ($page) {
$output = "<ul class=\"toc\">\n<details>\n<summary>TOC</summary>\n";
$major = $minor = $lower = 0;
$location = $page->getPage("main")->getLocation(true);
$rawData = $page->getPage("main")->parserData;
preg_match_all("/<h(\d) id=\"([^\"]+)\">(.*?)<\/h\d>/i", $rawData, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
switch ($match[1]) {
case 2: ++$major; $minor = $lower = 0;
$output .= "<li><a href=\"$location#$match[2]\">$major. $match[3]</a></li>\n";
break;
case 3: ++$minor; $lower = 0;
$output .= "<li class=\"subitem\"><a href=\"$location#$match[2]\">$major.$minor. $match[3]</a></li>\n";
break;
case 4: ++$lower;
$output .= "<li class=\"subsubitem\"><a href=\"$location#$match[2]\">$major.$minor.$lower $match[3]</a></li>\n";
break;
}
}
$output .= "</details>\n</ul>\n";
return $output;
};
return preg_replace_callback("/<p>\[toc\]<\/p>\n/i", $callback, $text);
}
} |
Beta Was this translation helpful? Give feedback.
-
You are right, I overlooked the CSS classes in my version. It would be easy to add them [Edit: I just did it], but your modification solves your needs. Perhaps the following two lines should be corrected like this? case 2: ++$major; $minor = $lower = 0;
case 3: ++$minor; $lower = 0; |
Beta Was this translation helpful? Give feedback.
-
Yes you are right. I just noticed it a moment ago |
Beta Was this translation helpful? Give feedback.
-
Hi, I've also been experimenting with modifying the TOC extension! I have been trying to make sub-headings into nested lists, so
would be rendered as
and look like
I tried to figure it out, but I can't actually code. So instead I resorted to styling sub-headings with CSS. However, I think this is how it might work:
The numbered list setting could be greatly simplified by wrapping the list in Any help would be greatly appreciated. I'll also update here if I figure it out by myself. Update: Done! I used the settings from @GiovanniSalmeri's version, but used I had an absolute blast doing this! I learned a lot about for loops. |
Beta Was this translation helpful? Give feedback.
-
Oh this could have been me. I remember there was more information and I converted GitHub issues into GitHub discussions at that time. Can't remember how many, it was a few hundreds that I converted and edited at that time. If something got lost, it's 100% certain that I am to blame. Sorry about that. Today I found your comment and I personally like the solution with the additional CSS classes. It's small and customisable. GitHub uses a similar solution in their TOC for Markdown files. I would be interested to add this to the existing toc extension. Any thoughts? |
Beta Was this translation helpful? Give feedback.
-
The toc extension now supports all headings (h2-h6) and additional CSS classes. |
Beta Was this translation helpful? Give feedback.
More or less it works, but
tocLevel
cannot currently exceed 3, because h4..h6 are not given an id (I do not know why...).