jsdvi - JavaScriptでdviプレビューアを書いてみるというネタ（→ dvi.jsに改名しました）

[TeX & LaTeX Advent Calendar 2012](http://atnd.org/events/34318)に捧ぐ

公式サイトは[こちら](https://github.com/naoyat/dvi.js/wiki)。

## デモ

http://naoyat.github.com/dvi.js/

> ※iOS5のSafariで見る人は http://naoyat.github.com/dvi.js/iphone-safari.html でどうぞ。さもないとブラウザが落ちます。Chromeは http://naoyat.github.com/dvi.js/ で大丈夫でした。

Google Chrome前提。Firefox, Safariでも大丈夫っぽい。その他のブラウザは未調査。

矢印キーとか hjkl とかでページを移動できます。
TFM読み終わるまでページを表示しないので、サンプルによっては起動がちょっと重いかも。（画面遷移しなくて心配なので "now rendering..." とか言うようにしました）

## 動機

ブログでTeX数式を使いたい、のだけれどそこだけ画像で埋め込むと何か不自然な感じになってちょっと嫌。地の文章もTeXで書きたい。TeXでブログを書けないかな？

かといって、dviファイルをPDFに変換して公開、だと最早ブログじゃないし…

というか今のJavaScriptとCSSならdvi出力をごにょごにょリアルタイムに変換してそのまま表示できるんじゃないか？

と思ってdviをブラウザ上でJavaScriptで展開してjQueryで動的に画面を組み立ててみるテストがこれ

## 道のり

* dviファイル（バイナリ！）の読み込み
* 組版命令のデコード
* TeXの中身の日本語がJISコードなのでUnicodeに変換
* spanブロックを絶対位置に配置していく
* とか普通に実装すると1文字1文字がspanになる。嫌
* なので、文字列としてくっつけられる所はできるだけくっつける的モードもある（が、文字の位置はずれる。ちょっと高度な計算をして何とかならないか）
* [NEW!] TFM/JFMの情報を使ってきっちり揃える。だいぶ綺麗に出るようになった！
* [NEW!] Webフォント（というかその元になってるbakomaフォント）では0x00-0x20のグリフが0xA0以降に移動しているのでそれに対応したらπもff/ffl/ffiも数式記号もちゃんと出るようになった！
* [NEW!] オールインワンっぽい dvi.min.js を用意。（@garaemonさんのminify-jsを使ってます！）これとwebフォントと texfonts.min.css があれば多分どこででもdviが見られる。（一応どれもローカルに持ってなくてもURL指定で動く）

## 使い方

```
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>dvi.js demo</title>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  <script type="text/javascript" src="http://naoyat.github.com/dvi.js/dvi.min.js"></script>
  <link rel="stylesheet" type="text/css" href="http://naoyat.github.com/dvi.js/texfonts.min.css"></style>
</head>
<body onload="dvi_load({out:'#out',file:'sample.dvi'});">
<div id="out"></div>
</body>
</html>
```

## 表示例

[R5RS日本語訳](http://naoyat.github.com/jsdvi/?r5rs)
![sample](http://www1419ue.sakura.ne.jp/jsdvi/sample_r5rs.png)

----

[色のサンプル](http://naoyat.github.com/dvi.js/?rgbcolor)
![sample](http://www1419ue.sakura.ne.jp/jsdvi/sample_color.png)

----

[dviout/prtに付属のpTeX縦書きサンプル](http://naoyat.github.com/dvi.js/?naochan!)
![sample](http://www1419ue.sakura.ne.jp/jsdvi/sample_ptex.png)

----

[数式サンプル1](http://naoyat.github.com/dvi.js/?sample)
![sample](http://www1419ue.sakura.ne.jp/jsdvi/sample_math.png)

----

[数式サンプル2](http://naoyat.github.com/dvi.js/?sample)
![sample](http://www1419ue.sakura.ne.jp/jsdvi/sample_math2.png)

[ドラゴン曲線（TeXブック付録Dのあれ）by @golden_luckyさん](http://naoyat.github.com/dvi.js/iphone-safari.html?dvi=dragonheart)
![sample](http://www1419ue.sakura.ne.jp/jsdvi/sample_dragonheart.png)

----

TFMを読む前は、フォントのデザインサイズ値と、webフォントでcanvasに描いてどのくらいの幅になったかで近似していた。

1文字ずつDOM作って絶対位置に置いて行ってるのでコピペしづらいから同じフォントの連続した文字列は一塊にするなどしたい（が途中にグルーが入ってたりするので幅を再計算して均等割にするとか必要）。
これはURLに付加するパラメータで切り替えられるようにしたい。

Computer Modernフォントをpkフォントとかから読むとかはしてなくて、[webフォント化されたもの](http://jadzia.bu.edu/~tsl/using-tex-fonts-in-html/)を利用。FirefoxだとComputer ModernのWebフォントが読み込めなかったり縦書きがうまく出なかったりなのでChrome推奨。

当初、ff とか fi みたいな合字とか、cmmi10 の π とか（おそらく文字コード0x00〜0x1f）このWebフォントだと出ない文字があって表示が抜け落ち数式が正しく表示されなかったのでPKフォント読んで自作する必要があるかと思ったが、BakomaフォントがTrueType化する際にOSが正しく扱えるコード領域に移動させているのが原因だった。これに対応することでちゃんと表示されるようになった。

## コード (github)

https://github.com/naoyat/dvi.js

## TODO

* 日本語の約物の位置が合ってなさげ（JFMの情報がちゃんと使えてない？）なので何とかしたい。 → TeXが、というかJFMが想定しているJIS日本語フォントは可変幅だけれど、dvi.js では固定幅フォントで表示しているのでその分の幅の補正を行うことで解決。
* コピペfriendlyなモードを作る →作った
* TFMの置き場を考える（現状１ディレクトリにひとまとめ） →webフォント準備済みフォントのTFMをJS化したものを用意してある
* システムフォントのメトリクスとの誤差を考慮 →それなりに。ブラウザやOSの違いがあるのでやるべき事は多いかも。
* dvi.min.js 的な物を作る →作った
* 英語の紹介ページを作る →作った

## ライセンス

MIT Licenseで