[perl]Spreadsheet::XLSXのeast asia localな事情について

とある事情からperlでXLSXファイルを読まなければならなくなり、cpanから
それっぽいSpreadsheet::XLSXをインストールしてテストしてみた。

|佐藤|
|鈴木|
|田代|

これをSpreadsheet::XLSXでcsvに変換したいわけだが、どういうわけか、

佐藤サトウ
鈴木スズキ
田代タシロ

となってしまうというのが今回の話。

XLSXあるいはOpen Office XMLあるいはecma-376の亡霊

こういう時はgoogle先生の出番なので調べると、というタグに
読み仮名があり、それをレンダリングするためにこうなっているらしく、
いろんな人がタグの部分を無視するようなパッチを作っていた。
これはこれで素晴らしいのだが、これでいいのだろうか? rPhは本当に
無視してしまっていいのだろうか? と思い元の規格であるecma-376
読んでみた。
18.4.6と18.4.3にrPhとphoneticProについて以下のように書かれている。

18.4.6 rPh (Phonetic hint)

This element represents a run of text which displays a phonetic hint
for this String Item (si). Phonetic hints are used to give
information about the pronunciation of an East Asian language. The
hints are displayed as text within the spreadsheet cells across the
top portion of the cell.

18.4.3 phoneticPr (Phonetic Properties)

This element represents a collection of phonetic properties that
affect the display of phonetic text for this String Item (si).
Phonetic text is used to give hints as to the pronunciation of an East
Asian language, and the hints are displayed as text within the
spreadsheet cells across the top portion of the cell. Since the
phonetic hints are text, every phonetic hint is expressed as a
phonetic run (rPh), and these properties specify how to display that
phonetic run.

つまり東アジアの言語の発音のヒントとして使われるためのものらしい。
実際、ExcelではIM入力したものは、読み仮名でソートされるが、他所から
コピぺで貼り付けたものは読み仮名情報が欠落するので文字コード順の
ソートになる。Excelきもいよ。

ということは、無下に捨てるわけにもいかないな。

いつもの変態ハック

ということで、

phonetic hint support cf ecma-376 Part1 18.4.6 rPh, 18.4.3 phoneticPr by k1complete · Pull Request #1 · k1complete/Spreadsheet-XLSX · GitHub

に勝手にプルリクを作ってみた。

これは、セルA1に'課きく 毛こ'を入れた場合(なおこれは、ecma-376で
exampleとして挙げられている由緒正しい例です)、

$cells->[0][0]->{Val}; # =>'課きく 毛こ'
$cells->[0][0]->{Rph}->[0]->{Val}; # => 'キク'
$cells->[0][0]->{Rph}->[0]->{Sb}; # => '0'
$cells->[0][0]->{Rph}->[0]->{Eb}; # => '1'
$cells->[0][0]->{Rph}->[1]->{Val}; # => 'コ'
$cells->[0][0]->{Rph}->[0]->{Sb}; # => '4'
$cells->[0][0]->{Rph}->[0]->{Eb}; # => '5'
$cells->[0][0]->{PhoneticPr}->{FontId}; # => 1

のように取り出せるものです。Sb, Ebは読み仮名に対応する文字列の開始と終了の0始まりのインデックスです。始まりは'=<'、終わりは'<'な感じのインデックスです。
ValはSpreadsheet::XLSXの値取り出しのキーとして使われているので、それを踏襲していますが、そのほかのハッシュのキーはecma-376の属性名やタグ名の先頭文字を大文字化したものを使っています。なお、PhoneticPrにはtypeという属性も定義されていて、デフォルトはfullwidthKatakanaです。

結論

なお、LibreOfficeで開いてからOpen Office XML形式で閉じると、rPhやphoneticPrといった、これらの情報は捨てられます。極東アジアでしか使われていないからね。先輩曰く「east asisaの人間は本当に捨ててもいいのか? おまえら一体どうしたいんだ? ということをwest europaの人にわかってもらわないとマージしてくれないよ」とのことで、格調高く作ってみたものの、やっぱり捨ててもいいんじゃないかと。