(メモ)
— 某ZR(ざんねん🙃) (@zr_tex8r) 2019年6月5日
PandocでWindowsをシャットダウンする件#Pandoc #ぱんどっく #ええっ
皆さんもよくご存知の通り、LuaLaTeXでは「Windwosをシャットダウンする文書」が作成できます。これはLuaコードを通じて(C言語をコンパイルして生成した)マシン語のプログラムが実行できることを利用しています。
ところで、以前のネタで紹介した通り、PandocではLuaでフィルターを実装することができます。となると、マークダウンという不思議な形式の文書でWindowsをシャットダウンしてみたくなるのは当然の帰結でしょう。
どうもPandocでWindowsをシャットダウンできそうにない件
Luaでバイナリ(マシン語)のモジュールを作製する際には、次のような感じのC言語の関数を実装します。
※以下のコードはLuaLaTeXのやつで使っているモジュール1のソースコードからの抜粋。
/* Opens the module. */ __declspec(dllexport) int luaopen_shutwindown(lua_State *L) { luaL_newlib(L, registry); return 1; }
Luaでモジュールを読み込む(require "shutwindown"
)と、この関数が実行されるのですが、この中で使われているluaL_newlib
というのは「Lua処理系の連携用API」の一つです。連携APIはLua処理系と外部のコードの間のやり取りを行う機構で、バイナリのモジュールの実装に不可欠なものです。
つまり、バイナリのモジュールを動作させるには、Lua処理系の連携APIの関数が「外から見えている」必要があるわけです。TeX Live配布におけるLuaTeXのLua処理系は動的リンクのライブラリ(WindowsだとDLL形式)になっているため、連携APIは外から見えています。これに対して、Pandocの公式のWindwos用バイナリではLua処理系が静的にリンクされていて連携APIが外から見えません。これではLuaTeXの時と同じようには「Windowsをシャットダウンするモジュール」を実装することはできません。
それでもPandocでWindowsをシャットダウンしたい件
絶望的な状況になっていしまいましたが、もう少し考えてみましょう。
先程述べた通り、Luaコードにおいてモジュールshutwindown
の読込(require)を行うとC言語の関数luaopen_shutwindown
が呼ばれます。Luaのrequire "shutwindown"
に対応する動作なので、通常はこの関数では「モジュールの関数を収めたLuaテーブルを作成して返す」ことが期待されています。しかし、とにかくモジュールの実装コードに実行を移すことができているのだから、ここで早々とシャットダウン開始の処理を済ませてしまえばいいわけです。
/* Opens the module. */ __declspec(dllexport) int luaopen_shutwindown(void *L) { shutdown_system(); /* シャットダウン! */ return 0; }
すなわち、このモジュールがインストールされたLua処理系では、require "shutwindown"
を実行するだけでシャットダウンが開始します。
改めてPandocでWindowsをシャットダウンする件
というわけで、作ってみました。
- pcshutwindown(GitHub/zr-tex8r)
このリポジトリにあるファイルpcshutwindown.dllとshutdown.luaをカレントディレクトリ2に置いた上で、何か適当なMarkdown文書’(リポジトリにあるREADME.mdでもいいでしょう)をPandocで変換しましょう。もちろんフィルタにshutdown.luaを指定することを忘れずに。
C>pandoc README.md --lua-filter shutdown.lua System will be shutdown in 10 seconds... System will be shutdown in 9 seconds... System will be shutdown in 8 seconds... System will be shutdown in 7 seconds... System will be shutdown in 6 seconds... System will be shutdown in 5 seconds... System will be shutdown in 4 seconds... System will be shutdown in 3 seconds... System will be shutdown in 2 seconds... System will be shutdown in 1 second... FAREWELL!
まとめ
結局、PandocのLuaフィルタでバイナリモジュールを利用するのは難しい、のかな?