Logo address

HTML to LaTeX

目次

2007/09/18

HTML2TeX

HTML を LaTeX に変換してくれる

HTML を LaTeX に変換してくれるツールを使ってみた。URL は:
プログラムソースには Written by F.J. Faase の署名が入っている。

このようなツールは僕にとって実に有り難いのである。

僕は tt 形式を基に ptt と言う変換ツールを使って HTML を生成している。tt 形式は HTML 形式に比べて遥かに文章を書きやすい。だから僕の web ページは(古い一部の記事を除けば)全て tt 形式で書かれている。

僕のような事をしなくても、現在世の中にはワープロの文書を HTML に落とす環境は整っている。だから変換ツールがちゃんと働けば、ワープロ感覚で LaTeX の文書が作れるのだ。

僕の当面の目標は HTML で書かれた僕の Rit に関する記事
http://plan9.aichi-u.ac.jp/rit/rit-1.4.html
を LaTeX に自動変換することである。なにしろ僕は英作文が上手とは言えない。だから僕の英文は五月雨式に改訂される。その度に手作業で LaTeX に変換していたのでは堪らない。だから質の良いツールが欲しいのである。

注: 他にもいろいろあるらしい。次の URL が紹介されていた。
http://html2latex.sourceforge.net/
http://www.w3.org/Tools/html2things.html

コンパイル

html2tex は C で書かれている。gcc でコンパイルできると言う事である。文書変換のツールと言うのは OS 依存性が無いので、単に
	cc -o html2text html2tex.c
で、Mac ですんなりコンパイルできた。(Mac OSX の cc は gcc である。)

コンパイラの警告メッセージ

#ifndef ASCII8
		if ((unsigned char)*str >= 160 && (unsigned char)*str <= 255)
		{   special = TRUE;
			v = (unsigned char)*str - 160;
			ch = ch_table[v].ch;
		}
		else
#endif
当然だ。
	&& (unsigned char)*str <= 255)
何を考えていたんだろう? まあもっともバグと言うのはそう言うものだ。

使い方

変換の対象は本当は "rit-1.4.html" である。しかし以下では(面倒なので)単に "rit.html" とする。
	html2tex rit.html
これで LaTeX ファイル "rit.tex" が生成される。

エラーメッセージ

どうも "<span>" と "<div>" を認識しないらしい。これらのタグの中でのフォントの指定は手作業になりそう。たま次のメッセージ:
	file `rit%20Files/fig1.png' does not exist.
Mac の Camino は web ページを保存する時に、画像も保存する。その時にページに多少の変更が加えられる。
	<img src="fig1.png">
となっていたものが
	<img src="rit%20Files/fig1.png">
に書き換えられるのである。そのときにディレクトリ "rit Files" が作成され、そこに画像ファイルが保存されているのだが、html2tex は "rit%20Files" が "rit Files" の事だと認識していない。まあ、この問題に対してパッチを充てる事は簡単だから後で修正しましょう*

注*: 結局 "wget" を使う事にした。Camino は元の HTML ファイルを変更する。それが嫌なのだ。

変換の基礎能力

でき上がった結果を見ていると "rit.html" に含まれていた以下のタグは認識しており正しく処理できている。
	<h1>, <h2>, <h3>, ...
	<br>, <p>, ...
	<pre>, <code>, <em>
	<ol>, <ul>, <dl>, <li>,
これだけでも今回はずいぶん助かる。(これ以外にももっと多くのタグを認識しているに違いない。)
しかしテーブルはどうやら認識していないらしい。テーブルは難しそうだからねぇー。
-bash$ grep table *.c
html2tex.c:216:         - ignore HTML3 tables and meta (for now).

画像を含むページの保存

画像を含むページの保存は悩ましい問題で、

結局僕は "wget" を使う事にした。

特殊文字の認識

元のテキスト "rit.html" には "&mdash;" が含まれていた。これは長い dash であり、LaTeX では "---" に変換すべきであろう。しかし "\^a" に変換されていた。これは何だろう?

"html2tex.c" を見るに

-bash$ grep mdash *.c
                  { "emdash", "---",      '-' },
となっていた。ここの "emdash" は "mdash" でなくてはならない。ここで使われている "emdash" は以前にどこかのページで長いダッシュとして解説されていたのを見た事があるが、実際にはダメなのだ。(ブラウザ依存性があるのだろうか?)

以下に HTML で使われる特殊文字を解説したサイトを 2 つばかりリストアップしておく。これらによると "mdash" なのだ。

スタイルタグ

html2tex が HTML のスタイルタグを認識しているかどうかはかなり怪しい。何しろこの部分は難しい。しかしこの事はあまり重要ではないかも知れない。

リンクの扱い

<a href="http://plan9.aichi-u.ac.jp/netlib/cmd/rit/">http://plan9.aichi-u.ac.jp/netlib/cmd/rit/</a><br>

http://plan9.aichi-u.ac.jp/netlib/cmd/rit/\footnote{See URL http://plan9.aichi-u.ac.jp/netlib/cmd/rit/}\newline
となっていた。ptt は URL が文章中に現れると自動的にリンクを付ける。ところが html2tex はリンクがあると自動的にその情報をフットノートに持って行く。そうすると情報がダブルと言う変な事になる。どちらかが控えなくてはならない。

幸い html2tex には "-b" のオプションがある。これによってフットノートにではなく、bibliography にレファレンスを書くらしい。しかしそのファイルが何処に作られたのか、見当たらない。取りあえず問題は解決だが...、僕はまだ良く分かっていないらしい。

HTML と LaTeX の目標の違い

HTML と LaTeX は目標とするものが異なる。htmh2tex はこの違いをある程度埋める仕組みを持っている。数式に対する能力の違いはもちろん大問題だが、HTML で数式を扱っていなくても LaTeX に変換する場合にはいろいろな問題が発生する。

極く簡単な例として abstract を考えてみる。
HTML に "abstract" タグがあれば問題ないが、残念ながら存在しない。そこで rit.html では abstract の部分は

<div class="abstract">
....
</div>
と書いてスタイルシートで
div.abstract{
	margin-left:10%;
	margin-right:10%;
	margin-top: 1ex;
	margin-bottom:0ex;
}
としている。しかし html2tex は "class" を認識しない。そもそも "div" タグを認識しないのだ。

それでも妥協の方法として(美しくはないが)

<abstract>
<div class="abstract">
....
</div>
</abstract>
と書いた時に
\begin{abstract}
...
\end{abstract}
を吐き出してくれるようにできないか? HTML は "<abstract>" を理解しないし、html2tex は "<div>" を理解しないので釣り合いはとれているのだ。

しかし何かできるようだがよくわからん!

注: html2tex は HTML3 で定義されていないタグを機械的に撥ねているようだ。 "<abscract>" などと書くと文句を言われる。だから僕がここに書いたような方向では処理できない!

何とか...

どうも html2tex の使い方に問題があったらしい。
HTML と LaTeX の違いの一つに、表題の置き場所があるのだ。
HTML では "<body>" の後に "<h1>" で表題を書く。ところが LaTeX では "\begin{document}" の前に書く。この違いを処理させるのは面倒なので、html2tex は次のように妥協している。

「スケルトンファイル」に基本的なドキュメントの骨格を書く。そしてこのファイルを html2tex コマンドの引数として与える。 "rit.html" のためのスケルトンファイルを "rit" とすると

	html2tex rit
とするのが html2tex の本来の使い方なのだ。

スケルトンファイルは基本的に LaTeX のファイルであり、主たる役割は "\begin{document}" の前に書くべき情報を html2tex に与える事らしい。以下このファイルを rit とする。

\documentstyle[A4j,12pt]{article}
%html -s article
\pagestyle{empty}
....
\title{Rit \newline --- Embedded Rc in Text ---}
\date{}
\author{Kenji Arisawa, Aichi University\\
{\normalsize\tt arisawa@aichi-u.ac.jp}}
\begin{document}
\sf
\maketitle\thispagestyle{empty}
%html -b
%html rit.html
\end{document}
この中で rit.html を取り込む事が
	%html rit.html
で指示されている。しかしもはや全てを取り込む訳にはいかない。標題を除去しなくてはならないのだ。そこで "rit.html" に次のように除去すべき部分を書き込む。
<!--latex-off-->
<h1>Rit<br>
<span style="text-align: center; font-size: 80%;"> — Embedded Rc in Text —</span>
</h1>
<!--latex-on-->
<div class="abstract">
....
</div>
除去の制御は HTML のコメントを利用しているので、ブラウザの表示には影響を与えないと言う理屈である。

注意: "latex-off" と "latex-on" の書き方は注意を要する。余計な空白は許されないのだ。他方 "<!latex-off>" のように "--" は付けなくても OK である。(僕はこのために随分余計な時間を取られた...)

要約の整形にはさらに工夫が必要である。

プログラムの説明欄

さて "rit.html" には大量の
<div class="code"><pre>
....
</pre></div>
のが現れる。ここに "...." はファイルの内容を表している。それらを全て
\begin{center}
\begin{boxedminipage}[h]{14cm}
\begin{verbatim}
....
\end{verbatim}
\end{boxedminipage}
\end{center}
に変換したいのた。さてどうするか?

注: html2tex の内部では

%html -d pre     -verb "\begin{verbatim} "  "\end{verbatim}\nl"
が定義されている。

貴重な情報が捨てられている!

html2tex は HTML3 で未定義のタグがあると
	rit.html (355) : unknown <div>.
	rit.html (366) : unknown </div>.
のようなメッセージを出して、出力から捨てる。だがこれは良くない! 未定義タグの情報が出力に残っていれば、後は何とかなるのだ。問題のソースコードの箇所は
	else if (tagkind == T_ILL)
	{   	if (freport != NULL)
			fprintf(freport, "%s (%d) : unknown <%s>.\n",
				html_fn, ln, html_com);

	}
で、これを次のように変更すれば良い。

	else if (tagkind == T_ILL)
	{   	if (freport != NULL)
			fprintf(freport, "%s (%d) : unknown <%s>.\n",
				html_fn, ln, html_com);
		if(fout){  // Kenar
			if(attr_name)
				fprintf(fout, "\n%% <%s %s=\"%s\">\n",
					html_com, attr_name, attr_val);
			else
				fprintf(fout, "\n%% <%s>\n", html_com);
		}
	}
これで
<div class="code"><pre>
....
</pre></div>
の出力は
% <div class="code">
\begin{verbatim}
....
\end{verbatim}

% </div class="code">
となる。これは期待以上の成果だ! ( "</div>" にはなっていないことに注意する。)
注: この情報がきっちりと 1 行で収まるようにしたのは、自動処理で面倒がないようにするためである。余分な空行は気にしない事にしよう。

これで abstract の問題も自動的に解決する。つまり sed を使って html2tex がやれなかった事をやるのである。今回僕が使った sed のプログラムを以下に示す。(各自の状況や好みに依存している)
s/^% <div class="abstract">/\\begin{abstract}/
s/^% <\/div class="abstract">/\\end{abstract}/
s/^% <div class="code">/\\begin{center}\\begin{boxedminipage}[h]{14cm}/
s/^% <\/div class="code">/\\end{boxedminipage}\\end{center}/
/thebibliography/,$ { s/\\cite{[^}]*}//g; }
# -------------------
s/^fig1$/\\begin{center}\\scalebox{0.5}{\\includegraphics{fig1.pdf}}\\end{center}/
s/^fig2$/\\begin{center}\\scalebox{0.5}{\\includegraphics{fig2.pdf}}\\end{center}/
s/^Fig\..:.*/\\begin{center}&\\end{center}/
s/subsection/section/
s/\\section{References}//
なお、このファイルで
	/thebibliography/,$ { s/\\cite{[^}]*}//g; }
となっているのは html2tex の過剰な親切を断るためである。

HTML では全ての URL にリンクを張っておくのは自然であるが、htmp2tex は全てのリンクを "\footnote{...}" にするか "\cite{...}" で参考文献と結びつける。本文ではこの考えで良いのであるが、bibliography の URL に対しても行うのである!

また、このファイルの

	s/subsection/section/
は、html2tex が "<h2>" を "subsection" にマップするからだ。 "<h3>" は "subsubsection" だ。このマップは変更できるらしいが、僕は面倒だから sed でやっている。

注意: 結局僕は Reference の参照関係を ptt を使って解決する事にした。従って sed のプログラムは多少変更されている。

Reference の処理

Reference の問題はどのように解決しているのだろう?

HTML 文書中に LaTeX の命令を埋め込むことができる。これはコメントとして埋め込む。例えば

To the contrary, both Rit and Rc<!--latex \cite{kn:Rc}--> is small.
こうすると html2tex で処理された LaTeX の文書は
To the contrary, both Rit and Rc\cite{kn:Rc} is small.
となる。従って LaTeX の bibliography
\begin{thebibliography}{99}
...
\bibitem{kn:Rc}
http://cm.bell-labs.com/sources/plan9/sys/src/cmd/rc/
...
\end{thebibliography}
が準備されていればよい事になる。

現在の正しいコメントスタイル "<!--latex \ref{kn:Rc}-->" は冗長である。html2tex は古いコメントスタイル "<!latex \ref{kn:Rc}>" をも処理してくれるが、これはブラウザ依存性を持つので使用は止めた方が良いであろう。

数式

今回の文書には 2 つの数式が現れた。
	n - 1
のような簡単な数式だ。これは HTML では
	<i>n</i> &minus; 1
でまあいいだろう。このままでも PDF になった文書では見栄えは悪くない。しかし正式な TeX の数式ではない。TeX では単に
	$n - 1$
である。一つの数式表現を両方に対応させる事は難しい事なのかも知れない。html2tex では同じ数式を二通りの形式で書く。つまり
	<!--latex-off--><i>n</i> &minus; 1<!--latex-on $n - 1$-->
と書く。僕は ptt を使って HTML を自動生成しているので、単に
	<$n - 1$>
と書いて HTML と LaTeX の両方を自動的に生成してくれるのが良いと思う。LaTeX の方は簡単だ。でも HTML の方は極く極く簡単なものしかやる気になれないね。

結論

"html2tex" はテーブルや数式を使っていない文書を LaTeX に落とすには役に立つ。HTML を LaTeX に変換する場合には好みの問題が発生する。変換ツールに完全性を求めづらいのである。従って sed のようなツールで好みに応じて再変換できる仕組みが欲しい。そのためには処理しなかった情報を捨てないでコメントに残す配慮が必要である。

HTML2LaTeX

これは先の html2tex のドキュメントの中で
Another interesting, and probably more powerfull, HTML to LaTeX converter using Perl can be found here.

として紹介されている。説明を読む限りかなり高度な事をしているらしい。しかしファイルをダウロードしようと思ってもできない。サーバがダウンしたままだ!