GenerateTOC: Generator for Table of Contents from HTML Headings

HTMLの見出しh1-h6要素から目次を自動生成するシングルページアプリケーションGenerateTOCを作ったので紹介する。

Introduction

ある程度まとまった量の文章には全体を概観するために目次があると便利だ。特に,電子データにおいては,ハイパーリンクにより目次から目当ての節に即座に移動でき,利用者の利便性が高い。

ワープロソフトである,MS WordやLibreOffice Writer,TeXなどには標準で目次の自動生成機能があり,特に設定などしなくても利用できる。しかし,Webの標準文書形式であるHTMLには目次を自動で生成する仕組みはない。つまり,目次を作りたければ,手作業を含め何らかの方法で目次用のHTMLコードを用意する必要がある。このことについては以下2点の問題があると考えている。

  1. 目次生成機能の互換性のなさ
  2. 正しい目次のマークアップの欠如

まず1点目だ。HTMLに目次を生成する仕組みがないということは,目次を必要とするならば各人が個別に目次を作ることになる。勿論手作業で作ってもいいのだが,目次を作る場合,基本的に以下の3工程を行うことになり,これを毎回手作業でやるのは時間がかかる

  1. 目次からハイパーリンクを貼るための,リンク対象の見出し要素にid属性を設定
  2. 目次一覧の文字列を生成
  3. 見出しへハイパーリンクを設定

CMSやブログサービスであれば,拡張機能などで目次を自動生成してくれるところもある。しかし,サービスが提供する目次は形式がばらばらであり,サービスが提供されていなければ利用不可能という互換性の問題がある。

そして2点目の問題だ。仮に手作業で目次を作ったり,外部サービスが提供する目次生成機能を使って目次を生成したとしても,その目次のマークアップがよくないことがある。例えば,この記事では目次のマークアップにblockquote要素を使っている。しかし,blockquoteは引用を示す要素なので,目次のマークアップに使うのは的はずれだ。さらに,外部サービスが対応する見出しの自動生成はsection要素を伴わずにh1-h6要素を単独で使う暗黙のセクションニングのみであることが多かった。

この2点の不満を解消するため,自分で目次を自動生成するツールを作成した。

Markup for Table of Contents

作成したツールの紹介の前に,HTMLではどのように目次をマークアップするのが正しいのかという点についての検討する。

HTMLの仕様を勧告しているW3CのHTML 5.1では,目次のマークアップについて決定的な記述は見当たらなかった。しかし,HTMLをベースにした電子書籍の仕様であるEPUB 3のガイドラインで以下の記述がある。

Each publication must provide a table of contents in the EPUB navigation document (the toc nav).

The table of contents is constructed using ordered lists (ol). Each list item must either contain a single link (a) to a section of the document, or a link or heading (span) followed by a list of subsections.
Table of Contents | Navigation | EPUB 3 Accessibility Guidelines

つまり,目次全体をnav要素で囲み,ol要素で各項目を記述し,a要素でリンクを貼ればよいことがわかる。また,目次には通常「目次」や「Table of Contents」という見出しを付ける。この見出しをどのようにマークアップするかという議論がある。これはnav要素の直下にh1-h6要素で見出しを付けることにするのがよい。理由は以下2点だ。

  1. nav要素がセクショニングコンテンツ(sectioning content)
  2. 目次マークアップ方法の指針を出していたEPUB 3 Accessibility Guidelinesの目次見出しで採用。

ここまでのことから目次のマークアップは例えば以下のようになる。

<nav>
<h2>Table of Contents</h2>
<ol>
<li><a href="#Heading-1">Heading 1</a></li>
<li><a href="#Heading-2">Heading 2</a></li>
</ol>
</nav>

なお,書籍のように目次自体を一つのセクションとして扱う場合は,以下のExampleにあるようにnav要素全体をsection要素で囲むことで行う。

Table of Contents | XHTML Content Documents | EPUB 3 Accessibility Guidelines

<section>
<nav>
<h2>Table of Contents</h2>
<ol>
<li><a href="#Heading-1">Heading 1</a></li>
<li><a href="#Heading-2">Heading 2</a></li>
</ol>
</nav>
</section>

GenerateTOC

HTMLで目次を自動で作るための不満を解消するために作成したGenerateTOCを紹介する。

GenerateTOC

このツールはHTML+JavaScriptによるシングルページアプリケーションである。リンク先のgeneratetoc.xhtmlの1ファイルで完結しているのでこのファイルをダウンロードすればオフラインでも利用可能だ。

使い方は簡単で,以下の手順となる。

  1. [Input HTML]に目次を生成したいHTMLコードを記入する。
  2. [Convert]を押下する。
  3. [Output HTML]に目次とリンクの作成のために見出し要素(h1-h6)のid属性が記入されたHTMLコードが出力される。また,[Result View]に見出し追加後のHTMLコードの描画結果を表示する。

注意点は以下2点となる。

  1. 入力はXHTML。
  2. section要素を使った明示的なセクショニングのみ対応。

1点目の入力形式がXHTMLなのは,出力形式を自分がメインで使っているXHTML形式にするためだ。JavaScriptでinnerHTMLなどのプロパティにアクセスしており,XHTMLの形式で出力するにはこのツール自体をXHTMLにする必要があったからだ。こうしなければ,ブラウザーが勝手に整形してHTML形式にするため,拡張子をgenteratetoc.xhtmlとした。XHTML形式にするといっても,基本的にはaimgなどの空要素の終端スラッシュを付ける必要があるなどいくつか細かい点で修正が必要なくらいで,修正自体不要なケースもあるだろう。変換自体も以下のサイトで簡単にできる。

HTML To XHTML Code Converter

2点目の対応する見出し要素の制限だが,目次自動生成ツールでは単にh1-h6要素だけをみて作るものが多い。作る側にしたら,h1-h6だけに対応するほうが簡単だ。しかし,僕は明示的にセクショニングを行うべきだと思い,これに従ったHTMLを記述しているので,これに対応していないと困る。だからこのような仕様にした。明示的と暗黙的の両方セクショニングに対応できればベストなのだが,そこまでの力が及ばなかったので最低限自分に必要な機能に限定した。

ツール自体は2016年10月頃にほぼできており,その頃から自分の書くブログではこの記事も含めてこのツールを使って目次を生成していた。しかし,一部&<>'"などの文字列のエスケープ処理がうまくできておらず,これに対処するのに時間がかかり放置していた。連休により時間に余裕ができて対応できたので今頃の公開となった。

Summary

HTMLにおける目次の作成という問題について自分なりに取り組んで解決のためのツールを作った。自分に必要だからという理由で作ったのもあり,個人的には満足している。長い記事を書く場合,目次は必要であるが,これを手作業で作るのはかなり面倒だった。このツールが作れて本当に良かったと思っている。今後も使い続けるつもりだ。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です