「小説家になろう/小説を読もう」の最新xx部の横書きを縦書きにしてみた
読んでみるとなかなかおもしろい作品が結構ある(転生ものが多すぎるのは残念。転生の下りだけなくせば良いのにと思うものも多々)ので、気分転換に「小説家になろう/小説を読もう」で読書すること(読むだけでは悪いので、気がつけば誤字脱字はして着るようにしています。)がありますが、更新部分だけを読む場合、横書きのテキストなので、少々読みにくいと感じていたので、簡単なプログラムを作ってみました。
いつもの如く、pythonで、結果は、ブラウザで表示させる。かなり手抜きですが、日本語の小説はやっぱり縦書きが読みやすい。
ブックマークの最新xxxx部分のところのリンク先のURLをコピーして貼り付けて、Openボタンを押すと横書きを縦書きに変換してブラウザで表示します。
私の環境は、通常xubuntu環境になってしまっているので、Chromiumで表示します。Windowsの場合はブラウザコマンド部分を変更すれば同様に動作すると思います。
本当は、PDFに変換しようとか思いましたが、なかなか縦書きPDF化は面倒な様子でしたのでやめました。更新部分だけなら短いので、ブラウザの横スクロールで問題ないですしね。
ちなみに縦書きPDFをダウンロードできますが、パケットサイズを小さくするためでしょうか、これフォントを含んでいないので、環境によっては中身が表示されません。ちなみに、linuxの場合は、「Atril Document Viewer」で読むと表示崩れもなく(文字の向きがほぼ期待通りになり)快適に読めます。
pdf2ps %1 temp.ps mv %1 %1.bk ps2pdf14 temp.ps %1 rm temp.ps
こんな感じで、一度フォントを含んだps(ポストスクリプトファイル)に変換して、再度pdf化でフォントを含んだpdfが出来上がるのでどこでも同じように表示ができるようになります。(フォントを含む分サイズが大きくなりますが)
縦書きHTMLをpdf化するのも同様にgs(ゴーストスクリプト)を使ってpsに変換してからpdf化すると比較的簡単にできそうですが…..
さて、作ったプログラムは以下(pyとcssの2個からなります。)
#!/usr/bin/env python # -*- coding: UTF-8 -*- # import wx import requests from bs4 import BeautifulSoup import subprocess import os html_path = os.path.join(os.path.abspath(os.path.dirname( __file__)), 'tategaki.html') otPrint = 'chromium-browser ' u_agent = {"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0"} class MyFrame(wx.Frame): def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) self.SetSize((400, 120)) self.text_ctrl_1 = wx.TextCtrl(self, wx.ID_ANY, "") self.button_1 = wx.Button(self, wx.ID_OPEN, "") self.__set_properties() self.__do_layout() self.Bind(wx.EVT_BUTTON, self.evtURL, self.button_1) # end wxGlade # close event self.Bind(wx.EVT_CLOSE, self.frame_close) # end def __set_properties(self): # begin wxGlade: MyFrame.__set_properties self.SetTitle("Tategaki") self.text_ctrl_1.SetToolTip("Input URL https://xxxxx.xxxx/xxx/xxx") # end wxGlade def __do_layout(self): # begin wxGlade: MyFrame.__do_layout sizer_1 = wx.BoxSizer(wx.VERTICAL) sizer_1.Add(self.text_ctrl_1, 0, wx.ALL | wx.EXPAND, 4) sizer_1.Add(self.button_1, 0, wx.ALIGN_RIGHT | wx.ALL, 9) self.SetSizer(sizer_1) self.Layout() # end wxGlade def evtURL(self, event): # wxGlade: MyFrame.<event_handler> url = self.text_ctrl_1.GetValue() res = requests.get(url, headers=u_agent) #print(res.encoding) #res.raise_for_status() content_type = 'UTF-8' soup = BeautifulSoup(res.content, 'html.parser', from_encoding=content_type) soup_novel_subtitle = soup.find_all('p', {'class': 'novel_subtitle'}) soup_content0 = soup.find_all('div', {'id': 'novel_p'}) soup_contents = soup.find_all('div', {'id': 'novel_honbun'}) content = '' for l in soup_novel_subtitle: content += f'<p class="title">{l.get_text()}</p>' content += '<br><br>' for l in soup_content0: soup_content = l.find_all('p') for lm in soup_content: #content += f'<p class="honbun_p">{lm.get_text()}</p>' content += f'{lm}' content += '<br><br>' for l in soup_contents: soup_content = l.find_all('p') for lm in soup_content: #content += f'<p class="honbun">{lm.get_text()}</p>' content += f'{lm}' html = f"""<!DOCTYPE html> <html lang="jp"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="css/tate.css"> <title>Tategaki</title> </head> <body> <section class="sheet"> {content} </section> </body> </html> """ with open(html_path, 'wb') as fo: fo.write(html.encode('UTF-8')) cmd = otPrint + html_path proc = subprocess.Popen(cmd.split()) event.Skip() def frame_close(self, event): # main_MyFrame. close<event_handler> DialogMessage = '終了しますか?' dialog = wx.MessageDialog(None, DialogMessage, '確認', style=wx.YES_NO | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP | wx.NO_DEFAULT) res = dialog.ShowModal() if res == wx.ID_YES: self.Destroy() else: dialog.Destroy() # end of class MyFrame class MyApp(wx.App): def OnInit(self): self.frame = MyFrame(None, wx.ID_ANY, "") self.SetTopWindow(self.frame) self.frame.Show() return True # end of class MyApp if __name__ == "__main__": app = MyApp(0) app.MainLoop()
何故か文字化けが起きることがあるので、BeautifulSoupでUTF-8エンコードするように変更
ルビ表示できるように少し修正。(本文を生のHTMLで表示するようにした content += f'{lm}’)
/* * 0.01 2019.04.20 draft */ * { margin: 0; padding: 0; color: #1f1f1f; font-family: IPAexMincho, TakaoExMicho, serif, helvetica, arial, sans-serif; font-size: 14pt; font-weight: normal; -webkit-print-color-adjust: exact; line-height: 2em; } body{ writing-mode: vertical-rl; writing-mode: tb-rl; -moz-writing-mode: vertical-rl; -ms-writing-mode: tb-rl; -ms-writing-mode: vertical-rl; line-break: normal; text-indent: 1ex; text-orientation: mixed; -epub-writing-mode: vertical-rl; -webkit-writing-mode: vertical-rl; -epub-line-break: normal; -webkit-line-break: normal; } body title span{ text-combine-upright: all; -ms-text-combine-horizontal: all; -webkit-text-combine: all; } ruby rt{ font-size: 25%; } a { text-decoration: overline; } p.newpage{ page-break-before: always; } .sheet { overflow: hidden; position: relative; box-sizing: border-box; page-break-after: always; height: 100vh;/*80ex;297mm;*/ width: auto;/*100vw;40em;210mm;*/ padding-top: 8mm; padding-bottom: 8mm; padding-left: 2ex; padding-right: 2ex; } @media screen { body { background: white; } .sheet { background: white; margin: 0mm auto; } }
余分なコードや、全く持って洗練されていませんが、まぁ、おまけ便利ツール?ということでご容赦^_^
追記:(2019.04.26)
Chrome/Chromiumの拡張機能に「Nehan Reader」なるものを入れるとページ機能(広告・サイド表示を除く)がそのままで縦書き表示にできました。
こういったものまでに発展させようと思っていたんですが….