-エンコーダー、ヘッダーの順序が厳密でない場合はどうしますか?
-何? どう?
-h1が移動し、テキストh2、h3、再びh2、h1、h2、h3、h4に移動すると想像してください。 これは厳密な順序です。なぜなら、 下位レベルの見出しは、厳密に親に従います。 ここで、h2の後、テキストはh3ではなくh4またはh6に続くと想像してください! そして、h6、h4などの後、イコライザーのように。
ここで私は冷たい汗で覆われました。 「まあ」、「これはありえない」と思う。 私は顧客に確認することにしました! これは可能です!..
コードの最初の行は次のとおりです。
$description = preg_replace("/<(p|[hH](10|[1-9]))>(<[hH](10|[1-9]).*?>(.*?)<\/[hH](10|[1-9])>)<\/(p|[hH](10|[1-9]))>/", "$3", $description);
彼女はすぐにはリーダーになりませんでしたが、wysiwygエディターにはないh7-h10ヘッダーを挿入できるという要件が追加された後に登場しました。 このために、独自の魔法が作成されました。その結果、タイトルタグを段落で囲むことができる状況になりました。 ここに指定された行があり、このまさに段落(pタグ)を削除します。
次に、$ items配列内のテキストにあるすべてのヘッダーを配列に収集します
preg_match_all("/<[hH](10|[1-9]).*?>(.*?)<\/[hH](10|[1-9])>/", $description, $items);
そして、カルーセルが始まります。 まず、目次全体を開く必要があります。
$menu = "{";
次に、見出しの下で大きなサイクルが開始され、そこに飛び込みます:
for ($i = 0; $i < count($items[0]); $i++) {...}
まず、ヘッダーのテキストを取得して、タグやその他の殻を削除する必要があります。 replaceH1Symbols関数は、一部のhtmlエンティティを特殊文字に置き換えます (たとえば、<turns into ")。 stripTagsプロパティには、このような通常の
/<\/?[^>]+>|\&[az]+;|\'|"/
$name = preg_replace($this->stripTags, "", trim(html_entity_decode($this->replaceH1Symbols($items[2][$i]), ENT_QUOTES)));
名前を受け取ったら、そのリンクを作成します。
$link = preg_replace($this->symbols, "", strtolower($name)); $link = preg_replace($this->spaces, "-", $link);
、 symbolsプロパティはすべての破壊文字(引用符、角かっこ、アポストロフィ、句読点など)を格納し、 スペースではすべてがスペースに見えます。リンク内にあるべきではないためです。
そのため、リンクがあります。 次に、テキスト内にそのようなリンクが既にあるかどうかを確認する必要があります。 実際、テキストには同じ見出しが含まれている場合があります。 そのようなリンクがあり、おそらくそれだけではない場合は、新しいリンクにシリアル番号を割り当てる必要があります
$repeatCount = count(array_keys($usedItem, $name)); if ($repeatCount > 0) { $link .= "-" . ($repeatCount + 1); }
if ($i == 0) { $menu .= '"' . $i . '": {'; $menu .= '"title": "' . $name . '",'; $menu .= '"link": "' . $link . '"'; }
始まりの場合、すべてがうまくいきますが、そうでない場合は? 現在のヘッダーのレベルが前のヘッダー(たとえば、前のh2、現在のh4)よりも大きいかどうかを確認します。 おそらくこの言い回しは完全に正しいわけではありませんが、hに近い数字から始めて、多かれ少なかれ書いています。
elseif ($i != 0 && $items[1][$i] > $items[1][$i - 1]) {
その場合、これらのヘッダー間の差を計算する必要があります。
$quantity = $items[1][$i] - $items[1][$i - 1];
子サブメニューを開きます
$menu .= ', "subItems": {';
次に、前の見出しがあるレベルを記録します。 順序が小さい場合(2 <4)、現在のヘッダーの親になります。
array_push($parentItem, (int)$items[1][$i - 1]);
そして、内部要素の総数を書きます:
$subItemsCount += $quantity;
次に、存在しないこれらの非常に内部的な要素のネストサイクルを開始します。
for ($j = 1; $j <= $quantity - 1; $j++) { $menu .= "\"" . $j . "\":{"; $menu .= '"subItems": {'; array_push($parentItem, $items[1][$i - 1] + $j); }
そして、最後にヘッダーを挿入します
$menu .= '"' . $i . '": {'; $menu .= '"title": "' . $name . '",'; $menu .= '"link": "' . $link . '"'; }
elseif ($i != 0 && $items[1][$i] < $items[1][$i - 1]) {
次に、ヘッダー間の差を計算し、 subItemsCountがある場合は、以前に開いたすべての内部要素を閉じる必要があります。 なぜ2倍するのかと尋ねますか? 信じて、ただ信じて。 これは魔法であり、かつては説明がありましたが、今では開き/閉じ中括弧のペアに関する神話で覆われています。
$quantity = $items[1][$i - 1] - $items[1][$i]; $menu .= "}"; if ($subItemsCount) { for ($j = 1; $j <= $quantity * 2; $j++) { $menu .= "}"; if ($j % 2 == 0) { $subItemsCount--; array_pop($parentItem); } } }
そして現在のタイトルを挿入します
$menu .= ', "' . $i . '": {'; $menu .= '"title": "' . $name . '",'; $menu .= '"link": "' . $link . '"'; }
else { $menu .= '}, "' . $i . '": {'; $menu .= '"title": "' . $name . '",'; $menu .= '"link": "' . $link . '"'; }
if (!array_key_exists($i + 1, $items[1])) { $a = $items[1][$i]; $lastParent = array_shift($parentItem); if ($lastParent && $lastParent < $a) { for ($q = 0; $q <= ($a - $lastParent) * 2; $q++) { $menu .= "}"; } } else { $menu .= "}"; } }
そして、使用する名前の配列に名前を入れることを忘れないでください:
$usedItem[] = $name;
$menu .= "}";
それだけです 目次はすぐに使用できます。 ヘッダー自体にアンカーを配置するのはテキストのみです。