feature image

2018年12月13日 | ブログ記事

漫画のEpubを自動作成など

前回、どうやってEpubが作られているのか、作り方について延々と無駄にお話ししました。でもこれって自動化できるんじゃね??と気が付き、自動化させてみました。

まず言語選び

ファイルのコピーや編集をするので、脳死でPythonを選択しました。
今思うとこの選択は正解でした。

それでは作っていく

xhtml

そもそも自動化できる部分はそれなりにありますが、人間が入力したほうが早いものもあります。

これらはinputされるように書いています。最初はPythonに慣れていなくて、めちゃくちゃなコードになっています。どういうことかというと、中身が.pyファイルに全て格納されています。

for i in range(maisuu):
    shutil.copyfile("./" + image_pass + "/" + "%03.f"%(i+1) + ".jpg", title + " " + "%02.f"%(numberling) + "/item/image/" + "%03.f"%(i+1) + ".jpg")
for i in range(maisuu):
    if i == 0:
        file = open(os.path.join(title + " " + "%02.f"%(numberling) + "/item/xhtml", "p-cover.xhtml"), "w",encoding="utf-8")
    else:
        file = open(os.path.join(title + " " + "%02.f"%(numberling) + "/item/xhtml", "p-"+"%03.f"%(i)+".xhtml"), "w",encoding="utf-8")
    file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE html><html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\" xml:lang=\"ja\">\n")
    file.write("<head>\n")
    file.write("<meta charset=\"UTF-8\"/>\n")
    file.write("<title>")
    file.write(title)
    file.write("</title>\n")
    file.write("<link rel=\"stylesheet\" type=\"text/css\" href=\"../style/fixed-layout-jp.css\"/>\n<meta name=\"viewport\" content=\"width=")
    file.write(str(width))
    file.write(", height=")
    file.write(str(height))
    file.write("\"/>\n\n")
    file.write("<!--made by TM -->\n")
    file.write("<script type=\"text/javascript\" src=\"js/kobo.js\"/>\n")
    file.write("<style type=\"text/css\" id=\"koboSpanStyle\">.koboSpan { -webkit-text-combine: inherit; }</style>\n\n")
    if i==0:
        file.write("</head>\n<body epub:type=\"cover\">\n<div class=\"main\">\n\n")
    else:
        file.write("</head>\n<body>\n<div class=\"main\">\n\n")
    file.write("<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" width=\"100%\" height=\"100%\" viewBox=\"0 0 " + str(width) + " " + str(height) + "\">\n")
    file.write("<image width=\""+str(width)+"\" height=\""+str(height)+"\" xlink:href=\"../image/"+image_plus+"%03.f"%(i+1)+".jpg\"/>")
    file.write("\n\n</svg>\n\n</div>\n</body>\n</html>")
    file.close

バカすぎるコード例
まあ出来ているので良しとします。直すのも面倒

standard.opf,目次の作成

新たに入力してもらうデータがあります。

metadataというフォルダがあり、スケルトン状態のstandard.opf,navigation-documents.xhtml,toc.ncxが保存されていて、作成しているepubフォルダにコピーし、それぞれの対応された行にデータを挿入しています。

with open(os.path.join(title + " " + "%02.f"%(numberling) + "/item", "standard.opf"),encoding="utf-8") as f:
    l = f.readlines()
l.insert(5,"<dc:title id=\"title\">" + title + "%02.f"%(numberling) + "</dc:title>\n")
l.insert(6,"<meta refines=\"#title\" property=\"file-as\">" + title_yomi + "</meta>\n")
l.insert(22,"<meta name=\"original-resolution\" content=\"" + str(width) + "x" + str(height) + "\"/>")
l.insert(9,"<dc:creator id=\"creator01\">" + creator + "</dc:creator>\n")
l.insert(11,"<meta refines=\"#creator01\" property=\"file-as\">" + creator_yomi + "</meta>\n")
l.insert(15,"<dc:publisher id=\"publisher\">" + publisher + "</dc:publisher>\n")
l.insert(16,"<meta refines=\"#publisher\" property=\"file-as\">" + publisher_yomi + "</meta>\n")
l.insert(20,"<dc:description>" + description + "</dc:description>\n")
l.insert(36,"<meta property=\"fixed-layout-jp:viewport\">width=" + str(width) + ", height=" + str(height) + "</meta>\n")
with open(os.path.join(title + " " + "%02.f"%(numberling) + "/item", "standard.opf"), mode='w',encoding="utf-8") as f:
    f.writelines(l)
file = open(os.path.join(title + " " + "%02.f"%(numberling) + "/item", "standard.opf"), "a",encoding="utf-8")
for i in range(maisuu):
    if i == 0:
        file.write("<item media-type=\"image/jpeg\" id=\"cover\" href=\"image/" + image_plus + "001.jpg\" properties=\"cover-image\"/>\n")
    else:
        file.write("<item media-type=\"image/jpeg\" id=\"i-" + "%03.f"%(i) + "\" href=\"image/" + image_plus + "%03.f"%(i+1) + ".jpg\"/>\n")
file.write("\n\n<!-- xhtml -->\n")
for i in range(maisuu):
    if i == 0:
        file.write("<item media-type=\"application/xhtml+xml\" id=\"p-cover\" href=\"xhtml/p-cover.xhtml\" properties=\"svg\" fallback=\"cover\"/>\n")
    else:
        file.write("<item media-type=\"application/xhtml+xml\" id=\"p-" + "%03.f"%(i) + "\" href=\"xhtml/p-" + "%03.f"%(i) + ".xhtml\" properties=\"svg\" fallback=\"i-" + "%03.f"%(i) + "\"/>\n")
file.write("\n<item id=\"xhtml-js-kobo.js\" href=\"xhtml/js/kobo.js\" media-type=\"application/javascript\"/><item id=\"js-kobo.js\" href=\"js/kobo.js\" media-type=\"application/javascript\"/></manifest>\n<spine page-progression-direction=\"rtl\" toc=\"ncx\">\n")
for i in range(maisuu):
    if i == 0:
        file.write("<itemref linear=\"yes\" idref=\"p-cover\" properties=\"rendition:page-spread-center\"/>\n")
    elif i % 2 == 1:
        file.write("<itemref linear=\"yes\" idref=\"p-" + "%03.f"%(i) + "\" properties=\"page-spread-right\"/>\n")
    else:
        file.write("<itemref linear=\"yes\" idref=\"p-" + "%03.f"%(i) + "\" properties=\"page-spread-left\"/>\n")
file.write("\n</spine>\n\n</package>")
file.close
//ここまででstandard.opfの編集が終わる
with open(os.path.join(title + " " + "%02.f"%(numberling) + "/item", "navigation-documents.xhtml"),encoding="utf-8") as f:
    l = f.readlines()
with open(os.path.join(title + " " + "%02.f"%(numberling) + "/item", "toc.ncx"),encoding="utf-8") as f:
    k = f.readlines()
for i in range(mokuji_suu):
    print("ページ数:")
    x = int(input())
    x -= 1
    if link_tuika == 0 and i == 0:
        mokuji_page = x
        with open(os.path.join(title + " " + "%02.f"%(numberling) + "/item/xhtml", "p-" + "%03.f"%(mokuji_page) + ".xhtml"),encoding="utf-8") as f:
            s = f.readlines()
    print("サブタイトル名:")
    y = input()
    l.insert(15+i,"<li><a href=\"xhtml/p-" + "%03.f"%(x) + ".xhtml\">" + y + "</a></li>\n")
    k.insert(15+i*5,"<navPoint id=\"xhtml-p-" + "%03.f"%(x) + "\" playOrder=\"" + str(i+1) + "\">\n")
    k.insert(16+i*5,"<navLabel><text>" + y + "</text></navLabel>\n")
    k.insert(17+i*5,"<content src=\"xhtml/p-" + "%03.f"%(x) + ".xhtml\"/>\n")
    k.insert(18+i*5,"</navPoint>\n\n")
    if link_tuika == 0 and i != 0:
        s.insert(16+i,"<a xlink:href=\"p-" + "%03.f"%(x) + ".xhtml\" target=\"_top\"><rect fill-opacity=\"0.0\" x=\"" + str(link_x) + "\" y=\"" + str(link_y) + "\" width=\"" + str(link_width) + "\" height=\"" + str(link_height) + "\"/></a>\n")
        if(link_direction == 0):
            link_y += link_height
        elif(link_direction == 1):
            link_x -= link_width

実はこれ、目次に対してリンクが付けられるようになっています。
どういうことかというと、目次ページには大抵「第hoge話 hogehoge」って一覧が載ってますよね??(それが目次)
そこをタッチすると、なんとその話まで一気に飛べるようになるんです!!便利~
ただ、linkはhtml方式なので、画像のx,y座標、ボックスの長方形の大きさは自分で調べてあげる必要があります。
まあそれも選択式で、さらには目次の無い4コマ漫画みたいなのも対応できるようにしています。
これでepubの素材の完成です。最後に、packingしましょう。

.batファイルによる実行

結論から言うと、

@cd %~dp0
set /P direction="Epubを最初から編集しますか?Yes:0 No:1 "
if %direction%==0 (
@python test.py
pause
)
@set /P USR_INPUT_STR="先ほど作ったフォルダを入力してください: "
cd %USR_INPUT_STR%
zip -0 -X ../"%USR_INPUT_STR%.epub" mimetype
zip -r ../"%USR_INPUT_STR%.epub" * -x mimetype
pause
exit

これで実行できます。

cd %USR_INPUT_STR%
zip -0 -X ../"%USR_INPUT_STR%.epub" mimetype
zip -r ../"%USR_INPUT_STR%.epub" * -x mimetype

これがepubを作るためのコマンドです。詳しくは知りません。コピりました。
まあこれでめでたく1からepubが作れる実行ファイルが完成しました。
今までそれなりに手作業でやってたのが自動化されて非常に便利になりました。

最後に

これ公開してもいいかなって思ったんですが、基本的なデータ(metadataフォルダ内)は全て楽天koboのepubからパクってきた参考にオマージュしたものなので、そこらへん著作権とかどうなのか怪しいと判断したため、非公開にします。少なくともここに書いたコードは自分作成なので大丈夫でしょう・・・(ところどころにkoboの文字があるのはそのせい)
なにかしら要望があれば公開はするかもしれません。その時は中身大幅に変えて自作を名乗れるようにします

TM icon
この記事を書いた人
TM

時間が足りない

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2019年11月12日
電子書籍の基本情報をebooklibで変更する方法(前編)【アドベントカレンダー2019 13日目】
TM icon TM
2020年3月14日
SysAd TechBook2 を出しました!
temma icon temma
2018年11月17日
電子書籍の解体【アドベントカレンダー2018 24日目】
TM icon TM
記事一覧 タグ一覧 Google アナリティクスについて