トップ > ソフトウェア > doctools > tunahtml

[前ページ][次ページ]


tunahtml - HTMLリンカ

Author: Takeshi Fujiyoshi
Last update: 2010/03/21

目次

概要

tunahtml は複数の HTML ファイルをリンクするツールである。 ユーザが記述したコンフィグスクリプトの内容に従い、 HTML ファイルの中にページ移動のためのリンクを埋め込む。

使用例

今、カレントディレクトリに以下の HTML ファイルが置いてあったとする。

ファイル タイトル
index.html トップページ
canada.html カナダの基本情報
usa.html アメリカの基本情報
mexico.html メキシコの基本情報
route-canada.html カナダのルートデータ
route-usa.html アメリカのルートデータ
route-mexico.html メキシコのルートデータ

それぞれは独立した HTML ファイルであり、 ウェブブラウザでページの内容を表示することができるが、 ハイパーリンクされていないためページ間で移動することができないものとする。 また、HTML ファイルの文字コードは全て UTF-8 とする。

ここで、同じディレクトリに以下のような内容のファイル (コンフィグファイル)を作成する。 ファイル名は config.rb としておこう。:

lang "ja"
page {
  file "index.html"
  page { file "canada.html" }
  page { file "usa.html" }
  page { file "mexico.html" }
  page { file "route-canada.html" }
  page { file "route-usa.html" }
  page { file "route-mexico.html" }
}

このファイルはページ間の階層構造の関係を表している。 最上位に index.html (トップページ)、 その一段下に残りのページが入るような関係である。

ファイルを作成したら、次のコマンドを実行する。:

$ tunahtml -f config.rb

その結果、以下のファイルが新しく生成された。

生成されたファイル 元ファイル タイトル
tuna-index.html index.html トップページ
tuna-canada.html canada.html カナダの基本情報
tuna-usa.html usa.html アメリカの基本情報
tuna-mexico.html mexico.html メキシコの基本情報
tuna-route-canada.html route-canada.html カナダのルートデータ
tuna-route-usa.html route-usa.html アメリカのルートデータ
tuna-route-mexico.html route-mexico.html メキシコのルートデータ

これらは、元のファイル名の先頭に tuna- を付加したものであり、 元のファイルを加工した結果が格納されている。

tuna-index.html をブラウザで開くと以下のような内容のページが表示される。:

トップページ                                 ← (1) ナビゲーション
[前ページ] [次ページ]
-------------------------------------------
ここはサンプルデータのトップページです。     ← (2) 元からあった部分

 - カナダの基本情報
   ~~~~~~~~~~~~~~~~
 - アメリカの基本情報
   ~~~~~~~~~~~~~~~~~~
 - メキシコの基本情報                        ← (3) 目次
   ~~~~~~~~~~~~~~~~~~
 - カナダのルートデータ
   ~~~~~~~~~~~~~~~~~~~~
 - アメリカのルートデータ
   ~~~~~~~~~~~~~~~~~~~~~~
 - メキシコのルートデータ
   ~~~~~~~~~~~~~~~~~~~~~~
-------------------------------------------
トップページ                                 ← (4) ナビゲーション
[前ページ] [次ページ]

このうち、元の index.html に書かれていたのは (2) の部分のみであり、 (1)と(4)のナビゲーション、(3)の目次は tunahtml により挿入されたものである。 目次は下位ページへのリンクになっている。

ところで、目次の中の「カナダの基本情報」などの文字列は、 HTML ファイルの <title> 要素から抽出したものである。 同様にナビゲーション部の「トップページ」は index.html の <title> 要素から抽出したものである。

では、目次の中の「アメリカの基本情報」のリンクをクリックしてみる。 その結果、tuna-usa.html の内容が表示される。:

トップページ > アメリカの基本情報            ← (1) ナビゲーション
~~~~~~~~~~~~
[前ページ] [次ページ]
~~~~~~~~~~ ~~~~~~~~~~
-------------------------------------------
アメリカの基本情報

田舎には白人が多いが都市に入ると急激に黒人   ← (2) 元からあった部分
が増える。しかし中国人はどこにでもいる。

田舎には変な警察官がいるので気をつけた方が
良い。

レストランでチップを払う必要はない。

-------------------------------------------
トップページ > アメリカの基本情報            ← (3) ナビゲーション
~~~~~~~~~~~~
[前ページ] [次ページ]
~~~~~~~~~~ ~~~~~~~~~~

このページには下位ページがないため目次は挿入されていない。 一方、ナビゲーションにはトップページと現ページのタイトルが表示されている。 「トップページ」をクリックすれば tuna-index.html に戻る。 2行目の「前ページ」をクリックすると tuna-canada.html へ、 「次ページ」をクリックすると tuna-mexico.html へジャンプする。

コマンドの使い方

コマンドの使い方:

tunahtml [options] [<target_file or dir> ...]

options:
  -e <config_script>  コンフィグスクリプト (複数回現れてもよい)
  -f <config_file>    コンフィグファイル (複数回現れてもよい)
  -v                  バージョン表示
  -w                  冗長メッセージ表示

tunahtml は、-e および -f オプションで指定された コンフィグスクリプトを全て評価したあと、 その結果に従ってリンク処理を行ない、加工したファイルを出力する。

-e および -f オプションは複数回現れてもよく、現れた順に評価される。 コンフィグスクリプトの書き方については次節で説明する。

-e <config_script>

評価するコンフィグスクリプトを文字列で直接指定する。

使用例:

$ tunahtml -e 'page{file "canada.html"}; page{file "usa.html"}'

この例の場合、以下のようにスクリプトを分解して指定してもよい。:

$ tunahtml -e 'page{file "canada.html"}' -e 'page{file "usa.html"}'

1つ目のスクリプトは tunahtml が起動したときのカレントディレクトリで 評価される。各スクリプトの終了時のカレントディレクトリがそのまま 後続のスクリプト評価時のカレントディレクトリとなる。:

$ pwd
/home/fujiyosi/tmp
$ tunahtml -e 'puts Dir.pwd; Dir.chdir "/usr"' -e 'puts Dir.pwd'
/home/fujiyosi/tmp
/usr

コンフィグスクリプトの文字コードは UTF-8 でなければならない。

-f <config_file>

コンフィグファイル(=コンフィグスクリプトを格納したファイル)を指定する。

使用例:

$ tunahtml -f ~/www/ja/config.rb -f ~/www/en/config.rb

この例では、~/www/ja/config.rb と ~/www/en/config.rb が 順に評価される。

各コンフィグファイルが評価されるとき、カレントディレクトリは そのコンフィグファイルと同じディレクトリにセットされ、 評価が終了すると元のディレクトリに戻る。 そのため、コンフィグファイルの中でカレントディレクトリを変更しても 他のスクリプトの評価には影響しない。

コンフィグファイルの文字コードは UTF-8 でなければならない。

オプション -e と -f を一緒に使用する例を以下に示す。:

$ tunahtml -e 'lang "ja"; dst_default nil' -f config.rb

最初に lang "ja" により言語を日本語に設定し、 dst_default nil により HTML ファイルの上書きを指示した上で config.rb を評価している。

<target_file or dir>

コンフィグスクリプトで定義された内部リンクページのファイルのうち、 実際に加工して出力するファイル名を指定する。 ディレクトリ名を指定したときは、そのディレクトリより下の全ての ファイルが対象となる。 1つも指定しなかったときは全てのファイルが対象となる。

存在しないファイル名を指定するとエラーになる。 存在するファイルかディレクトリであれば、 コンフィグファイル内で定義されていなくてもエラーにはならない。

例:

$ cat config.rb
dst_default nil
page {
  file "index.html"
  page { file "canada.html" }
  page { file "usa.html" }
  page { file "mexico.html" }
  page { file "route/route-canada.html" }
  page { file "route/route-usa.html" }
  page { file "route/route-mexico.html" }
}

$ tunahtml -f config.rb index.html route

この例では、index.html、 route/route-canada.html、 route/route-usa.html、route/route-mexico.html は加工されるが、 canada.html、usa.html、mexico.html は加工されない。

コンフィグスクリプトの書き方

tunahtml のプログラムは Ruby で書かれている。 そして、コンフィグスクリプトもまた Ruby のスクリプトである。 tunahtml では、あるインスタンスメソッドの中で instance_eval() を使ってコンフィグスクリプトの内容を評価している。 従って、Ruby でインスタンスメソッドの定義の中で使える記述は全て有効である。

例えば、最初の例で使用したコンフィグスクリプト:

lang "ja"
page {
  file "index.html"
  page { file "canada.html" }
  page { file "usa.html" }
  page { file "mexico.html" }
  page { file "route-canada.html" }
  page { file "route-usa.html" }
  page { file "route-mexico.html" }
}

は、以下のように書き換えることもできる。:

lang "ja"
page {
  file "index.html"
  kuni = ["canada", "usa", "mexico"]
  kuni.each {|k| page {file "#{k}.html"} }
  kuni.each {|k| page {file "route-#{k}.html"} }
}

余計にややこしくなった感じもするが、 ファイル数が増えてくるとこのようなやり方は有用である。

コンフィグスクリプトでは、コンフィグ用のメソッドを用いてページ間の 階層構造と各ページのファイル名などの属性を設定していく。 コンフィグ用メソッドの一覧を下表に示す。

メソッド名 機能
page 下位ページを定義
file 表示するリソースを指定
dst_file 出力ファイル名を指定
dst_default 出力ファイル名の自動生成ルールを設定
title 目次用タイトル文字列の指定
label ナビゲーション用タイトル文字列の指定
lang 言語を指定
index_depth 目次の最大深さを指定
include コンフィグファイルを評価
root リンクセットを定義

page、include、root 以外のメソッドは 引数を指定したらその値を設定し、 引数を指定しなければ現在の設定値を返す。 Ruby で一般的に使われる 属性=(値) 形式のセッターは定義されない。

dst_default、index_depth、lang の設定値は、 上位ページの設定値が下位ページでの初期値として引き継がれる。 下位ページで行なった設定が上位ページに影響することはない。

コンフィグスクリプトの文字コードは UTF-8 でなければならないので注意。

ページの定義

page { ... }

カレントページに下位ページを追加し、そのページをカレントページとして ブロックを評価する。このブロックの中でコンフィグ用のメソッドを用いて ページの属性を設定していく。

page { ... page { ... } } のように page をネストすることで ページ間の階層構造を構築できる。 目次の項目の順序と [前ページ][次ページ] によるページ移動の順序は このメソッドの実行順序に一致する。

例えば、コンフィグスクリプトが以下のような内容とき、:

page {
  file("index.html"); index_depth(2)
  page {
    title "基本情報"
    page { title("カナダ"); file("canada.html") }
    page { title("アメリカ"); file("usa.html") }
    page { title("メキシコ"); file("mexico.html") }
  }
  page {
    title "街情報"
    page { title("カナダの街"); file("canada-cities.html") }
    page { title("アメリカの街"); file("usa-cities.html") }
    page { title("メキシコの街"); file("mexco-cities.html") }
  }
}

トップページの index.html には以下のような目次が挿入される。:

- 基本情報
   - カナダ            ← canada.html へのリンク
     ~~~~~~
   - アメリカ          ← usa.html へのリンク
     ~~~~~~~~
   - メキシコ          ← mexco.html へのリンク
     ~~~~~~~~
- 街情報
   - カナダの街        ← canada-cities.html へのリンク
     ~~~~~~~~~~~~
   - アメリカの街      ← usa-cities.html へのリンク
     ~~~~~~~~~~~~
   - メキシコの街      ← mexico-cities.html へのリンク
     ~~~~~~~~~~~~

最上位で定義された page がトップページとなる。 トップページが複数存在することも可能であり、その場合はトップページ間で [前ページ]、[次ページ]のリンクにより移動できる。

本メソッドは、ブロックを評価する前にカレントディレクトリを保存し、 ブロックの評価が終了するとカレントディレクトリを元に戻す。 そのため、 下位ページでカレントディレクトリを変更しても 上位ページの評価には影響しない。

本メソッドは TunaHTML::Page クラスのインスタンスを1つ生成し、 それを self としてブロックを評価し、そのインスタンスを返す。 本メソッドを含めコンフィグ用のメソッドは全て TunaHTML::Page クラスのインスタンスメソッドとして定義されている。

ページの種類とリソースの指定

メソッド file() を用いてカレントページに表示するリソースを指定する。 リソースの種類により引数の指定方法が異なる。

file(<path>)

このページを「内部リンクページ」とする。 内部リンクページには、ナビゲーションと(あれば)目次が挿入され、 上位ページの目次と下位ページのナビゲーションにはこのページへの リンクが挿入される。 それらのリンクは <path> への相対パスで記述される。

引数 <path> にはこのページに表示する HTML ファイル名を 絶対パスかカレントディレクトリからの相対パスで指定する。 この HTML ファイルの文字コードは UTF-8 でなければならない。 そうでないファイルはあらかじめ UTF-8 に変換しておくこと。

戻り値は <path> の絶対パス。

file(<path>, :nolink)

このページを「内部非リンクページ」とする(名前苦しい…)。 このページ自体は何も加工されない。 上位ページの目次と下位ページのナビゲーションにはこのページへの リンクが挿入される。 それらのリンクは <path> への相対パスで記述される。

引数 <path> にはこのページに表示する HTMLファイル名、 あるいは CGI や PHP などのプログラムファイル名を絶対パスか カレントディレクトリからの相対パスで指定する。 プログラムファイル名の末尾には引数が付加されていても構わない。 ファイルの文字コードに制限はない。

戻り値は <path> の絶対パス。

file(<path>, :extern)

このページを「外部ページ」とする。 このページ自体は何も加工されない。 上位ページの目次と下位ページのナビゲーションにはこのページへの リンクが挿入される。 それらのリンクには <path> がそのまま記述される。

引数 <path> にはこのページに表示する任意の URI を指定する。

戻り値は <path> そのまま。

file
引数なしのときは現在の設定値を返す。初期値は nil。 設定後の戻り値は上記を各形式を参照。

具体例として、コンフィグスクリプトが以下の内容のとき、:

dst_default nil
page {
  title("トップページ"); file("index.html")
  page { title("カナダ"); file("canada.html") }
  page { title("アメリカ"); file("usa.html", :nolink) }
  page { title("メキシコ"); file("mexico.cgi?mode=1", :nolink) }
  page {
    title("ベリーズ")
    file("http://en.wikipedia.org/wiki/Belize", :extern)
  }
}

index.html には以下のような目次が挿入される。:

- カナダ      ← "canada.html" へのリンク
  ~~~~~~
- アメリカ    ← "usa.html" へのリンク。別ウィンドウで表示
  ~~~~~~~~
- メシキコ    ← "mexico.cgi?mode=1" へのリンク。別ウィンドウで表示
  ~~~~~~~~
- ベリーズ    ← "http://en.wikipedia.org/wiki/Belize" へのリンク。
  ~~~~~~~~       別ウィンドウで表示

また、canada.html にはナビゲーションが挿入されるが、 usa.html, mexico.cgi および http://en.wikipedia.org/wiki/Belize は何も加工されない。

1つのページで指定できるリソースはただ1つのみである。 file() を複数回実行したときは最後の設定が有効になる。

file() によるリソース設定が行なわれていないページは「擬似ページ」となる。 擬似ページは表示すべきリソースが割当てられていないページである。 上位ページの目次と下位ページのナビゲーションには擬似ページに対して title() または label() で設定したタイトル文字列がリンクなしで 格納される。

出力ファイル名の設定

出力ファイル名は内部リンクページに対してのみ意味を持つ。 内部非リンクページ、外部リンクページでは出力ファイルが存在しないため 無関係である。

dst_file(<path>)
カレントページの出力 HTML ファイル名を <path> とする。 設定値の絶対パスを返す。 内部リンクページ以外では設定しても意味はない。
dst_file
カレントページの出力 HTML ファイル名の設定値を返す。 初期値は nil だが、file(<path>) を実行したときに自動的に設定される (dst_default の説明を参照)。
dst_default {|path| ... }

出力 HTML ファイル名の自動生成ルールを設定する。 ソース HTML ファイルの絶対パスを引数としてブロックを評価した結果が デフォルトの出力ファイル名となる。 ただし、 dst_file(<path>) により出力ファイルを指定したときは、 そちらが優先される。

例: コンフィグスクリプトが以下の内容のとき、:

Dir.chdir "/home/fujiyosi"

dst_default {|fn| fn.sub(/\.[^\.]*$/, '-out\&') }
page { file "canada.html" }
page { file "usa.html" }

dst_default {|fn| "/tmp/ " + File.basename(fn) }
page { file "mexico.html" }

各ページのソースファイルと出力ファイルのパスは以下のようになる。

ソースファイル 出力ファイル
/home/fujiyosi/canada.html /home/fujiyosi/canada-out.html
/home/fujiyosi/usa.html /home/fujiyosi/usa-out.html
/home/fujiyosi/mexico.html /tmp/mexico.html

初期値はカレントページが定義された時点の上位ページの設定値が引き継がれる。 最上位での初期値は、ファイル名の先頭に文字列 tuna- を 付加したものとなる。

dst_default(nil)

出力 HTML ファイルがソース HTML ファイルと同じ名前になるよう 出力ファイル名自動生成ルールを設定する。以下と同じである。:

dst_default {|fn| fn.dup}

この結果、デフォルトではソース HTML ファイルは加工後のデータで 上書きされる。

タイトル文字列の指定

title(<string>)
カレントページの「目次用タイトル」を <string> とする。 <string> を返す。 目次用タイトルは上位ページの目次に表示されるものである。 初期値は HTML ファイルの中の <title> 要素から抽出した文字列となる。 HTML ファイル名が未設定の場合や <title> 要素が無かったときは no title がデフォルトとなる。
title
title(<string>) で設定した目次用タイトルの現在の設定値を返す。
label(<string>)
カレントページの「ナビゲーション用タイトル」を <string> とする。 <string> を返す。 ナビゲーション用タイトルはカレントページと下位ページのナビゲーション 部に表示されるものである。初期値は title() の戻り値。
label
label(<string>) で設定したナビゲーション用タイトルの現在の設定値を返す。

その他のページ属性の設定

extra_link(<string>, <path>)
ナビゲーションの [前ページ][次ページ] の右に任意のリンクを追加する。 <string> には表示する文字列を指定する。 <path> にはリンク先の URI を指定する。
index_depth(<depth>)

カレントページに挿入される目次の最大深さを <depth>.to_i とする。 設定値を返す。設定値が 0 のとき目次は挿入されない。

初期値はカレントページが定義された時点の上位ページの設定値が引き継がれる。 最上位での初期値はとても大きな数。

メモ: 上位ページの目次の深さにも影響する。 自分用と上位用を別個に指定できた方がいいのかも。

index_depth
目次の最大深さの現在の設定値を返す。
lang(<lang>)

言語を <lang>.to_s に設定する。 設定された値を返す。 この文字列は ISO 639 で定義される言語コードであること。 tunahtml が現在サポートしている言語は ja (日本語) と en (英語)のみ。未サポートの言語は全て en として処理する。 初期値はカレントページが定義された時点の上位ページの設定値が引き継がれる。 最上位での初期値は en (英語)。

現状はナビゲーション部の前後ページ移動リンクの文字列にのみに影響する。 ja ならば "[前ページ] [次ページ]" となり、 それ以外のときは "[Previous Page] [Next Page]" となる。

lang
言語の現在の設定値を返す。

コンフィグファイルの分割

include(<config_file>)

コンフィグファイル <config_file> をこの位置で評価する。 評価を開始する前にカレントディレクトリを <config_file> と同じディレクトリに変更し、評価が終了すると元に戻す。 コンフィグファイルの中で最後に評価した値を返す。

例えば、以下のようなファイルがあり、:

config.rb
index.html
tabi/report.html
tabi/canada.html
tabi/usa.html
tabi/mexico.html

コンフィグファイル config.rb の内容が以下のとき、:

page {
  file "index.html"
  page {
    Dir.chdir "tabi"
    file "report.html"
    page { file "canada.html" }
    page { file "usa.html"}
    page { file "mexico.html" }
  }
}

次のように config.rb の一部を別ファイル tabi/config.rb にくくり出して分割することができる。

config.rb:

page {
  file "index.html"
  include "tabi/config.rb"
}

tabi/config.rb:

page {
  file "report.html"
  page { file "canada.html" }
  page { file "usa.html"}
  page { file "mexico.html" }
}

リンクセットの定義

root { ... }

現在のリンクセットとは独立したリンクセットを新しく定義し、 そのリンクセット上でブロックを評価する。 このリンクセットは現在のリンクセットに含まれるどのページとも (tunahtmlによって)リンクされることはない。

page {...} によるサブページの定義と同様に、 lang, index_depth, dst_default の初期値と カレントディレクトリはカレントページのものが引き継がれる。 この点を除けば、ブロックの部分を別のコンフィグファイルにくくり出して 別々に tunahtml を実行するのと同じである。

使用例:

dst_default nil
index_depth 2

# 日本語版のページ
root {
   lang "ja"
   include "doc/ja/config.rb"
}

# 英語版のページ
root {
   lang "en"
   include "doc/en/config.rb"
}

# プライベートページ
root {
   lang "ja"
   include "private/config.rb"
}

HTMLファイルの加工内容

内部リンクページには目次とナビゲーションが挿入される。

加工前の HTML ファイルの文字コードは UTF-8 を前提としている。 それ以外の文字コードのファイルは、加工した際に文字化けを起こすかも知れない。

目次部とナビゲーション部には XHTML 形式のデータが挿入される。 XHTML とそうでない HTML のデータが混在していてもブラウザは期待通り 表示してくれるとは思うが、自信はない。

目次

HTMLボディの末尾に以下のような形で挿入される。:

<div class="tunahtml-toc">
  <ul>
    <li>
      <a href="ファイル1">タイトル1</a>
      <ul>
        <li><a href="ファイル2">タイトル2</a></li>
        <li><a href="ファイル3">タイトル3</a></li>
        ...
      </ul>
    </li>
    <li>
      ...
    </li>
    ...
  </ul>
</div>

ファイル1、ファイル2、... は下位ページのファイルへの相対パス、 タイトル1、タイトル2、... はそれらのページタイトルである。 擬似ページならば <a> 要素はなく単にタイトル文字列が入るだけである。

但し、<div class="tunahtml-toc ..."> の要素が既に存在するときは、 その <div> 要素が上記の内容に書き換えられる。位置は移動しない。

上部ナビゲーション

HTMLボディの先頭に以下のような形で挿入される。:

<div class="tunahtml-head tunahtml-navi">
  <p>
    <a href="ファイル名1">タイトル1</a> &gt;
    <a href="ファイル名2">タイトル2</a> &gt;
    ...
  </p>
  <p>
    <a href="前頁のファイル名">[前ページ]</a>
    <a href="次頁のファイル名">[次ページ]</a>
  </p>
  <hr />
</div>

ファイル名1、ファイル名2、... には上位ページのファイルへの相対パス、 タイトル1、タイトル2はそれらのページタイトルである。 擬似ページならば <a> 要素はなくタイトル文字列が入るだけである。

但し、<div class="tunahtml-head ..."> の要素が既に存在するときは、 その <div> 要素が上記の内容に書き換えられる。位置は移動しない。

下部ナビゲーション

HTMLボディの末尾に以下のような形で挿入される。:

<div class="tunahtml-tail tunahtml-navi">
  <hr />
  <p>
    <a href="ファイル名1">タイトル1</a> &gt;
    <a href="ファイル名2">タイトル2</a> &gt;
    ...
  </p>
  <p>
    <a href="前頁のファイル名">[前ページ]</a>
    <a href="次頁のファイル名">[次ページ]</a>
  </p>
  <hr />
</div>

中身は上部ナビゲーションと同じである。

但し、<div class="tunahtml-tail ..."> の要素が既に存在するときは、 その <div> 要素が上記の内容に書き換えられる。位置は移動しない。

問題点・課題・検討事項など


トップ > ソフトウェア > doctools > tunahtml

[前ページ][次ページ]