epub3電子書籍制作作業メモ
今やってるepub3電子書籍制作仕事、というか作業に使ってるperlスクリプト類のメモ。
どのクライアントさんも、元データをいただいて、こちらでepub3ファイルに梱包するという作業。自分で原稿を集めて編集して、ということではなくて文字通り「電子書籍制作」で実態はファイル変換作業。
扱うのは、ほぼほぼ小説なのでデザインやレイアウトはシンプルなものばかり。
(以下はNDAに抵触しない、わたしの作業と使用スクリプトについて)
作業フローとしては
・事前確認
・変換作業
・事後確認
このために作って使ってるスクリプトは、元データ次第なんだけど、
事前確認に5本、変換作業に4本、事後確認に11本
だいたいこんな感じ。
元がひとの入力だし、表記表現の揺れがあったり、タイプミスもあるので、それをスクリプトでひっかけるために、確認用だけで16本のスクリプトが必要となっている。
最終的に目視するにしても、ひとの目視確認は信用できないので、スクリプトで対応できそうなものはスクリプトに任せたい…気がついたら確認用が次々と増えてきた。
もう大丈夫だろうと思っても、ひとのすることは例外処理だらけで、毎回何かある。
1)
原本がPDFの場合、pdf2textを使ってPDFとテキストを比べて確認。
PDFで見た目を調整されてる場合、元データのテキストと違いが出てしまう。違う箇所を引っ張り出して、元データを編集する必要がある。
2)
元データにスタイルが指定されている場合、どんな指定をされているのか確認。
縦中横などの漏れを防ぐためのすべてピックアップして確認をする。
3)
絵文字のチェック。
今どきはutf8なので機種依存についてはあまり気にする必要もないハズだけど、絵文字はさすがにアウト。エッセイなんかだとたまに入ってることがある。レアなケースだから目視で見落とすので、スクリプトにした。
4)
ルビのチェック。
ルビの使い方がわりとフリーダムなこともあって、これをルビにするの?というのを確認しておく。
5)
元データを変換しやすくするために、使わない部分を削除。
必要なのは本文部分で、それ以外が入ってるケースがあるのでスクリプトでカット。
その後、改ページの指定など手作業を入れて事前整形して変換用のテキストデータを作る。
6,7,8,9)
epub3ファイル群に変換する。
10)
半角文字の確認。
縦中横に指定されるべき半角文字列の確認。ついでに、感嘆符や疑問符の後ろに空白がひとつあるかないかの確認。
11)
半角縦中横のタグについての確認。
10で確認した箇所に意図通りのタグが当たってるか、あるいは意図通りタグが当たっていないことの確認。
12)
メタ情報の確認。
epub3に梱包するに当たっては書誌情報ファイルが必要。スクリプトで自動生成させてるので、その確認用
13)
全てのタグの確認。
epub3電子書籍というのはHTMLの集まり。変換スクリプトで正しくタグが当たってるか、どんなタグが当たってるか確認用。
14)
無用な空行、必要な空行の確認。
PDFとの目視確認だと見落としがちなので怪しいところをピックアップ。
15)
目次の確認。
5で改ページ指定などを手作業していて、ここでミスが入り込む可能性がある。ので、epubにした後に原本と目次があってるか確認が必要。
16)
圏点やダーシの確認。
ものによって、原本ままだったり調整が必要だったりするので、確認。
17)
変換後のルビの確認。
4でチェックしたものと差異はないかの確認
18)
変換後の目次の確認。
15とはまた別。こちらは表示用目次の確認。正しく設定されているか。
19)
句読点で終わってないのに改行されている箇所の確認。
見た目の改行とデータ的の改行で違う可能性がある。特にワードなんかが元データの場合。
20)
epubファイルからHTMLタグを削除してただのテキストデータにする。
5で作った変換直前のテキストファイルと差分を確認するため。
列挙してみるとやっぱり確認作業だらけ。確認でなにかひっかかると元データに戻って編集して変換スクリプトで変換してまた確認、というループになる。
スクリプトでやっつけてるので、機械的流れ作業に見えるけど、本(小説やエッセイ、俳句なんか)が好きで読んでなかったら見逃す見落とすケースの確認作業。それらをepub3ファイルにすり合わせるのがキモということになる。紙本と電子書籍、両方のことを知ってないとわからない、というか勘が働かないところだろう。
そこが面白いところだし、わたしが仕事をもらえてるところだと思う(思いたい)。
まだ確認すべきトラップというかご新規さんが出てくるだろうから、確認用スクリプトと目視確認作業は増えるんだろなあ。
ひとの入力は予想がつかないし手強い。
[2024/11/29 10:07:01]追記
スクリプトでもろもろ確認後
kinoppyとkindle previewerでの実際の表示、動作の確認。これが最終形態なので、ここでの目視確認の負担軽減がスクリプト類での確認作業、てことになる。
トーハクは庭園もおすすめスポットだった。
» ローカル環境で電子書籍を作る、Macアプリ・Windows版ツール 「かんたんEPUB3作成easy_epub」
SNS・ブログ・ホームページ
SNSとブログとホームページの棲み分け、というか自分的整理。
同じようなことをここに何度も書いてきてるんだけど、その都度その都度で環境も変わってるんでエントリとして残す意味は少しはあるかと。
先月、個人ホームページを改めてというか、ふたたびみたび、また作った。
これが面白い(今のところ)ので、棲み分けを意識しないとわやくちゃになりそうだ、ということでメモ。
・SNS
言葉を投げるもの。リアルタイムで言葉のキャッチボール
・ブログ
言葉を定着させるもの。言葉を蓄積されている場所。
・ホームページ
ページをひとつずつ「作って」いくもの。言葉だけじゃ足りない。
てな色分けでいいような気がする。
いま、このエントリも、思いついてなんとなくSNSに投げたものが最初。特にリアクションなど期待はしてなくて、思いついた言葉をそのまま投げただけ
それが自分的に発火点となって、いま、こうやってブログのエントリを書いてる。記録しておこうという動機がそこにできたわけで、投げっぱなしのSNSに意味はあった。
で、ホームページ。
たぶん、この手のことをこのブログ(ひまつぶし雑記帖)にだらだら書き殴ってると思うんで、そのうちまとめてページに起こそうと思う。ページを「作る」感覚ということになるかな。
SNSとブログ、ホームページの仕組みとも密着していて。
SNSは自作実装のActivityPubサーバー。
びっくりしたのが、何をするにしてもリクエストを飛ばすし、リクエストが飛んでくる。その回数が予想を遥かに超えていた。
言葉を投げる、言葉のキャッチボールというのはまさにこのことだなあ、と実感。
ブログは自作のブログっぽいCGI
ブログって何が必要なんだろうと既存のブログサービスを眺めて実装したんだけど。
言葉、データの蓄積がその本体。蓄積されたデータからどうやって引っ張り出すか表示させるかどんなふうに見せるか、というのが基本の仕組み。タグ付けなんかはまさにそれ。
ホームページは手作業作成
それこそ1ページずつコンセプト、テーマがあって、それに沿って「ページを作る」
SNSやブログとはレイヤーが違うシロモノ。1ページで完結させるし、1ページごとに動線を作って誘導する必要がある。
てな感じで棲み分けていこうと思う。
ホームページは「ページを作る」という意識が、SNSやブログと比べるとちょっとハードルが高いなあ、とも。
ちなみに各URL
・SNS「ため池::ところてん」 https://tokoroten.doncha.net/t2aki
・ブログ「ひまつぶし雑記帖」 https://t2aki.doncha.net
・ホームページ「On Golden Pond」 https://www.doncha.net
ネットは言葉で溢れかえってるなあというのを埴輪集団の画像で。
» ローカル環境で電子書籍を作る、Macアプリ・Windows版ツール 「かんたんEPUB3作成easy_epub」
戸籍証明書等の広域交付
年金受給手続きに必要な書類、証明書があるのでメモ
・戸籍謄本
戸籍証明書等の広域交付
https://www.moj.go.jp/MINJI/minji04_00082.html
マイナンバーがあるのになんで謄本が必要なの?と思うんだけど、一応準備をしておいた方がいいみたい。
わたしの場合「なんとなく」本籍地は動かしちゃいけないもの、という意識がどこかにあって、住所が変わってもずっと同じところ。なもんで、戸籍謄本なんかが必要になったら、その都度本籍地の市役所に返信用封筒をつけて、郵送で送ってもらってた。
また面倒くさいなあ、と思って調べてみたら、今年3月から地元の役所で遠方にある本籍の戸籍謄本などを発行(?)してもらえる。らしい。
お役所なので、週末祝日は休み。平日のどこかで聞きに行く。
・被雇用者番号
https://jsite.mhlw.go.jp/tokyo-hellowork/kakushu_jouhou/koyouhoken/koyouhoken/QA/hihokensya_qa.html#11
ハローワークでわかる。
いま契約している会社に連絡してPDFはもらっておいた。ただ、もしかすると「紙」が必要だったら困るな。
で、この被雇用者番号って、一度割り振られた番号をずっと使い続ける。これはもはやマイナンバーと何が違うの?という感じだなあ。
とりあえずこのふたつを用意すれば大丈夫っぽい。
まだまだ余裕があるけど、検索してみると謄本の広域交付はシステムが安定しないみたいで、交付まで10日ぐらいかかるところもあるらしい。その日その場でもらえない。
早めに確認しておくのが吉、っぽいな。
トーハク常設展の遮光土偶
» ローカル環境で電子書籍を作る、Macアプリ・Windows版ツール 「かんたんEPUB3作成easy_epub」
特別支給老齢年金のお知らせ
来年で64歳になる。
ということで「特別支給老齢年金」の請求書が郵送されてきた。
いよいよ年金受給者となるんだけど、まあ、年金だけじゃ食っていけない。学生のアルバイトにも届かない金額。
その程度とはいえ、一定の金額が安定的に入ってくる状態、というのはありがたいのも確か。
年金プラスなにかアルバイトなどの別収入を、と考えられるので少し気楽、かな。
還暦過ぎて働かなきゃ食っていけないのはなかなか鬱陶しい話で。
以前は、ライスワークとして割り切って、とか思ってたけど、歳を食うにしたがって当然ながら残り時間が少なくなってくる。
残り時間が少ないとなると、興味もないくだらないライスワークに貴重な時間を使いたくない。
現状2本立てでやってる。
現場に行って時間で身柄拘束される仕事と在宅で成果物を制作納品する仕事。
在宅の制作仕事は電子書籍の制作。
これはライフワーク。本が好きで新卒で底辺エロ出版社に入社して退社後もずっと本、出版にこだわってきた。電子書籍の制作はやっていて楽しい。
身柄拘束仕事が、本当にライスワーク。
会社ごっこにはストレスしかないけど、ライスワークとして割り切ってきた。
収入、ギャラでいうと、時給換算すると10倍ほど違う(改めて自分でも吃驚)
もちろん制作仕事の方が桁違いに高い。ただ、安定しない。多い時と少ない時の差が大きくて、これだけだと不安っちゃ不安。
しかたなくライスワークで老人の貴重な時間を切り売りするしかなかった。
このライスワーク部分。年金で補填、なんてのはさすがに無理だけど、年金と制作仕事で食っていけないこともない。
安定収入ってありがたいよなあ(今さら)
これでやっとライスワークに時間を使う必要がなくなった。
特別支給老齢年金というのは。
昭和60年(1985年)の法改正により、「老齢厚生年金」の受給開始年齢が60歳から65歳に段階的に引き上げられることになりました。このとき、現役世代への影響を軽減するため、引き上げ完了までの「つなぎ」として新設されたのが「特別支給の老齢厚生年金」です。
ということで昭和36年4月1日以前に生まれた人間が対象。
そう、ぎりぎり滑り込みセーフだ。
東京国立博物館は各館の常設展も充実してる。
特別展だけでお腹いっぱいで帰ってきてたんだけど、先日は昼食休憩を挟んでいろいろ観てきた。ほんと飽きない。マジおすすめ。
» ローカル環境で電子書籍を作る、Macアプリ・Windows版ツール 「かんたんEPUB3作成easy_epub」
LWPでtimeout指定が効かない
自作実装のActivityPubサーバーから、フォロワーさんの所属しているリモートサーバーに投稿を送信する時に、お相手のリモートサーバーがなんらかの事情で落ちてるケースがある。
レスポンスは500番代のエラーとなる。
perlで定番のLWP UserAgentを使ってリクエストを投げてるんだけど。
400番代のエラーと違って、サーバーに問題が発生している500番のエラーの場合、返事が戻ってくるのに時間がかかる、待たされる。投稿するためのPOSTもアカウント情報取得のためのGETもなかなか戻ってこない。
デフォルトだと、リクエストを投げてお相手の反応が返ってくるまで180秒(3分)待つことになっている。
LWP::UserAgent - Web ユーザエージェントクラス
https://perldoc.jp/docs/modules/libwww-perl-6.04/LWP/UserAgent.pod
timeout( $secs )
秒単位のタイムアウト値を取得または設定します。 デフォルトのtimeout()の値は180秒、つまり3分です。
サーバへの接続においてtimeout秒反応がないと、リクエストは中断します。 つまり、トランザクションが完了してrequest()メソッドが実際に返るまでの 時間を意味します。
ということなのでtimeoutに10秒とか設定してみてたんだけど、どうもそれが効いてない。
検索したら、やっぱりtimeoutの指定は効かないことがあるらしい。
LWP::UserAgentのタイムアウトがうまく効かなかった事象の調査 (序章)
https://papix.hatenablog.com/entry/2020/12/25/180640
もう少し粘って検索してみると
lWP::UserAgentの「:content_cb」(コールバック)のサブルーチンでSIGNALを設定してalarmで対応できるという記事を発見。
LWP::UserAgent get callback with timeout
https://stackoverflow.com/questions/29071348/lwpuseragent-get-callback-with-timeout
リクエストをサブルーチンで処理することになるのが、素人のわたし的に難しそう…影響範囲がわからない。
思いつきでデフォルトを180秒にしたわけじゃあるまいし、なにか理由がありそう。それをここで指定しちゃうと、全部に影響するわけだしなあ、と。
てことで、それならリモートに投稿を送信するリクエストのサブルーチン限定にしてしまえば大丈夫っぽいんじゃないかと。
サブルーチン丸ごとSIGNALのALRMを設定してevalで捕まえることにした。
結果オーライとか、やっつけ仕事だけは昔から得意だし。
my $res = "";
eval{
local $SIG{ALRM} = sub{die "timeout";};
alarm $self->{timeout};
$res = $self->post_actpb({url=>$u, content=>$args->{json}});
alarm 0;
};
if( $@ ){
printf qq{ERROR deliver %s ::: %s}, $u, $@;
}
設定を15秒にしてみたら、意図通りにtimeoutをキャッチして、待ち時間が少なくなった。
ちゃんとしたActivityPubサーバーのMastodonなんかだと、リクエストの送受信は裏側でやってるんで、アクセスしてるユーザーが待たされることはないはず。
わたしの自作ActivityPubサーバーは最低限で、いろいろ手抜きしていて表示するだけのために3分以上待たされるんだよなあ。自業自得というか。
サーバーのお守り代わりの画像
(松戸市立博物館)
» ローカル環境で電子書籍を作る、Macアプリ・Windows版ツール 「かんたんEPUB3作成easy_epub」
perlの再帰でlocalの使い途
perlでディレクトリを辿ってファイルをリストする。
というのは File::Find というモジュールがあるのでそれを使えば一発で解決するんだけど。自分のモジュールに組み込む方法がよくわからず。
File::Find - ディレクトリツリーを辿る
https://perldoc.jp/docs/modules/File-Find-1.19/File/Find.pod
読んでもなんか使い勝手が違う、というかナニソレwanted?
てことで自分のモジュールで使えるものを自作。
「static」というディレクトリ以下にある、ホームページ用のhtmlファイルをリストアップする。というもの。以前から同じことをやってるスクリプトからの使い回しのサブルーチンの再帰。
use vars qw( $HTML );
〜〜〜〜〜
〜〜〜〜〜
sub parse_static{
my $self = shift;
my $args = shift;
my @dirs = ();
my $d = ($args->{dir} || 'static');
opendir(DIR, $d ) || die;
@dirs = grep(!/^\.\.?/, readdir(DIR));
closedir(DIR);
foreach my $f (sort @dirs){
if(-d $d . '/' . $f ){
$self->parse_static({dir=> sprintf(qq{%s/%s}, $d ,$f) });
}
else{
push(@{$HTML}, $d . '/' . $f) if $f =~ m!\.x?html!;
}
}
return $HTML;
}
1)ディレクトリ一覧を取得して
2)ファイルなら配列に放り込んで
3)ディレクトリなら(1)に戻る
というありがちなスクリプト。
…なんだけど、放り込む配列は use vars を使ってのグローバル変数。そうグローバル変数!なのが前から気に入らなかった。
もっと「かっこいい書き方」があるんじゃないかと。わたしのような野良、素人にとって「かっこいい」かどうかがポイント。
検索してみた。やっぱりこれも以前からちょっと気になってた my と local の違いがきっと魔法の種だと思ったらビンゴだった。
Perl で再帰呼出し時のスタック間データ共有
https://amachang.hatenablog.com/entry/20061010/1160506848
知りたかったのが、まさにこれ。かっちょええよなあ。
ダイナミックスコープとかレキシカルスコープとか意味は分からない、グローバル変数を局所化するとかも分からない。
けど、匂いでわかるかっこよさ。さっそくこのままいただいた(多謝!
sub parse_static{
my $self = shift;
my $args = shift;
my @dirs = ();
my $d = ($args->{dir} || 'static');
local $ongoldenpond::html = $ongoldenpond::html;
opendir(DIR, $d ) || die;
@dirs = grep(!/^\.\.?/, readdir(DIR));
closedir(DIR);
foreach my $f (sort @dirs){
if(-d $d . '/' . $f ){
$self->parse_static({dir=> sprintf(qq{%s/%s}, $d ,$f) });
}
else{
push(@{$ongoldenpond::html}, $d . '/' . $f) if $f =~ m!\.x?html!;
}
}
return $ongoldenpond::html;
}
おかげで、このサブルーチンの中だけで記述が完結することができた。
パッケージ名ongoldenpondというのは、わたしがここんとこどっぷりハマってる 個人ホームページ(On Golden Pond) 用のオレオレMovableTypeのスクリプトだから。
このブログ『ひまつぶし雑記帖』にはperlの小ネタもあるから、その手のも集めて、改めて個人ホームページに掲載するかなあ。
前にも書いたように、ここは日常雑記のために記法というか、書き込んだものを変換するけど、perlやhtmlのコードをそのまま掲載しても見づらいだけになってしまう。今さら変換規則を変えると過去25年以上の分全部に影響するんで、HTMLやperlのコードをそのまま掲載できる個人ホームページの方が見やすくなる。
ちょっと整理してみるか。
「よんでますよアザゼルさん」
アザゼル篤史とベルゼブブ優一
たぶん、今、こんなものTV放映したら大騒ぎだろう(最上の褒め言葉
» ローカル環境で電子書籍を作る、Macアプリ・Windows版ツール 「かんたんEPUB3作成easy_epub」