inquisitor -common lispに文字コード判定を-

30
Inquisitor -Common Lispに文字コード判定を-

Upload: t-sin

Post on 26-Jan-2017

7.340 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Inquisitor -Common Lispに文字コード判定を-

Inquisitor-Common Lispに文字コード判定を-

Page 2: Inquisitor -Common Lispに文字コード判定を-

自己紹介● なまえ:ぐれー

– Twitter: sin_clav– Github: t-sin

● 昼はSE、夜はLisper– 9月よりPythonistaに

● Common Lisp、Clojure使い● 前回:Meetupデビュー● 今回:LTデビュー

– (((( ;゚Д゚)))ガクガクブルブル

Page 3: Inquisitor -Common Lispに文字コード判定を-

As known as...● 「口にマクロを(ry」の人です

Page 4: Inquisitor -Common Lispに文字コード判定を-

今日は、

膝にマクロを受けにきました

Page 5: Inquisitor -Common Lispに文字コード判定を-

今日は、

膝にマクロを受けにきました

つくったものを紹介します

Page 6: Inquisitor -Common Lispに文字コード判定を-

lnquisitorとは● 文字コード/改行コード判定ライブラリ● 機能

– 文字コード判定– 改行コード判定– external-formatの処理系差を吸収– ベクタ、ストリーム、pathnameから

external-format生成

Page 7: Inquisitor -Common Lispに文字コード判定を-

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))))=>" 我輩は猫である。名前はまだない。"

Page 8: Inquisitor -Common Lispに文字コード判定を-

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)))=>" 我輩は猫である。名前はまだない。"

Page 9: Inquisitor -Common Lispに文字コード判定を-

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

Page 10: Inquisitor -Common Lispに文字コード判定を-

Inquisitor以前● でも…● 対応している処理系が少ない

– 例)CCLに対応していなかった● 改行コード判定してくれない

– そもそも改行コードを扱えない処理系もある● SBCL、おまえのことだ!

● external-formatが処理系でまったく異なる– SBCL: :UTF-8 --- ただのキーワード– CCL: #<EXTERNAL-FORMAT :UTF-8/:UNIX #xxxxx> --- オブジェクト– ECL: (:UTF-8 :CRLF) --- リスト

● いちいちベクタをつくらないと判定できない

Page 11: Inquisitor -Common Lispに文字コード判定を-

ないので…

\自分でつくるしかないじゃない!/ *     +    巛 ヽ            〒 !   +    。     +    。     *     。      +    。  |  |   *     +   / /   イヤッッホォォォオオォオウ!       ∧_∧ / /      (´∀` / / +    。     +    。   *     。      ,-     f      / ュヘ    | *     +    。     +   。 +     〈_} )   |        /    ! +    。     +    +     *       ./  ,ヘ  | ガタン ||| j  / |  | |||――――――――――――

Page 12: Inquisitor -Common Lispに文字コード判定を-

Inquisitor● 文字コード判定● 改行コード判定 new!

● external-formatの処理系差を吸収 new!

● ベクタ、ストリーム、pathnameからexternal-format生成 new!

● パッケージ構造をちょっぴり整理… new!

Page 13: Inquisitor -Common Lispに文字コード判定を-

Inquisitorひとめぐり with CCL● 文字コード判定

– 言語圏たち● 改行コード判定

– 改行コードを扱える処理系か?● external-formatづくり

– ベクタから– ストリームから– pathnameから

Page 14: Inquisitor -Common Lispに文字コード判定を-

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

Page 15: Inquisitor -Common Lispに文字コード判定を-

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 バルト語 - -

Page 16: Inquisitor -Common Lispに文字コード判定を-

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

Page 17: Inquisitor -Common Lispに文字コード判定を-

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

Page 18: Inquisitor -Common Lispに文字コード判定を-

Inquisitorひとめぐり with CCL● external-formatづくり --- ベクタ

(let ((str (ccl:encode-string-to-octets "公的な捜索係、調査官がいる。"))) (inquisitor:detect-external-format str :jp))=>#<EXTERNAL-FORMAT :UTF-8/:UNIX #xxxxxxxxxx>

Page 19: Inquisitor -Common Lispに文字コード判定を-

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>

Page 20: Inquisitor -Common Lispに文字コード判定を-

Inquisitorひとめぐり with CCL● external-formatづくり --- pathname

(inquisitor:detect-external-format #P"/path/to/utf8-lf.ja" :jp)=>#<EXTERNAL-FORMAT :UTF-8/:UNIX #xxxxxxxxxx>

Page 21: Inquisitor -Common Lispに文字コード判定を-

LTでなにを話せば……

Page 22: Inquisitor -Common Lispに文字コード判定を-

LTでなにを話せば……_人人人人人人人人人人人人_> 技術的に面白いところ < ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

Page 23: Inquisitor -Common Lispに文字コード判定を-

苦労話● 技術的に面白いところはありません

– 泥くさいだけでした● ある文字コードについて、各処理系で違う名前が…

– 実質的に同じ? それとも別名?– マニュアルを見比べWikipediaを見続け、ゲシュタルト崩壊

● 文字コードの闇の深さ– 一般には普及していない文字コード(CNS 11643)– 各種規格のマイク○ソフト拡張たち(CP932, etc…)

● 誤判定の原因か?

『深淵をのぞく時、深淵もまたこちらをのぞいているのだ』--- フリードリヒ・ニーチェ

Page 24: Inquisitor -Common Lispに文字コード判定を-

それって…

はい。

Page 25: Inquisitor -Common Lispに文字コード判定を-

Inquisitorの現状● 誤判定多し

– UTF16とUCS2とか(サロゲートペア)● そもそも文字コードの境界テストがない● テストにはTravisCIとRoswell

– 複数の処理系でのテストが楽チン● ECLで動かない

– ECL本体のバグ– 次回リリースでなんとかなる

● Quicklispに申請してみた– まだ反応なし

Page 26: Inquisitor -Common Lispに文字コード判定を-

今後のinquisitor● 誤判定減らしたい

– 各文字コードについて更に調べる?● 深淵がこちらを見ています。仲間にしますか?

● babelとの親和性– 独自のexternal-format持つ– 対応したほうがいいのかなあー

Page 27: Inquisitor -Common Lispに文字コード判定を-

Inquisitorをどうぞよろしくhttps://github.com/t-sin/inquisitor

Page 28: Inquisitor -Common Lispに文字コード判定を-

以下、おまけ

Page 29: Inquisitor -Common Lispに文字コード判定を-

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"

Page 30: Inquisitor -Common Lispに文字コード判定を-

命名inquisitor● ホルヘ・ルイス・ボルヘス『バベルの図書館』

– 本の詰まった書架からなる宇宙のお話– 真理の書かれた本を探す役人:捜査官 (inquisitor)

● babel (Common Lisp)– 文字列エンコーダ/デコーダ

● 文字コードは闇が深そうだなあ– 文字コードの深淵を探る

● そうだ、捜査官にしよう!