Auteur: Thomas - 10 februari 2016 - 17:11 - Gekeurd door: Thomas - Hits: 7817 - Aantal punten: (0 stemmen)
De code omvat een functie: generateToC($in, $class='toc'). Deze genereert aan de hand van een HTML-tekst $in op grond van de daarin aanwezige headers (<h1> t/m <h9>) een zogenoemde table of contents, oftewel een inhoudsopgave in de vorm van een (geneste) bulleted list. Deze bulleted list wordt, inclusief een wrapper div met stijlklasse $class (standaard waarde "toc") geretourneerd als string.
Om deze table of contents te genereren moet wel aan een aantal randvoorwaarden voldaan worden:
- de structuur van de HTML in $in moet kloppen, oftewel, de headers mogen te allen tijde maar maximaal met 1 niveau toenemen (eerst een of meer <h1>'s voor hoofdstukken, met hierin weer nul of meer <h2>'s voor paragrafen en hierin weer nul of meer <h3>'s voor subparagrafen et cetera) zoals in een kloppend document het geval is
- de "bookmarks" waarmee aan deze headers gerefereerd wordt moeten al aanwezig zijn in de headers middels een id-attribuut; dit geeft je tevens de vrijheid om de bookmarks zelf een format te geven
<?php
function generateToC($in, $class='toc') {
// Regexp voor het vangen van headers (h1 t/m h9).
preg_match_all('#<h([1-9])([^>]*)>([^<]*)<\/h\1>#', $in, $matches);
// Verzamel gegevens.
$toc = array();
// $matches[0][x] bevat totale header matches
// $matches[1][x] bevat de header nummers
// $matches[2][x] bevat alle overige data van de openingstag van een header, waaronder het id
// $matches[3][x] bevat de tekst tussen de header tags (de header titels)
foreach ($matches[1] as $k => $h) {
// abstraheer het id
$id = 'not found !';
if (preg_match('#id="([^"]*)"#', $matches[2][$k], $match) === 1) {
$id = $match[1];
} else {
// kon id niet uit de header tag vissen - doe iets?
}
$toc[] = array(
'header' => $h,
'title' => $matches[3][$k],
'bookmark' => $id,
);
}
// Bouw de ToC.
$currentDepth = 0;
ob_start(); //vang de HTML op
// Zet er een wrapper omheen
?><div class="<?php echo $class ?>"><?php
foreach ($toc as $i => $data) {
if ($i > 0 && $currentDepth == $data['header']) {
// item op zelfde niveau, sluit eerst vorige tag
?></li><?php
}
if ($data['header'] > $currentDepth) {
// we gaan altijd 1 niveau omhoog als je een hoger header nummer hebt, anders klopt je structuur niet
?><ul><?php
$currentDepth++; // altijd 1 niveau hoger
}
if ($data['header'] < $currentDepth) {
// we gaan weer een of meer niveaus omlaag, sluit deze tags
while ($currentDepth > $data['header']) {
?></li></ul><?php
$currentDepth--;
}
?></li><?php
}
// Noot: ook de bookmarks zouden geldig moeten zijn
?><li><a href="#<?php echo $data['bookmark'] ?>"><?php echo $data['title'] ?></a><?php
}
// sluit het restant
while ($currentDepth > 0) {
?></li></ul><?php
$currentDepth--;
}
// sluit de wrapper
?></div><?php
// retourneer de gegenereerde HTML
return ob_get_clean();
} // einde functie
?>
<?php
function generateToC($in,$class='toc'){
// Regexp voor het vangen van headers (h1 t/m h9).