table of contents (toc) generator
Auteur: Thomas - 10 februari 2016 - 17:11 - Gekeurd door: Thomas - Hits: 7681 - 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
|
Code: |
De functie:
<?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). // Verzamel gegevens. // $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? } 'header' => $h, 'title' => $matches[3][$k], 'bookmark' => $id, ); } // Bouw de ToC. $currentDepth = 0; // 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 } // einde functie ?>
Voorbeeld van invoer:
<h1 id="1-introductie">1. Introductie</h1>
<h2 id="1.1-inleiding">1.1 Inleiding</h2>
<p>Blablabla</p>
<h3 id="1.1.1-subparagraaf">1.1.1 Subparagraaf</h3>
<p>Blablabla</p>
<h2 id="1.2-nogwat">1.2 Nog wat</h2>
<p>Lalalalal</p>
<h1 id="2-meer">2. Meer</h1>
<h2 id="2-1-vervolg">2.1 Vervolg</h2>
<p>Lalalalal</p>
<h3 id="2-1-1-enzo">2.1.1 Enzo</h3>
<p>Lalalalal</p>
<h4 id="2-1-1-1-edoch">2.1.1.1 Edoch</h4>
<p>Lalalalal</p>
<h3 id="2-1-2-maar">2.1.2 Maar</h3>
<p>Lalalalal</p>
<h2 id="2-2-en-ook">2.2 En ook</h2>
<p>Lalalalal</p>
<h1 id="3-dus">3. Dus</h1>
<p>Lalalalal</p>
<h1 id="1-introductie">1. Introductie </h1> <h2 id="1.1-inleiding">1.1 Inleiding </h2> <h3 id="1.1.1-subparagraaf">1.1.1 Subparagraaf </h3> <h2 id="1.2-nogwat">1.2 Nog wat </h2> <h1 id="2-meer">2. Meer </h1> <h2 id="2-1-vervolg">2.1 Vervolg </h2> <h3 id="2-1-1-enzo">2.1.1 Enzo </h3> <h4 id="2-1-1-1-edoch">2.1.1.1 Edoch </h4> <h3 id="2-1-2-maar">2.1.2 Maar </h3> <h2 id="2-2-en-ook">2.2 En ook </h2> <h1 id="3-dus">3. Dus </h1>
Voorbeeld van gegenereerde uitvoer (enigszins gefatsoeneerd):
<div class="toc">
<ul>
<li><a href="#1-introductie">1. Introductie</a><ul>
<li><a href="#1.1-inleiding">1.1 Inleiding</a><ul>
<li><a href="#1.1.1-subparagraaf">1.1.1 Subparagraaf</a></li>
</ul></li>
<li><a href="#1.2-nogwat">1.2 Nog wat</a></li>
</ul></li>
<li><a href="#2-meer">2. Meer</a><ul>
<li><a href="#2-1-vervolg">2.1 Vervolg</a><ul>
<li><a href="#2-1-1-enzo">2.1.1 Enzo</a><ul>
<li><a href="#2-1-1-1-edoch">2.1.1.1 Edoch</a></li>
</ul></li>
<li><a href="#2-1-2-maar">2.1.2 Maar</a></li>
</ul></li>
<li><a href="#2-2-en-ook">2.2 En ook</a></li>
</ul></li>
<li><a href="#3-dus">3. Dus</a></li>
</ul>
</div>
<li><a href="#1-introductie">1. Introductie </a><ul> <li><a href="#1.1-inleiding">1.1 Inleiding </a><ul> <li><a href="#1.1.1-subparagraaf">1.1.1 Subparagraaf </a></li> <li><a href="#1.2-nogwat">1.2 Nog wat </a></li> <li><a href="#2-meer">2. Meer </a><ul> <li><a href="#2-1-vervolg">2.1 Vervolg </a><ul> <li><a href="#2-1-1-enzo">2.1.1 Enzo </a><ul> <li><a href="#2-1-1-1-edoch">2.1.1.1 Edoch </a></li> <li><a href="#2-1-2-maar">2.1.2 Maar </a></li> <li><a href="#2-2-en-ook">2.2 En ook </a></li> <li><a href="#3-dus">3. Dus </a></li>
Download code (.txt)
|
|
Stemmen |
Niet ingelogd. |
|