adbird(広告鳥) 備忘録

スマホの画面に適した「小説家になろう」縦書きPDF作成

スマホ小説家になろうを読むのには、すでに

の方法があるのだけれど、これらはページを移動するたびにブックマークレットを起動したりしないといけない。

数話程度を読む分にはブックマークレット起動は大して苦ではないけど、多くの話を一気読みしたいときには面倒くさい。

公式でも縦書きPDFにする機能はあるけど、そのPDFはパソコンでの表示を前提にしているので、スマホでの表示には適していない。

そこでスマホの画面に適した縦書きPDFにする方法。

※2020年11月7日更新。

目次

環境

  • Ubuntu18.04
  • TeXLive

Windowsではちょっと無理かも。頑張って環境そろえれば、できるかもしれないけど。

ディレクトリ構成

小説家になろう
   ├── Narou_tex.sh
   └── 小説タイトル (このディレクトリ名がpdfファイル名になる)
        ├── 001.html
        └── 002.html
             ︙

スクリプト作成

k-igrsさんという方が作ったスクリプトを拝借、少々カスタム。

Narou_tex.sh という名前で「小説家になろうディレクトリに保存。なお、「小説タイトル」ディレクトリに入れておくと、後述する連番にするコマンドでhtmlに変換されてしまうので注意。

スマホの画面の大きさに応じて、「原稿ページ設定(スマホ用)」の箇所などの調整が必要。

LaTeXの版面については、版面のパラメータにはどのようなものがありますか? - TeX・LaTeXについての覚え書きをご参考に。

フォントは僕のオススメの源暎ちくご明朝(GenEiChikugoMin2-R)とIPAexゴシックを使用する設定になっているので、源暎ちくご明朝とIPAexゴシックをPCにインストールするか(LaTeXで使えるようにするにはフォントを/home/〜/.fontsフォルダ内に入れる)、変えたい場合は「欧文・数字フォント」「ここで日本語フォント指定」の箇所を変更する。

#!/bin/bash

if [ -e ./tmpfile ]; then
    \rm -r tmpfile
fi

mkdir -p tmpfile
if [ -e ./outputb.tex ]; then
    \rm -r outputb.tex
fi

touch outputb.tex
onetimeflag=0

for fh in *.html
do
#
if [ $onetimeflag -eq 0 ]; then
    grep '^作者:<a href' $fh |sed -e 's/^作者.*">//' -e 's/<\/a>$//' > ./tmpfile/tmp_auth
    grep '^dc:title="' $fh |sed -e 's/^dc:title="//' -e 's/"$//' > ./tmpfile/tmp_title
    echo "" > ./tmpfile/tmp_section
    onetimeflag=1
fi
#
perl -e '
while(<>){
    if(/^<p class="chapter_title">/){
        chomp;
        s/^<p class=.*title">//;
        s/<\/p>$//;
        $section=$_;
        open(RDFILE, "< ./tmpfile/tmp_section");
            $tmp_section=<RDFILE>;
            chomp($tmp_section);
        close(RDFILE);
        if( $section ne $tmp_section ){
            print "\\section{$section}\n" ;
            open(WRFILE, "> ./tmpfile/tmp_section");
                print WRFILE "$section\n";
            close(WRFILE);
        }
    }
    if(/^<p class="novel_subtitle">/){
        chomp;
        s/^<p class=.*title">//;
        s/<\/p>$//;
        $subsection=$_;
        print "\\subsection{$subsection}\n";
    }
}' $fh >> outputb.tex
#
perl -e '
while(<>){
if(/^<p id="L[0-9]+"/){
    s/<\/rb><rp>\(<\/rp><rt>/<\/rb><rp>(<\/rp><rt>/g;
    s/<\/rt><rp>\)<\/rp><\/ruby>/<\/rt><rp>)<\/rp><\/ruby>/g;
    print $_ }
}' $fh > ./tmpfile/tmpf1
# ↓改行をオリジナルの見た目のままにするには、1番目を s/^<p id="L[0-9]+"> *<br \/><\/p>/\\vskip\\baselineskip/; にする。ルビpxrubricaパッケージ対応
perl -e '
while(<>){
    s/^<p id="L[0-9]+"> *<br \/><\/p>/【k改行k】/;
    s/<ruby><rb>(.*?)<\/rb><rp>(<\/rp><rt>(.*?)<\/rt><rp>)<\/rp><\/ruby>/\\ruby[g]{$1}{$2}/g;
    s/<ruby><rb>(.*?)<\/rb><rp>《<\/rp><rt>(.*?)<\/rt><rp>》<\/rp><\/ruby>/\\ruby[g]{$1}{$2}/g;
    s/!\?/\\rensuji{!\?}/g;
    print $_;
}' ./tmpfile/tmpf1 > ./tmpfile/tmpf2
#
perl -e '
while(<>){
    s/^<p id="L[0-9]+">(.*)<\/p>$/$1\n/;
    s/^ +//;
    print $_
}' ./tmpfile/tmpf2 >> outputb.tex 
done
#改行調整。改行が2つ連続の時は、改行1つ分に。改行1つ分は改行削除。
sed -i -z -e 's/【k改行k】\n【k改行k】/\\vskip\\baselineskip/g' outputb.tex
sed -i -e 's/【k改行k】//g' outputb.tex

#半角数字を全角数字に置換
sed -i -e 'y/1234567890/1234567890/' outputb.tex
#アポストロフィー変換、半角数字を全角数字など諸々置換
sed -i -e "s/\&#39;/\'/g" -e 'y/1234567890/1234567890/' -e 's/“/〝/g' -e 's/”/〟/g' -e 's/\&quot\;/"/g' -e "s/&lt;/</g" -e "s/&gt;/>/g" -e "s/\#/#/g" -e 's/\$/$/g' -e 's/%/%/g' -e "s/&/&/g" -e 's/\~/〜/g'  -e 's/?/?/g' -e 's/!/!/g' outputb.tex
#タイトルも諸々置換
sed -i -e "s/\&#39;/\'/g" -e 'y/1234567890/1234567890/' -e 's/“/〝/g' -e 's/”/〟/g' -e 's/\&quot\;/"/g' -e "s/&lt;/</g" -e "s/&gt;/>/g" -e "s/\#/#/g" -e 's/\$/$/g' -e 's/%/%/g' -e "s/&/&/g" -e 's/\~/〜/g'  -e 's/?/?/g' -e 's/!/!/g' ./tmpfile/tmp_title
#作者名も諸々置換
sed -i -e "s/\&#39;/\'/g" -e 'y/1234567890/1234567890/' -e 's/“/〝/g' -e 's/”/〟/g' -e 's/\&quot\;/"/g' -e "s/&lt;/</g" -e "s/&gt;/>/g" -e "s/\#/#/g" -e 's/\$/$/g' -e 's/%/%/g' -e "s/&/&/g" -e 's/\~/〜/g'  -e 's/?/?/g' -e 's/!/!/g' ./tmpfile/tmp_auth
# 括弧(「)の行の字下げ(半文字だけ字下げ)
sed -i -e 's/^「/\\noindent\\hspace{0.5em}「/g' outputb.tex
#リンクを非表示に
sed -i -e 's/^<a href=/%<a href=/g' outputb.tex

#背景色画像を上位フォルダからコピー
#cp ../background.png ./

#LaTex
perl -e '
    open(RDFILE, "< ./tmpfile/tmp_auth");
        $tmp_auth=<RDFILE>;
        chomp($tmp_auth);
    close(RDFILE);
        open(RDFILE, "< ./tmpfile/tmp_title");
        $tmp_title=<RDFILE>;
        chomp($tmp_title);
    close(RDFILE);
    #
    print "\\documentclass[a5j,12pt]{ltjtarticle}\n";
    print "\n";
    print "% -----章番号を無しにする-----\n";
    print "\\setcounter{secnumdepth}{0}\n";
    print "\n";
    print "%目次をハイパーリンク付きにする\n";
    print "\\usepackage[luatex,pdfencoding=auto,hidelinks]{hyperref}\n";
    print "\n";
    print "%フォント指定のためのパッケージ\n";
    print "\\usepackage{luatexja-fontspec}\n";
    print "%欧文・数字フォント(フォントによっては文字が欠落する場合があるので注意)\n";
    print "\\setmainfont{GenEiChikugoMin2-R}\n";
    print "\\setsansfont{IPAexGothic}\n";
    print "%ここで日本語フォント指定 (フォントによっては文字が欠落する場合があるので注意)\n";
    print "\\setmainjfont{GenEiChikugoMin2-R}\n";
    print "\\setsansjfont{IPAexGothic}\n";
    print "\n";
    print "%見出しのフォントサイズ(smallやfootnotesizeに)等\n";
    print "\\makeatletter\\renewcommand{\\section}{\\\@startsection{section}{2}{\\z\@}{1.5\\Cvs \\\@plus.5\\Cvs \\\@minus.2\\Cvs}{.5\\Cvs \\\@plus.3\\Cvs}{\\gtfamily\\small\\mdseries}}\\makeatother\n";
    print "\\makeatletter\\renewcommand{\\subsection}{\\\@startsection{subsection}{3}{\\z\@}{1.5\\Cvs \\\@plus.5\\Cvs \\\@minus.2\\Cvs}{.5\\Cvs \\\@plus.3\\Cvs}{\\gtfamily\\footnotesize\\mdseries}}\\makeatother\n";
    print "\\makeatletter\\renewcommand{\\subsubsection}{\\\@startsection{subsubsection}{3}{\\z\@}{1.5\\Cvs \\\@plus.5\\Cvs \\\@minus.2\\Cvs}{.5\\Cvs \\\@plus.3\\Cvs}{\\gtfamily\\footnotesize\\mdseries}}\\makeatother\n";
    print "\n";
    print "% -----図の設定-----\n";
    print "\\usepackage{graphicx}\n";
    print "\\usepackage{float}\n";
    print "\n";
    print "% -----ルビ使用の設定-----\n";
    print "%\\usepackage{luatexja-ruby}\n";
    print "\\usepackage{pxrubrica}\n";
    print "\n";
    print "% -----囲みの設定-----\n";
    print "\\usepackage{boites}\n";
    print "\n";
    print "% -----ヘッダ・フッタの設定 フォントサイズをtinyに-----\n";
    print "\\makeatletter\\def\\ps\@myheadings{\\let\\ps\@jpl\@in\\ps\@plain\\let\\\@oddfoot\\\@empty\\let\\\@evenfoot\\\@empty\\def\\\@evenhead{{\\leftmark}\\hfil\\tiny{\\thepage}}\\def\\\@oddhead{\\tiny{\\thepage}\\hfil\\rightmark}\\let\\\@mkboth\\\@gobbletwo\\let\\sectionmark\\\@gobble\\let\\subsectionmark\\\@gobble}\\makeatother\n";
    print "\\pagestyle{myheadings}\n";
    print "%------ヘッダの右に章=subsectionmark を表示----\n";
    print "\\renewcommand{\\subsectionmark}[1]{\\markright{#1}}\n";
    print "\n";
    print "\% -----原稿ページ設定(スマホ用)-----\n";
    print "\\paperwidth 62mm %ページの幅。スマホの画面を定規で測る。\n";
    print "\\paperheight 121mm %ページの高さ。スマホの画面を定規で測る。\n";
    print "\\setlength{\\topmargin}{-1in} %%topmarignを一度余白なしにする。いじらない。\n";
    print "\\addtolength{\\topmargin}{5mm} %%あらためて上余白を設定する。 \n";
    print "\\headheight 0mm\n";
    print "\\headsep 8mm %ヘッダーと本文の間\n";
    print "\\setlength{\\oddsidemargin}{-1in} %%奇数ページの左余白を一度余白なしにする。いじならい。\n";
    print "\\addtolength{\\oddsidemargin}{3.5mm} %%あらためて奇数ページの左余白を設定する。\n";
    print "\\setlength{\\evensidemargin}{-1in} %%偶数ページの左余白を一度余白なしにする。いじらない。\n";
    print "\\addtolength{\\evensidemargin}{3.5mm} %%あらためて偶数ページの左余白を設定する。\n";
    print "\\textwidth 100mm %縦書なので、これがテキストの「高さ」\n";
    print "\\textheight 55mm %縦書なので、これがテキストの「幅」(値:ページの幅ー左右の余白。フォントサイズとの兼ね合いもあるので、余白と本文テキストの幅を試行錯誤で調節する。)\n";
    print "\\footskip 0mm\n";
    print "\n";
    print "% hyperref.styの関係で、目次ページ番号が寝てしまうので、正しく縦向きに。 参考:http://id.fnshr.info/2017/05/20/my-latex-templates-201705/\n";
    print "\\makeatletter\n";
    print "\\def\\contentsline#1#2#3#4{\\csname l\@#1\\endcsname{\\hyper\@linkstart{link}{#4}{#2}\\hyper\@linkend}{\\rensuji{#3}}}\n";
    print "\\makeatother\n";
    print "\n";
    print "%目次のリーダー(点線)を消す。節(section)以降のページ下余白調整\n";
    print "\\makeatletter\n";
    print "\\def\\\@dottedtocline#1#2#3#4#5{%\n";
    print "  \\vskip\\toclineskip \\\@plus.2\\p\@%\n";
    print "  {\\setlength{\\parfillskip}{0em} %節(section)以降の下余白\n";
    print "    \\parindent #2\\relax\\\@afterindenttrue\n";
    print "   \\interlinepenalty\\\@M\n";
    print "   \\leavevmode\n";
    print "   \\\@lnumwidth #3\\relax\n";
    print "   \\advance\\leftskip \\\@lnumwidth \\hbox{}\\hskip -\\leftskip\n";
    print "    {#4}\\nobreak\n";
    print " \\leaders\\hbox to 3pt{\\hfil\\raise3pt\\hbox{}\\hfil}% ここのhbox{}でリーダーを設定\n";
    print "     \\hfill \\nobreak\\hbox to\\\@pnumwidth{%\n";
    print "         \\hss\\reset\@font\\rmfamily\\small \\normalcolor #5}\\par}}\n";
    print "\\makeatother\n";
    print "\n";
    print "% -----タイトル、筆者の設定-----\n";
    print "\\title{\\vspace{9.5mm} \\hspace{0cm} \\large $tmp_title}  %vspaceは右余白、hspaceは上余白調整\n";
    print "\\author{\\normalsize \\hspace{5cm} $tmp_auth}\n";
    print "\\date{\\hspace{\\fill}}\n";
    print "\n";
    print "%ページ背景 別途画像用意。ページサイズと合わせる。\n";
    print "%\\usepackage{wallpaper}\n";
    print "%\\TileWallPaper{62mm}{121mm}{background.png}\n";
    print "% -----本文-----\n";
    print "\n";
    print "\\begin{document}\n";
    print "\n";
    print "% -----タイトル表示-----\n";
    print "\\maketitle\n";
    print "\\thispagestyle{empty}\n";
    print "% -----目次-----\n";
    print "\\tableofcontents\n";
    print "\\newpage\n";
    print "\n";
    open(RDFILE, "< ./outputb.tex");
    while(<RDFILE>){ print $_; }
    close(RDFILE);
    print "\n\n";
    print "\\end{document}";
' > output.tex

#一時ファイル削除
\rm -rf outputb.tex tmpfile

小説をダウンロード

小説タイトルのディレクトリで端末を開いて、以下のようなコマンドで小説ページのhtmlをダウンロード。

$ wget -w 30 https://ncode.syosetu.com/n9636x/{1..20}/

薬屋のひとりごと(作者:日向夏)という小説を1話〜20話までダウンロード。

小説家になろうのサーバーに負担をかけて、アクセス制限を喰らわないように、30秒の間隔を入れている。のんびりダウンロードしよう。

htmlを連番にする

小説タイトルのディレクトリ内にダウンロードされたhtmlファイルは、index.html、index.html.1、index.html.2、…となっているので、これを001.html、002.html、003.html、…というように連番にする。

$ ls -v | awk '{ printf "mv %s %03d.html\n", $0, NR }' | sh

小説タイトルのディレクトリ内の全てのファイルが連番のhtmlに変換されてしまうので注意する。

スクリプト実行

$ bash ../Narou_tex.sh && lualatex output && lualatex output && mv output.pdf `pwd`.pdf

↑目次作成のために2回lualatexしている。

実行すると、小説タイトルのディレクトリの上位の、「小説家になろうディレクトリ内に「小説タイトル.pdf」ができているはず。

PDFをスマホに移動させて、閲覧。

縦書きPDFの閲覧には、今のところSideBooks -PDF・電子書籍・コミックViewer - Google Play のアプリがいい感じ。

f:id:adbird:20201031222554p:plain f:id:adbird:20201029221955p:plain