format慣らし。

「息吹」の辞書を、JIS X 208を止めて、頻度を元にして並び替えることにした。2打鍵字とは独立して、3打鍵字と4打鍵字を頻度を元に選択する。選択するのは良いのだが、これを辞書の形式に合わせて

亜唖阿哀愛挨逢葵茜悪握旭芦鯵梓圧扱宛姐飴絢綾鮎或粟安庵暗案闇
鞍杏以伊位依偉囲夷委威尉意慰易椅為畏異移維緯胃萎衣謂違遺医井
域育郁磯一壱溢逸稲茨芋印咽員因姻引飲淫院陰隠韻右宇烏羽迂雨卯
...
鷂鷙鷓鷸鷦鷯鸛鹹鹽麁麈麋麌麕麑麥麪黌黏黐黔黜黝黠黥黯黶黷黹黻
黼黽鼇皷鼕鼡齒齔齠齦齪齷齲齶龕龜

と並び替えるのは意外と面倒である。字単位ののっぺりとしたリストを、30字ずつの文字列にして(余りもある)、1行ごとに出力し、最後に空白行を残さない。前はformatに渡す前に文字列を整形していたのだが、formatだけで出来るようになったのでメモしておく。

(format t (format nil "~A~V@{~A~:*~}~*~A" "~{~&" 30 "~^~A" "~}") char-list)

ここで利用している出力指定子は次の通り。

  • ~A アスキー指示。引数を出力形式で表示する。
  • ~& fresh-line 行頭以外で改行を出力する。
  • ~{~} 反復指示。リストの中身を引数として引数を使い尽くすまで出力する。V@は良く分かっていないが、リストを与える代わりに数値で出力回数を制御するようだ。
  • ~* 引数無視指示。引数を1つ飛ばす。~n*でn個飛ばす。~:*で1つ戻る。~:n*でn個戻る。回数を指定しない~{~}内で使うと止まらないので注意。
  • ~^ ゼロ終了指示。引数がなくなったら止める。

formatを使えば、日本語で説明するよりよほど短く書けるということだ。lispでレイアウトを考えると、書き方が割とくどくなるので、formatのような出力形式は重宝する。

書いていて気が付いたけど

この処理ってxyzzyのfill-regionで出来るよね・・・