17 February 2013

(Ubuntu) 青空キンドルの変換システムをローカルコンピュータにインストールする

青空文庫をPDFファイルに変換するオンラインサービス「青空キンドル」はとても便利なサイトで、何度も利用させてもらっていますが、フォントを自分の好みのものに入れ替えることが出来ない。もちろん、それはフォントの著作権の問題があるからですが…。

それなら、青空キンドルの変換システムをローカルコンピュータに移植してしまえば…

■ 検証環境
・Ubuntu Linux 12.04 LTS
Amazon Kindle 3 (表示が出来るか確認する)
TeX Live 2012.20120611-3~ubuntu12.04.1

・Ubuntu Linux 14.04 LTS (2014年4月21日 追記)
・TeX Live 2013.20140215-1

TeX Liveのインストール

TeX Wiki - Lunux/Ubuntuに書かれている通り、Ubuntu 12.10のリポジトリのバックポートを使えば、パッケージで一式丸ごとインストールできる。 新規にインストールした場合、1〜3ギガバイト程度のディスク容量が必要となる。(Ubuntu 14.04ではバックポートのリポジトリは不要)

$ sudo apt-add-repository ppa:texlive-backports/ppa
$ sudo apt-get update
$ sudo apt-get upgrade
 
$ sudo apt-get install texlive-lang-cjk
$ sudo apt-get install texlive-latex-recommended
$ sudo apt-get install texlive-fonts-recommended

ユーザフォントの追加

TeXのフォントディレクトリに、システムにインストールされているフォントファイルのシンボリックリンクを作成する。(後で説明する)フォントの埋め込み指定のために、適当なディレクトリ名を作成しその中に入れておくほうが良い。

下の例は、ヒラギノ、青キン明朝(IPAカスタマイズ)、HG教科書・行書の各フォントのシンボリックリンクを作成している。(青キン明朝フォントは、このページ内の「青空キンドルのソースコードを入手」で入手先を説明している)

シンボリックリンクを作る先のディレクトリは、/usr/share/texliveの中で日本語フォントがインストールされているそれらしきディレクトリとしている。他のディレクトリでも問題ないはずだ。

$ cd /usr/share/texlive/texmf-dist/fonts/truetype/public
 
$ sudo mkdir hiragino
$ sudo ln -s /usr/share/fonts/truetype/HiraKakuPro-W3.otf hiragino/
$ sudo ln -s /usr/share/fonts/truetype/HiraKakuPro-W6.otf hiragino/
$ sudo ln -s /usr/share/fonts/truetype/HiraMinPro-W3.otf hiragino/
$ sudo ln -s /usr/share/fonts/truetype/HiraMinPro-W6.otf hiragino/
$ sudo ln -s /usr/share/fonts/truetype/HiraMaruPro-W4.otf hiragino/
 
$ sudo mkdir aozora
$ sudo ln -s /usr/share/fonts/truetype/aokin-mincho.ttf aozora/
 
$ sudo mkdir hg
$ sudo ln -s /usr/share/fonts/truetype/HGRKK.TTC hg/
$ sudo ln -s /usr/share/fonts/truetype/hgrgy.ttc hg/

これらの日本語フォントをPDFに埋め込む設定を行う。

$ cd /usr/share/texlive/texmf-dist/fonts/truetype/public
 
$ sudo updmap --setoption kanjiEmbed hiragino
$ sudo updmap --setoption kanjiEmbed aozora
$ sudo updmap --setoption kanjiEmbed hg

TeXの設定ファイル等を追加・削除した場合は、データベースを更新しておく

$ sudo texhash

PDF変換の時に利用するフォントマップを作成する

・フォントマップ ファイルaz2tex-diff-20130220.zipをダウンロードする

例えば、dvipdfmx -f [マップファイル名]のようにマップファイルを指定することで、デフォルトフォントを変更することが出来る。(何も指定しない時はIPA明朝が使われるようだ)

ヒラギノ角ゴの例は、このような感じになる

/usr/share/texlive/texmf-dist/fonts/map/dvipdfmx/jfontmaps/aozora-hirakaku.map
rml         H               HiraKakuPro-W3.otf
rmlv        V               HiraKakuPro-W3.otf
 
gbm         H               HiraKakuPro-W6.otf
gbmv        V               HiraKakuPro-W6.otf
 
% 明朝体
hminr-h     H               HiraKakuPro-W3.otf
hminr-v     V               HiraKakuPro-W3.otf
otf-ujmr-h  UniJIS-UTF16-H  HiraKakuPro-W3.otf
otf-ujmr-v  UniJIS-UTF16-V  HiraKakuPro-W3.otf
otf-cjmr-h  Adobe-Japan1-6  HiraKakuPro-W3.otf
otf-cjmr-v  Identity-V      HiraKakuPro-W3.otf
 
% 明朝体ボールド
hminb-h     H               HiraKakuPro-W6.otf
hminb-v     V               HiraKakuPro-W6.otf
otf-ujmb-h  UniJIS-UTF16-H  HiraKakuPro-W6.otf
otf-ujmb-v  UniJIS-UTF16-V  HiraKakuPro-W6.otf
otf-cjmb-h  Adobe-Japan1-6  HiraKakuPro-W6.otf
otf-cjmb-v  Identity-V      HiraKakuPro-W6.otf
 
% ゴシック体
hgothr-h    H               HiraKakuPro-W3.otf
hgothr-v    V               HiraKakuPro-W3.otf
otf-ujgr-h  UniJIS-UTF16-H  HiraKakuPro-W3.otf
otf-ujgr-v  UniJIS-UTF16-V  HiraKakuPro-W3.otf
otf-cjgr-h  Adobe-Japan1-6  HiraKakuPro-W3.otf
otf-cjgr-v  Identity-V      HiraKakuPro-W3.otf
 
% ゴシック体ボールド
hgothr-h    H               HiraKakuPro-W6.otf
hgothr-v    V               HiraKakuPro-W6.otf
otf-ujgr-h  UniJIS-UTF16-H  HiraKakuPro-W6.otf
otf-ujgr-v  UniJIS-UTF16-V  HiraKakuPro-W6.otf
otf-cjgr-h  Adobe-Japan1-6  HiraKakuPro-W6.otf
otf-cjgr-v  Identity-V      HiraKakuPro-W6.otf

青空キンドルのソースコードを入手する

青空文庫を読もう!」より、青空文庫パッケージ(aozora.zip)をダウンロードする。

青空キンドル」より、aozora.sty, az2tex.rb の2つのファイルをダウンロードし、上のaozora.zipに上書きする。

青空キンドル」より青キン明朝フォント(aokin-mincho.ttf)をダウンロードし、上のセクションで説明したようにTeXフォントディレクトリにシンボリックリンクを作成する。

TeX/LaTeX Applications by Shinsaku Fujita」よりfurikanaパッケージ (中ツキルビ) furikana.styをダウンロードする。

ファイルを修正する

・パッチファイルaz2tex-diff-20130220.zipをダウンロードする

furikana.styをUTF-8エンコードに変換して保存する。 この処理を行わないと、最終出力のPDFでルビ(ふりがな)の横にアットマーク「@」のゴミが表示される。

aozora.styもUTF-8エンコードに変換して保存する。(こちらは、行わなくても特に問題はない)

$  nkf -w --overwrite aozora.sty
$  nkf -w --overwrite furikana.sty

az2tex.rbに少し手を入れて、出力TeXファイルのエンコードをUTF-8に変更できるようにすると共に、設定値などを画面表示するようにする。

青で着色した部分 : PDFに著作者名・タイトルを埋め込む(『青空文庫をソニーリーダーで読む』のコードを流用)。 緑で着色した部分 : ヘルプ表示。 赤で表示した部分 : 出力文字コードの指定、他、青で表示した部分 : ruby 1.9以降で必要(jcodeが無くなったため)

az2tex.rb
#!/usr/bin/ruby -Ks
# 青空文庫→TeX(ver. 0.9.5 2004/5/5 psitau)
require 'jcode' if RUBY_VERSION < '1.9'
require 'kconv'
 
PreambleLineNumber=13
MidashiType = { "小" => "ko",  "中" => "naka",  "大" => "oo" }
BoutenType = {
   "傍点" => "bou", "白ゴマ傍点" => "sirogomabou", "丸傍点" => "marubou",
   "白丸傍点" => "siromarubou", "黒三角傍点" => "kurosankakubou",
   "白三角傍点" => "sirosankakubou", "二重丸傍点" => "nijyuumarubou", "蛇の目傍点" => "jyanomebou"
}
 
$log_text = []
$line_num=0
 
# 
# ハッシュを作成
$gaiji = {}
 
# texファイル出力の文字コード
$output_encode = "utf8"
 
# メインパート
def main
   meta_data = []
   empty_line = 0
   in_note = false
   block_jisage = false
   block_jituki = false
   retsage = false
 
   while gaiji_line = DATA.gets
      gaiji_line.chomp!
      key, data = gaiji_line.split
      $gaiji[key] = data
   end
 
    puts File.basename($0) + " - convert Aozora Bunko txt into tex"
    puts ""
    # 引数が無い場合はヘルプを表示
    if(ARGV.length <=0)
        puts "usage : " + File.basename($0) + " filename [-s small|normal|large] [-d kindle2|kindledx] [-o utf8|jis|sjis]"
        puts ""
        exit
    end
 
   # 入出力ファイルの定義
   inputfile_name = ARGV.shift
   outputfile_name = inputfile_name.sub(/\.txt$/, ".tex")
   begin
       inputfile = open(inputfile_name)
   rescue
       inputfile_name += ".txt"
       inputfile = open(inputfile_name)
       outputfile_name = inputfile_name.sub(/\.txt$/, ".tex")
   end
   outputfile = open(outputfile_name, "w")
 
   # 文字サイズ、段組みのオプション
   require 'optparse'
   charsize = "normal"
   kindle = "kindle2"
   OptionParser.new{|opt|
      opt.on('-s [VAL]') {|v| charsize = v if(v) }
      opt.on('-d [VAL]') {|v| kindle = v if(v) }
      opt.on('-o [VAL]') {|v| $output_encode = v if(v) }
   }.parse!(ARGV)
 
   #設定値を画面表示
   puts "input filename  = " + inputfile_name
   puts "output filename = " + outputfile_name
   puts "font size       = " + charsize
   puts "target device   = " + kindle
   puts "output encode   = " + $output_encode
 
   count = 0
   while empty_line < 2
       count += 1
       line = inputfile.gets
        if(!line or count > 50)
           # 否青空分形式
           meta_data = []
           inputfile = open(inputfile_name)
           break
       end
       line = line.chop
       if in_note
           if line =~ /^-+$/ then in_note = false end
       else
           if line =~ /^-+$/
               in_note = true
           else
               if line =~ /^$/
                   empty_line += 1
               else
                   meta_data << translate_gaiji(line.gsub(/《[^》]+》/, ''))
               end
           end
       end
   end
 
    # dvipdfmxコマンドでPDF属性値を埋め込む場合の文字列変換設定
    outputfile.puts '\\ifnum 42146=\\euc"A4A2 \\AtBeginDvi{\\special{pdf:tounicode EUC-UCS2}}\\else'
    outputfile.puts "\\AtBeginDvi{\\special{pdf:tounicode 90ms-RKSJ-UCS2}}\\fi"
 
   # dvipdfmxコマンドで埋め込むPDF属性値(著者名、題名)
   meta_data2 = Marshal.load(Marshal.dump(meta_data))
   if (meta_data2.size > 0)
      outputfile.puts "\\special{pdf:docinfo <<"
      outputfile.print "/Title ("+normalize(meta_data2.shift)+")\n"
      case meta_data2.size
      when 1
         outputfile.print "/Author ("+normalize(meta_data2.shift)+")\n"
      else
         outputfile.print "/Subtitle ("+normalize(meta_data2.shift)+")\n"
         outputfile.print "/Author ("+normalize(meta_data2.shift)+")\n"
      end
      outputfile.puts ">>}"
   end
 
   # プリアンブルの処理
   outputfile.print write_preamble()
 
   # 文字サイズ、段組みのオプション
   outputfile.puts "\\usepackage[device=#{kindle},size=#{charsize}]{aozora}"
 
   use_title = false
 
〜 途中省略 380行目辺り 〜
 
# JISで出力
def normalize(l)
  if ($output_encode == "utf8")
    Kconv::toutf8(l.to_s)
  elsif ($output_encode == "jis")
    Kconv::tojis(l.to_s)
  elsif ($output_encode == "sjis")
    Kconv::tosjis(l.to_s)
  end
end

縦長の画像ファイル(epsファイル)の組み込み時に、用紙幅からはみ出す不具合を解消するため、次の所を少し修正する。

aozora.sty の370行目あたり
\def\sashie#1{%
   \hbox{\yoko\includegraphics[keepaspectratio=true, width = 8cm, height = 10cm]{#1}}
}%

各ファイルをTeXのディレクトリにコピーする

$ sudo cp az2tex.rb /usr/local/bin/
$ sudo chmod +x /usr/local/bin/az2tex.rb
 
$ sudo cp azlogo.eps /usr/share/texlive/texmf-dist/tex/platex/japanese/
$ sudo cp aozora.sty /usr/share/texlive/texmf-dist/tex/platex/japanese/
$ sudo cp furikana.sty /usr/share/texlive/texmf-dist/tex/platex/japanese/

TeXの設定ファイル等を追加・削除した場合は、データベースを更新しておく

$ sudo texhash

青空文庫のテキストファイルをPDF化する

20130217-azora-pdf.png

「吉川英治 私本太平記 みなかみ帖」 をPDF変換する例を取り上げる。青空文庫のウエブページより「テキストファイル(ルビあり) zipファイル」をダウンロードし解凍する。

テキストファイルをaz2tex.rbplatexコマンドでDVIファイルに変換。画像はconvertコマンドでEPSファイルに変換。最後に、dvipdfmxコマンドでPDFに変換する。(eps画像ファイル化はplatexコマンドの実行前に行うこと)

$ wget http://www.aozora.gr.jp/cards/001562/files/52423_ruby_49680.zip
$ unzip 52423_ruby_49680.zip
  inflating: fig52423_01.png
  inflating: 03minakami_jo.txt
 
$ convert fig52423_01.png fig52423_01.png.eps
 
$ az2tex.rb 03minakami_jo.txt
$ platex 03minakami_jo.tex
 
$ dvipdfmx -f aozora-hirakaku.map -p a5 03minakami_jo.dvi

複数の画像ファイルが存在する場合は、次のようにして一括でeps化出来る。

$ find ./*.png -print -exec convert {} {}.eps \;

PDFのメタデータ(書籍名、作者)を入力する。(az2tex.rb の変更で著作者名・タイトルを埋め込むようにした場合は、この処理は不要)

$ exiftool -Title="私本太平記 03 みなかみ帖" -Author="吉川 英治" 03minakami_jo.pdf

PDFファイルをKindle 3に転送する

Kindleのメールボックスに送信するのが簡単。もしくは、USBケーブルをパソコンに接続して、ファイルコピーする方法もある。

Kindleメールボックスは、Manage Your Content and Devices - Amazon.comにログオン後、「Settings」メニュー → 「Send-to-Kindle E-Mail Settings」で確認できる。

変換結果のKindle 3での表示例

20130217-kindle3-aokin.jpg
青空キンドルフォントの場合


20130217-kindle3-hirakaku.jpg
ヒラギノ角ゴシックの場合


20130217-kindle3-hiramaru.jpg
ヒラギノ丸ゴシックの場合


20130217-kindle3-hggyosyo.jpg
HG行書体の場合