HTML Tidyで整形
はじめに
このサイトはxtを使用してxmlからxhtmlに変換して公開している.ブラウザで見る分には支障ないのだが,ソースとしてみた場合,xtの作成するxhtmlは決して見やすいものではない.整形するためのperlスクリプトを作ってみたのだが,なかなかきれいには整形できない.HTML Tidy(以下tidy)はこの悩みを解消してくれそうだ.
インストール
Windowsで動くバイナリもあるが,普段cygwinを使っているのでcygwin版をインストールする.cygwinからsetup.exe
をダウンロードして起動する.tidyはカテゴリTextの中にある.デフォルトではインストール対象から外れているので,インストール対象に変更する.後はsetup.exe
がうまい具合にやってくれる.
コマンドラインで動かしてみる
トップページのindex.htmlをサンプルにして動かしてみた.index.htmlの文字コードに合わせてオプションに-utf8
,インデントをしてほしいので-i
をつけた.なお,-h
でヘルプを見ることができる.
$ tidy -utf8 -i index.html Info: Document content looks like HTML 3.2 No warnings or errors were found.
index.htmlはxhtml1.1なのだが,html3.2になってしまっている.xml(xhtml)に見てくれるように-xml
を指定した.
$ tidy -xml -utf8 -i index.html No warnings or errors were found.
エラーにはなっていない.しかし,標準出力に出てくるはずの処理結果が出てこない.もっと簡単な別ファイルを作って試してみた.
$ cat sam.html <html> <head> <title>sample</title> </head> <body> this is sample </body> </html> $ tidy -xml -i sam.html No warnings or errors were found. <html> <head> <title>sample</title> </head> <body>this is sample</body> </html>
うまく動いている.
文字コードなのだろうか?試しに,imdkcvを使って文字コードをシフトJISにしてみた.
$ imdkcv -sn index.html|tidy -shiftjis -xml -i Info: Doctype given is "-//W3C//DTD XHTML 1.1//EN" No warnings or errors were found. <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xml:lang="ja" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Script-Type" content="text/javascript" /> <meta name="Generator" content="written by xyzzy. transformed by XT" /> <meta name="wwwc" content="2003.7.13 歳時記・リンク更新" /> <link rel="stylesheet" type="text/css" href="css/tabs_in_top.css" /> <link rel="stylesheet" type="text/css" href="css/top.css" /> <link rel="start" href="index.html" /> ---以下省略---
うまくいった.
utf8とutf8nの違いなのだろうか.xmlファイルはutf8nで書いている.utf8だとxtがうまく動かなかったからだ.xtはutf8nならうまく動いた.xtが対応しているutf8はutf8ではなくutf8nのようだ.
tidyはutf8nではうまく動かない.tidyが対応しているutf8はutf8nではなくutf8のようだ.utf8nではうまく動かない.ややこしい.とりあえず,シフトJISに変換すると何とかなるので,良しとしよう.ビバ,シフトJIS.
preタグと改行
これで終わりかと思ったが,<pre>タグで囲った内容が一行おきに出てきてしまうことに気がついた.
$ imdkcv -sn _tidy.html|tidy -shiftjis -xml -i No warnings or errors were found. <?xml version="1.0"?> <html> <head> <title>sample</title> </head> <body>this is sample <pre> this is pre line1. this is pre line2. </pre></body> </html>
imdkcvにオプション-aを指定して,改行コードを0x0a(lf)だけにしたら解決した.
$ imdkcv -sn -a _tidy.html|tidy -shiftjis -xml -i No warnings or errors were found. <?xml version="1.0"?> <html> <head> <title>sample</title> </head> <body>this is sample <pre> this is pre line1. this is pre line2. </pre></body> </html>
できあがったファイルの改行コードは0x0aのはずなのだが,エディタ(xyzzy)で見ると,crlfになっている.よく分からない.実害がないのでとりあえず放置.
ant用タスクの修正
xmlからxhtmlへの変換はantを使って行っている.antで使うxmlファイルの該当部分にimdkcvとtidyを使った整形を追加する.パイプの使い方が分からないので,データの受渡しには一時ファイルを使っている.
<target name="format"> <tempfile property="sjis"/> <tempfile property="utf8"/> <!-- シフトJISに変換 --> <exec executable="imdkcv" output="${sjis}"> <arg line="-sn -a '${html}'"/> </exec> <!-- 整形 --> <exec executable="tidy"> <arg line="-xml -shiftjis -wrap 500 -im '${sjis}'"/> </exec> <!-- utf8nに変換 --> <exec executable="imdkcv" output="${utf8}"> <arg line="-u8 '${sjis}'"/> </exec> <!-- 微調整 --> <exec executable="perl" output="${html}"> <arg line="'${xsl.path}/format.pl' '${utf8}'"/> </exec> <delete file="${sjis}"/> <delete file="${utf8}"/> </target>
xmlをxhtmlに変換するためのxmlファイルは,共通で使うbase.xmlと個別に用意したbuid.xmlを作成している.あんまり格好の良い物ではないが,付録として全リストをつけた.
おわりに
今回はtidyを整形にしか使っていない.これ以外にも様々な機能があるのだが,それについては,以下に挙げた参考サイトを参照してほしい.そちらのほうがずっと詳しい.参考サイト
- HTML Tidy Project Page
- 本家.Windowsで動くバイナリもあり.
- プログラマー天国
- プログラマーのためのHTML Tidy入門を読めば,一通り使えるようになれる.
- cygwin
- Windowsで動くunix環境.
- いまでぃのホームページ
- 文字コード変換プログラムimdkcvがダウンロードできる.今回も大活躍.
付録
<!-- base.xml --> <project name="xml2html" default="xslt" basedir="."> <property environment="env"/> <property name="xt.path" value="${env.PROGRAMFILES}/xt"/> <property name="xsl.path" value="${user.home}/My Documents/web/xsl"/> <property name="htmllint" value="${env.PROGRAMFILES}/htmllint/htmllint"/> <target name="up-to-date"> <uptodate property="isIndexUpToDate" targetfile="${html}"> <srcfiles dir="." includes="${xml}"/> <srcfiles dir="${xsl.path}" includes="${xslt} framework.xsl"/> </uptodate> </target> <target name="xslt" depends="up-to-date" unless="isIndexUpToDate"> <java classname="com.jclark.xsl.sax.Driver" failonerror="true"> <classpath> <pathelement path="${xt.path}/xt.jar;${xt.path}/lib/xp.jar;${xsl.path};."/> <pathelement path="${java.class.path}"/> </classpath> <arg line="${xml} '${xsl.path}/${xslt}' ${html}"/> </java> <antcall target="format"/> <antcall target="htmllint"/> </target> <target name="format"> <tempfile property="sjis"/> <tempfile property="utf8"/> <exec executable="imdkcv" output="${sjis}"> <arg line="-sn -a '${html}'"/> </exec> <exec executable="tidy" failonerror="true"> <arg line="-xml -shiftjis -wrap 500 -im '${sjis}'"/> </exec> <exec executable="imdkcv" output="${utf8}"> <arg line="-u8 '${sjis}'"/> </exec> <exec executable="perl" output="${html}"> <arg line="'${xsl.path}/format.pl' ${utf8}"/> </exec> <delete file="${sjis}"/> <delete file="${utf8}"/> </target> <target name="htmllint"> <tempfile property="lint.result"/> <exec executable="perl" output="${lint.result}"> <arg line="'${htmllint}' ${html}"/> </exec> <exec executable="imdkcv"> <arg line="-sn '${lint.result}'"/> </exec> <delete file="${lint.result}"/> </target> <target name="clean"> <delete> <fileset dir="." includes="*.html"/> </delete> </target> </project> <!-- build.xml --> <project name="xml2html" default="index" basedir="."> <property name="root" value="."/> <target name="index"> <ant antfile="${root}/base.xml"> <property name="xslt" value="top.xsl"/> <property name="xml" value="index.xml"/> <property name="html" value="index.html"/> </ant> </target> <target name="all" depends="index"/> <target name="clean"> <ant antfile="${root}/base.xml" target="clean"/> </target> </project>