資料室へ

Dart 言語仕様書の LaTeX ファイルについて

2014-08-12 (鈴)

1. はじめに

プログラミング言語 Dart の言語仕様書は ECMA-408 "Dart Programming Languages Specification" PDF [ecma-international.org] としてだけでなく,そのソース・ファイルにあたる LaTeX ファイルとしても与えられている。 本稿では同ファイルを取得し独自に PDF を作成する方法,およびその日本語版を作成する手順について記す。

本稿で説明する手順は Mac OS X 10.7.5, 同 10.8.5, 同 10.9.4 にそのまま適用でき,次節 (2. MacPorts) を除けば Unix/Linux 全般にも適用できる。

2. MacPorts

ここでは TeX 一式を MacPorts [macports.org] で用意する。 下記を実行する (時間がかかるから,どこか出かける前などに始めておいて,しばらく放置しておくとよい)。

01:~$ sudo port install texlive +full

以下,この節の残りでは MacPorts がインストールされていない場合 (上記が sudo: port: command not found でただちに終わる場合) の MacPorts の導入方法を簡単に説明する。 上記で無事インストールが始まった場合,または別に TeX 一式をインストール済みの場合は §3 へと読み飛ばされたい。

  1. Xcode アプリケーションをインストールする。 Mac App Store 経由でも Apple (無料)登録開発者用ダウンロード・ページ経由でもどちらでもよい。 いったん起動してライセンス条件を受諾しておく。
    このステップを省くと後で LLVM 関連の一部の MacPorts パッケージの導入に失敗する結果になったと思います。
  2. Command Line (Developer) Tools をインストールする。 Xcode アプリケーションの Preferences... メニューの Downloads タブ経由でも Apple (無料)登録開発者用ダウンロード・ページ経由でもどちらでもよい。
    OS X 10.9.4 の場合,Xcode アプリケーションからはインストールできない。ネットにつながった状態でターミナルから下記を実行するのが簡単である。
    01:~$ xcode-select --install
    
    これでどこにどんなファイルがインストールされたかは事後,/var/db/receipts/com.apple.pkg.MacOSX10_9_SDK.bomcom.apple.pkg.CLTools_Executables.bomlsbom コマンドで見ると分かります。
  3. The MacPorts Project -- Download & Installation [macports.org] から MacPorts-2.3.1.tar.bz2 をダウンロードし,
    01:~/src$ tar xf ~/Downloads/MacPorts-2.3.1.tar.bz2
    01:~/src$ cd MacPorts-2.3.1
    01:~/src/MacPorts-2.3.1$ ./configure
    
    とする。デフォルトで --prefix=/opt/local が指定され MacPorts が /opt/local/ 以下にインストールされるように設定が行われる。 例によって
    01:~/src/MacPorts-2.3.1$ make
    
    をしてから
    01:~/src/MacPorts-2.3.1$ sudo make install
    
    をする。/opt/local/ 以下に MacPorts の骨組みが作られる。 この時点で用意されるコマンドはパッケージ管理用の /opt/local/bin/port などだけである。
    /opt の下にインストールされる他の代表的なソフトウェアとして XQuartz [macosforge.org] (X11 および OS X について [apple.com] 参照) があります。 XQuartz は /opt/X11 以下にインストールされます。 XQuartz と MacPorts のファイル群に依存関係はなく,両方をインストールしても問題ありません。 典型的な使い方は
    1. XQuartz 由来の X サーバと基礎的な X11 クライアントをそのまま利用し,MacPorts でその他を用意する。または
    2. XQuartz をインストールせずに X11 関連のすべてを MacPorts でまかなう。
    のどちらかです。 1. の場合,例えば MacPorts の kinput2canna で XQuartz の xterm の日本語入力をします。
  4. ~/.bash_profile に下記を加えて MacPorts へ PATH を通す。
    PATH="/opt/local/bin:/opt/local/sbin:$PATH"
    
    いったんターミナルを起動し直して PATH の設定を有効にする。
  5. ネットにつながった状態で
    01:~$ sudo port -v selfupdate
    
    を行い,現在のパッケージ情報を取得する (-v は冗長モード, verbose mode のオプションである)。 この取得は毎日とは言わないまでも時々は行い,情報を更新するとよい。
  6. 今インストールされているパッケージの一覧を見たければ
    01:~$ port installed
    
    全パッケージの一覧を見たければ
    01:~$ port list
    
    例えば wget パッケージの説明を読みたければ
    01:~$ port info wget
    
    この説明で Variants: [+]ssl, test, universal と表示されますが,この [+] は ssl バリアントがデフォルトで選択されていることを意味します。
    $ port info wget -ssl のように - を接頭して選択を外すことができます。
    $ port info wget +test のように + を接頭して選択に加えることができます。
    選択によって依存関係が変化しますから Dependencies の表示も変化します。
    wget パッケージのバリアントの説明を読みたければ
    01:~$ port variants wget
    
    $ port var wget のように略記できます。
    今仮に wget パッケージをインストールしたとき,依存関係にしたがってどんなパッケージがインストールされるかを知りたければ ("dry run" の -y オプションを使って)
    01:~$ sudo port -y install wget
    
    port info と同じように port install でも
    $ sudo port -y install wget -ssl などとバリアントを指定できます (ただし,実際に wget に -ssl を指定することはあまり勧めません)。
    wget パッケージをダウンロードしてインストールしたければ
    01:~$ sudo port install wget
    
    (sudo port selfupdate 後に) 古くなったパッケージを更新したければ
    01:~$ sudo port upgrade outdated
    
    (sudo port upgrade outdated 後に) 新バージョンに置換されて inactive になったパッケージを (ディスク容量の節約のために) 削除したければ
    01:~$ sudo port -u uninstall
    
    port コマンドにはいろいろな機能がありますが,日常的には上記だけで必要十分です。
  7. もし Java 6 をインストールしていなければ Java for OS X 2014-001 [apple.com] をインストールしておく。
    Java 6 のインストールを省いた場合,MacPorts の一部のパッケージがその存在を仮定している模様ですから依存関係によっては何かトラブルを起こすかもしれません。 どのみち Dart を使うつもりならば Dart Editor をハックなしに起動するために Apple の Java 6 を入れておくのが無難です (Troubleshooting Dart Editor [dartlang.org] および Bug 411361 – [Mac] Kepler doesn't launch without JRE 6, even if JDK 7 is installed [eclipse.org] 参照)。 ただし,今は状況が変化しているかもしれませんから,もし読者に関心があれば Java 6 の実際の要不要を検証してくれるとうれしいです。
  8. 今や MacPorts が機能しているから下記を成功裏に実行できる。
    01:~$ sudo port install texlive +full
    

3. Dart ソース取得

Dart のソースは http://code.google.com/p/dart/source/checkout に書かれているとおり下記のようにして取得できる。

01:~/tmp$ svn checkout http://dart.googlecode.com/svn/trunk/ dart-read-only

カレント・ディレクトリ直下に dart-read-only ディレクトリが作られ,そこにファイルが一式おかれる。 以下の説明ではリビジョン 38888 を取得したとする。

ちなみにリビジョン 38112 等では dart-read-only/dart/tools/utils/elisp/dart-mode.el がありました。
01:~/tmp/dart-read-only/dart/tools/utils/elisp$$ ls -l
total 16
-rw-r--r--  1 suzuki  staff  6886 Jul 10 19:34 dart-mode.el
01:~/tmp$  
これを Emacs の load-path の通っているところに置いて ~/.emacs
(autoload 'dart-mode "dart-mode" "Major mode for editing Dart source text." t)
(add-to-list 'auto-mode-alist '("\\.dart$" . dart-mode))
を書けば Emacs で快適に Dart プログラムを編集できます。

Dart 言語仕様書のソースは dart-read-only/dart/docs/language/ にある LaTex ファイル dartLangSpec.texdart.sty である。

01:~/tmp/dart-read-only/dart/docs/language$$ ls -l
total 688
-rw-r--r--  1 suzuki  staff    2610 Aug  5 08:50 dart.sty
-rw-r--r--  1 suzuki  staff  346100 Aug  5 08:50 dartLangSpec.tex
01:~/tmp/dart-read-only/dart/docs/language$  

この language ディレクトリを適当な場所,例えば ~/tmp/ にコピーして作業しよう。

4. 原語版 PDF 作成

すぐに分かるようにこのままでは LaTeX にかけることはできない。

まず dartLangSpec.tex 冒頭の

\usepackage{bnf}

に該当するファイル bnf.sty がない。 検索すると候補がいくつか見つかるが,試した範囲では下記のファイルが適合する。

これをダウンロードして dartLangSpec.tex と同じディレクトリに置く。

次に dart.sty\DEFERRED{} の定義が欠けている。 下記のように補う。

  \def\DEFAULT{\keyword{default}}
  \def\DEFERRED{\builtinId{deferred}}
  \def\DYNAMIC{\builtinId{dynamic}}

ここまでで一応 LaTeX ファイルをコンパイルできる。

01:~/tmp/language$ latex dartLangSpec.tex

インデックス作成のためこれを3回繰り返す。

しかし,でき上がった dartLang.dvi から pdf ファイルを作るとき

01:~/tmp/language$ dvipdfmx dartLangSpec.dvi

大量に dvipdfmx:warning: Unknown token "SDict" の警告が発生する。 dartLangSpec.tex 冒頭の

\usepackage{hyperref}

\usepackage[dvipdfmx]{hyperref}

として作り直す。 しおり付きの PDF ファイルが作成される。

5. 日本語版 PDF 作成に向けて

英文を日本語文に置き換えるために Emacs などのテキスト・エディタで dartLangSpec.tex を開くと,なぜか Shift JIS テキストとして認識される。 iconv でファイルの文字コードを変換し, diff で差分を調べると第2523行,第2525行,第5101行,第5194行に 0xD4 と 0xD5 のバイトが出現していることが分かる。 これらがそれぞれ Shift JIS の半角カタカナ「ヤ」「ユ」 に相当することが Shift JIS として認識された理由である (ちなみに LATIN-1 では Ô と Õ に相当する)。

前節で得られた PDF 等をみても特に対応する文字がないことから削除しても問題はないと見られる。 さしあたり dartLangSpec.tex を Shift JIS から UTF-8 に変換しておく。

LaTeX の \tableofcontents による目次出力が Contents ではなく 目次 となるようにしたい。 dartLangSpec.tex 冒頭の

\documentclass{article}

\documentclass{jarticle}

とする。

\section{} 内を日本語にすると PDF のしおりが文字化けする。 dartLangSpec.tex 冒頭の

\usepackage[dvipdfmx]{hyperref}

\usepackage[dvipdfmx]{hyperref}
\usepackage{pxjahyper}

とする。

MacPorts の texlive +full には pxjahyper が標準で含まれています。
01:~/tmp/language$$ grep pxjahyper dartLangSpec.log 
(/opt/local/share/texmf-texlive/tex/platex/pxjahyper/pxjahyper.sty
Package: pxjahyper 2012/05/27 v0.2
01:~/tmp/language$  

原注のスタイルは dart.sty

\newenvironment{commentary}[1]{{\sf #1}}

のように定義されている。 しかし,このままでは日本語にしたとき,地の文とほとんど区別できない。 決して最適ではないが,さしあたり,少し字を小さくして上下に空白をいれる。

\newenvironment{commentary}[1]{{\sf \small \vspace{1em} #1 \vspace{1em}}}

訳注を枠付き文章として書けるようにしたい。 とりわけこの仕様書はプログラム例がほとんどないため,

\begin{note}
  ……
\end{note}

のように囲んでコード断片などを自由に含められるようにしたい。 しかし,同時に,訳注を消して仕様書本来の文だけからなる PDF を簡単に作れるようにしたい。 そこで dartLangSpec.tex 冒頭付近または dart.sty に下記を追加する。

%% 訳注を出力したいとき
\usepackage{ascmac}
\newenvironment{note}{\begin{shadebox}}{\end{shadebox} \vspace{1em}}

%% 訳注を消したいとき
%\usepackage{environ}
%\NewEnviron{note}{}

dartLangSpec.tex\date{} がないため,LaTeX でコンパイルした日付がそのままタイトルに出力される。 dartLangSpec.tex\begin{document} の前あたりにソース取得の日付を入れる。

\date{平成26年8月5日}
\begin{document}
\maketitle

この後,ソースの変更差分を反映させるたびにこの箇所も変更していこう。

ここまでで一応,英語を日本語に置き換えた LaTeX ファイルをコンパイルできる。

01:~/tmp/language$ platex dartLangSpec.tex

インデックス作成のためこれを3回繰り返して

01:~/tmp/language$ dvipdfmx dartLangSpec.dvi

を行い,PDF ファイルを作成する。 下図は試みに一部を和訳した結果である。

6. おわりに

LaTeX ファイルは様々なプログラムで多様に処理できる人間可読なテキスト・ファイルですから,言語仕様書の広範な二次利用,三次利用が可能です。 Dart ソース [google.com] が寛大な修正 BSD ライセンスで公開されていること,また相当する ECMA-408 "Dart Programming Languages Specification" PDF ファイルがその Copyright Notice で英語以外の言語への翻訳や注解,アクセシビリティのための加工を陽に許可していることに感謝します。


Copyright (c) 2014 OKI Software Co., Ltd.