4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Wordでのルビ振りを一括でできるようにした話

Last updated at Posted at 2024-02-17

概要

process.png
Wordで教材を作るために、大量のテキストにルビを振りたい(ふりがなを設定したい)。しかし、Wordのルビ機能は貧弱なためほぼ手作業になり時間がかかる。そこで、ChatGPTとWord VBAを使って、ルビ振りの半自動化を目指した。

成果

  • ChatGPTでそこそこの精度でルビを振ることができた
  • Wordの機能を使ったふりがな設定はほぼ自動化できた

要約

  • Wordでのルビ振りは精度が低く、一括処理が難しい
  • ChatGPTなら自然なルビ振りが一括でできる
  • Wordに貼り付けたChatGPTの出力から、自動でルビ設定するVBAのコードを書いた

背景

Wordのルビ振りにはいくつかの問題点があり、とても時間がかかる。教材作成のため数千字にルビを振る必要があり、時間を短縮したかった。

Wordのルビ振り機能の問題点

  • カタカナ語にルビが振られる
  • 送り仮名にもルビが振られる
  • 正確とは限らない
  • 一度に100文字程度しか処理されない ←ゆるされない

やったこと

1. 文章を用意する

プレーンテキスト
あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。

2. ChatGPTでルビを振る

ChatGPTにルビを振るように指示し、文章を入力した。

今回はChatGPT 4を使ったが、ChatGPT 3.5でもおそらくそんなに変わらないと思う。プロンプトは次のようにした。

プロンプト
入力された文章に対して、 #青空文庫形式 でルビを振ってください。
熟語には、 #熟語のルビの例 のようにまとめてルビを振ってください。
送り仮名がある場合は、 #送り仮名のある場合の例 のように、漢字部分のみにルビを振るようにしてください。
#注意事項 を守って出力してください。

#青空文庫形式
|漢字《かんじ》

#熟語のルビの例
- 「初夏」→「|初夏《しょか》」

#送り仮名のある場合の例
- 「越えて」→「|越《こ》えて」

#注意事項
- すべての漢字に対してルビを振る。
- ひらがな、カタカナ、アルファベットにはルビを振らない。
- 可能であれば、意味の解釈が必要な部分では最も一般的な読み方を選ぶ。
- ルビ付きの文章のみを出力する。
- ルビを追加する以外の改変はしない。
- 読みが分からず、どうしてもルビを振れないときはそのままにしてよい。
入力
あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。
出力
あの|イーハトーヴォ《イーハトーヴォ》のすきとおった|風《かぜ》、|夏《なつ》でも|底《そこ》に|冷《つめ》たさをもつ|青《あお》いそら、うつくしい|森《もり》で|飾《かざ》られたモリーオ|市《し》、|郊外《こうがい》のぎらぎらひかる|草《くさ》の|波《なみ》。

「イーハトーヴォ」が漢字の熟語としてルビを振られてしまっているが、気にしないこととする。どうせルビに正解があるとは限らないので、最終的には人がチェックし、気に入らない部分は直すことになる。ここでは95%程度が自動で処理されれば御の字と考えてスルーする。

3. Wordに貼り付ける

ChatGPTで出力されたルビ付きのテキストをWordに貼り付ける。このように、Wordのテキストにルビを設定するわけではないので、教材づくりのプロセスは少し変える必要があった。

スクリーンショット 2024-02-17 230828.png

4. VBAでルビを設定する

貼り付けた青空文庫形式のルビ付きテキストをもとに、Wordのルビ機能でルビを設定する。文書全体を見て、青空文庫形式のルビを見つけたら、それをもとにルビを設定するコードを書いた(ChatGPTが)。

ApplyRuby.bas
Sub ApplyRubyToAll()
    Dim regex As Object
    Dim matches As Object
    Dim match As Variant
    Dim rubyText As String
    Dim mainText As String
    Dim startPos As Long, endPos As Long
    
    ' 正規表現オブジェクトの作成
    Set regex = CreateObject("VBScript.RegExp")
    With regex
        .Global = True
        .MultiLine = True
        .IgnoreCase = False
        .Pattern = "|(.*?)《(.*?)》" ' 青空文庫形式のルビを探す正規表現
    End With
    
    ' ドキュメント内の全てのテキストに対してルビを適用
    For i = ActiveDocument.Paragraphs.Count To 1 Step -1
        Set para = ActiveDocument.Paragraphs(i)
        If regex.Test(para.Range.Text) Then
            Set matches = regex.Execute(para.Range.Text)
            ' 最後のマッチから処理を開始
            For j = matches.Count - 1 To 0 Step -1
                Set match = matches(j)
                mainText = match.SubMatches(0) ' ルビを振る対象のテキスト
                rubyText = match.SubMatches(1) ' ルビのテキスト
                startPos = match.FirstIndex + 1
                endPos = startPos + Len(match.Value) - 1
                ' ルビのテキストを含む範囲を選択
                With para.Range
                    .Start = startPos - 1
                    .End = endPos
                    .Text = mainText ' ルビ記号とルビテキストを主テキストで置換
                    .PhoneticGuide Text:=rubyText ', Alignment:=wdPhoneticGuideAlignmentOneTwoOne, Raise:=10, FontSize:=5, FontName:="BIZ UDPゴシック"
                End With
            Next j
        End If
    Next i
End Sub

image.png

今後の課題

残る問題はいろいろあるが、手動よりはだいぶましな結果になった。

問題点

  • まれに本文が改変されることがある
  • カタカナにルビが振られることがある
  • 生成AIを利用している(私の所属では使用が面倒)

記事を書いている中で、Yahoo! JAPANがルビ振りAPIを提供していることを知った。これを使ったほうがいい気がする。

続編

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?