はじめに
hkob の雑記録の第406回目(通算1日目)は、先日失敗した音名の英語変換に再挑戦してみます。通算数値は今日から開始します。
前回の失敗を受けて
前回の失敗を受けて、アンダーラインの中に入っている文字を先にマーキング処理してみることにしました。

うまくいっているようです。

やはり何度も中断するものの続きを実行しているうちに全てのページが出来上がったと連絡がありました。このスクリーンショットで完成というつもりでよくみると、別のアノテーションが付いているものがアンダーラインの - がついていませんでした。やはり中断が何度かあると最初の指示を忘れてしまうようです。

結局いつもの API に
結局、AI に頼るのではなくいつもの自分らしく API でやることにしました。データ構造を確認しましたが、アノテーションごとに TextObject が分割されるので、underline の状態で tr の引数を変えるだけですみそうです。
src.text_objects[0..1] => [#<NotionRubyMapping::TextObject:0x00000001244638e8 @options= {"plain_text" => "し", "bold" => false, "italic" => false, "strikethrough" => false, "underline" => true, "code" => false, "color" => "default", "href" => nil}, @text="し", @type="text", @will_update=false>, #<NotionRubyMapping::TextObject:0x00000001244634d8 @options= {"plain_text" => "そみふぁ そそそ", "bold" => false, "italic" => false, "strikethrough" => false, "underline" => true, "code" => false, "color" => "red", "href" => nil}, @text="そみふぁ そそそ", @type="text", @will_update=false>]
とりあえず最初のページだけテストで試してみることにします。
#!/usr/bin/env ruby require "notion_ruby_mapping" include NotionRubyMapping NotionRubyMapping.configure { |c| c.token = ENV["NOTION_API_KEY"] } page = Page.find "https://www.notion.so/hkob/Golden-Keyboard-a90b1cb46a394b6d98a71ae6705eb53d?v=44f2448afeda494fb67a94655202bf0c&source=copy_link" print "#{page.title}\n" src = page.properties["音名"] dst = page.properties["音名2"] trans_hash = { false => ["どれみふそらしー", "CDEFGAB-"], true => ["どれみふそらしー", "cdefgab-"] } dst.text_objects.rich_text_objects = src.text_objects.map do |text_object| text = text_object.text underline = text_object.options["underline"] pre, post = trans_hash[underline] new_text = text.tr(pre, post).gsub("ぁ", "").gsub(" ", " ") options = text_object.options.dup options["underline"] = false TextObject.new(new_text, options) end page.save
問題なく動いていました。

あとは、回すだけです。途中で止まった時のために、finished のチェックも含めて追加してみました。
#!/usr/bin/env ruby require "notion_ruby_mapping" include NotionRubyMapping NotionRubyMapping.configure { |c| c.token = ENV["NOTION_API_KEY"] } trans_hash = { false => ["どれみふそらしー", "CDEFGAB-"], true => ["どれみふそらしー", "cdefgab-"] } ds = DataSource.find "79799295-3ea8-41e8-97b5-f1d46a118d17" query = ds.properties["finished"].filter_equals false ds.query_data_source(query).each do |page| print "#{page.title}\n" src = page.properties["音名"] dst = page.properties["音名2"] dst.text_objects.rich_text_objects = src.text_objects.map do |text_object| text = text_object.text underline = text_object.options["underline"] pre, post = trans_hash[underline] new_text = text.tr(pre, post).gsub("ぁ", "").gsub(" ", " ") options = text_object.options.dup options["underline"] = false TextObject.new(new_text, options) end page.properties["finished"].checkbox = true page.save end
実行してみると以下のようなエラーになりました。Notion API だと rich_text の長さに上限があるようです。
Over the Moore to Maggie /Users/hkob/.local/share/mise/installs/ruby/4.0.0/lib/ruby/gems/4.0.0/gems/notion_ruby_mapping-3.0.5/lib/notion_ruby_mapping/blocks/base.rb:396:in 'NotionRubyMapping::Base#update_json': {"object" => "error", "status" => 400, "code" => "validation_error", "message" => "body failed validation: body.properties.音名2.rich_text.length should be ≤ `100`, instead was `127`.", "request_id" => "44e30a59-90db-416b-9ed5-7d502127e9aa"} (StandardError)
実際にデータを確認してみると Dual の 3 パートなのでちょっと長いですね。とりあえずチェックマークだけつけて残りをやってもらいましょう。ただ、この程度でダメなら他の曲でも失敗しそうです。

アノテーションを回避
アノテーションが頻繁にあるとどうしても TextObject の数が超えてしまいます。ここでは、アノテーションを回避して単なるテキストに変換します。D と G だと「ど」の音が # のオンオフが変わります。色をなくす代わりに赤の「ど」だけ「C#」または「c#」に変換するようにしてみます。
#!/usr/bin/env ruby require "notion_ruby_mapping" include NotionRubyMapping NotionRubyMapping.configure { |c| c.token = ENV["NOTION_API_KEY"] } trans_hash = { [false, false] => ["どれみふそらしー", "CDEFGAB-"], [true, false] => ["どれみふそらしー", "cdefgab-"], [false, true] => ["どれみふそらしー", "CDEFGAB-"], [true, true] => ["どれみふそらしー", "cdefgab-"] } ds = DataSource.find "79799295-3ea8-41e8-97b5-f1d46a118d17" query = ds.properties["finished"].filter_equals false ds.query_data_source(query).each do |page| print "#{page.title}\n" src = page.properties["音名"] dst = page.properties["音名2"] texts = src.text_objects.map do |text_object| text = text_object.text underline = text_object.options["underline"] red = text_object.options["color"] == "red" pre, post = trans_hash[[underline, red]] text.tr(pre, post).gsub("ぁ", "").gsub(" ", " ").gsub("C", "C#").gsub("c", "c#") end dst.text_objects.rich_text_objects = texts.join("") page.properties["finished"].checkbox = true page.save end
再度実行してみました。API だと Notion AI よりも速く終わりますね。
hkob@hM1Pro tmp % time ruby kana.rb Glass of Beer New Copperplate (中略) The Kilmovee Miss McLeod Tattar Jack Walsh ruby kana.rb 2.66s user 1.05s system 0% cpu 11:50.74 total
実行結果はこんな感じです。

おわりに
結局、いろいろと Notion AI で頑張りましたが、テキストのアノテーションはかなり厳しそうでした。やはり得手不得手はありそうですね。