TeX」カテゴリーアーカイブ

TeX, LaTeX 関連の記事

LaTeX 文書から処理系を推定する(主に日本語)

前回の記事では、 LaTeX 文書にマジックコメントとして処理系やメインファイルを記述するやり方について書いた。今回は、マジックコメントがない場合に処理系を推定する方法について考える。

LaTeX 文書の処理系(エンジン)には色々あるが、このブログの読者が使うのは次の6種類のうちのどれかだろう(最近はデフォルトで e-TeX 拡張が使えるみたいなのでその辺の細かい区別は必要ない)

  • pdfLaTeX
  • XeLaTeX
  • LuaLaTeX
  • LaTeX + dviware (e.g. dvipdfmx)
  • pLaTeX + dviware (e.g. dvipdfmx)
  • upLaTeX + dviware (e.g. dvipdfmx)

(この他に、最近は pTeX-ng なる代物もあるらしいが、筆者はよく知らないのでこの記事では無視する)

日本語の場合は、文書が特定の処理系専用になることが多く、ドキュメントクラス等を調べることによって判別できる(できてしまう)ことが多い。逆に、欧文の文書を pdfLaTeX, XeLaTeX, LuaLaTeX のどれで処理すべきか判別するのは難しいと思われる(まあ、「どれでも処理できる」のであればデフォルトの処理系で処理するというので問題ないのだが)。

ドキュメントクラスから処理系を判定する

日本語の文書向けのドキュメントクラスは、特定の処理系専用に作られているか、もしくはクラスオプションで処理系を指定するようになっていることが多い。

pLaTeX 用:

  • jarticle, jbook, jreport
  • tarticle, tbook, treport
  • jsarticle, jsbook (without ‘uplatex’ option)

upLaTeX 用:

  • ujarticle, ujbook, ujreport
  • utarticle, utbook, utreport
  • jsarticle, jsbook (with ‘uplatex’ option)

LuaTeX 用 (LuaTeX-ja) :

  • ltjarticle, ltjbook, ltjreport
  • ltjsarticle, ltjsbook
  • ltjtarticle, ltjtbook, ltjtreport

BXjscls:

  • bxjsarticle, bxjsbook, bxjsreport, bxjsslide
  • クラスオプションとして処理系を指定: latex,platex,uplatex,lualatex,xelatex,autodetect-engine のいずれか
  • DVI 出力の場合、クラスオプションとして dviware を指定: dvips,dviout,xdvi,dvipdfmx のいずれか
  • autodetect-engine が使用されていた場合は、文書から処理系を判定することはできない。

もちろん、これらのドキュメントクラス自体の改訂によってこの辺りの仕様が変わる可能性があり、今後もずっとこの判定方法に頼れるとは限らない。(実際、この記事を書いている間に jsclasses に autodetect-engine が実装されてしまった

使うパッケージによって処理系を判定する

日本語文書であっても、例えば Beamer を使う場合は、ドキュメントクラスからエンジンの推定はできない。しかし、そのような場合でも、使うパッケージによってエンジンを判定できる場合がある。

  • minijs, okumacro, jsverb, okuverb, pxjahyper, etc: (u)pTeX 専用
  • luatexja, luatexja-ruby, luatexja-otf, luatexja-preset: LuaTeX 専用
  • xltxtra, xeCJK, zxjatype: XeTeX 専用
    • xltxtra パッケージは fontspec パッケージに取って代わられたようなので、見かけることは少ないかもしれない。
  • fontspec, unicode-math: XeTeX または LuaTeX
  • 以前このブログで言及した filemod パッケージは pdfTeX または LuaTeX を必要とするものだった。(しかし、広く使われているとは思えないので、判定には利用できないだろう)

もっと色々あるだろうが、網羅的に列挙しても仕方がないので、このぐらいにしておく。

ドキュメントクラスと同じく、パッケージについても、仕様の変化や代替パッケージの登場によって、ここに書いた情報が古くなっていく可能性がある。

雑感

このような heuristics はやはり筋が悪い気がしてきたし、確実な動作を望むなら、前回書いたような方法でユーザーが明示的に指定するべきだろう。

それでもこの記事に書いたような方法で処理系の推定を行いたいのであれば、なるべく最新の動向を追いかけるようにしたい。

TeX 文書の Magic Comment

この記事では、 TeX 文書におけるマジックコメントの種類と構文についてまとめてみた。

マジックコメントとは

プログラムのソースコードというのは、プログラミング言語の処理系(実行環境)向けに書かれているものである。しかし、テキストエディターなどの周辺ツールは、そのソースコードについて、処理系が必要とする以上の情報が欲しいことがある。そういう場合に、追加の情報をソースコードのコメントとして記述してやって、周辺ツールに与えてやるということがよく行われる。このようなコメントは、俗に、マジックコメントと呼ばれる。

「追加の情報」の中で典型的なものが、文字コードである。Emacs で編集されるソースコードに -*- coding: utf-8 -*- と書かれたコメントがあるのを見たことがある方も多いだろう。

(ちなみに、 Python や Ruby などの一部のスクリプト言語処理系は、マジックコメントによってファイルの文字コードを判定する場合がある。つまり、コメントとして書かれたものが処理系にとってい意味を持つ。) 続きを読む

LaTeX の数式をターミナルで手軽に MathML に変換する

テキストエディタで HTML 文書を直書きしていて、 MathML で数式を書きたいけど MathML 直書きは嫌だ!という時。Pandoc を使えば、ターミナルで手軽に LaTeX 形式の数式を MathML に変換できる。

例:

$ pandoc -f latex -t html5 --mathml
\(\frac{1}{e^z-1}\)
^D
<p><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>1</mn><mrow><msup><mi>e</mi><mi>z</mi></msup><mo>−</mo><mn>1</mn></mrow></mfrac><annotation encoding="application/x-tex">\frac{1}{e^z-1}</annotation></semantics></math></p>

太字の部分が自分で入力する部分である。(^D は Control-D の意)

\mathfrak と打つのがだるい

数学の一部の分野では、フラクトゥールが多用される。数式中でフラクトゥールな文字をLaTeXで書く際は \mathfrak{a} とか書くわけだが、たくさん出てくると入力するのがだるい。

短い名前をつける

幸い、LaTeXにはマクロ機能があるので、 \mathfrak のコマンド名が長いと思ったら、短い名前を与えてやれば良い。

\newcommand\mf{\mathfrak}
\mf{a} % → \mathfrak{a} になる
\mf a % → 上に同じ。コマンドの引数が1文字の場合は { } を省略できる

個々の文字にコマンドを割り当てるという手もある。

\newcommand\a{\mathfrak{a}}
\a % → \mathfrak{a} になる…はず

が、しかし、 \a という名前のコマンドは LaTeX によってすでに定義されているようで、 \newcommand でエラーが出る。\renewcommand を使えば定義を上書きできるが、副作用が怖い。

別の名前を試してみよう。

\newcommand\aa{\mathfrak{aa}}
\aa % → \mathfrak{a} になる…はず

が、しかし、\aa という名前のコマンドも LaTeX によってすでに定義されているのであった。

このように、「短い名前をつける」という戦略は「名前の衝突」によって阻まれる可能性がある。\renewcommand や、TeX primitive の \def によって上書きすることはできるが、既存のコマンドの不具合(副作用)を引き起こす可能性は否定できない。

ただ、上書きするスコープを限定してやれば、副作用を引き起こす可能性は小さくできるかもしれない。

{ % スコープを作る
\renewcommand\aa{\mathfrak{a}}
$\aa$ % → \mathfrak{a} になる
} % スコープを閉じる

\aa % → 元の意味(å)になる

\begin{center} % \begin{} 〜 \end{} は一つのスコープになる
\renewcommand\aa{\mathfrak{a}}
$\aa$ % → \mathfrak{a} になる
\end{center}

\aa % → 元の意味(å)になる

毎回 \renewcommand\aa{\mathfrak{a}} と打つのが面倒だったら、これもマクロにすると良いだろう。

\newcommand\UseMathFrak{%
  \renewcommand\aa{\mathfrak{a}}%
}

{ % スコープを作る
\UseMathFrak
$\aa$ % → \mathfrak{a} になる
} % スコープを閉じる

\aa % → 元の意味(å)になる

\begin{center} % \begin{} 〜 \end{} は一つのスコープになる
\UseMathFrak
$\aa$ % → \mathfrak{a} になる
\end{center}

\aa % → 元の意味(å)になる

短い名前をつける(亜種)

普通のコマンド名はバックスラッシュ \ から始まるが、コマンド名として使えるものはこれだけではない。TeX 標準では、半角チルダ ~ を単独で(バックスラッシュなしに)コマンド名として使うことができる。

知っての通り、半角チルダ ~ は標準では「改行しない空白」という意味を持つが、そこは\renewcommand で上書きしてやる。

\renewcommand~{\mathfrak}
~a % → \mathfrak a と等価

既存のコマンドを上書きすると副作用が怖い、とか、元のコマンドが使えなくなる、という場合は、スコープの中で \renewcommand することによって影響範囲を小さくできる。

Unicode の文字を使う

Unicode には、様々な字体の「数式用アルファベット」が用意されている。その中には、フラクトゥールもある。これらを LaTeX ソース中に直接記述すれば、\mathfrak といちいち書かなくても良くなるのではないか。

スクリーンショット 0028-05-26 19.24.28

unicode-math パッケージを使うと、 Unicode の数式用アルファベットで書いたものを LaTeX\mathfrak 等で書いたものと等価にしてくれる。

ただし、 unicode-math パッケージを使うには LuaTeXXeTeX が必要である(e-upTeX や pdfTeXでは使えない)。

注意点として、 unicode-math を使うと Unicode の数式用アルファベットのカテゴリーコードが変わるようだ。unicode-math を使わなければカテゴリーコード11 (letter) だが、unicode-math を使うとカテゴリーコード12 (other) になる。どう影響するかというと、 例えば

𝔞\to𝔟     % ← \to の後に空白がない

と書いた時に、 unicode-math を使わないと「文字 “𝔞”」「コマンド名 “\to𝔟”」として解釈されるのが、 unicode-math を使うと「文字 “𝔞”」「コマンド名 “\to”」「文字 “𝔟”」として解釈されるようになる。普通は前者の挙動の方が望まれるとは思うが。

unicode-math を使わない(使えない)場合、 Unicode の数式用アルファベットのカテゴリーコードを13 (active) にしてマクロを定義するという手がある。

\catcode`𝔞=\active % “𝔞” という文字を単独でコマンド名として使えるようにする
\newcommand{𝔞}{\mathfrak{a}}
𝔞 % → \mathfrak{a} に展開される

いずれにせよ、TeX エンジンの側で Unicode に対応している必要がある。

Unicode の数式用アルファベットを使う方法ならば、「短い名前をつける」方法にあった「コマンド名がかぶる」という問題は存在しない。ただし、デメリットとして、 Unicode の数式用アルファベットを入力するのは面倒くさいということが挙げられる。

結論

エディター側で入力支援的なものが欲しい。

LaTeX の \verb についてのメモ

導入

LaTeXをやったことがある人なら \verb コマンドはきっと知っているだろう。

例: \verb|hoge|hoge

例: \verb+foo bar+foo bar

亜種として、\verb の直後にスター * がついた版は、空白を可視化する(空白が ⎵ みたいな記号になる)。

例:\verb*+foo bar+foo⎵bar

この \verb というコマンドは、「TeXの特殊文字を無力化する」「任意の文字を終端として使える」という点で、非常に風変わりである。\verb コマンドを知ることは、TeXの字句解析のルール(カテゴリーコードとか)に対する理解を深めることに直結すると言っても過言でないだろう(たぶん)。というわけで、\verb について重箱の隅をつついた結果をここに書いておく。

なお、TeXにおける「カテゴリーコード」とかそういうアレはここでは解説しない(対象読者が謎)。

続きを読む

dvisvgmとSTIXフォント

以前、dvisvgmについてちょろっと書いた。その時は、dvisvgmでSVGファイルを生成する時に --no-fonts オプション(文字のアウトライン化をする)をつけないとフォントが正常に指定されないという結論だったわけだが、それではブラウザで表示した時に文字が選択できない。

そこで、dvisvgmで --no-fonts オプションを使わずに生成したSVGファイルで、文字が正常に表示されるような方法を考えてみよう。

続きを読む

LaTeXでPDF出力する際のTips その2

LaTeXでPDF出力する際のTips では、

  • PDFのメタデータの文字化けの解消方法
  • PDFのタイトルや作成者を \title, \author から自動的に設定する方法

を扱った。

今度は、PDFの目次(ブックマーク、しおりと呼ぶこともあるようだが、この記事では「目次」で通す)についてのTipsを扱う。

続きを読む

TeXでファイルの更新日時を取得する

TeXでは \today で現在の日付を取得できる。\maketitle\date を省略すると現在の日付になる。

しかし、TeX文書の「内容」に関わる日付と言ったら、ファイルの更新日時ではないだろうか。タイトルのところにファイルの更新日時を(自動で)出す方法はあるか。

ググってみたら割と簡単に答えが出てきた。

pdfTeXだと \pdffilemoddate というプリミティブがあるらしい。例えば \pdffilemoddate{\jobname} と書くとコンパイル中のファイルの更新日時が D:20150829212230+09'00' というようなフォーマットで取得できるようだ。

LuaTeXだと \pdffilemoddate はないが、Luaを使えば同じようなことはできるだろう。まあ自分でLuaコードを書いて実装するのは面倒なので、既製品を使おう。

filemodというパッケージはpdfTeXとLuaTeXで使えて、ファイルの更新日時を取得するだけじゃなくて、\today と同じような読みやすいフォーマットにしてくれるようだ。例えば、ファイルのプリアンブルに

\usepackage{filemod}
\date{\Filemodtoday{\jobname}}

と書けばタイトルの日付がファイルの更新日時になる。

複数のファイルの中で最も新しい更新日時を使いたいときは、試してないけど \filemodNewest を使えば良さそう。

既に書いたように、filemodパッケージはpdfTeXかLuaTeXが必要で、pTeXXeTeXでは動かない。

【2016年12月12日 追記】ε-pTeX では \pdffilemoddate を含むいくつかの pdfTeX primitive が実装されているため、 filemod パッケージを使うことができる。参考:ε-pTeX について