PHPWordで文書生成

文書を自動生成しようとして、そう言えばPHPExcelってあったよなと思って探していると、PHPWordというものも存在していることを知る(開発は2011年で止まっている)。

とりあえず、練習文書を作成してみようとすると、(紹介ページにあるとおり)日本語が文字化けしてしまってきちんと文書生成ができない。

PHPWordの内部で使われているutf8_encode()関数が悪さをしているらしく、該当箇所を探すと21件件出てきた。

$ grep -r -n utf8_encode ../PHPWord.php . | cat -n
     1  ../PHPWord.php:35:runkit_function_remove('utf8_encode');
     2  ../PHPWord.php:36:runkit_function_add('utf8_encode', '$text', 'echo $text."\n"; return mb_convert_encoding($text, "utf8", "auto");');
     3  ./Section/Footer.php:75:                $givenText = utf8_encode($text);
     4  ./Section/Footer.php:165:               $text = utf8_encode($text);
     5  ./Section/TextRun.php:83:               $givenText = utf8_encode($text);
     6  ./Section/TextRun.php:98:               $linkSrc = utf8_encode($linkSrc);
     7  ./Section/TextRun.php:100:                      $linkName = utf8_encode($linkName);
     8  ./Section/Table/Cell.php:111:           $text = utf8_encode($text);
     9  ./Section/Table/Cell.php:127:                   $linkSrc = utf8_encode($linkSrc);
    10  ./Section/Table/Cell.php:129:                           $linkName = utf8_encode($linkName);
    11  ./Section/Table/Cell.php:163:           $text = utf8_encode($text);
    12  ./Section/Table/Cell.php:272:                   $text = utf8_encode($text);
    13  ./Section/Header.php:75:                $givenText = utf8_encode($text);
    14  ./Section/Header.php:165:               $text = utf8_encode($text);
    15  ./Shared/String.php:150:                return utf8_encode(utf8_decode($value)) === $value;
    16  ./Section.php:112:              $givenText = utf8_encode($text);
    17  ./Section.php:128:              $linkSrc = utf8_encode($linkSrc);
    18  ./Section.php:130:                      $linkName = utf8_encode($linkName);
    19  ./Section.php:182:              $text = utf8_encode($text);
    20  ./Section.php:290:              $text = utf8_encode($text);
    21  ./Template.php:89:            $replace = utf8_encode($replace);

utf8_encode()自体はphp標準関数なのだが、utf8といってもISO-8859-1のLatin-1と呼ばれるものにしか対応していないため、文字化けを起こしているのらしい。

呼ばれ方は、基本的に「$X = utf8_encode($X)」という形式なので、呼び出したくなければその行をコメントアウトすればいいのだが、ところどころ「$givenText = utf8_encode($text)」という風に単にコメントアウトでは対応できなさそうな個所もある。また、先の紹介ページでは、該当箇所でutf8_encode()を削除すれば(関数呼び出しを外せば)いいという対応もあるのだが、複数個所存在するし対応抜けやらバージョンが更新された場合(は、当分実現しそうにないが)の対応などが面倒かと考えて、この関数自体をmb_convert_encoding()に置き換えればいいのではないか、と考えたのだが、そこからが長かった…。

Emacsでsmart-find.el

前のサーバのHDDが壊れて、以前からメモファイルを開くのに重宝して使っていた smart-find.el も失われてしまって、MuleからEmacsに移行してみたらライブラリに入っておらず配布サイトもなくなっているようで、新しいEmacsに対応していないため廃れたのかと思っていたが、改めて探してみるとEmacs上でのメモ書き環境を提供するHown

の作者の方が改造版を提供しているらしきものが見つかった。

早速試してみると、現行のEmacsでも(当然?)読み込めて動作したが、ディレクトリがmemoでファイル名もmemoの際に、ファイルを開くのを優先して欲しいのだがdiredでディレクトリ一覧が開いてしまう。何か優先指定の設定があったかも?

Google Groupで、smart-find.elのグループが見つかった。こちらで見つかるものも使えるのか…??

あと、Emacsの配布パッケージにも含まれている同種のツールにfilecacheというものがあるようで、これでもすぐにファイルが開けると紹介されているのだが、試したところでは選択一覧がずらずらっと出てきてしまって、あまり軽快に使えなかった。使い方が間違っているかもしれない。

Ruby gemが更新できない

ちょっと古いサーバ上のRuby (1.9.3p327) でRailsをgemでインストールしようとすると、Unsupported digest algorithm (sha256)のエラーが…。

$ gem install rails
ERROR:  Error installing rails:
        invalid gem: package is corrupt, exception while verifying: Unsupported digest 
algorithm (SHA512). (RuntimeError) in /usr/local/lib/ruby/gems/1.9.1/cache/atomic-1.1.14.gem

検索すると、Ruby自体コンパイルする際のopensslのバージョンが古かったためらしい…。

Rubyを再コンパイルすればいい(しかない)ということらしいが、サーバが古いためうまくいくかどうか…。あー、っていうか、OpenSSLから入れ替えないといけないのか…。

[追記]
OpenSSLを”0.9.7l 28 Sep 2006″から”1.0.1e 11 Feb 2013″に更新

して、Rubyも更新インストールしてみたら、gem installが動作するようになったが、今度は新たなエラーが…。

$ sudo gem install rails
Building native extensions.  This could take a while...
ERROR:  Error installing rails:
        ERROR: Failed to build gem native extension.

    /usr/local/bin/ruby extconf.rb
creating Makefile

make
compiling atomic_reference.c
atomic_reference.c:75:2: #error No CAS operation available for this platform
make: *** [atomic_reference.o] エラー 1


Gem files will remain installed in /usr/local/lib/ruby/gems/1.9.1/gems/atomic-1.1.14 
for inspection.
Results logged to /usr/local/lib/ruby/gems/1.9.1/gems/atomic-1.1.14/ext/gem_make.out

どうやら、gccも古いということらしい…。

$ gcc -v
 ...
gcc バージョン 3.3.6 release (Vine Linux 3.3.6-0vl7)

さて、gccを更新すれば作業は終わるのか…?

PHPのコマンドライン実行

PerlやRubyの -e オプションで、「ruby -e ‘puts “Hello”‘」と実行するように、PHPでも実行できたらいいのにとは以前から思っていて、で、-e オプションが動作しない(別用途になる)ため、代わりに

echo '<?php echo "Hello\n"; ?>' | php

のようにしてパイプでコマンド文字列を渡して実行していたのだが、今日ふとコマンドラインオプションをヘルプで見ていたら、

$ ruby -h
Usage: ruby [switches] [--] [programfile] [arguments]
  ...
  -r <code>        Run PHP <code> without using script tags <?..?>

の記載が…。しかも、いちいち「<? … ?>」で囲まないでもいいだと!?

ということで、

php -r 'echo "Hello\n";'

だけで済んでいたという…。

#こうなると、行末セミコロンが抜けてる場合も大目にみて実行してくれたりしないかな。

ちなみにPHPの -e オプションは

-e               Generate extended information for debugger/profiler

となっています。(なんとなく)このオプションは使用頻度低そうなので、ライン実行に置き換わってくれないかしら…。

Google SpreadsheetへのCSVデータコピペ

Google Spreadsheetは、CSVそのままの貼り付けには対応していないらしく、データを貼り付けると1つのセルにCSVデータ1行が入ってしまう。カンマをタブに(他のツールで)置き換えてTSVとすればコピペ可能らしい。また、貼り付けにはメニューからでなくCtrl-vを使う。

なお、エクセルの場合は「メニュー[データ]−[区切り位置]」でカンマを指定する。(氏名を空白区切りで姓と名のセルに分割したいような場合にも使える)