WindowsでProcessBuilderの文字コード周りがどうなるか検証した

外部のプログラムにデータを渡して、その結果を得たい。 標準入出力では問題が起こりそうにないが、コマンドライン引数まわりは怪しく思える。 Windows以外の、システムのデフォルトエンコーディングUTF-8な環境なら何も問題なくイケそうだが、Windowsではどうか。ここではコマンドライン引数について検証する。

こんなのを用意して、

object OuterProcess {
  def build(commands: List[List[String]]): Option[ProcessBuilder] = {
    if (commands.nonEmpty) {
      build(commands.tail) match {
        case Some(x) => Some(commands.head #| x)
        case None => Some(commands.head)
      }
    } else {
      None
    }
  }
  def call(commands: List[List[String]]): String = {
    build(commands) match {
      case Some(x) => x !!
      case None => ""
    }
  }
}

-Dfile.encoding=UTF-8な設定で以下のテストを実施した。

class OuterProcessTest extends SpecificationWithJUnit {
  "OuterProcess.call" should {
    "receive UTF-8 encoded output" in {
      OuterProcess.call(List(
        List("cmd", "/c", "type", "text.txt")
      )) mustEqual("éindʒəl") //success
    }
    "pass unicode arguments to a program" in {
      OuterProcess.call(List(
        List("cmd", "/c", "echo", "éindʒəl")
      )) mustEqual("éindʒəl") //fail
    }
    "pass unicode arguments to a program" in {
      OuterProcess.call(List(
        List("cmd", "/c", "chcp", "65001", "&&", "cmd", "/c", "echo", "éindʒəl")
      )) mustEqual("éindʒəl") //success
    }
  }
}

というわけで、引数は正しくUnicodeなまま、対象のプログラムに渡されている。そして、このechoのように、プログラムがUnicodeな引数を正しく扱えるかどうかは、そのプログラム自体(またはその設定など)に依存するようだ。例えば、Windowsで動くgrepを用意して以下のテストを行う場合、Gowgrepでは失敗してGnupackのものでは成功する。これは前者がUnicode(マルチバイト全般?)を与えた時にうまく動作せず、後者では問題ないため。

class OuterProcessTest extends SpecificationWithJUnit {
  "OuterProcess.call" should {
    "connect programs" in {
      OuterProcess.call(List(
        List("cmd", "/c", "chcp", "65001", "&&", "cmd", "/c", "echo", "éindʒəl"),
        List("grep", "éindʒəl")
      )) mustEqual("éindʒəl")
    }
  }
}

210円でiPhone5のケースにストラップを装着する方法

iPhone5を購入して、その足で100円ショップのセリアに寄って液晶保護シートとクリアケースを確保したのが昨日のこと。思いのほかケースの出来がよく、かなり満足なのですが、残念ながらストラップホールがありません。ケースに穴を開けてストラップを通すのもアリなんでしょうが、ケースの強度低下や、ストラップのヒモとiPhone本体との干渉などの不安材料があり、別の方法がないかなぁと考えました。

この改造のためのパーツを集めた100円ショップがちいさいダイソーだったので、他のショップにはもっといいものがあるかもしれませんが、今回はこんな感じです。

材料

  • 結束バンドベース (20mm角)
  • 超強力両面テープ (幅19mm)

方法

  1. 結束バンドベースにあらかじめ張ってある両面テープを剥がし、超強力両面テープ(19mm角)に張り替えます。
  2. クリアケースの好きな位置に貼ります。
  3. 完成!

どうでしょうか? それほど不恰好ではないと思います。つるつるのケースはどうしても手から離れやすいので、ストラップがあれば安心です。

Kobo Touchで目次画面の現在地が後方にズレる問題の対策

Kobo TouchはどうやらEPUBの目次に全てのページが存在していることを前提としているようで、

metadata.opfのspine内のN番目のitemref要素を開いている = toc.ncxのN番目のnavPoint要素が現在地ねっ!

と解釈するようです。目次画面を開いたとき、現在地が後方にズレるのはこれが原因です。楽天Koboから大手出版社の小説のサンプル版をいくつかダウンロードしてみましたが、普通にズレていましたので、あまり気にする人はいないのかもしれません。(というか使ってる人がそもそもいない…?)ですが、今自分がどこを開いているのかがわからないというのは、用途によってはかなり致命的です。

ところで、自炊した画像データやPDFからEPUBを作成するにはChainLPが大変便利で、僕はこのツールでデータをEPUBに変換しています。ChainLPで作成したEPUBは、一枚の画像(を表示するためのページ)と一つのitemrefが1対1になっています。このため、データに目次を設定し、出来上がったEPUBをKobo Touchで閲覧する場合、目次の現在位置が後方に(正確には、開いているページがN番目のページであった場合、N番目の目次に)ズレることになります。悲しいことですが、悲しんでばかりもいられません。少し考えると、Kobo Touchのこの仕様への対策がいくつか思いつきました。

対策A 全てのページを目次に登録する

目次の動作がすごく遅くなり、実用上問題がありました。また、意味のある目次項目が、便宜上加えられた無意味な目次項目に埋もれてしまい、加えてその位置が不規則に分散してしまうため、非常に使いづらいです。これはやめておいたほうがよいでしょう。

対策B 目次ごとにページを統合する

要するに

ページ番号 見出し
1 表紙
2
3 まえがき
4
5 第一章
6

とある場合、

ページ番号 見出し
1, 2 表紙
3, 4 まえがき
5, 6 第一章

のようにセクションごとにページをまとめてしまうわけです。この方法が今のところ最良だと思います。ページ送りも問題なく行え、またセクション内のでページ送りは、単一のページに格納する場合より高速なようです。 ChainLPで作成したEPUBに、この変更を施すスクリプトが以下です。

ところで、Kobo Touchで目次を使って別の位置にジャンプしたあと、”戻る”的な操作がうまく動作しないのはどうしてなんでしょうね…? しかたなく毎回しおりを挟んで、あとでそこに戻っていますが…。不便!

ChainLPで作成したEPUBで目次が使えない問題の対策

Open Packaging Format (OPF) 2.0.1 v1.0(http://www.idpf.org/epub/20/spec/OPF_2.0.1_draft.htm#Section2.4) の

The spine element must include the toc attribute, whose value is the the id attribute value of the required NCX document declared in manifest (see Section 2.4.1.)

あたりが問題のようです。 以下のように単純に書き換えるだけで、Kindle PaperwhiteやKobo Touchなどで目次が使えるようになります。

Kindleを買ってから延長保証を追加しようとして失敗した話

初期不良のKindleを新品交換すると、延長保証に入れなくなる

というのが今回のお話でして、実際に僕が体験したことを書こうと思います。

届いた!しかし…

いろいろ触っていると、画面に輝点というか、ディスプレイ内に金属片のようなものがあり、バックライトが反射して常に眩しく光っている感じだったのです。電話をし、返品をお願いしました。そして交換品が届き…

交換品は良い!延長保証を追加しよう!

再び電話で問い合わせ。調査後、メールで結果を報告してもらうことに。

無慈悲なメール

電話をした次の日にメールが届きました。

以下、メールを抜粋したもの

XXXX様

Amazon.co.jpにご連絡いただき、ありがとうございます。

このたびは、当サイトのご利用に際し、ご不便をおかけいたしましたことをお詫び申し上げます。

今回の延長保証を購入できない件につきまして確認させていただきましたところ、交換させていただきました端末には新たに購入した延長保証を紐付けることができないとの回答がございました。

そのため、お客様にご注文を進めていただきました際にエラーの表示がされたかと存じます。

お客様のご期待に沿う返答とならず、誠に恐れ入りますが、ご容赦いただきますようお願いいたします。

Amazon.co.jpのまたのご利用を心よりお待ちしております。

素早いレスポンスと正直な回答はGoodなのですが、改善策などは提示されず。ええーと思いつつ、仕方なく新しいものを注文しました。

そしてオチです

どうやら一度でも新品交換しちゃうと、その後購入したぶんにも延長保証を追加したりできないみたい…?

Kindle Paperwhite
Kindle Paperwhite
posted with amazlet at 13.05.13
Amazon.co.jp (2012-11-19)
売り上げランキング: 1
Kindle Paperwhite用長期保証 (自然故障・不具合を1年延長)
Techmark Japan (2012-11-19)
売り上げランキング: 247

一生手放せない本を永遠のものにした話

自炊に至った理由

普段から語学やプログラミングに関するわりと分厚い本を読まねばならないことが多く、なんとかソファーや机で読んでいたんですが、どうもムリがあると感じていました。というのもアイツらは平気な顔して馬鹿でかい空間を専有するんですよね。 ブックスタンド

ELECOM EDH-004 ブックスタンド
エレコム
売り上げランキング: 81

を使っても数冊広げれば机の上はそれでもういっぱいなわけです。紙と鉛筆を広げるスペースと食い合うんですよ。ブックスタンドを使うと多少はマシですが、今度はディスプレイを見る邪魔をする。机の上に置いてあるディスプレイの下の方が見えなくて、椅子から腰をあげて紙の上にキーボードを置いて作業をするとか…。何かが根本的に間違っている気がしました。

また、ソファーでの読書も限界が迫っていました。ふとした拍子に手首を痛めてしまい、弱ったところに数百グラムの荷重がかかるわけです。iPhoneですら持ちたくないのに、数百グラム。さすがに耐えられませんでした。結果としてこれが最後の一押しになり、自炊に挑戦して見ることにしました。

自炊する

紙の本をバラバラにしてデータ化するにはちょっと躊躇いがありました。別に作者様に申し訳ないとか、本を焼くとは何事だとか、そういった理由ではなく、単に読み終わった後に古本屋さんに売りに行くことができなくなるからです。物の価値というのは買値と売値の差額です。売れなくなるというのは、買値がそのままトータルコストになるわけで、僕のような貧乏暮らしをしている人にとってかなりの痛手になります。そこで、とりあえず手元に置いておくことが決まっている本

現代英文法講義
現代英文法講義
posted with amazlet at 13.05.13
安藤 貞雄
開拓社
売り上げランキング: 20,077

を自炊してみることにしました。 もちろん高級な自炊対応スキャナやカッターを僕は持っていませんので、自炊代行サービスに依頼しました。辞書タイプの本なのでジェットスキャンがベストなようでした。申し込み後、本を発送して、届いた本見積もりが以下のようなものです。

■お申込み内容
『 スタンダードスキャニングプラン 』
  [オーダー内容] カット+スキャン+OCR
 [納期プラン] かっとびプラン

 [解像度] 600dpiグレー
 [圧縮率] 低圧縮
 [カバースキャニング] 有り
 [ファイル名書換え] 有り
 [書籍の処分] ジェットスキャンで処分
 [納品プラン] データ送信
 [グレー割引] 希望 [10%値引き]

 ◆=====================================◆
      [最終お見積金額] 2,394円です。
 ◆=====================================◆

 ■内訳
 [851P~1050P] 1冊    @630円  小計 630円
 [ご依頼冊数合計] 1冊
 ■追加オプション
 [内:OCR加工冊数] 1冊    追加@105円  小計 105円
 [内: 辞    書 ] 1冊    追加@1,050円  小計 1,050円
 [ 解像度追加料金 ] 1冊    追加@315円  小計 315円
 [ 圧縮率追加料金 ] 1冊    追加@105円  小計 105円

 [作業料金] 2,205円

 ■納品方法
 [かっとび追加料金] 315円
 [データ送信料金] 105円

 [合計金額] 2,625円
 [割引料金] -231円  [割引率10% ]

 [最終お見積金額] 2,394円です。

これに加えて送料はこちら持ちですので、おおよそ3000円ほどかかったことになります。出来上がったものはデータで納品されます。僕の本は一日かけて運ばれ、バラバラになり、一枚ずつ丁寧に白い光で焼かれ、

現代英文法講義_安藤貞雄.zip

になりました。解凍すると中に700MBぐらいのPDFファイルが入っています。

できあがり

結論から述べますと、600dpiはかなりオーバークオリティです。しかし一生使うことを考えると、あるいは丁度よいぐらいなのかもしれません。OCRオプションは完璧ではありませんが、まずまずの精度です。現時点では完璧な結果を追求することは難しく、将来的に自炊代行サービスでのOCR精度を超えるものが、家庭で簡単に付加できるようになる時代を待たなければならないでしょう。

サンプル 現代英文法講義 p97 オリジナル

ブックスキャンでのOCRの結果

英文混じりの日本語なので難易度が高いです。ぼちぼちな精度ですが、AcrobatOCRをかけるのと大差はありません。手元にAcrobatがあるならあえてOCRオプションを選択する必要はないかもしれません。

Acrobat8でのOCRの結果

及第点でしょう。英文の中のスペースが認識されていないのが難点です。

Acrobat12でのOCRの結果

えっ これさいしんばんあくろばっとですよね えっ

天国へ旅立った本と、どこでもお話できる

PDF化した結果、PC、iPhone、タブレット、E-INK端末など、様々なデバイスから本にアクセスできるようになりました。特にKobo Touchは専用端末として活躍しています。軽く、バッテリーも長持ち、さらに紙のような視認性で、ソファーで読むための最高の選択肢です。PDFからEPUBに変換し、見出しを詳細に打つことで、目的のページを探す速度も十分に高速です。外出中にふと文法について疑問を感じても、手元のiPhoneでサクッと調べることができます。PCで英文を書いているときも、PDFを隣に開いておけます。僕のお気に入りのこの本は、紙の本というハードウェアから開放されたことで、より深く僕と繋がったと感じます。どこにいても、どんな姿勢でも、さっと手に取れるこの感覚は新しくて、すごく安心するものです。未来人はきっと、紙の本に対して不安を覚えるに違いありません。

結論

今回の試みは大成功といえると思います。しかし、まだ一冊です。僕の机にはまだまだ山のような本があり…。これらが全て天国へ旅立つとき、僕の机は(そして僕の財布も!)新しい時代を迎えるのかもしれません。