Upload
t-sin
View
7.340
Download
0
Embed Size (px)
Citation preview
Inquisitor-Common Lispに文字コード判定を-
自己紹介● なまえ:ぐれー
– Twitter: sin_clav– Github: t-sin
● 昼はSE、夜はLisper– 9月よりPythonistaに
● Common Lisp、Clojure使い● 前回:Meetupデビュー● 今回:LTデビュー
– (((( ;゚Д゚)))ガクガクブルブル
As known as...● 「口にマクロを(ry」の人です
今日は、
膝にマクロを受けにきました
今日は、
膝にマクロを受けにきました
つくったものを紹介します
lnquisitorとは● 文字コード/改行コード判定ライブラリ● 機能
– 文字コード判定– 改行コード判定– external-formatの処理系差を吸収– ベクタ、ストリーム、pathnameから
external-format生成
lnquisitorとは● たとえばこれ(SBCL)が(labels ((nkf (path) (let ((ret (with-output-to-string (out) (uiop:run-program `("nkf" "-g" ,(format nil "~a" path)) :output out)))) (first (split-sequence:split-sequence #\newline ret)))) (detect (path) (let ((enc (nkf path))) (cond ((string= "Shift_JIS" enc) :sjis) ((string= "EUC-JP" enc) :euc-jp) (t :utf-8))))) (let ((file #P"/path/to/iamacat.txt")) (with-open-file (in file :external-format (detect file)) (read-line in))))=>" 我輩は猫である。名前はまだない。"
lnquisitorとは● こう書けるようになる(let* ((p #P"/path/to/iamacat.txt") (ef (inquisitor:detect-external-format p :jp))) (with-open-file (in p :external-format ef) (read-line in)))=>" 我輩は猫である。名前はまだない。"
Inquisitor以前● 文字コードの判定ライブラリ自体はあった● Onjoさんのguess [2007]
– Gaucheの文字コード判定処理のCommon Lisp移植– http://lispuser.net/commonlisp/japanese.html#sec-2.1
● Zqwellさんのguess [2011]– 上記guessの多言語対応版– https://github.com/zqwell/guess
Inquisitor以前● でも…● 対応している処理系が少ない
– 例)CCLに対応していなかった● 改行コード判定してくれない
– そもそも改行コードを扱えない処理系もある● SBCL、おまえのことだ!
● external-formatが処理系でまったく異なる– SBCL: :UTF-8 --- ただのキーワード– CCL: #<EXTERNAL-FORMAT :UTF-8/:UNIX #xxxxx> --- オブジェクト– ECL: (:UTF-8 :CRLF) --- リスト
● いちいちベクタをつくらないと判定できない
ないので…
\自分でつくるしかないじゃない!/ * + 巛 ヽ 〒 ! + 。 + 。 * 。 + 。 | | * + / / イヤッッホォォォオオォオウ! ∧_∧ / / (´∀` / / + 。 + 。 * 。 ,- f / ュヘ | * + 。 + 。 + 〈_} ) | / ! + 。 + + * ./ ,ヘ | ガタン ||| j / | | |||――――――――――――
Inquisitor● 文字コード判定● 改行コード判定 new!
● external-formatの処理系差を吸収 new!
● ベクタ、ストリーム、pathnameからexternal-format生成 new!
● パッケージ構造をちょっぴり整理… new!
Inquisitorひとめぐり with CCL● 文字コード判定
– 言語圏たち● 改行コード判定
– 改行コードを扱える処理系か?● external-formatづくり
– ベクタから– ストリームから– pathnameから
Inquisitorひとめぐり with CCL● 文字コード判定
(with-open-file (in "/path/to/utf8-lf.ja" :direction :input :element-type '(unsigned-byte 8)) (inquisitor:detect-encoding in :jp))=>:UTF-8
Inquisitorひとめぐり with CCL● 文字コード判定
● 言語圏たち
(with-open-file (in "/path/to/utf8-lf.ja" :direction :input :element-type '(unsigned-byte 8)) (inquisitor:detect-encoding in :jp))=>:UTF-8
:jp 日本語 :tw 台湾語
:cn 中国語 :kr 韓国語
:ru ロシア語 :ar アラビア語
:tr トルコ語 :gr ギリシア語
:hw ヘブライ語 :pl ポーランド語
:bl バルト語 - -
Inquisitorひとめぐり with CCL● 改行コード判定
(with-open-file (in "/path/to/utf8-lf.ja" :direction :input :element-type '(unsigned-byte 8)) (inquisitor:detect-end-of-line in))=>:LF
Inquisitorひとめぐり with CCL● 改行コード判定
● 改行コードを扱える処理系か?
(with-open-file (in "/path/to/utf8-lf.ja" :direction :input :element-type '(unsigned-byte 8)) (inquisitor:detect-end-of-line in))=>:LF
(inquisitor.eol:eol-available-p)=>T ; on CCL=>NIL ; on SBCL
Inquisitorひとめぐり with CCL● external-formatづくり --- ベクタ
(let ((str (ccl:encode-string-to-octets "公的な捜索係、調査官がいる。"))) (inquisitor:detect-external-format str :jp))=>#<EXTERNAL-FORMAT :UTF-8/:UNIX #xxxxxxxxxx>
Inquisitorひとめぐり with CCL● external-formatづくり --- ストリーム
(with-open-file (in "/path/to/utf8-lf.ja" :direction :input :element-type '(unsigned-byte 8)) (inquisitor:detect-external-format in :jp))=>#<EXTERNAL-FORMAT :UTF-8/:UNIX #xxxxxxxxxx>
Inquisitorひとめぐり with CCL● external-formatづくり --- pathname
(inquisitor:detect-external-format #P"/path/to/utf8-lf.ja" :jp)=>#<EXTERNAL-FORMAT :UTF-8/:UNIX #xxxxxxxxxx>
LTでなにを話せば……
LTでなにを話せば……_人人人人人人人人人人人人_> 技術的に面白いところ < ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
苦労話● 技術的に面白いところはありません
– 泥くさいだけでした● ある文字コードについて、各処理系で違う名前が…
– 実質的に同じ? それとも別名?– マニュアルを見比べWikipediaを見続け、ゲシュタルト崩壊
● 文字コードの闇の深さ– 一般には普及していない文字コード(CNS 11643)– 各種規格のマイク○ソフト拡張たち(CP932, etc…)
● 誤判定の原因か?
『深淵をのぞく時、深淵もまたこちらをのぞいているのだ』--- フリードリヒ・ニーチェ
それって…
はい。
Inquisitorの現状● 誤判定多し
– UTF16とUCS2とか(サロゲートペア)● そもそも文字コードの境界テストがない● テストにはTravisCIとRoswell
– 複数の処理系でのテストが楽チン● ECLで動かない
– ECL本体のバグ– 次回リリースでなんとかなる
● Quicklispに申請してみた– まだ反応なし
今後のinquisitor● 誤判定減らしたい
– 各文字コードについて更に調べる?● 深淵がこちらを見ています。仲間にしますか?
● babelとの親和性– 独自のexternal-format持つ– 対応したほうがいいのかなあー
Inquisitorをどうぞよろしくhttps://github.com/t-sin/inquisitor
以下、おまけ
SBCL(Linux)にCRLF突っ込んだら● CRが読み込まれてしまいました
(let ((f "iamacat.txt") (ef (inquisitor:detect-external-format #P"iamacat.txt" :jp))) (with-open-file (in f :external-format ef) (read-line in)))" 我輩は猫である。名前はまだない。^M"
命名inquisitor● ホルヘ・ルイス・ボルヘス『バベルの図書館』
– 本の詰まった書架からなる宇宙のお話– 真理の書かれた本を探す役人:捜査官 (inquisitor)
● babel (Common Lisp)– 文字列エンコーダ/デコーダ
● 文字コードは闇が深そうだなあ– 文字コードの深淵を探る
● そうだ、捜査官にしよう!