青空文庫 - 本棚の整理

(2025-04-24)

夜は酒を飲んで暇なので kunokatura-library.site (青空文庫の縦読み) というものを作りましたが、作品の非常に多い作家では目的の作品を探すのに一苦労します。

図書館では作品名のアイウエオ順に並んでいると思いますが、やはり本棚を整理してアクセスが簡単にできるようにすべきと思います。

漢字の読みがなを辞書から検索

python では MeCab というモジュールがあります。

これは日本語の形態素解析器であり、これを利用すれば漢字に読みがなをつけることができます。

MeCab が使用できる辞書は以下のようにいくつかあります。

いろいろ試してみたところ、mecab-ipadic-NEologd が一番いいと感じました。以下のようにしてインストールします。

git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
cd mecab-ipadic-neologd
./bin/install-mecab-ipadic-neologd

古い漢字は読めない

mecab-ipadic-NEologd も古い漢字は読めないようです。

mecab <<< "杜子春"
杜子春 名詞,固有名詞,人名,一般,*,*,杜子春,トシシュン,トシシュン

トシシュンは読めますが、

mecab <<< "讀書の態度"
讀書 名詞,一般,*,*,*,*,*
の 助詞,連体化,*,*,*,*,の,ノ,ノ
態度 名詞,一般,*,*,*,*,態度,タイド,タイド

讀が読めません。

現在のところこれが限界のようです。

python コード

mecab-ipadic-NEologd を使って本棚を整理します。

import MeCab
import json
import os
import MeCab
def get_yomi(text):
import MeCab, os
os.environ["MECABRC"] = "/etc/mecabrc"
tagger = MeCab.Tagger("-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd")
node = tagger.parseToNode(text)
yomi = []
while node:
if node.stat != MeCab.MECAB_BOS_NODE and node.stat != MeCab.MECAB_EOS_NODE:
features = node.feature.split(",")
yomi.append(features[7] if len(features) > 7 else node.surface)
node = node.next
return ''.join(yomi)
# 作家ディレクトリ内のHTMLファイルを処理
def generate_yomi_for_directory(directory):
works_with_yomi = []
for filename in os.listdir(directory):
if filename.endswith(".html"):
title = os.path.splitext(filename)[0] # 拡張子を除いたファイル名が作品名
try:
yomi = get_yomi(title)
works_with_yomi.append({'title': title, 'yomi': yomi})
except Exception as e:
print(f"Error processing {title}: {e}")
return works_with_yomi
# 作家ごとに処理
def process_all_authors(base_dir, output_base):
for entry in os.scandir(base_dir):
if entry.is_dir():
author_name = entry.name
author_path = entry.path
print(f"Processing {author_name}...")
works = generate_yomi_for_directory(author_path)
output_dir = os.path.join(output_base, author_name)
os.makedirs(output_dir, exist_ok=True)
output_file = os.path.join(output_dir, 'names.json')
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(works, f, ensure_ascii=False, indent=4)
# 使用例
shelf_dir = '/home/mituo/aozora/shelf' # 作家が格納されているディレクトリ
output_dir = '/home/mituo/aozora/authors' # 出力先ディレクトリ
process_all_authors(shelf_dir, output_dir)

このようにすると、作家ごとの本棚の index ができます。完全ではないので、これを編集します。

php で編集

php で編集します。

<?php
// JSONファイルを読み込む
function load_json($filename) {
return json_decode(file_get_contents($filename), true);
}
function save_json($data, $filename) {
$result = file_put_contents($filename, json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
if ($result === false) {
echo "<p style='color:red;'>⚠️ 保存に失敗しました!ファイルパスまたはパーミッションを確認してください。</p>";
} else {
echo "<p>✅ <strong>" . $filename . "</strong> に保存しました。</p>";
}
}
// 読みを変更する関数
function edit_yomi(&$data, $title, $new_yomi) {
foreach ($data as &$entry) {
if ($entry['title'] === $title) {
$entry['yomi'] = $new_yomi;
}
}
}
// 使用例
$data = load_json('names.json');
// 一括編集処理
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['yomi'])) {
foreach ($_POST['yomi'] as $title => $new_yomi) {
edit_yomi($data, $title, $new_yomi); // 各タイトルごとに読みを更新
}
save_json($data, 'names_edited.json'); // 更新されたデータをJSONファイルに保存
echo "<p>すべての読みが更新されました。</p>";
}
// 一覧表示
echo '<h1>タイトル一覧</h1>';
echo '<form method="POST" action="">';
echo '<ul>';
foreach ($data as $item) {
echo "<li><span style='display:inline-block; width:300px;'>{$item['title']}</span>
- <input type='text' name='yomi[{$item['title']}]' value='{$item['yomi']}' placeholder='新しい読み'>
</li>";
}
echo '</ul>';
echo '<input type="submit" value="一括編集">';
echo '</form>';
?>