電子書籍でエラーになる絵文字の検知

2024/8/24 [17:10:50] (土) 天気

今回のエントリは。

経緯

・電子書籍でエラーになるのが絵文字だった。

・元データから絵文字を検知する必要が出てきた。

結論

・perlを使えば絵文字のチェックも簡単だった。


てことなんだけど、調べてみたらunicodeまわりが魔窟でびっくり。またハマりそうなのでメモ。

以下は、何を今さらという話が無駄に長くて、既知のかたには役に立たない内容です。



電子書籍に求められる基準はほぼ以下のふたつ

・Epubcheckでエラーはない。

・kindle previewerでエラーはない。


epubcheckでエラーがなければEPUB3の電子書籍として問題はないし、kindle perviewerでエラーをチェックするのは最大の配信サイトであるAmazonでエラーがあったら商売上よろしくないから。


上記2つのチェックをクリアしたのに、一部の配信サイトでエラーになるという指摘があって、追いかけてみると、問題になったのが「絵文字」

「😀」←こういうやつ


原稿に絵文字があったんで、あれ?これってイケるんだっけと思って作ってみて、上記2つのチェックにかけてもエラーはなかった。

文字コードがShiftJISの時代ならともかく、今どきはutf8。

utf8のおかげで文字化けなんかを気にする必要はほぼなくなった。機種依存、環境依存文字に神経質にならなくていいのはストレスフリーで、いい時代になったもんだとのんきに感慨深い今日この頃だったのに…。


文字として問題はないんだけど、配信サイトごとにビューワーが違ってたりして、そのビューワーが絵文字に対応してるかどうかのことだと思う。


「EPUB | CSS組版ブログ」

https://blog.antenna.co.jp/CSSPage2/archives/category/epub


↑絵文字なんかについて、縦書きのepub3が始まった頃に議論があったらしい。

(電子書籍元年当時の話が読めるのでオススメ)


「横倒しのまま」にするのか「正立させる」のか。文字の意味的に方向があるものは正立させる?とか。そのあたりのすり合わせが問題になってたっぽい(という理解でいいのかなあ)


これは縦書きの場合、見た目けっこう致命的なので、たぶん、絵文字の対応を見送ったビューワー=配信サイトがあったんじゃないかと思う(憶測)

あるいは、そもそも、絵文字は環境ごとで見え方も違うのでそこが問題なのかもしれない(憶測)

そんなこんなの名残りもあって、面倒なものは却下、ということで今でもエラーにする配信サイトがある、んだろう(めっちゃ憶測)


epubcheckでもkindle previewerでもエラーにならない文字を自前で検知する必要にせまられる事態となった。

電子書籍のボリュームを目で追ってその中から絵文字を見つける、目視で探すなどありえない。必ず漏れが出る。


なもんで、絵文字の文字コードを調べてみて改めて今さらびっくりのunicodeだ。


ちなみに、文字を表示させるためには、以下の2本立てになっている。

・unicodeの文字コード表で文字を指定特定していて

・文字コードをエンコードすることで文字を表現する

これ、けっこう勘違いするんだけど、utf8というのは文字コードではなくてunicodeの文字コードをエンコードする方法の名前のこと。


以下のサイトを読んでまたびっくりすることをおすすめする。

「文字コード再入門 ─ Unicodeでのサロゲートペア、結合文字、正規化、書記素クラスタを理解しよう!」

https://en-ambi.com/itcontents/entry/2020/04/28/103000/

「書記素クラスタ - daiizfeel 2022」

https://isobe-yaki.hateblo.jp/entry/2023/07/20/194803


てのはともかく、読んでも難しいんで、なにか大変なことになってるんだなあ、でOK。


そもそもutf8でエンコードされた、日本語などは、ひと文字を表すのに、そのコードは3バイト使う。

ひとつの文字がアルファベットのように1バイトではないので

たとえば「日本語の文字」の6文字は、1つの文字に3バイトのコードが必要で、文字列の長さをバイト数でいうと18となる。


文字数いくつだっけ?て時に、バイト数の18ではなくて「正しく」6と数えるためにエンコードされている必要がある。


unicodeのコードをエンコードして初めて「文字として認識される」

このエンコードする方法がutf16だったりutf8とか呼ばれて、エンコードすることで初めて「文字として認識された文字を表示する=扱うことができる」という変な日本語。


perlの場合、utf8フラグというのを使うことで問題解決する。


my $str = ’日本語の文字’
my $utf8 = Encode::decode(’utf8’,$str)
print length($str)
→18文字 
print length($utf8)
→6文字

perlはこのおかげで、文字の扱いについて、普段はまずほとんど、こんな面倒くさいことを意識する必要はなくて、なもんで、すっかりわけがわからず混乱してしまったのが昨日今日の話、だ(とほほ


unicodeとutf8についてのおさらいができたところで、やっと本題。

じゃあ、絵文字を検知するには絵文字が使ってるコードを見つければいいだけじゃん。簡単だろ、と思ったらまたひと悶着。


ていうか、ここからが今回の本丸、一丁目一番地(死語)

utf8フラグだけでは解決しない「結合文字」というのがあった。


「1つの文字を表示しているのは、1つのunicodeのコードポイント」とは限らない。

ひとつの文字を表示、扱うのに、複数のunicodeのコードポイントを使ってるケースがあって、見た目のひと文字とそれを表すコードは1対1ではない、ということ。


perlでutf8フラグがついていてもutf8の文字コード(←unicodeコード表によるコードではなくてエンコード後の文字コード)2つ結合した文字はlength()では意図通りに取得できない。ひと文字として扱ってほしいのに、たとえば二文字としてカウントされてしまってお手上げ。


実のところ、書記素クラスタというのはこういう結合文字も含めた呼び方で、書記素クラスタに対応すれば「結合文字」も「ひと文字」として扱うことができる。書記素クラスタというのがなんだか「とても面倒くさい」というのはこのあたり。


こうなってくると、電子書籍でエラーをなくすために、なんでこんなことまで調べにゃならんのか。そもそもレアケースだし、配信サイト個別のクレーム対応でいいんじゃないのか。と思わないでもないけど。乗りかかった船だししょうがない。


話がそれた。

perlはこれも解決してくれる。て、テキストを扱わせたらperl最強じゃね?


「絵文字を含む文字列を分割~解説編~」

https://www.lemorin.jp/perl/3b_split_char.html

↑こちらのサイトに知りたいことのすべてがあった(多謝


 my $line = Encode::decode(’utf8’, $_);
    my $len = length($line);
    print $len . "\n";
    my @x = $line =~ m!\X!g;
    print scalar(@x) . "\n";

length()では「見た目のひと文字」じゃなくて困ってたところ、perlでは「いい感じに」「ちゃんと」文字として認識できる文字のための正規表現「\X」が用意されてた。


「perlの正規表現」

https://perldoc.perl.org/perlrebackslash#Misc


ということで、やっと本エントリの締めとなります(長っ!

問題のない文字ダネを削除して残った文字を正規表現「\X」で配列に取り出して、「見た目のひと文字」をコードポイントにバラして16進表現して絵文字のコードに検索をかける。検索がヒットしたら、それはイコール絵文字。


「HTMLの絵文字 文字コード表」

https://gray-code.com/html_css/list-of-emoji/

↑絵文字のコードはこちらの一覧から拝借しました。

こちらで掲載されているコードを絵文字判定の対象としました。


これでやっと絵文字検知。

前から言ってるんだけど、人間の目視確認、手作業修正(目grep、手marge)なんて1mmも信用できない。特におれ。なので機械に頼めるなら機械に任せるのが正解。


↓こちらも参考になりました

「Perl 5.26 & Unicode 9.0 で変わる書記素クラスタ(grapheme cluster)のお話」

https://shogo82148.github.io/blog/2017/08/25/unicode9-grapheme-cluster/


「UTF-8の文字コード表」

https://orange-factory.com/dnf/utf-8.html

image

本エントリとはまったく関係ないけど。


この埼玉県八潮市の資料館はびっくりの充実。行く前は小学校の教室ぐらいなもんだろ、と思っててすみませんでした。

交通アクセスにちょっと難があって、気楽にとはいえないけど、行けるかたはぜひぜひ

https://www.city.yashio.lg.jp/kurashi/shisetsuguide/shiryokan/index.html


[08/25 16:58:54] いろいろ間違えてたので改稿

「文字につかうバイト数」と「コードポイント」を混用していた、という乱暴な理解だった(恥

<<2026/1>>
    123
45678910
11121314151617
18192021222324
25262728293031
検索:

【最近の20件】