[英]php: How to convert HTML headings (h2,h3,h4) to nested unordered list?
input array with html headings from a WordPress post来自 WordPress 帖子的 html 标题的输入数组
<?php
$headings = array(
0 => "<h2>Number One</h2>",
1 => "<h2>Number Two</h2>",
2 => "<h2>Number Three</h2>",
3 => "<h3>Number Four</h3>",
4 => "<h2 id='iamanexistingid'>Number Five</h2>",
5 => "<h3>Number Six</h4>",
6 => "<h4>Number Seven</h2>",
7 => "<h2>Number Eight</h2>"
);
Now I want to generate a structure in a nested unordered list.现在我想在嵌套的无序列表中生成一个结构。
Output Output
<ul>
<li>Number One</li>
<li>Number Two</li>
<li>Number Three
<ul>
<li>Number Four</li>
</ul>
<li>Number Five</li>
<li>Number Five
<ul>
<li>Number Six
<ul>
<li>Number Seven</li>
</ul>
</li>
</ul>
</li>
<li>Number Eight</li>
</ul>
Is there simple way to generate this with Simple HTML DOM Parser?有没有简单的方法可以使用简单的 HTML DOM Parser 生成它? Or a trick?还是诡计?
My initial solution does not really work for levels deeper than one level and is not good in general.我最初的解决方案不适用于比一层更深的级别,而且总体上也不好。 I also can't figure out how to handle a H4 following a H3 or a H3 follow a H3.我也无法弄清楚如何处理 H3 之后的 H4 或 H3 之后的 H3。
<?php
$headings = array(
0 => "<h2>H2 Number One</h2>",
1 => "<h2>H2 Number Two</h2>",
2 => "<h2>H2 Number Three</h2>",
3 => "<h3>H3 Number Four</h3>",
4 => "<h2 id='iamanexistingid'>H2 Number Five</h2>",
5 => "<h3>H3 Number Six</h4>",
6 => "<h4>H4 Number Seven</h2>",
7 => "<h3>H3 Number Eight</h2>",
8 => "<h2>H2 Number Nine</h2>"
);
$array = array();
$lastlevel = 2;
foreach ($headings as $key => $value) {
preg_match("/\<(?<name>\w+)(?<attributes>\s+[^>]*|)>/", $value, $matches);
$tagname = $matches[1];
$currentlevel = str_replace("h", "", "$tagname");
if($currentlevel == $lastlevel OR $currentlevel < $lastlevel) {
array_push($array, $value);
} elseif ($currentlevel > $lastlevel) {
array_push($array, [$value]);
}
$lastlevel = $currentlevel;
}
echo printArrayList($array);
function printArrayList($array)
{
echo "<ul>";
foreach($array as $k => $v) {
if (is_array($v)) {
printArrayList($v);
continue;
}
echo "<li>" . $v . "</li>";
}
echo "</ul>";
}
Found an answer myself.自己找到了答案。 Uses code from https://github.com/shazahm1/Easy-Table-of-Contents使用来自https://github.com/shazahm1/Easy-Table-of-Contents的代码
function generateToc($matches) {
$list ='';
$current_depth = 7;
$numbered_items = array();
$numbered_items_min = null;
array_walk($matches,"removelines");
// find the minimum heading to establish our baseline
//for ( $i = 0; $i < count( $matches ); $i ++ ) {
foreach ( $matches as $i => $match ) {
if ( $current_depth > $matches[ $i ][2] ) {
$current_depth = (int) $matches[ $i ][2];
}
}
$numbered_items[ $current_depth ] = 0;
$numbered_items_min = 7;
foreach ( $matches as $i => $match ) {
$level = $matches[ $i ][2];
$count = $i + 1;
if ( $current_depth == (int) $matches[ $i ][2] ) {
$list .= '<li>';
}
// start lists
if ( $current_depth != (int) $matches[ $i ][2] ) {
for ( $current_depth; $current_depth < (int) $matches[ $i ][2]; $current_depth++ ) {
$numbered_items[ $current_depth + 1 ] = 0;
$list .= '<ul><li>';
}
}
$list .= strip_tags($match);
// end lists
if ( $i != count( $matches ) - 1 ) {
if ( $current_depth > (int) $matches[ $i + 1 ][2] ) {
for ( $current_depth; $current_depth > (int) $matches[ $i + 1 ][2]; $current_depth-- ) {
$list .= '</li></ul>';
$numbered_items[ $current_depth ] = 0;
}
}
if ( $current_depth == (int) @$matches[ $i + 1 ][2] ) {
$list .= '</li>';
}
}
}
return '<ul class="toc">' . $list . "</li></ul>";
}
echo generateToc($headings);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.