RegexFor プラグインを利用してブログ記事の目次を生成する方法

Posted by
ぴろり
Posted at
2014/10/30 19:38
Trackbacks
関連記事 (0)
Post Comment
コメントできます
Category
プラグイン カテゴリ
カバーイメージ

 指定したパターンにマッチした文字列を処理する RegexFor プラグインを利用すると、例えば、ブログ記事内から h* タグを抽出して、目次を自動生成することができます。目的のヘッダにリンクするような目次を生成する場合、アンカー文字列を適切に設定するために、テンプレートにもう一工夫が必要です。このエントリでは、RegexFor プラグインで抽出した目次項目に、リンク可能な目次を生成するためのテンプレートの記述例を解説しています。

この記事を Delicious に追加する   このエントリーをはてなブックマークに追加  

例-1. アンカーを自動付与する場合

 テンプレートの前半で無印(?)の h3 タグを抽出し、連番のアンカー付きのリンクで目次を生成しています。また、テンプレートの後半では、ブログ記事に含まれる h3 タグにアンカーを付与しています。

  • とりあえず何も考えずに記事を書いても、ヘッダを抽出して、自動的にアンカーを振ってリンクしてくれます。
  • アンカー文字列が無機的です。
  • ヘッダ タグに余計なプロパティが入ると目次にリストされません。
<h1>目次</h1>
<mt:SetVar name="header_index" value="1">
<ol><mt:RegexFor tag="mt:EntryMore" regex="<h3>(.+?)</h3>">
    <li><a href="#toc-<mt:Var name="header_index">"><mt:Var name="__$1__"></a></li>
    <mt:SetVar name="header_index" op="++">
</mt:RegexFor></ol>

<mt:SetVar name="header_index" value="1">
<mt:RegexReplace tag="mt:EntryMore" regex="<h3>">
    <h3 id="toc-<mt:Var name="header_index">">
    <mt:SetVar name="header_index" op="++">
</mt:RegexReplace>

テンプレートの解説

2 行目
 連番を生成するためのカウンタ変数(header_index)の初期値を設定します。
3 行目
 ブログ記事の追記内容(tag="mt:EntryMore")から、h3 タグを抽出し、タグに挟まれた文字列を __$1__ 変数に取得します。
4 行目
 カウンタ変数(header_index)を利用してアンカーを生成し、ヘッダの文字列(__$1__)にリンクを設定します。
5 行目
 次のアンカーのためにカウンタ変数(header_index)を増やしておきます。
8 行目
 アンカー用に連番をもう一度生成するため、カウンタ変数(header_index)の初期値を設定します。
9 行目
 ブログ記事の追記内容(tag="mt:EntryMore")から、h3 タグを抽出しています。mt:RegexReplace ブロックタグを利用して、h3 タグを、ブロックの内容で置き換えます。
10 行目
 カウンタ変数(header_index)を利用してアンカー付きの h3 タグを生成しています。
11 行目
 次のアンカーのためにカウンタ変数(header_index)を増やしておきます。

例-2. ユーザがアンカーを指定する場合

 例-1 では、アンカー文字列は無機質な連番ですが、場合によっては #access#topic といった意味のあるアンカー文字列をユーザが明示したい場合があると思います。

  • 例-1 と違って、アンカー文字列をユーザが明示的に指定できます。
  • id プロパティがないヘッダは目次にリストされません。
  • 目次に表示するためには、必ず何等かの id プロパティを指定しなければなりません
<h1>目次</h1>
<ol><mt:RegexFor tag="mt:EntryMore" regex="<h3 id="(.+?)">(.+?)</h3>">
    <li><a href="#<mt:Var name="__$1__">"><mt:Var name="__$2__"></a></li>
</mt:RegexFor></ol>

<mt:EntryMore>

テンプレートの解説

2 行目
 ブログ記事の追記内容(tag="mt:EntryMore")から、id プロパティを持った h3 タグを抽出し、id プロパティ値を __$1__ 変数に、タグに挟まれた文字列を __$2__ 変数に取得します。
3 行目
 id プロパティ値(__$1__)を飛び先として、ヘッダの文字列(__$2__)にリンクを設定します。
6 行目
 ブログ記事の追記内容の h3 タグには、既にアンカーが設定されているため、そのまま無加工で出力します。

例-3. アンカーが明示されたヘッダと、無指定のものが混在する場合

 この例は、アンカーが明示的に指定されたヘッダと、指定されていないヘッダが混在していても、どちらも処理できるようにしたものです。例-3 のようにユーザが明示的にアンカーを指定している場合には、それをアンカー文字列とし、指定されていない場合には、例-1 のように連番のアンカー文字列を生成します。

  • とりあえず何も考えずに記事を書いて、特定任意のヘッダにだけ id プロパティを明示しても、全て目次にリストされます。
  • 目次にリストされないヘッダを作れません
<h1>目次</h1>
<mt:SetVar name="header_index" value="1">
<ol><mt:RegexFor tag="mt:EntryMore" regex="<h3(?:\s+id="(.+?)")?>(.+?)</h3>">
<mt:If name="__$1__">
    <li><a href="#<mt:Var name="__$1__">"><mt:Var name="__$2__"></a></li>
<mt:Else>
    <li><a href="#toc-<mt:Var name="header_index">"><mt:Var name="__$2__"></a></li>
    <mt:SetVar name="header_index" op="++">
</mt:If>
</mt:RegexFor></ol>

<mt:SetVar name="header_index" value="1">
<mt:RegexReplace tag="mt:EntryMore" regex="<h3>">
    <h3 id="toc-<mt:Var name="header_index">">
    <mt:SetVar name="header_index" op="++">
</mt:RegexReplace>

テンプレートの解説

2 行目
 連番を生成するためのカウンタ変数(header_index)の初期値を設定します。
3 行目
 ブログ記事の追記内容(tag="mt:EntryMore")から、h3 タグを抽出し、id プロパティが指定されていればその値を __$1__ 変数に、タグに挟まれた文字列を __$2__ 変数に取得します。
4 行目
 もし、id プロパティが指定されていた場合にはになります。
5 行目
 id プロパティ値(__$1__)を飛び先として、ヘッダの文字列(__$2__)にリンクを設定します。
7 行目
 id プロパティが指定されていなかった場合には、カウンタ変数(header_index)を利用して連番のアンカー文字列を生成し、ヘッダの文字列(__$1__)にリンクを設定します。
8 行目
 次のアンカーのためにカウンタ変数(header_index)を増やしておきます。
12 行目
 アンカー用に連番をもう一度生成するため、カウンタ変数(header_index)の初期値を設定します。
13 行目
 ブログ記事の追記内容(tag="mt:EntryMore")から、id プロパティが指定されていない h3 タグを抽出しています。mt:RegexReplace ブロックタグを利用して、h3 タグを、ブロックの内容で置き換えます。
14 行目
 カウンタ変数(header_index)を利用してアンカー付きの h3 タグを生成しています。
15 行目
 次のアンカーのためにカウンタ変数(header_index)を増やしておきます。
この記事を Delicious に追加する   このエントリーをはてなブックマークに追加  


この記事を読んだ人はこんな記事も読んでいます記事リコメンデーションについて

カバー画像:パターンにマッチした文字列を処理する MovableType プラグイン:RegexFor

関連記事/トラックバック

関連記事/トラックバックはまだありません

この記事にトラックバックを送るには?

コメントを投稿する

 
 (必須, 匿名可, 公開, トリップが使えます)
 (必須, 匿名可, 非公開, Gravatar に対応しています)
 (必須)
スパム コメント防止のため「投稿確認」欄に ランダムな数字 CAPTCHAについて を入力してから送信してください。お手数ですがご協力のほど宜しくお願いいたします。