読者です 読者をやめる 読者になる 読者になる

もしTeX芸人が遠藤侑介の『あなたの知らない超絶技巧プログラミングの世界』を読んだら

Quine書きますよね。

というわけで、TeXでQuineを書く話。ただし、前例(TeX de Quine!! - 0番染色体)にあるように、dviやpdfに書き出す例は多いみたいなので、私はコンソール出力結果がQuineになるようにしてみた。コードはこちら。

gist.github.com

これをquine.texとし、

max_print_line=10000 etex -no-shell-escape quine.tex

なんていう風に実行すると、そのコンソール出力がソースコードと一致する。これを書くための技法を紹介しよう。

基本的なQuineの書き方

まずは『あなたの知らない超絶技巧プログラミングの世界』(Amazon.co.jp: あなたの知らない超絶技巧プログラミングの世界: 遠藤 侑介: 本)を読もう。その第3章の技術を使っただけである。なお、その技術をTeXで再現するに際し、e-TeX拡張の\unexpandedを用いて展開制御している*1

TeXでやるにあたっての工夫

TeXのコンソール出力は使いづらいことで有名である[要出典]。まず、バージョン情報や読み込んだファイル、実行結果のサイズなどを勝手に出力する。しかも抑制できない。また、長い文字列を出そうとすると勝手に改行する。これらを解決する必要があった。

ユーザの意図しない出力への対応

まずは、ユーザの意図しない出力への対応である。今回のQuineではdviやpdf側の出力は一切気にする必要がないので,どんな文字列が出力されようが問題ないだろう,と思う読者もいるかもしれない.しかし,それは大きな間違いである.etexを起動したときの文字列を見てもらいたい.

$ etex
This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2014/W32TeX) (preloaded format=etex)
 restricted \write18 enabled.
**

TeXエンジンのバージョン情報などとともに,restricted \write18が有効になっている旨の出力がある.この「\write18」という文字列がQuineでは邪魔になる.そのままソースコードにこれを書くとエラーになるためである.これを回避するために,いささか邪道ではあるが-no-shell-escapeオプションをつけて回避した.\write18さえ禁止してしまえば,出力は

$ etex -no-shell-escape
This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2014/W32TeX) (preloaded format=etex)

となり,無害な出力が得られる.なお,この出力を見てもらえばわかるが,TeXエンジンの情報が入るので,Quineのソースコードは実行するTeXエンジンに(バージョンなども含めて)依存する.

長い出力の強制改行対策

この問題を認識してもらうために,次のコードを考える.

\message{wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww}\bye

これをsample.texとして実行してみる.

$ etex sample
This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2014/W32TeX) (preloaded format=etex)
 restricted \write18 enabled.
entering extended mode
(./sample.tex
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
wwwwwwwwwwwwwwwww )
No pages of output.
Transcript written on sample.log.

なぜか改行される.これは,このツイート


にあるように,TeXの設定ファイルで規定されるものらしい.TeX側からこれを変更するのはつらい.そこで,その設定自体は環境変数を使えば動的に書き換えられることを利用し,これも邪道ではあるが,max_print_line=10000と環境変数を設定して実行することにより,これを回避した.

まとめ

TeXのコンソール出力は扱いづらい.

*1:別に使わなくてもできる

Windows PhoneでテザリングしつつICSするために

数か月ぶりの記事はTeX関係ないという.

はじめに

Windows 10にしてから数日が経った.Hyper-Vを有効にしてもスリープできるようになったと聞き,喜々としてICSでNATもどきして楽しもうした.うまくいっているようだった.しばらくして,持っているWindows Phoneでそのマシンをテザリングして外につないだ.なぜか,ホスト側のWifiに与えられているIPアドレスと,ICSで共有している仮想ネットワークのNICに与えられているIPアドレスが同じだった.別に問題ないけども気持ち悪い.

問題

Windows Phone(試した実機はMADOSMA)でテザリングしたとき,ICSしているWifiアダプタ(試した実機はSurface Pro 3)に割り当てられるIPアドレスと,ICSのローカル側(Hyper-Vの内部ネットワーク)に与えられるIPアドレスが同一になる場合がある.

原因

テザリングで割り振られるアドレスの範囲と,ICSで振られるIPアドレスの範囲が同じ192.168.137.0/24になっている.

対処法

ICSで振られるIPアドレスの範囲を変更する.レジストリ「HKLM\System\CurrentControlSet\services\SharedAccess\Parameters」の

  • (REG_SZ) ScopeAddress
  • (REG_SZ) StandaloneDhcpAddress

の値を,192.168.x.1に変更する.サブネットマスクは255.155.255.0固定で変更できない.


参考
https://support.microsoft.com/en-us/kb/230148

LaTeXでマクロの引数をオーバーロード

はじめに

TeX Forumにこんな質問が来ていた.

TeXにおける制御綴の引数の個数について

要は,TeXのマクロを関数っぽいものとみなし,その上で同名のマクロに引数の個数が異なるものをオーバーロードさせたいというものである.TeXのマクロは単なる字句の置き換え規則に過ぎない*1ので,これを実現するにはTeX言語沼に入らないといけない*2

先の記事の場合,要件は1引数および2引数の場合のみだったが,今後,複数の場合でオーバーロードしたい場合があるかもしれない.単に,そのようなマクロを定義するためのマクロをつくるのが面白そうなので作ってみた.

スタイルファイルの紹介

公開場所

今回,スタイルファイルをoverload.styとして,hak7a3 / overload — Bitbucketに公開しておいた.

使い方

overload.styの使い方は,非常に簡単である.まず,\usepackageでoverload.styを読み込む.

\usepackage{overload}

次に,\newoverloadでオーバーロードするコントロールシーケンスを登録する.

\newoverload{\foo}

ここでは,\fooを「これから複数の引数に対応するマクロ」として登録している.最後に,各引数の個数に対応する動作を\addoverloadで登録する.\addoverloadは\newoverloadで登録したコントロールシーケンス,引数の個数,およびマクロの置き換えテキストを引数として受け取り,オーバーロード用のマクロを作成する.

\addoverload{\foo}{2}{(2):#1 and #2}
\addoverload{\foo}{1}{(1):#1 only}
\addoverload{\foo}{0}{(0):orz}

この例では,上から順に2引数,1引数,および引数がない場合の動作を登録している*3

引数をオーバーロードするように定義したマクロは,引数の末尾を示す\endinvokeを末尾に付加して呼び出す必要がある.例を示す.

\foo\endinvoke

\foo{bar}{baz}\endinvoke

\foo{bar}\endinvoke

上から順に,引数なし,2引数,および1引数呼び出しに対応する,先に述べたように,TeXのマクロは単純なテキストの置き換えしかできないので,そもそも引数の扱いが普通の言語と異なる.それを回避する方法として,今回は末尾を明記する手法を用いた.

これを実行すると,次の結果を得ることができる.
f:id:hak7a3:20150524201435p:plain
引数の個数に従って,マクロの動作が変化していることがわかる.

overload.styで提供されるマクロ展開部分は完全展開可能にしてあるので,\edefの内部でも利用可能である.実際,overload.styのテストコードでそのような使い方をしている.

制限

overload.styで定義したマクロの呼び出しには,いくつか制限がある.大きなものとしては,

  1. 各引数の先頭に\endinvokeが出現してはいけない
  2. 各引数にバランスの取れていない\fiが存在してはいけない

が挙げられる.これらの問題は引数の末尾か否かの判定処理のためのものである.完全展開可能にするため,どうしてもこのようにするしかなく,現状で解決の糸口はつかめていない.

また,内部でeTeX拡張を使っているので,古いTeX処理系では動作しない.もっとも,現在使用されているほとんどのTeXエンジンがeTeX拡張を認めているため,この制限に引っかかる可能性は低いだろう.

*1:これは上記の記事の回答にも示されている

*2:ようこそ

*3:一応注意しておくと,定義順は自由である

TeXで色々な無限ループ

小ネタ.思うところがあったのでいくつか試してみた.

自身が再帰的に展開されていく例

TeXで無限ループやる場合は大抵これ[要出典].実装法はいくつかある.

単純なマクロ
\documentclass{article}
\begin{document}
\newcommand\hoge{\hoge}
\hoge
\end{document}

よくやる.

\aftergroup
\documentclass{article}
\begin{document}
\newcommand\hoge{{\aftergroup\hoge}}
\hoge
\end{document}

\aftergroupにより,\hogeが波閉じ括弧(グループの終了)の直後に挿入される.結構使う.

\afterassignment
\documentclass{article}
\begin{document}
\newcount\fuga
\newcommand\hoge{\afterassignment\hoge\fuga=0 }
\hoge
\end{document}

\aftergroupと同様に,代入の終了時に\hogeが挿入される.

垂直モードに移行しない\par

\documentclass{article}
\begin{document}
\def\par{}
hoge
\end{document}

どこで見たか思い出せないけど,割と面白い例.TeXは\parを挿入することで,垂直モードに移行しようとする.オリジナルの\parには垂直モードに移行する機能があるが,この例では,\defすることによってその機能を奪っている.結果,垂直モードに移行できない.で,水平モードのままなのでTeXが\parを挿入し,……を無限に繰り返す.なぜこんな仕様になってしまったんだ.

追記: あった
水平モードにおける垂直モード用グルーと\par

TeXだってテスト書きたい(続)

前回は,LaTeX単体テストを書くためのスタイルファイルであるqstest.styを紹介したが,今回はそれをJenkinsと連携させる方法を述べる.

Jenkinsからqstest.styの出力結果は直接読み取れない.テスト結果ならJUnitなどが吐き出すXML文書と同様の形式である必要がある.しかし,qstest.styを書き換えるのはもっと面倒である.なので,

  1. latexでqstest.styの形式で記述されたテストコードを処理し
  2. 結果をJUnitが吐き出すXML文書の形式に変換する

Pythonスクリプトを書いた.ここに公開している.変換自体は単純で,特筆することはないので省略.jenkins-qstest.pyがスクリプト本体で,次のように利用する.

python3 jenkins-qstest.py example.tex

実行するとexample.xmlができるので,これをテスト結果としてJenkinsに読ませればOK.標準でlatexコマンドを使用するようになっているが,その辺はオプションでコントロール可能にしてある.

次のテストファイ

\documentclass{article}
\usepackage{qstest}
\IncludeTests{*}
\LogTests{lgout}{*}{*}
\begin{document}
\begin{qstest}
\begin{qstest}{Example}{label}
 \Expect*{\the\numexpr1+2}{3}
\end{qstest}
\begin{qstest}{Example-fail}{label}
 \Expect*{\numexpr1+2}{3}
\end{qstest}
\end{qstest}
\end{document}

で実行した結果がこちら.



やったぜ.

ちなみに,これはLISP on TeXの今後の開発で利用するために作成したスクリプトで,実際に運用を開始している.

pdfTeXじゃないけどGhostscriptさえあれば画像は埋め込めるよねっ

2015/1/24 16:48 GhostscriptをGhostScriptと記述していました.お詫び申し上げます.

はじめに

こんなことTeXユーザの集いであった.そのなかで,TeXの限界というタイトルでいくつかのトピックが示された.私の知る限り,TeXチューリング完全なのだから,原理的に計算可能ならどうにかなるだろうと思った.実際,「え,list環境再実装すれb……」などの容易に実現できそうな項目もある.ただ,一つのトピックに目を奪われた.

画像のBase64埋め込みの非対応

確かに,TeXでバイナリを扱うのは面白そうな課題である.

やってみた.

といっても,Base64はまだ実現していないので,画像埋め込みをするお話*1

技術概要

某奥底にあるように,LuaTeXのような特殊な場合を除き,TeXエンジンでバイナリファイルを書くことは困難である.よって,TeXでバイナリで与えられる画像データを直接扱うのは不可能である.すなわち,テキストで書き出して,そのバイナリへの解釈をTeXの外部に任せることになる.さて,どうしようかと悩んだところで,ふと思いついた.EPSに出力して\includegraphicsで読めばいいじゃないか,と.EPSはテキスト形式なのでTeXから出力できる.また,ラスタ画像を埋め込むための命令もある.

作成した機能は,LaTeXのパッケージとして動作するようにした.そのパッケージ,binaryimage.styはここに置いておいた.このパッケージは,次のようにして利用する.

\documentclass{article}
\usepackage[dvipdfmx]{graphicx}
\usepackage{binaryimage}
\begin{document}
  ...
  \includebinary[size=wxh,option={width=6cm, clip}]<<バイナリの16進数表現>>\endbinary
  ...
\end{document}

画像を入れるために,includebinaryという命令を用意している.この命令は,オプションにsize(必須)とoptionをとる.sizeはwxhの形で幅と高さのピクセル数を与える.例えば,幅400px,高さ300pxの画像ならばsize=400x300とする.optionはこの命令によって自動的に挿入される\includegraphicsへ与えるオプションである*2.オプションの後には画像のバイナリを16進数表現したものを入れる.このバイナリは,JPEGなどの画像形式をそのまま入れるのではなく,「左上から右へ,右端まで行ったら次の行の左端へ」という順で対応するピクセルのRGBをそれぞれ1Byteで表現したものである.こんなPythonコードで変換できる*3

# -*- coding:utf-8-unix -*-
from PIL import Image
import sys


def main():
    img = Image.open(sys.argv[1])
    for j in range(img.size[1]):
        for i in range(img.size[0]):
            print("{:02X}{:02X}{:02X}".format(*img.getpixel((i,j))), end="")
        print()
    

if __name__ == "__main__":
    main()

実行すると,なぜか-binaryimage<0からの通し番号>.epsというファイルが生成され,\includegraphicsされる.epsファイルの中身は次のようになっている.

%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 0 0 w h
/DeviceRGB setcolorspace
1 1 scale
<<
/ImageType 1
/Width w
/Height h
/BitsPerComponent 8
/Decode [0 1 0 1 0 1]
/ImageMatrix [w 0 0 h neg 0 h]
/DataSource currentfile /ASCIIHexDecode filter
>>
image

バイナリの16進数表現

ここで,w,h,および「バイナリの16進数表現」には\includebinaryで指定した値が入る.

これらの処理の結果,画像がtexファイルに埋め込まれたように見える.サンプルはここ(ソース結果).

実装小話(急カーブ注意×1)

ここで,binaryimage.styを実装するにあたり利用したテクニックを紹介する.

%の出力

TeXにおいて,%はコメントの開始文字なので,単純に出力できない.さらに,今回の場合は,\%も利用することはできない.\write(ファイル出力)のタイミングで\%が処理できないからである.そこで,binaryimage.styでは\lccodeを使ってコメント開始の役割を持たない%を作り出すことにした.

次のコードを見てみよう.

\lccode`+=`\%%
 \lowercase{\def~{+}}%

\lccodeはある文字に対して,その小文字の文字コードを指定するプリミティブである.上記のコードの1行目では,「+」の小文字に「%」を指定している.そして,\lowercaseを用いて「\def~{+}」の部分を小文字化する.これにより「\def~{%}」となるのだが,このときのカテゴリーコード(文字の役割)は変換前のものが使用されるため,「%」はカテゴリーコード12,すなわち一般の文字として扱われる.後は,%を出力したいところに~を書けば,~が展開されて%が出力される.

長いバイナリ入力への対応

\binaryimageでは,その用途の関係上,長大な入力を必要とする.しかし,TeXのマクロの引数として与えられる文字列はそんなに大きくない.そこで,今回は\edefを使って長大な入力を受け付けるようにした.

\binaryimageは,最初,オプション部分しか読まないようになっている.そして,\binaryimageを展開すると,末尾は次のようになる.

\edef\@bin@data{\ifnum`}=0\fi
       image^^J^^J

\@bin@dataの定義になっているように見えるが,閉じ波括弧が「\ifnum`}=0\fi」となっている.この部分が展開され,空になるので,上記のコードは

\edef\@bin@data{image^^J^^J

という閉じ波括弧がない未完成の\edefになる.いわゆる\ifnumトリックである.ここから,<<バイナリの16進数表現>>が読み込みおよび展開されていき,\endbinaryに達する.\endbinaryを展開すると,その先頭は次のようになっている.

\ifnum`{=0\fi}% end of \edef

これは,先の\ifnumトリックの対をなすコードで,閉じ波括弧単体となる.結果,\@bin@dataの定義が完成する.

この後,\endbinaryによってepsファイルの出力と\includegraphicsが行われ,画像が読み込まれる.

副次効果

binaryimage.styを通じて,Ghostscriptの闇などに触れてしまった.ここでは,その一部を紹介しよう.

Ghostscript9.10と9.15におけるヘッダ解釈の差異

現在,binaryimage.styが吐き出すepsファイルの1行目は「%!PS-Adobe-3.0 EPSF-3.0」となっている.実は,つい最近まで「%!PS-Adobe-3.0」という誤った出力をしていた.後者の出力の場合,Ghostscriptのバージョンが9.10なら動作するが9.15だと読み込めないという謎の事象に見舞われた.本記事の投稿が遅れた最大の理由がこれである.

epstopdfのMSYS対応

graphicxのドライバをpdftexにしたところ,指定した覚えのないディレクトリがエラーメッセージに出るという不可解な現象に遭遇した.中身を開いて調べたところ,epstopdfがMSYSに対応していないことが原因だと発覚した.仕方がないので自分で直し,フォーラムに投げた.現在は,Akira Kakutoさん,KUROKI Yusukeさん,およびKarl Berryさん*4のご尽力により,改良されたMSYS対応コードが本家に取り込まれたはずである*5

関連研究

ZRさんによって,このような記事がすでに発表されている.これはpdfTeXの機能を用いて,直接pdfファイル中に画像を埋め込む手法になっている.Ghostscriptに悩まされない分,綺麗な手法といえるが,pdfTeX依存になるため,TeXエンジンを複数使い分ける場合などに支障が出る.

今後の課題

Base64デコーダの実装が今後の課題にある.今回の使用目的に対してならいくつか実装アプローチがある.完全展開可能なデコーダTeX上に実装するか,PostScript側にデコーダを実装するかである.どちらもそれなりに苦行なので,そもそもbinaryimage.styに需要があるなら実施してもいいかもしれない*6

*1:某奥底に先を越されたのはGSの謎仕様のせい.

*2:命名規則が酷いのは仕様

*3:これが初Pythonであることを告白しておく

*4:著名人しかいない怖さ

*5:なお,全部rungsでもいいのではないかという提案を投げるのは私の仕事になっているが未実施である.仕事が早いのも見習いたい点である

*6:少なくとも,作者である私は使用する予定はない

TeXだってテスト書きたい

これはTeX & LaTeX Advent Calendar 2014,14日目の記事です.
13日目はneruko3114さん,15日目はh-kitagawaさんです.

はじめに

TeXでマクロを記述するにあたり,問題になるのはマクロが想定した動作をするか否かである.他のプログラミング言語*1と比較しても,TeXキチガイとしか言いようのな文法と評価規則をもち,思ったような動作をさせるのに苦労する.LaTeXのパッケージを公開するなら,せめてテストくらいしておきたい.特に,マクロでよくわからないことを実装しようとする私のような人間には切実な問題である.実は,これをサポートするパッケージがある.今回は,そのパッケージqstest.styを紹介する.

qstest.styとは

CTANにも登録されているLaTeXパッケージで,LaTeXにunit testを提供する.2007年のTUGboat記事がある.

基本的な使い方は,次のソースコードのようになる.

\documentclass{article} % 実際は何でもよい
\usepackage{qstest}
\IncludeTests{*}
\LogTests{lgout}{*}{*}
\begin{document}
  \begin{qstest}{Example}{label}
     \Expect*{\the\numexpr1+2}{3}
  \end{qstest}  
\end{document}

まず,qstest.styを使うために\usepackage{qstest}とする.

\IncludeTestsは実際に実施するテストに付加されたキーワード*2を指定する.テスト用に別ファイルを用意するなら*,すなわちすべてのテストを実施するように指定するのがよいだろう.テストを別ファイルに定義しておき,時間のかからないテストだけ実施するようなことも可能である.

次の\LogTestsはログファイルへの出力設定を行う.第一引数はログファイルの拡張子で,この例の場合,ログは\jobname.lgoutというファイルに出力される.第二引数は成功したテストのうち,ログへ出力するもののキーワード,第三引数は失敗したテストのうちログへ出力するもののを指定する.大抵の場合,すべてのログを記録するため,\LogTests{lgout}{*}{*}としておけばよいだろう.

テストケースはqstest環境に記述する.環境に与える引数は,テストケース名とキーワード*3である.

qstest環境中では,値の確認を\Expectを使って行う.\Expectは\Expect{確かめたい値}{予想する結果}のように使用する.要はassertである.引数を展開したい場合は,開き波括弧の前に*をつける.先に挙げた例でも,\the\numexpr1+2を展開するために*を使用している.もちろん,予想する結果の方を展開することもできる.ただし,展開には\edefを使用しているため,代入などの副作用をもっている場合には,注意が必要である.

値の確認に関しては,\Expect以外にもマクロが用意されている.確かめたい長さが特定の範囲に含まれるかを確認する\InRangeなど,TeXに特化したものもあるので,興味のある人はマニュアルを読んでみるといいだろう*4

先の例を実行すると,ログファイルに次の出力を得る*5.これは,Exampleテストをパスしたことを表している.

Passed: Example


テストにパスしなかった場合も示しておこう.次の例を考える.

\documentclass{article}
\usepackage{qstest}
\IncludeTests{*}
\LogTests{lgout}{*}{*}
  \begin{document}
    \begin{qstest}{FailExample}{label}
    \Expect*{\the\numexpr1+2}{hoge}
  \end{qstest}
\end{document}

これを実行すると,コンソールに予想していた値と実際の値が出力される.

! Package qstest Error: Failed: FailExample
 \Expect: \the \numexpr 1+2
 <hoge
 >3.

この後,実行を続けるか否かの入力を求められる*6ので,ENTERを押して実行を続け,ログファイルに次の出力を得る.

Failed: FailExample
 \Expect: \the \numexpr 1+2
 <hoge
 >3

副作用のみが重要なマクロに対する知見

さて,\Expectで展開しようとした場合,\edefを使うというということは先に述べた.これにより,\Expectでは内部で\defなどの代入を伴うプリミティブを単純にテストできない.LISP on TeXのテストコードを記述しようとした際,これは大きな問題だった.ここで,私はLISP on TeXのマクロのほとんどが空のトークンに展開され,副作用のみが重要であるという特徴を利用した.

LISP on TeXのコードでは大きすぎるため,次の例を考える.マクロ\hogeは二引数をとり,\fugaに第一引数と第二引数の和を代入することを目的としたマクロである.当然,展開結果には空のトークン列であることを想定している.

\newcount\fuga
\newcommand{\hoge}[2]{
  \fuga=#1
  \advance\fuga by #2
}

これをテストするために

\Expect*{\hoge{4}{2}\the\fuga}{6}

と記述することはできない.\fugaへの代入や\advenceが展開できないため,次のようにテストをパスできないことがログに残る.

Failed: Example
 \Expect: \hoge {4}{2}\the \fuga 
 <6
 > \fuga =4 \advance \fuga by 2 0

ここで,\fugaに和が代入されていること,\hogeは空のトークン列に展開されるという性質をテストするには,次のようにすればよい.

 \setbox0=\hbox{\hoge{4}{2}\xdef\fugafuga{\the\fuga}}
 \Expect*{\fugafuga}{6}
 \Expect*{\the\wd0}{0.0pt}

わざと水平ボックス内でマクロを展開し,結果を大域環境に出してやる.そして,出した結果が想定した結果であるかを\Expectでチェックする.空のトークン列に展開されているかどうかは作った水平ボックスの幅が0.0ptかどうかを確認すればよい.この手のマクロは空白トークンを入れてしまいおかしくなることがほとんどであるため,これで十分である.

さて,実際にテストしてみよう.次のようなログを得ることができる.

Failed: Example
 \Expect: \the \wd 0
 <0.0pt
 >3.33333pt

あれ……

そう,\hogeを定義する際,開き波括弧の後の改行をコメントアウトしていないため,空白トークンが出力されてしまっているのである.\hogeを次のように修正して再度テストする.

\newcount\fuga
\newcommand{\hoge}[2]{%
  \fuga=#1
  \advance\fuga by #2
}

テストを実行して次の結果を得る.

Passed: Example

世界が平和になった.

課題

副作用を持ちつつトークン列を出力する場合,どうしたらいいのかまだ知見が得られていない*7

*1:比較対象として妥当かは議論しないこととする

*2:正確にはキーワードのパターン

*3:ストファイルを別で作成している場合,特に入れるものがないので,私はテストするマクロのコントロール・シーケンスを入れるようにしている

*4:そんなに長くない

*5:誰かJenkins用のXMLに変換してくれないかなー(棒

*6:LaTeXのいつものあれ

*7:\unhboxとかでいいのかなぁ