なろう作品をSend to Kindleする(ツール不要)

背景

小説家になろう」の作品をKindleの電子インクペーパーで読みたい。以前は便利なWebサービスがあったが、つかえなくなって久しい。代替ツールはあるが、インストールに手間がかかるようだ。

Kindleは、mobiやepubのような電子書籍専用のファイル形式のほかに、textやhtmlにも対応している。よって、複数話をひとつのhtmlファイルに結合するだけで、Kindleにテキストを表示することはできる。この際、縦書きではなくてもよかろう!挿絵もいらない。

やったこと

以下のRubyスクリプトを任意のディレクトリに保存して、

$ ruby narou2zip.rb [ncode]

のようにコマンドラインで実行すると、zipファイルができる。このファイルを手動でSend to Kindleすればよい。

ただし、もし未インストールのときは、一度だけ事前にNokogiriとRubyzipのインストールが必要。

$ gem install nokogiri
$ gem install rubyzip

require 'open-uri'
require 'nokogiri'
require 'zip'


def scrape(url)
  html = open(url) do |io|
    charset = io.charset
    io.read
  end
  
  return Nokogiri::HTML.parse(html, nil, charset)
end

#
def puts_novel(io, doc)
  results = doc.xpath('//div[@id="novel_p"]')
  unless results.length == 0
    io.puts results.inner_html.gsub(/<p id="L?\d+">/, '<p>')
    io.puts '<hr>' 
  end
  
  results = doc.xpath('//div[@id="novel_honbun"]')
  io.puts results.inner_html.gsub(/<p id="L?\d+">/, '<p>')
  
  results = doc.xpath('//div[@id="novel_a"]')
  unless results.length == 0
    io.puts '<hr>' 
    io.puts results.inner_html.gsub(/<p id="L?\d+">/, '<p>')
  end
end

#
ncode = (ARGV[0].nil?) ? 'n6316bn' : ARGV[0]
doc = scrape('https://ncode.syosetu.com/'+ncode+'/')

title = doc.xpath('//p[@class="novel_title"]').inner_text
writer = doc.xpath('//div[@class="novel_writername"]').inner_text.gsub(/[\r\n]/,"")
chapters= []
episodes = []

results = doc.xpath('//dl[@class="novel_sublist2"]')
results.each do |r|
  chapter_title = r.xpath('preceding-sibling::div[@class="chapter_title"][1]').inner_text
  subtitle = r.xpath('descendant::a').inner_text
  link = r.xpath('descendant::a/@href').inner_text
  
  chapters.push chapter_title unless chapters.last == chapter_title
  episodes.push [chapters.length-1, subtitle, link]
end

#io = File.new(File.basename(title) + '.html', 'w')
io = Zip::OutputStream.open(ncode+'.zip')
io.put_next_entry(File.basename(title) + '.html') 

io.puts '<!DOCTYPE html>'
io.puts '<html>'
io.puts '<head>'
io.puts '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'
io.puts '<title>'+title+'</title>'
io.puts '</head>'
io.puts '<body>'
io.puts '<h1>'+title+'</h1>'
io.puts writer

if chapters.length > 1
  io.puts '<h2>目次</h2>'
  chapters.each_index {|i| io.puts '<a href="#Ch_'+i.to_s+'">'+chapters[i]+'</a><br>'}
elsif episodes.length > 1
  io.puts '<h2>目次</h2>'
  episodes.each {|e| io.puts '<a href="#Ep'+e[2].gsub("/", "_")+'">'+e[1]+'</a><br>'}
else
  io.puts '<hr>'
end

if episodes.length == 0
  puts_novel(io, doc)
else
  temp= nil
  episodes.each do |e|
    STDERR.puts e.join(' ')
    
    unless temp == e[0]
      io.puts '<h2 id="Ch_'+e[0].to_s+'">'+chapters[e[0]]+'</h2>'
      temp = e[0]
    end
    
    io.puts '<h3 id="Ep'+e[2].gsub('/', '_')+'">'+e[1]+'</h3>'
    
    puts_novel(io, scrape('https://ncode.syosetu.com'+e[2]))
    sleep 3
  end
end

io.puts '</body>'
io.puts '</html>'
io.close

きづいたこと

  • 拡張子を".html"に変更するだけでは、html形式として識別されない。「<!DOCTYPE html>」や「<html></html>」などの最低限の構成要素を含めるべき。
    • 「<!DOCTYPE html>」がないと、markdown形式に認識されるらしい。なぜならば、単語の中に"*"(半角アスタリスク)があると、以降がすべて斜体で表示されていたため。
  • ページ内リンク(<a href="#sample">...</a>と<h2 id="sample">...</h2>のセット)がつかえるので、目次もかんたんに作れる。name属性も可。
  • ルビタグ(<ruby>...</ruby>)はつかえる。
  • アイテム名には、ファイル名が表示される。titleタグ(<title>...</title>)では表示されなかった。
  • 著者名は、metaタグ(<meta name="Author" content="...">)では表示されなかった。
  • 改行コードは、macOS/UNIX(LF)でもOK。
  • CSSによる縦書き表示(writing-mode: vertical-rl;)はできなかった。
  • 挿絵の画像は、表示できない。
  • MacOSでは、ファイル名を右クリックして圧縮したものをSend to Kindleすると、Amazonからエラーメールが返ってくる。zipコマンドで圧縮しないとだめ。
  • 短編の場合とそうでない場合との両方に対応する必要がある。

つぎやること

著者名が自動で入力できるようにしたい。

四国八十ハ箇所メモ

阿波編

  • 1番から10番は、1日でも歩ける。ただし10番の切幡寺周辺には公共交通機関がなく、帰りの行程も含めると、足にマメができてしまう。このため途中の5番の安楽寺で宿坊に泊まるのが良さそう。
  • 宿坊や民宿もよいが、電車/バス遍路ならば徳島駅のビジネスホテルに連泊するのも有効。徳島県内の札所に最寄りの電車やバスは、すべて徳島駅につながっている。フェリーも。
  • 駅やバス停から1番遠いのは切幡寺、ついで鶴林寺
  • 焼山寺徳島駅から神山線に乗る。この路線は大日寺を経由するので、先に井戸寺から大日寺まで参拝してバスを待つとよい。寄井中バス停でもよいが、ひとつ手前の役場前バス停で町営バスにのりかえる。町営バスはダイヤが薄いので、行き帰りを考慮すると、2021年時点では1択のみである。神山町営バス
  • 徳島駅から役場前まで1,000円なので、あらかじめバスの一日乗車券を購入しておく。同じ券で、鶴林寺下の生名バス停や太龍寺のロープウェイ駅にも行ける。
  • 太龍寺ロープウェイは雷雨などで止まる。歩いて登ると歩いて下山するしかなくなる。

讃岐編

伊予編

土佐編

  • 室戸という名前のバス停はふたつある。高速バスのバス停は、幹線道から外れたところにある。
  • 高知も廃仏毀釈が激しい。旧札所の高岡神社と現札所の岩本寺とはずいぶん離れている。
  • 高知市付近の札所は電車の駅から遠く、バスも本数も少ない。レンタルサイクルでロードバイクを借りるのが現実である。

丸亀製麺スパイラル

基本

  1. うどんがおいしい
  2. 客が増える
  3. 麺が打ちたて/茹でたてになる
  4. さらにうどんがおいしくなる
  5. さらに客が増える/店舗が増える

応用(人気連載作の場合)

  1. 作品がおもしろい
  2. 人気がでる
  3. 余裕や自由度が増える
  4. さらに作品独自の魅力が増す
  5. さらに人気がでる

これに汎用性を加える。

  1. A is good.
  2. A becomes popular.
  3. A upgrades A' on the effect by #2.
  4. A' is better than A.
  5. A' becomes more popular.

フレームワーク集め

これはフレームワークだ!

1

NOR、NAND、唯一神

2

静的動的、原因結果、帰納法演繹法、顕在潜在、Hardware/Software、有線無線、固定費変動費、定期不定期、一般特殊、暫定恒久、主観客観、優性劣性、ミクロマクロ、ロジ/サブ、攻撃防御、As is/To be、個別全体、充電放電、消費生産、地方中央、陰陽*、明暗、白黒、紅白、勝負、縦横、長短、多少、重軽、強弱、乾湿、善悪、寒暑*、遠近*、険易*、広狭*、死生*、往復、文武、文理、生死、新旧、古今、先後、前後、開閉、質量、現役退役、精神物体、粗密、正(Primary)副(Slave)、主(Master)従(Secondary)、現用(Active)/待機(Standby)or激甚、Yes/No、正誤、合否、諾否、入出、01、有無、+−、寄正*、虚実*、赤字黒字、積極消極、自他、はと派たか派 、穏健派強硬派、ラング/パロール、内外、吉凶、形而上形而下、売買、糶糴、秩序混沌、凹凸、勤怠、親子、進退、既婚未婚、セパ、物理論理

3

Hardware/Middleware/Application、大中小、高中低、守破離序破急、松竹梅、ヒトモノカネ、RGB、CMY、機密性/完全性/可用性、私共公、父子霊、陸海空、朝昼夜、衣食住、心技体、身口意、立法行政司法、走曲止、気体液体固体、身体生命知、3C、AND/OR/NOT、XYZ、input/processing/output、RFM、STP、右派中道左派、勝利友情努力、走攻守、内政/外政/事態対処・ 危機管理、YWT(やったこと/わかったこと/つぎやること)、スリーラインズオブディフェンス、短期中期長期、真核生物ドメイン/細菌ドメイン/古細菌ドメイン

4

上下左右、起承転結、開発/生産/運用/廃棄、東西南北、春夏秋冬、火風水土、老若男女、兄弟姉妹、I/my/me/mine、大過去/過去/現在/未来、都道府県、市区町村、加減乗除、ABOAB、⚪︎×△□、TP/TN/FP/FN、♠♥♦♣、士農工商、4M、マーケティングの4P、4C、SWOTPDCA、OODA、PEST、吸入/圧縮/燃焼/排気、荒魂/和魂/幸魂/奇魂

5

東西南北中、火水木金土、5M、AIDMA、AISAS、HEART、国社数理英、道天地将法*、智信仁勇厳*、度量数称勝*、小少軽短美、超富裕層/富裕層/準富裕層/アッパーマス層/マス層、視覚/聴覚/嗅覚/味覚/触覚、甘味/酸味/塩味/苦味/うま味、特定/防御/検知/対応/復旧、キマジメ大食らい/ハラハチブ自由人/ヒマツブシ貴族/探索ナルシスト/社交的ハンター、Innovators/Early Adopters/Early Majority/Late Majority/Laggards

6

5W1H、先勝/友引/先負/仏滅/大安/赤口、STRIDE、先史/古代/中世/近世/近代/現代、東西南北天地、喜怒哀楽愛憎、地獄/餓鬼/畜生/修羅/人間/天上、用語/調子/文体/体裁/品格/含蓄

7

組織の7S、日月火水木金土、ドレミファソラシ、知恵/勇気/節制/正義/信仰/希望/愛、暴食/色欲/強欲/憤怒/怠惰/嫉妬/傲慢、OSI7階層モデル、7つのムダ(加工のムダ/在庫のムダ/造りすぎのムダ/手待ちのムダ/動作のムダ/運搬のムダ/不良・手直しのムダ)

8

M1層M2層M3層F1層F2層F3層C層T層、側勒努趯策掠啄磔

10

0123456789、十干

12

12時間、12ヶ月、十二支

24

24時間、二十四節気

その他

頻度、交通手段

これはフレームワークはにゃ

絶対/相対