メッセージフォームのサポート (Nginx + FastCGI + spawn-fcgi + Rack + Ruby)

あらまし

Mimir Yokohamaでついにお問い合わせ方法として「メッセージフォーム」が追加された。

なにがついになのか、なにをドヤっているのかと思うかもしれない。 まぁ、ドヤってはいないのだが。

実は私はかなり長い間ウェブアプリケーションをほとんど作っていない。 そして、今まで私が作ったウェブアプリケーションは、専用サーバーを持つサーブレットタイプか、もしくはCGIだった。

馬鹿にされがちなCGIだが、利便性は高く、頻繁にアクセスする性質を持たないアプリケーションには適している。

そして、そもそもウェブアプリケーションを作っていなかったのは、私が「事前生成戦略」の研究と実験に注力していたからで、 どちらかといえばウェブアプリケーションからは離れる方向にあった。 そして、ウェブアプリケーションを必要とするとしても大部分は静的ページとして提供できる方式を目指していたため、CGIで十分事足りたのである。

ちなみに、これまでウェブサーバーは

  • Apache
  • lighttpd
  • delegate
  • Nginx

という経過をたどっている。 Apacheは言うに及ばずlighttpdとdelegateはApacheよりもCGIが簡単だったので、「ほぼCGI」だった。

だが、時代は変わった。NginxはCGIをそもそもサポートしない。 私も新しい時代に対応する必要がある。

ちなみに、この作業は次の仕事のための実戦テストという意味合いもあった。

方針を考える

最も話が速いのはFastCGI Wrapである。

NginxはFastCGIをサポートしている。 FastCGIはプログラムをデーモンのように起動しっぱなしにする。

だが、通しで実行するプログラムとデーモンではそもそもの前提が違う。 そのためCGIプログラムをFastCGIとして動かすのはそれなりにハードルが高い。

そこでFastCGI Wrapの登場である。 FastCGIとして利用されるプログラムをFastCGI Wrapにする方式だ。 このラッパープログラムは要求に合わせて都度CGIプログラムをCGIインターフェイス経由で起動する。 結果的にFastCGIの意図は無視して従来型CGIを動作させるようにするというものだ。

この方法は結構出てくるのだが、基本的には既存のCGIプログラムを動作させる話である。

個人的な感覚としては、無駄なプロキシを噛ませるような方法を使ってまでCGIに固執したくない…というか、実はfcgi-wrapってそれなりにめんどくさい。

だったらFastCGI直というのもありかなぁ、と考えるわけだ。

ところが、やっぱりFastCGIはデーモン状のプログラムを想定しているわけで、やはり前提が違う。 要求として割と複雑なのか、デーモン化に関してはspawn-fcgiに担ってもらって、さらにRackを使う、というのがどうやら主流らしい。

だいぶ話が複雑になってきた。

サーバーはNginxである。NginxはFastCGIインターフェイスを経由してFastCGIプログラムにパラメータを渡し、応答を受け取る。

FastCGIプログラムはデーモンである。 Rubyでは次のようにしてFastCGIプログラムを書くことができる。

あるいは、CGIライブラリ互換インターフェイスを使うことで、#each_cgiの中身はまるっきりCGIと同じにすることもできる。

spawn-fcgiはこのデーモン部分を担う。 つまりeachしてる部分を担ってくれるわけだ。

プロセスとしてCGIインターフェイスで起動するわけではないので、fcgiwrapほどの互換性はない。 感覚はCGIに近いが、インターフェイスは意識する必要がある。

Rackはミドルウェアと呼ばれている。これはまずFastCGI抜きで話そう。

Rackはインターフェイスを担っている。 今までプログラムはCGIなり、あるいはFCGIなり、さらには各種フレームワークやサーブレットの様式(例えばSinatraとか)で書いていた。

Rackはこれらの違いを吸収するモジュール設計のものだ。 Rackに準拠したプログラムを書いておけば、たとえ愛用のフレームワークがディスコンになっても、サーバーが変わっても安心、というわけだ。

だが、Rack自身はサーバーではないからサーバーがいるのだが、Rack組み込みのサーバーというのはもう完全にRuby世界の住人だ。 だってRackはRubyのWebアプリケーションインターフェイスだから。

Passengerというソフトウェアがあって、これはwebサーバーのモジュールとしてRackに対応する。 Apacheでは比較的簡単だけれど、Nginxだと結構きつい。

そこでRackに対応したサーバーを立ててサーバーとサーバーでやりとりさせる、という方式がすごく現代的。 直接にRack経由でプログラムとやりとりするのはRackに対応したサーバーだけれど、Rackに対応したサーバーにwebサーバーとしての機能を持たせると大変なので、「本物のwebサーバーに矢面に立ってもらって、RackサーバーはあくまでRack対応に特化」というわけである。

Rackに特化したサーバーとしては(別にRackだけではないんだけど)、Webrick, Mongrel, Puma, Thin, Unicornあたりがある。

しかしRackでやりとりする方法があればいいので、FastCGI + Rackという方法もある。 それはRack側でFastCGI経由で受け取って、応答するためのハンドラが用意されている。

つまり、Unicornのようなサーバーを立てる代わりの手段としてFastCGIが使える。 FastCGIもデーモンを必要とするので別にFastCGIにすることで間に挟まってるものを減らす効果はない。 ただ話が楽になるだけである。

Unicornはむちゃくちゃ速いので、UnicornでUnixドメインソケットを使えば形式とししてはspawn-fcgiでUnixドメインソケットを使っているのと一緒だし、やっていることははるかに高度になる。 これが超モダンなやり方である。

が、あえてのFastCGI。 理由は管理する要素数を減らすためである。必要がないのにいかついものを使うことはしない。 これはサーバー運用のコツでもある。

なお、Rackに関してはかなり情報が少ない。 なんらかのフレームワーク…というか、ほぼRailsのバックエンドとしてのRackの話だけで、Rack単独の話ってない。 そして、FastCGIを使う話もない。これもだいたいなんらかのアプリケーションが「使ってる」あるいは「使わせる」話になる。

なんというか、みんなそんなに自分でプログラム作るってことをしてないのか… 世の中エンジニアたくさんいるのに、WordPressとRailsだけで満足なのか…

そんなわけで情報が猛烈に足りていない中、FastCGIとRackについて勉強することになったわけだ。

なお、Nginxでアプリケーションとやりとりする方法に関してはDiscourceで散々やったので経験済みだ。

なぜRackなのか

もちろんこのことからもわかるようにRackはなくても構わない。 spawn-cgiも使用せず単独のFastCGIアプリケーションを開発するのは容易である。

私が気にしたのはRubyのfcgiライブラリは2013年から更新が止まっているとい点だ。 また、Arch LinuxではfcgiライブラリはAURにもなく

# gem install --no-user-install fcgi

とするよりない。

ベーシックな機構であるFastCGIそのものが廃止になるようなことは考えにくいが、NginxのCGIの扱いのように消極的なサポートへと変遷する可能性はある。 その場合にアプリケーションの書き直しが発生してしまう。

Rackは現在主流であり、新規採用例も多い。 Rackが廃止になると影響を受ける範囲も非常に広いので今後10年は安泰だと思われる。

そこでFastCGI+Rackという構成にしたわけだ。 この場合でもRackはFastCGIをネイティブサポートしているわけではく、fcgiライブラリを使ったハンドラを同梱しているだけなのでfcgiライブラリは必要となる。実はこれを回避したかったのだが、結局はできなかった形だ。

とはいえ、この状態であればFastCGIを捨ててUnicornに移行するのも難しくはない。

とりあえずやってみる

Nginx

location / {
    root /var/www/testapp;
    fastcgi_pass /var/run/fcgi-testapp.sock
    fastcgi_index testapp.rb;
    include fastcgi_params;
}

Rack Application

Requestのほうはインターフェイスに絡むけれど、 Responseは単純に#finishでRackに沿った配列を返すための便利クラス。なくてもいい。

spawn-fcgi

# spawn-fcgi -U http -s /var/run/fcgi-testapp.sock /var/www/testapp/testapp.rb -n

試してるうちは-nつきにしてフォアグラウンドで実行するのが楽

実用的にする

起動スクリプト

forkingなので停止・再起動の制御のためPIDファイルを作る。

Systemd Unit

[Unit]
Description = FastCGI Rack Test Application
After = nginx.service

[Service]
Type = forking
PIDFile = /var/run/fcgi-testapp.pid
ExecStart = /usr/local/sbin/fcgi-testapp.bash
ExecStop = kill $MAINPID

[Install]
WantedBy = multi-user.target

forkingなので$MAINPIDがそのままでは使えないため、PIDFileで指定しておく。 Nginxのあとに起動しておいたほうがいいような気がしたけど、なくても構わない。 アクセスが激しい場合は逆にNginxの前に起動したほうがいいだろう

spawn-fcgi自体にはアプリをリロード、再起動するような機能はない。

おまけ

S-NailがSubjectも本文も、UTF-8をちゃんとエンコードしてくれるのですごくびっくりした。

「mailxとは違うのだよ!!!」ってことか。 さすがSMTPやPOPやIMAPにも対応しているだけのことはある。

ここの部分(MIMEエンコーディング)も自分でやるつもりだったので、かなり省力化された形。

今回の構築は他にも色々やったのだけれど、共有して意味のある部分はこれくらいのものだろう。

P720 * Windows 10 にDTM環境を構築した

Windows 10でDTM環境を作った

前回の記事の流れで諦めてWindows 10のDTM環境を作った。

Windows 10でDTM環境を整備

もう、すごくめんどくさくて、これに何日使ったかわからない。

色々と買い揃えている人ほどではないが、全部入り上位パッケージを買うタイプなのでこれはこれでひと財産という感じである。

環境としては

  • Cakewalk SONAR X3 PRODUCER
  • FL STUDIO PRODUCER Signature Bundle
  • Internet Ability 2.5 Pro
  • KOMPLETE 9 ULTIMATE
  • Air Music Technology Xpand! 2
  • Air Music Technology Hybrid 3
  • CeVIO Creative Studio 2 初回限定盤パッケージ (6.1アップグレード)
  • Soundspot Nebula

という構成になっている。

Windows 10 * SONAR X3 Producer

Windows 10上でSONAR X3 Producer自体は動作する。

ただし、動作しない(みつからない)プラグインがいくつかある。 dllをレスキューすればいける、みたいな話もあるのだけど、全プラグインを把握しているわけではないので確認はできていない。

SONAR X3をWindows 7上で使っている人はWindows 10に移したら完全には動作しない可能性を考えたほうがいい。

SONAR X3 Producerに付属しているAddictive DrumsなどはSONARとは独立してそのまま利用することができる。

非常に使える戦力なので、ぜひ活用していきたい。 今のところ一番イケてるドラム音源だと思う。

スタイリッシュになったものの難易度の上がったFL Studio 20

Macに対応したりして注目を集めるFL STUDIO。 変化が大きかったのでしばらく12と併存でいくのかと思いきや、バッサリとリリースと同時に12を切ってきた。

今までの使い方がわかっている人にとってはアクセスしやすくなって素晴らしいのだけど、そうでない人にとっては操作方法のヒントが激減した。

まぁ、デザイン重視なのはFLの伝統でもある。

プリセット設定ができてわかりやすくなったプラグインはインストールプラグインと扱いが異なるためわかりづらくなった。 インストールしたプラグインの操作はFile Settings -> Manage plugins -> Start Scanとやったあと、Plugin Database -> Installed という流れになっている。

ちなみに、私はSignature Bundle使いなのだけど、いつもバージョンがあがったあとアクチベーションするとPRODUCER - Signature Bundleと表示されるようになるのが好き。

FL STUDIO 11 のときは背景はFL-chanだったし、読み上げもしてくれていたのに、 12からはなくなってしまって残念。

なんだか懐かしいAbility

Singer Song Writerといったら初心者御用達のDAWだったし、割と舐められてた気がするのだけど、Abilityになってスタイリッシュになった。

SONARが終わったときに異様なまでのセールでAbilityが出ていて、まさにこういう事態(DTM環境のWindows 10化が避けられない)のために買っておいた。 いつも通りというか、最上位のAbility 2.5 Proである(パッケージ的には2.0)。

ちなみに、私はSinger Song Writerは使ったことがない。

もう一言で言うと

すごーく、シーケンサっぽい。

私はもともとXGWorksを使っていて、MIDIを組むのがお仕事だったりした。 当時はレコンポーザとかがあった。 そしてその他のライバルとしてRolandが売っているミュージ郎というパッケージがあって、それにシーケンサとしてSinger Song Writerがバンドルされていた。 ミュージ郎はそのうちCakewalkと組んでCakewalk(こっちはソフト名)をバンドルしたバージョンを出して、その後CakewalkがSONARになった。 RolandがCakewalkと組んだからインターネット(これは会社名)が出ていったのか、それともインターネットがSinger Song Writerの商品力で勝負しようとしたからRolandが見放したのかはわからないけれども。

Singer Song Writerはそれなりに波乱に満ちた歴史があって、wikipediaの記事を読むと面白いかもしれない

YAMAHAだってSOLがあったからXGWorksというとお手軽MIDIソフトだったのだけれど、販売面でいうとミュージ郎のほうビキナーパック感があった。 ちなみに、プロでSOL使っている人はすごく少なかった。当時はオーディオ化がコンピュータで完結しなかったので、オーディオになったあとの面倒をみるところをMIDIを組んでいるソフトでやる必要がまったくなかった。 ほぼProToolsの独壇場だったけれど、Cubaseを使っている人はまぁまぁいた印象。MIDIの組み方としてはSOLよりXGWorksのほうが簡単だったので、XGWorksを使っているプロはそこそこいた。

そんな歴史を語ってしまうほど、Abilityには当時の匂いがした。 洗練されていない四角いアイコンが並んで、操作方法も表示方法も現代的な視覚性を持っていない。 とにかく表示を並べる昔のままのスタイルだ。

少しはCubaseやStudio Oneを見習えというべきなのか、それともいやよくぞこのまま貫いてくれたと言うべきなのか。

だが、古臭いけれどなんとなく直感的で良い。 15分ほど触っただけだけど、なんとなくつかめたような気がする。

SONARはかなり気に入っていたので、それより良いものになるかはわからないけど。

Ability 2.5 の UVI GrandPianoModelD はかなり面倒

わかりづらくてかなり手こずった。

UVI WorkstationはKONTAKT PLAYERみたいなもので、これ自体はなにもない。 サウンドバンクの母艦になるものだ。

SSWのアカウントを発行するまではAbilityを起動してアクティベーションするところまでは済ませておくこと

  1. SSWのサポートセンターのマイページに行く (メールのリンクから行ける)
  2. パスワードをリセットする (Abilityから登録した時点でパスワードが発行されていない)
  3. マイページのリンクからBFD EchoとGrandPianoModelDのダウンロードを行う
  4. これらはPDFファイルのアーカイブになっているので展開する
  5. UVI Workstation サウンドバンクインストールガイド を読む
  6. ここに書かれていることを無視して 「UVI workstation ダウンロード」で検索してアプリを入手する
  7. UVI Workstationをインストールする。このときiLok License Managerもインストールされる
  8. しかしiLok License Managerは動作しないので、License Suport Installerを別途インストールする (iLok License Manager起動時にインストールするように言われる)
  9. iLok License Managerを起動する
  10. UVIのマイページから製品登録を選択し、iLokのアカウントと接続を選択してiLokのアカウントを作る
  11. iLOk License Managerでログインする
  12. 製品登録の画面でアクティベーションキーを入力、iLokアカウントに接続を選択してログイン、その状態で次へをクリックする
  13. マイプロダクトからGrandPianoModelDをダウンロードする
  14. rarファイルになっているので展開して、C:\Program Files\UVISoundBanks以下に展開して得られたファイルを配置する
  15. UVI Workstationを起動する

最高にめんどくさい。

BFD Ecoはそんな変なことはないので大丈夫なはず。 もっとも、ドキュメントから導入するのは変わらないけど。

Air Music Technology のアクティベーション

プラグインスキャン時にアクティベーションになる。

iLokも利用可能。

Nebulaは…

なんとシリアルナンバーすらない。

ものすごく安売りしてることが多いけど、商売っ気なさすぎないか。

CeVIOはスタンバイ

CeVIOは初回限定パッケージを入手済み。

ONEはまだ買ってないので、とりあえず今年中にさとうささらの曲を書くのが目標だ。 本当は使い慣れたSONAR上でさくさくっとやるつもりだったのだけれど、ソフトウェアが変わってしまったので厳しいかもしれない。 FLでやってもいいけれど、実はFLのほうもあまり自信がない。

EDMジャズみたいな曲を作りたいなと思っているのだけど、そういうのはとにかく時間がかかるので、 いつもどおり音数の少ない曲をとりあえず書こうかな、と思う。

ただ、ずっと思っていたことがあって、 プロになってからとにかくがんじがらめで曲を作ってきたから、 プロになる前みたいに、好きなように音を並べて音楽を作りたい。 楽器がどうとかじゃなくて、とにかく音を並べて音楽にしたい。

多分、CeVIO曲はそんな曲になると思う。

なお、CeVIO CS 2のときは機能らしきものはほとんどなかったのだが、CS 6になってなんかちゃんと音楽制作ソフト感ある感じになった。 なお、CS6になっても相変わらず出力オーディオは選択できない。

なお、なぜ2の次が6なのかは全く不明。VOCALOIDを追い越すためか???

あと、IAはトークがCeVIOでソングはVOCALOIDなので、PVではCeVIOでVOCALOIDの宣伝をする。

アクティベーションとライセンス管理

基本的には各メーカーのユーザーアカウントと結びつける方式。

XLNやNIは専用のアプリを使ってインストールやアップデートの管理も行う。 この方式はなかなか優秀。

iLokも以前のような凶悪なものではなくて、メーカーでユーザーアカウントは登録するものの、 マシン管理はiLokのアプリケーションで行う、というような形になっている。

マシン管理は厳しく行うもの(ディアクティベーションが必要)とゆるやかに行うもの(使わなくなった環境はそのまま使わなければいい)に分かれる感じ。

ただしCeVIOはやたら厳しく、使いにくい方式をとっている。

TASCAM

シリアルナンバーとは別の認証コードを発行。 インストール後は直ちに認証コードを入力しないと使えなくなる。

認証コードはユーザー登録と製品登録を行うことで発行。 一度発行したあとはそのコードをディアクティベーションなしで利用できる。 利用状況はチェックされる。

Image Line

ソフト上からログイン、あるいはマイページから登録用ファイルを獲得して登録。

ユーザーアカウントと結び付けられる。

Internet

メールとURLを使った登録とダウンロード、そしてインストール時にシリアルナンバー入力。

マシン同定に使用するデバイスをシステムドライブとネットワークインターフェースカードから選べる。

XLN Audio

専用アプリで管理。

ディアクティベーションはマイページから行うものの、専用アプリから通知してくれる。 マシン管理が簡単でとてもうれしい。

ただし、ソフトウェアごとではなく、専用アプリ単位でのアクティベーション。

Native Instruments

専用アプリで管理。

マシン管理はチェックのみで、特にディアクティベーションは不要(古い環境がそのまま使っていなければ破棄されたものとされる)。

Air Music Technology

ユーザーアカウント、あるいはiLok。

UVI

iLok。

昔のように専用ハードウェアは必要ない。

BFD

ユーザーアカウント。

ダウンロード時に認証される。 マシン管理はあるのか不明。

Soundspot

多分ない

Celemony

「鬼畜Melodyne」とか呼ばれていた。

インストール時ユーザーアカウントとの結びつけだけれども、ディアクティベーションがアプリ上からしかできない仕様で、マシンが壊れるとメールするしかなかった。

最近はしれっとマイページからディアクティベーションできるようになっている。

CeVIO

現状もっとも鬼畜。

ユーザーアカウントと結びつけるタイプだけれども、認証を起動ごとに行うため、ネットがない環境では起動不可。 さらに、CeVIOのサーバーが落ちてることがまあまああるため、そのときも利用不可。

Lenovo ThinkStation P720 に Windows 7 をインストールする

なんとかしてP720でWindows 7を使う

私が音楽のお仕事するときの環境は以前としてその中核にSONAR X3が据えられているため、Windows 7が欠かせない。

ThinkStation P720は将来性を考えてWindows 10モデルを選択したが、手元にあるリテール版Windows 7 Professionalのライセンスを利用してWindows 10, Windows 7, そしてLinuxという構成にするのが私の目論見であった。

Skylake-SPプロセッサはWindows 7を使うことができる最強にして最終のプロセッサである。

だが、これはかなりの困難に阻まれた。

もちろん、Windows 10は(いささかの問題はあれど)動作するし、Linuxもなんら問題はない。 だが、Windows 7に関してはインストールディスクから起動すると “Starting Windows” の表示と共に停止してしまうのだ。

様々なトライをしたがうまくいかず、Windows Updateを適用したディスクの作成を試みた。

内容としてはここここを参考にしたが、そのままは適用できなかった。 特にIE11関連はアップデートの配布がされていなかった。

とはいえおおよそ必要と思われるものを統合した。

だが、これでも問題が発生した。

Legacy (BIOS) なら起動できるのだが、UEFIだとUEFIアプリケーションを見つけてもらえない。 bootx64.efiの用意もしたのにだ。

調べたり質問したりしたのだが、解決には至らなかったので、結局UEFI Onlyでの運用を諦めてハイブリッドブートとした。

さて、これでインストーラが起動するようになったのだが、残念ながらUSB2.0ポートにつなぐ場合(P720はキーボード/マウス用ポートのみがUSB2.0)を含めてUSBデバイスが一切反応しない。

幸いにもPS/2ポートが存在しているので、これを利用する。PS/2-USBアダプタは機能しなかったため、PS/2キーボードを新規に購入した。

これでWindows 7は起動するのだが、まともに動かない。 とにかくドライバがない。そして何も動かない。

仕方ないので別のマシンから SCCM Packages For Windows 7 (64-bit) – ThinkStation P720, P920 をゲットして、CD-Rに焼いて展開する。

そう、USBもイーサネットコントローラも動作しないのでCD-Rだけが頼りなのだ。

この状態でC:\DRIVERS以下にドライバファイルが配置された状態になるので、デバイスマネージャからドライバの場所の指定でここを指定すればインストールできるようになる。

大量の動作しないデバイスがあるためかなり大変な作業である。

Windows 7をP720にインストールした状態

とりあえず2つのネットワークコントローラとUSB(4つある)をインストールすればWindows Updateもできるようになり、楽な進行になるだろう。 USB3.0ルートハブにUSB2.0ハブがぶら下がっている格好であるためUSBマウスが動作しなかったのだが、USB2.0ハブのほうもWindows 7はドライバーを持っていなかった。

実際は全部をインストールしなくてもよかった(ある段階でCPU内蔵機能に関しては残りすべて導入されていた)が、Windows Updateと並行するのでなかなか複雑なことになる。

注意点としては、「Blink系ブラウザはシステムがフリーズする」。 原因はわからないが、とりあえずブラウザはFirefoxに限る、ということになりそうだ。導入作業でChrome, Vivaldi, Sleipnirなどを使って作業しようとするとハマることになる。

Windows 7 は動いたが、断念せざるをえず

「特定のタイミングでフリーズする」という問題が「ASIOなどでの音声再生時」に発生したことが致命的で、どうすることもできないので断念することとなった。

そもそもWindowsは音楽制作専用である。他にWindowsを使う機会はない。 厳密に言えばそこから派生した作業もWindowsですることになるが、中核になるのは音楽制作であり、それがなければWindowsはいっそなくても構わない。

だからASIOでの音声再生でフリーズする、というのは音楽制作に使用できないということであり、私としては全く価値がない。

記事としては「Windows 10 プリインストールなP720でWindows 7を動かす」というテーマだからここから先は重要ではないとも言えるんだけど、私としては10日程度を無駄に費やしてここからがスタート地点ということになる。

とりあえずDTM系ソフトウェアは2台に対してアクチベーションが可能なものが多いので、P720 Windows 7は諦めて、 Z400 Windows 7とP720 Windows 10に対して構築していく方針としている。

P720のWindows 7もASIOで落ちたりしていたのだが、アップデートで落ち着いたようだ。

SONAR X3は残念ながらWindows 10では動かない部分がある。 D-Proが動かなかったような気がする…D-Proは私の主力なのでなくなると大変痛い。

(D-ProはどのみちSONAR以外では利用できないようになっている)

DTMの話は続きとして書いていたのだが、主旨の全く異なる話になったため、分割する。

imagine YOKOHAMAフォントを実用しよう

imagine YOKOHAMAフォントは横浜市が制作したヨコハマをイメージしたフォントだ。

ダウンロードは簡単だし、使うのも特に問題はない。

このフォントの特色は「漢字は横浜市と18区の分しかない」ということである。横浜市神奈川区は書けるが神奈川県横浜市は書けない闇フォントとも言われている。

なかなか強烈だ。そして困る。 もちろん、イラストレーターなどで好きに組み合わせられる状態であればどうとでもなるので気にならないが、テキストフォントとして選択してしまうとimagine YOKOHAMAが持っている漢字と持っていない漢字の落差が激しい。

よりにもよってごく少数漢字を持っている上に、その漢字がまたちょっと変わったデザインだったりするので組み合わせもなかなか厳しい。 漢字を持たないフォントよりもずっと厳しい。

LinuxならばFontConfigがあるから任意のフォントを組み合わせることができる。 できるはできるのだが、それで解決しないのがこのフォントだ。「明朝体と組み合わせればいいんでしょ」と思うかもしれないが、だいたいどの明朝体と組み合わせても違和感激しい。

Linuxで使えるフリーの明朝体はだいたい

  • さざなみ明朝
  • IPA明朝 / Takao明朝
  • 梅明朝 / 花園明朝
  • Source Han Serif JP
  • さわらび明朝

あたり。あとは、こころ明朝体とかはんなり明朝体とかもあるけれど。

こころ明朝体やはんなり明朝体を指定することはあまり進められない。 確かにある程度の漢字は持っているが、これらのフォントは持っていない字を空グリフにしてしまっているため、これらのフォントに含まれない字は空白として表示されてしまう。

梅明朝に関してはかなりウェイトが細い。組み合わせたときの違和感は強い。

IPA明朝は字形が近いため、違和感が少ない。 ただし、ウェイトが違うため漢字とそれ以外で馴染みが悪いことになる。

Source Han Serif JPはそれなりに違和感がない。

さわらび明朝はややウェイトが太く、その点では違和感があるが、字形は近い。

というわけで私のお勧めは

である。

imagine YOKOHAMA フォントに源ノ角明朝を組み合わせた

Linuxで将棋倶楽部24 (Java Web, jnlp) アプリを動かす

概要

日本将棋連盟が運営する将棋倶楽部24はなかなかレトロなシステムを採用している。

Webでjava Appletという構成だが、まぁ当然ながら現代的な環境では動かない。

で、アプリ版があるのだが、「Windowsだけか…」と思いきや、Javaで書かれているのでLinuxでも動いたりする。 だが、ひと工夫は必要だ。

Java Web Start (jnlp)

Iced Teaという名称でおなじみのJavaのweb技術だが、ウェブブラウザプラグインを介してでなくともJavaが起動することができる。

コマンドはjavawsである。 ではjavawsに引数として渡せば動くのか?

javawsコマンドはIced Teaに含まれているのだが、Iced TeaはデフォルトのJava環境を使用する。 そして、OpenJDKだと7でも8でも9でも10でも動かなかった。

Oracle Javaにもjavawsが含まれている。 こちらなら起動できる。

$ /usr/lib/jvm/java-8-jre/jre/bin/javaws 24TokyoDojo.jnlp

Java Web Startのフォント改善

一見して「うへぇ…」となるフォントが表示される。

Java Web Startの場合オプションが渡せないのでちょっと面倒だが、環境変数にセットしてあげれば大丈夫だ。

先程の起動スクリプトに追加してあげよう。

しかしこれでもロビーのフォントは改善されなかったりするのだが。

openJDKだと結構きれいなフォントで出るんだけどなぁ…

Cinnamonのシステムサウンドはwavが再生できない

だいたいWindowsのシステムヴォイスはwavなので(最近はwav以外も再生できるけど)高確率でハマるトラップ。

FLACは“sound file”の候補に出ないのに対して、wavは選択可能であるにもかかわらず再生できない。

Ogg VorbisならOK。KDE Plasmaもそんな感じだった気がするので、「LinuxのシステムサウンドはOgg Vorbis」で。

Mimir Yokohamaに用語集機能

Mimir Yokohamaに用語集機能が追加された。

用語集機能はACCS(PureBuilderに取り込まれる以前の)やAki PHP Content Collection時代に実装されていた。

シンプルにACCSではJavaScript+Ruby/CGIで、本文エレメント(テキストノード)を探索し、文字列を送信してRubyで置き変えたものを返してもらい、innerHTMLを置き換える方式だった。

APCCでは単純に力技で置換えていた。

PureBuilderではこの機能を実現していなかった。 正確には一時期実装していたこともあるが、十分な質でなかったのだ。

そしてついに復活した用語集機能。

Pre Pluginsで処理することも考えたが、Post PluginsでRubyで処理している。

「辞書をワード長が長い順に並べ替えて|で結合し、正規表現としてコンパイルして置き換える」という手法はかつてのコードで考えたものである。

用語集のページも単純な手法でMarkdownを生成している。

で、今回もライブラリなしのPureJSで処理している。 今回は44行ほどだが、18行は共有化できるものなので、もう少し短くすることも可能だ。 DHTMLのお手本のような初歩的なものである。

Event.stopPropagation()Event.stopPropagationと書いて悩むはめになったけど。

PureBuilder Simply 1.4 リリース

PureBuilder Simplyの1.4をリリースした

特に大きな変更点は以下の通りだ。

  • HTML生成前に処理できるPre Pluginsに対応した
  • Pre Plugins/Post Pluginsで環境変数から文書メタデータにアクセスできるようになった

Pre PluginsはPandocにかける前のドキュメントを加工するものである。 Markdownと比べReSTは自由度が低いこと、それぞれのドキュメントフォーマットに基づいて処理しなければならないことから、新たに_docformatというメタ値が追加された。

今回のポイントはPre Pluginsであり、メタデータを渡す仕様は反映していなかっただけで、実は1.2時代からあった。

Pre Pluginsはおもしろいこと書いていないので、どちらかといえばメタデータ渡しの話をしよう。

これはPre Plugionsの一部である。 IO.popenはコマンド群の前に環境変数を置くことができる。 シェル的にいうと

みたいなことだ。

もちろん、同じような手法はRubyでも使えるけれど、ちょっとめんどくさい。IO.popenの利便性は簡便に損なわれてしまう。

かゆいところに手の続くRubyは、ちゃんとそのプロセス用に環境変数を渡す方法を用意してくれているわけだ。

予め環境変数にセットするのと何が違うのか。

まず、自身の環境変数としてセットすると、メモリーを2個分使う。

また、環境変数がそのプログラム自身の制御に影響するケースでは問題が生じる。

さらに、何度もプロセスを起動するたびにセットしてしまうと、ガベージコレクションの問題が出る可能性がある。

結局、子プロセスに対して伝播したいだけの環境変数はこのプロセスに対してのみセットするのが適切、ということになる。 シェルにおいても

ではなく、

あるいは

とすべきである。

静的ウェブページでタグ機能を提供する

Mimir Yokohamaのページでタグ機能がバージョンアップし、完全に動作するようになった。

もともとWordPressで提供していたMimir Yokohamaのウェブページだが、独自システムに移行する際には「WordPressで利用していた機能はすべて提供する」という方針のもと、新しいサイト構築システムPureBuilder Simplyを開発して構築した。

PureBuilder Simplyは静的ページを生成するプログラムであり、webサーバーには静的ファイルを配置する。 これはパフォーマンス、セキュリティ、管理、リソースいずれにおいてもメリットが大きい。

基本的にこの考え方は「異なる内容を生成するタイミングより、同一の内容を返すタイミングのほうがずっと多い」ということに基づいており、キャッシュよりも合理的である。 一方、どうしても難しい要素もある。ひとつはページ生成パターンが無限である検索機能、そしてもうひとつはヒントを日本語のみにした場合のタグ機能だ。

検索機能はGoogleに頼っているが、タグ機能は難関だった。

タグ機能を作る

方針

  • 要求タイミングでの動的生成は行わない
  • PureBuilder Simplyの枠内で解決する。 もし解決不能な場合はPureBuilder Simplyを拡張する
  • (PureBuilder Simplyでサポートされている) eRubyテンプレートは使わない。あくまでPandocテンプレートで生成する
  • ファイル名が日本語になることはやむを得ないものとする (Nginxは日本語ファイル名に対してURIエンコーディングされたパスでアクセスできる)
  • リンクを日本語で書く(エンコードをブラウザに委ねる)ことは許容しない
  • ユーザー (この場合自分だけど) にタグに関して文書にタグ付けする以上の手間をかけさせない

タグをつける

既にPureBuilder Simplyでは 「Frontmatterに文書に関する追加的情報を書く」 という仕様となっている。1

単純にこれを反映したタグを書けば良い。

ページにタグ情報をつける

Pandocテンプレートで簡単につけることができる。

英語なら割とこれで済む話なのだけど2、日本語だと当然

みたいなHTMLが生成されてしまう。

そこで、post generate機能を利用する。 post generate機能はページを生成したあと生成ページを加工できるものだ。 基本的に第一引数として生成されたファイルパスが渡される。 このほか環境変数を通じて他の情報にもアクセスできたりするのだが、これはあまり利用を想定していない。

post generateは.post_generateディレクトリ内のファイルを順次Perlに渡す形で実行される。 Perlはshebang行を解釈するので、Perlで書かなければならないわけではない。 そして、スクリプトの出力にファイルは置き換えられる。

これは例えば

のような非常に簡単なフィルタが書けるということだ。

これを使って

のように変換してあげればタグのタイトルは日本語だがURIはエンコード済み、という形ができあがる。 もちろんスラッグへのマップを書いてもいいのだが、タグを管理するのは手間なので避けた。

タグページを作る

生成されたページの情報はindexes.rbmというファイルにRuby Mershal形式で保存される。 ここには本文は含まれないが、大概メタ情報にアクセスしたい場合と本文にアクセスしたい場合は別なので、分けている。

PureBuilder Simplyにおいて、「メタ情報を文書に書き、処理した情報はデータベースに書いておく」というのは設定上の核であると行って過言ではない。 これにより、文書のメタ情報を扱うことはPureBuilder Simplyの外で行うことができるのだ。

タグページは.tagcloud.rbというスクリプトによって生成しているが、 これはMarkdownページを生成する。つまり、「タグページ自体をPureBuilder Simplyによって生成すべきページとして生成する」のである。 タグを含むページを生成・更新した場合は再度タグページを生成し直すことになり、そのためにrefreshというスクリプトもある。この場合、文書ページではないタグのindexを処理されてしまうと困るので次のような処理になっている。

では.tagcloud.rbは、というとこちらも結構単純。

見ての通り著しい力技でデータベースを集計し、最終的にはMarkdownを出力している。

従来もほとんどこうだったのだが、ページ側でエスケープしていないという理由でエスケープしていなかったので追加した。

おわりに

もう少し難しいかと思っていたのだが、どうやらPureBuilder Simplyの設計が思っていた以上に優れていたようで、タグ機能もスムーズに実装することができた。

PureBuilder Simplyは傑作といって差し支えない出来になっている。 もともと思っていたよりもずっと優れたツールになっているのだ。

PureBuilder SimplyはPureBuilderとしては実に3作目である。 Zshの機能をフル活用したPureBuilder, Windowsでも動作可能なようRubyで書かれたPureBuilder2。ページの生成にはいずれも活用できたが、サイト構築労力が高く、安価な案件で利用するにはしんどいものがあった。 また、構築できる内容も割と画一的だったため、様々な要求に応えるのは難しかった。 Zshで書かれたPureBuilderは構築時に任意のZshスクリプトを実行できる方式だったため、なんでもできるといえばできるのだが、サイト構築がプログラミング色の強いものになっていた。これはちょっとユーザーフレンドリーではない。

PureBuilder Simplyは名前の通りずっとシンプルだが、いままでよりずっと強力になった。

小さなスクリプトを書くことは、多くのプログラマにとってはあまり馴染みのないことかもしれないが3、やろうと思えば発想さえ知れば決して難しいことではないはずだ。


  1. これはReSTでもdocutilが許容しないような規格化されていないメタ情報を書くということだ。

  2. ちなみに、Chienomiではタグはすべて英語になっている

  3. Unixに浸っている人はむしろ息をするようにのように行動するだろう。PureBuilder Simplyの考え方はこれに基づいている。

LuaTex-jaでNumber too big.エラーがようやく解消

LuaTexで日本語ドキュメントクラス(ltjsarticle, ltjarticleなど)を処理すると

! Number too big.
ltj@@jfont ->luafunction ltj@@jfont@inner 

l.53 \kanjiencoding{JY3}\selectfont

と言われてしまう、という問題が続いていた。 Manjaro Forumで質問したところ、再現するけどupstreamへ、ということだったのでLuaTeX-jaのほうにご報告させていただいたところ、チケットを切っていただいた

Manjaroではつい先日Texliveが201804にアップデートされたが、この問題はLuaTeX-jaが201806として解決してくださっている。

このため、

$ git clone 'https://scm.osdn.net/gitroot/luatex-ja/luatexja.git'
$ sudo rsync -r luatex-ja/src/ /usr/share/texmf-dist/tex/luatex/luatexja/

とすればとりあえずこの問題は解決する。

だが、今度は

! Undefined control sequence.
\lltjp_um_unmag_fsize: ...@preadjust@extract@font 
                                                  \cs_gset_eq:NN \lltjp_um_f...
l.106 \begin{document}

なんて言われてしまう。 これは、

ltjsarticle + unicode-math で をしていないときに起きるエラーのようです. 別チケットにします.(#38372)

とのことで、チケットを切っていただいた

現在のところkitagawa_testブランチになっているが、恐らく近日中に取り込まれるだろう。 なかなか長い戦いだったが、ようやく論文や教材の清書も捗るというものだ。

ちなみに、この影響でgendoc-pandoc.zshのほうはMathfontに対応した。