「PHP Simple HTML DOM Parser」でHTMLファイルの目次を作成

スポンサーリンク

「PHP Simple HTML DOM Parser」を使って、 HTMLファイルの目次を作成する関数を作りました。 WordPress用ではなく、普通のHTMLファイル用の目次を作ります。

最初に「h2 タグのみ」を対象にした目次作成関数を紹介し、 次に「h2 と h3 タグ」を対象にした目次作成関数を紹介します。

h2のみの目次作成

h2のみの目次を作成する関数です。

  • PHPコード
  • HTMLコード(目次作成前)
  • HTMLコード(目次作成後)

の順番で紹介します。

PHPコード: 目次作成関数

引数: HTMLファイル名
戻り値: HTMLコードの文字列

(準備)
HTMLファイルの中に、「id="toc"」のdiv タグを用意しておきます。

<?php

include("./inc/simple_html_dom.php");


function f_add_toc_h2($file_name) {
	
	// simple_html_dom オブジェクト生成 (改行コードも取得)
	$html = file_get_html($file_name, false, null, 1, -1, true, true, DEFAULT_TARGET_CHARSET, false);

	// id = toc
	$toc = $html->find("#toc", 0);
	
	$str_toc = "";   // toc用 文字列

	$c_h2 = 0;       // カウンタ

	foreach( $html->find( 'h2' ) as $h ) {
		
		$c_h2++;
		
		// toc用 liタグ作成
		$str_toc .= "<li><a href=\"#toc-$c_h2\">$h->plaintext</a></li>\n";
		
		// spanタグを埋め込む
		$h->innertext = "<span id=\"toc-$c_h2\">" . $h->innertext . "</span>";

	}

	// div と ol タグで囲む
	$str_toc = "\n<div class=\"toc-content\">\n<ol>\n". $str_toc . "</ol>\n</div>\n";
	
	// 目次タイトル を前に挿入
	$str_toc = "\n<div class=\"toc-title\">目次</div>" . $str_toc;

	// <p id="toc">タグ内にtocを埋め込む
	$toc->innertext = $str_toc;

	//echo $str_toc;

	// 【必要に応じて】  先頭に"<"を付加  
	$html->outertext = "<" . $html->outertext;

	$str = $html->outertext;

	$html->clear();
	
	return $str;
	
}

// 実行例
$file_name = "test.html";
$re = f_add_toc_h2($file_name);

echo "$re";

?>

(注意点)
関数の終盤の方で次のコードがあります。


	// 【必要に応じて】  先頭に"<"を付加  
	$html->outertext = "<" . $html->outertext;

この部分は環境によっては必要ないかもしれませんので、 必要なければコメントアウトしてください。
(file_get_html()の引数次第で、先頭の"<"が付いたり付かなかったりします)

HTMLコード 目次作成前

目次を作成する前のHTMLコードです。


<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>テスト</title>
</head>
<body>
<div id="toc"></div>

<h2>ヘッダー a</h2>
<h3>ヘッダー a-1</h3>

<h2>ヘッダー b</h2>
<h3>ヘッダー b-1</h3>
<h3>ヘッダー b-2</h3>

<h2>ヘッダー c</h2>

</body>

HTMLコード 目次作成後

戻り値として返ってくるHTMLコード文字列です。


<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>テスト</title>
</head>
<body>

<div id="toc">
<div class="toc-title">目次</div>
<div class="toc-content">
<ol>
<li><a href="#toc-1">ヘッダー a</a></li>
<li><a href="#toc-2">ヘッダー b</a></li>
<li><a href="#toc-3">ヘッダー c</a></li>
</ol>
</div>
</div>


<h2><span id="toc-1">ヘッダー a</span></h2>
<h3>ヘッダー a-1</h3>

<h2><span id="toc-2">ヘッダー b</span></h2>
<h3>ヘッダー b-1</h3>
<h3>ヘッダー b-2</h3>

<h2><span id="toc-3">ヘッダー c</span></h2>


</body>

目次部分は次のように、タイトル部分とコンテンツ部分に分かれています。


<div id="toc>
  <div class="toc-title"></div>
  <div class="toc-content"></div>
</div>

h2 と h3 の目次作成

h2 と h3 の目次を作成する関数です。 引数や戻り値、必要な準備は前の関数と同じです。

PHPコード: 目次作成関数

引数: HTMLファイル名
戻り値: HTMLコードの文字列

(準備)
HTMLファイルの中に、「id="toc"」のdiv タグを用意しておきます。

<?php

include("./inc/simple_html_dom.php");

function f_add_toc_h3($file_name) {
	
	// simple_html_dom オブジェクト生成 (改行コードも取得)
	$html = file_get_html($file_name, false, null, 1, -1, true, true, DEFAULT_TARGET_CHARSET, false);

	// id = toc
	$toc = $html->find("#toc", 0);
	
	$str_toc = "";   // toc用 文字列
	$pre_tag = "";   // 前のタグを格納

	$c_h2 = 0;       // h2 カウンタ
	$c_h3 = 0;       // h3 カウンタ
	
	foreach( $html->find( 'h2, h3' ) as $h ) {
		
		if ($h->tag == "h2") {
		// h2 の場合
		
			$c_h2++;
			$c_h3 = 0;  // リセット
			
			// toc用 olタグ
			if ($pre_tag == "h3") $str_toc .= "  </ol>\n";

			$pre_tag = "h2";
			
		} else {
		// h3 の場合
		
			$c_h3++;
			
			// toc用 olタグ
			if ($c_h3 == 1) $str_toc .= "  <ol>\n";

			$str_toc .= "  ";   // liタグ用インデント

			$pre_tag = "h3";
		}
		// toc用 liタグ作成
		$str_toc .= "<li><a href=\"#toc-$c_h2-$c_h3\">$h->plaintext</a></li>\n";
		
		// spanタグを埋め込む
		$h->innertext = "<span id=\"toc-$c_h2-$c_h3\">" . $h->innertext . "</span>";
		
	}
	// <ol>タグを閉じる
	if ($pre_tag == "h3") $str_toc .= "  </ol>\n";

	// div と ol タグで囲む
	$str_toc = "\n<div class=\"toc-content\">\n<ol>\n". $str_toc . "</ol>\n</div>\n";
	
	// 目次タイトル を前に挿入
	$str_toc = "\n<div class=\"toc-title\">目次</div>" . $str_toc;
	
	// <p id="toc">タグ内にtocを埋め込む
	$toc->innertext = $str_toc;

	// 【必要に応じて】  先頭に"<"を付加  
	$html->outertext = "<" . $html->outertext;

	$str = $html->outertext;

	$html->clear();
	
	return $str;
	
}


$file_name = "test.html";
$re = f_add_toc_h3($file_name);

$k = file_put_contents("out.html", $re);
echo "$re";

?>

HTMLコード 目次作成前

目次を作成する前のHTMLコードです。 上と同じHTMLコードを使用します。


<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>テスト</title>
</head>
<body>
<div id="toc"></div>

<h2>ヘッダー a</h2>
<h3>ヘッダー a-1</h3>

<h2>ヘッダー b</h2>
<h3>ヘッダー b-1</h3>
<h3>ヘッダー b-2</h3>

<h2>ヘッダー c</h2>

</body>

HTMLコード 目次作成後

戻り値として返ってくるHTMLコード文字列です。


<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>テスト</title>
</head>
<body>

<div id="toc">
<div class="toc-title">目次</div>
<div class="toc-content">
<ol>
<li><a href="#toc-1-0">ヘッダー a</a></li>
  <ol>
  <li><a href="#toc-1-1">ヘッダー a-1</a></li>
  </ol>
<li><a href="#toc-2-0">ヘッダー b</a></li>
  <ol>
  <li><a href="#toc-2-1">ヘッダー b-1</a></li>
  <li><a href="#toc-2-2">ヘッダー b-2</a></li>
  </ol>
<li><a href="#toc-3-0">ヘッダー c</a></li>
</ol>
</div>
</div>

<h2><span id="toc-1-0">ヘッダー a</span></h2>
<h3><span id="toc-1-1">ヘッダー a-1</span></h3>

<h2><span id="toc-2-0">ヘッダー b</span></h2>
<h3><span id="toc-2-1">ヘッダー b-1</span></h3>
<h3><span id="toc-2-2">ヘッダー b-2</span></h3>

<h2><span id="toc-3-0">ヘッダー c</span></h2>

</body>

赤字の部分が目次で、青字の部分がidを付加したヘッダーです。