[35] 
[[Unicode]]
には
[DFN[annotation characters]]
と称する[[特別][Specials]]な[[文字]]があります。
[[ルビ]]を記述することを想定した[[並列文字列構造]]の一種のようですが、
ほとんど使われていません。

* 代替

[25] ほとんど実装されていないので、使うべきではありません。
[[ルビ]]は [[HTML]] の [CODE[ruby]] [[要素]]など、
[[マーク付け言語]]などの機能によって記述するべきです。

* 仕様書

[REFS[
- [33] 
[CITE[The Unicode Standard, Version 13.0 - ch23.pdf]], [TIME[2020-03-09T17:53:52.000Z]], [TIME[2020-12-13T07:28:31.667Z]] <https://www.unicode.org/versions/latest/ch23.pdf#G27446>
- [1] [CITE[[[The Unicode Standard]], Version 12.0 - ch23.pdf]] ([TIME[2019-03-02 07:15:46 +09:00]]) <https://www.unicode.org/versions/latest/ch23.pdf#G15944>
]REFS]

* 意味

[2] 
[DFN[interlinear annotation]]
は、
[DFN[annotated]] [[文字]]群の列に関係付けられた
[DFN[annotating text]]
によって構成されます。
[SRC[>>1]]
[[paired stateful controls]] です。

[3] 
通常の[[編集]]や[[テキスト処理]]のアルゴリズムにあっては、
[[annotated]]
[[文字]]群は[[テキストストリーム]]の一部として扱います。
[SRC[>>1]]

[8] 
[[適合実装]]は、
[[annotation character]]
に[[対応]]する場合にあっては、
base text
を annotate されていない[[テキストストリーム]]の一部である場合と同様に解釈します。
[SRC[>>1]]



[7] 
[[annotating text]]
も[[内容]]の一部ですが、
[[テキスト処理]]の一部または全部においては[RUBYB[主たる][main]][[テキストストリーム]]の一部を構成しません。
[SRC[>>1]]

[4] 
ただし、
[[annotating text]]
中の[[文字]]は、
[RUBYB[基底テキスト][base text]]と同種の[[配置]]、
[[テキスト処理]]、
[[編集]]のアルゴリズムでアクセス可能です。
[SRC[>>1]]

[9] 
[[適合実装]]は、
[[annotation character]]
に[[対応]]する場合にあっては、
[[annotating text]]
中の
annotating character
を通常の [[Unicode]] の[RUBYB[[[意味]]][semantics]]によって解釈します。
[SRC[>>1]]


[5] 
[[annotation character]] は、
[[annotating text]] と
[[annotated]] text
を区切り、
これを annotation の一部として示すものです。 [SRC[>>1]]

[REFS[
- [32] [[annotation characters]]
の一覧
<https://chars.suikawiki.org/set/%24unicode%3Aannotation-characters>

]REFS]

[10] 
[DFN[[CODE(char)[U+FFF9]]]]
[DFN[[CODE(charname)@en[INTERLINEAR ANNOTATION ANCHOR]]]]
は、
[[interlinear annotation]] の前に来る anchor [[文字]]です。
[SRC[>>1]]

[11] 
[DFN[[CODE(char)[U+FFFA]]]]
[DFN[[CODE(charname)@en[INTERLINEAR ANNOTATION SEPARATOR]]]]
は、
[[テキストストリーム]]中の base character 群を次の
[[annotation character]] 群から区切るものです。
[SRC[>>1]]

[12] [CODE(char)[U+FFFA]] は複数あっても構わず、
[RUBYB[複数部分][multipart]]の [[annotating text]]
の各部を区切ります。
[SRC[>>1]]

[13] 
[DFN[[CODE(char)[U+FFFB]]]]
[DFN[[CODE(charname)@en[INTERLINEAR ANNOTATION TERMINATOR]]]]
は、
annotation object を終端する
(通常の[[テキストストリーム]]に復帰する) ものです。
[SRC[>>1]]



[6] 
[[annotation character]] は、
[RUBYB[外部][out-of-band]]情報が[[文字ストリーム]]に関連付けられているときに内部処理で使います。
[[annotation]]
の正確な性質や[RUBYB[書式付け][formatting]]は、
[[平文ストリーム]]の一部ではない追加の情報に依存します。
これは [CODE(char)[U+FFFC]] [CODE(charname)@en[OBJECT REPLACEMENT CHARACTER]]
とよく似ていますが、
[CODE(char)[U+FFFC]]
はこの[[文字]]によって不透明なオブジェクトを隠すのに対し、
annotation の場合それ自体はテキストなのであります。
[SRC[>>1]]

;; [26] [CITE[Unicode Standard]] の規定はあやふやで用語も揺れまくっていて、
[[行間を読む]]他ない惨状です。 [[HTML]] の [CODE[ruby]]
を知っていれば、だいたい何をやりたかったのかは推測できます。

* 構文

[17] 
anchor 文字は、
対応する
terminator 文字の前になければなりません。
[SRC[>>1]]

[19] 
annotation
は入れ子にして構いません。
[SRC[>>1]]

[FIG(railroad)[ [27] [[interlinear annotation]]
= [CODE[U+FFF9]]
= [[annotated]]
= +
== [CODE[U+FFFA]]
== [[annotating text]]
= [CODE[U+FFFB]]

]FIG]

[29] 
[[annotated]] と
[[annotating text]]
に[[改段落]]を含むことはできません (>>16)。
[[空文字列]]でも良いのかは定かではありません。

* 文脈

[28] 
[[annotation character]]
は、
通常は[[末端利用者]]に直接[[入力]]、[[編集]]されません。
一般的には[[応用]]が[[テキスト]]の[[選択]]と[RUBYB[注釈付け][annotating]]の[[利用者インターフェイス]]を提示し、
挿入と管理を行うものです。
[SRC[>>1]]


[14] 
[[annotation character]]
の[[平文]]における使用は、
[[送受信者間の事前の合意][当事者間の合意]]がある場合を除き、
[[内容]]が誤解されるおそれがあるため、
[RUBYB[強く非推奨][strongly discouraged]]です。
[SRC[>>1]]

[15] 
[[annotation character]]
を除去するだけでは読めない結果が生成されたり、
最悪、意味が逆になってしまうかもしれません。
[[平文]]の受信者は、
入力中のすべての[[文字]]をそのまま残すか、
[[interlinear annotation character]] と [[annotating text]]
を削除するかのいずれかとするべきです。
[[平文]]の出力時に送信者が受信者を知らない場合、
[[interlinear annotation character]] と [[annotating text]]
を削除するべきです。
[SRC[>>1]]

* 処理

[16] 
[[実装]]は、
anchor 文字の後、
terminator 文字の前に[[改段落]]が出現した場合、
開いている [[annotation]] を閉じなければなりません。
[SRC[>>1]]

[18] 
組になっていない
anchor 文字や
terminator 文字は、
無視するべきです。
[SRC[>>1]]


[20] 
anchor 文字と
terminator 文字の組の外側に出現した 
separator 文字は、
無視するべきです。
[SRC[>>1]]

[30] 
[[照合]]では、
annotation
を[[整列キー]]として使うことを想定する特殊な場合を除き、
無視するか、
任意選択により前処理して [[tie breaker]] としてのみ使うこととするのが普通です。
annotation base character 群は無視せず、
通常の[[テキスト]]として扱うことが重要であります。
[SRC[>>1]]


* レンダリング

[21] 
[RUBYB[書式付け][formatting]]に関する情報は、
[[上位層プロトコル]]によって提供されます。
[[配置]]の詳細は[[実装定義]]です。
正確な書式付けのために必要な追加情報は[[文字ストリーム]]中に現れず、
[RUBYB[外部][out-of-band]]に示されるかもしれません。
従って annotation marker は別情報源の情報にアクセスできる実装のための
[[placeholder]]
として機能するのです。
[SRC[>>1]]

[22] 
書式付けその他[[行組版]]の特殊機能については [[JIS X 4051]]
で議論されています。
[SRC[>>1]]
と説明されていますが、
[[JIS X 4051]]
の[[ルビ]]のモデルに
[[annotation characters]]
がどう当てはまりどう処理しどう表示するべきなのか、
説明が無さすぎます。

[23] 
[CITE[Unicode Standard]] の利用例図 [SRC[>>1]]
にある通り、 [[ルビ]]として[[レンダリング][文字のレンダリング]]されることが想定されていますが、
利用方法は実装依存となっていて [CITE[Unicode Standard]]
は完全に丸投げしています。

[24] 
意図通りに正しくレンダリングする実装があるのかは不明であり、
主要な実装では皆無です。外部情報が必要とされ、
具体的なことは何も定められていないのですから、
実装できるはずもありません。

[34] 
未対応の実装は、
通常の未対応の[[文字]]のときのように、
可視的なグリフを表示する[RUBYB[べき][should]]です。
そうしなければ境目がわからなくなって誤読を招くおそれがあります。
[SRC[>>33]]


[31] 
[[bidi]] アルゴリズムは、
[[interlinear annotation]]
を
[[annotated text]] 
に置き換えた上で各々の [[annotated text]]
が視覚的に連続するよう
[[bidirectional format control character]]
で囲んだ主たるテキストに適用するべきであり、
更にそれぞれの [[annotating text]]
に別個に適用するべきであります。
[SRC[>>1]]


* 実装

[38] [CITE@ja[5-0-5. Solstitium(txt→縦書きPDF変換ソフト)]], [TIME[2020-11-12T14:58:48.000Z]], [TIME[2021-01-15T08:58:23.368Z]] <http://www.akenotsuki.com/eyeben/fonts/solstitium.html>


* 歴史


[45] 
[TIME[1996-04-18]], [TIME[1996-04-19]]に
[[Junichiro Kida]]
が
[[8th Unicode conference]]
で[[日本]]文化における[[ルビ]]について講演しました [SRC[>>47 #page=3]]。
これが大いに話題になりました。

- [47] 
[TIME[2024-08-26T03:50:50.500Z]]
<https://ipsj.ixsq.nii.ac.jp/ej/index.php?action=pages_view_main&active_action=repository_action_common_download&item_id=59153&item_no=1&attribute_id=1&file_no=1&page_id=13&block_id=8>

;; [46] ここから分岐 [SEE[ [[ruby=""]] ]]

- [43] [CITE@ja[98055.pdf]], 
Februrary 22, 1998,
[TIME[2005-04-07T21:19:01.000Z]], [TIME[2024-08-26T03:53:55.896Z]] <https://www.unicode.org/L2/L1998/98055.pdf>

[44] >>43 この時点では最終版より複雑なものが書けた。提案者
[[Asmus Freytag]]
は [[Unicode]] 役員。

;; [52] [TIME[1994年][1994]]頃まで [[Microsoft]] 社員。

- [53] [CITE@ja[L2/98-281 - 98281r.pdf]], [TIME[2005-09-07T17:28:58.000Z]], [TIME[2024-08-26T07:37:58.252Z]] <https://www.unicode.org/L2/L1998/98281r.pdf#page=20>

[54] >>53 会議踊ってんなーw

- [55] [CITE@ja[Unicode Meeting Minutes UTC 78, L2 #175 - 98419.pdf]], [TIME[2005-09-07T17:29:28.000Z]], [TIME[2024-08-26T07:39:13.440Z]] <https://www.unicode.org/L2/L1998/98419.pdf#page=24>



- [48] 
[CITE@ja[8929-re-ken.PDF - 98312.pdf]], [TIME[2002-09-27T02:37:00.000Z]], [TIME[2024-08-26T03:57:41.520Z]] <https://www.unicode.org/L2/L1998/98312.pdf#page=6>
- [49] 
[CITE[Source: Interlinear annotation ad hoc group]], [TIME[2024-08-26T03:58:32.000Z]] <https://www.unicode.org/L2/L1998/98421.htm>

- [50] [CITE[L2 Document Register 1998]], [TIME[2024-08-26T03:59:13.000Z]] <https://www.unicode.org/L2/L1998/Register-1998.html>

[51] >>50 にはこの他にもいくつか関連文書が掲載されているが、本文は非公開。


- [56] 
[CITE[Body]], [TIME[2024-08-26T07:42:41.000Z]] <https://www.unicode.org/L2/L1999/99176.htm>


* メモ

[36] 
この機能は[[プレインテキスト]]での使用は強く非推奨とされています。
特定の[[アプリケーション]]で、あるいは内部処理で利用することが想定されているようです。
しかしながら、
この機能で記述できる[[ルビ]]は、現実に利用されるもののごく一部でしかなく、
貧弱です。
[[アプリケーション]]依存の情報を追加して利用することが想定されているようですが、
[[アプリケーション]]依存の仕組みによるのであれば、
[[アプリケーション]]のネイティブの仕組みの方が扱いやすいでしょうから、
敢えてこの機能を使う理由がありません。
実際に
[[HTML]]
はこの機能を使わず、
[[HTML]]
の[[要素]]の仕組みに載せた
[CODE[ruby]]
[[要素]]を使っています。
つまるところ、
この機能が便利に使える場面はありません。

[37] 
もうちょっとうまいことモデル化して定義してあれば、
[[bidi]]
制御用の文字のように[[プレインテキスト]]でもそれ以外でも[[ルビ]]状構造をうまく扱える世界が実現していたかもしれないのに、
残念なことです。




[39] 
[[21世紀]]初頭にこれが出てきたときこんなの誰が実装するんだ阿呆か?みたいな空気だったそうですが(実際誰も実装しないで死んでったわけですが)、
[[bidi]] は自動で出来ないところは[[制御文字]]みたいなやつ使っててみんな実装してるのだから、
[[ルビ]]も意外とこの方法で良かったかも知れんですよね。知らんけど。

[[bidi]] もそれは[[プレインテキスト]]用で [[HTML]] では[[要素]]使えよってことになってますけど、
[[ルビ]]も[[制御文字]]みたいなのと [[HTML要素]]の2段構えで全然良かった。

[41] 
[[日本]]で[[日本語]]使って生活してれば[[ルビ]]が[[日本語]]に不可欠な存在だってのは誰でもわかることで、
[[20世紀]]の情報機器があまり対応してなかったりした 
(そして21世紀に入って何十年か経った今もいささか厳しい)
のは[[ルビ]]がない[[日本語]]の処理にも苦労してたからで、
要らなかった、オプションだったからでは決してなくて。

[[プレインテキスト]]に[[ルビ]]要らんやろってのは[[テキスト]]は[[線形]]っていう[[欧米中心主義]]なわけでしょう。
それは [[bidi]] で破綻したんだし、[[日本語]]の[[縦書き]]でも破綻してるんだから、
何の意味もないやせ我慢でしかない。
[[コピペ]]で別アプリに[[ルビ]]付きで移したいし、
[[漢字変換]]の[[辞書]]に[[ルビ]]付きで登録したいし、
[[SNS]] に[[ルビ]]付きで投稿したいよね。

[40] 
[[ルビ]]を[[文字コード]]で表すのがうまくいってれば、次は[[縦中横]]とか[[横中縦]]とかも
[[bidi]] みたいに[[文字コード]]で記述できるようになってたかもしれんのにねえ。






[42] 
[[ARIB STD-B3のルビ]]は対象文字列の前後を[[制御文字]]で括る形式でした。
ただし[[親文字列]]と[[ルビ文字列]]は[[文字コード]]とは別のパケット構造で区切られていました。






[57] ほとんどすべての[[振り仮名]]は[[漢字]]に対して[[仮名]]2,3文字と決まっているのだし、そうでないものも一般的な日本語文で出現するパターンは限られているのだから、それを [CODE[GSUB]] と [CODE[GPOS]] でがんばれば今や [[OpenType]] フォント1つで「実装」できちゃいそうでは? もちろんこの方法には色々な限界があるのだけれども、それが問題になるところでは [[HTML]] の [CODE[ruby]] でも [CITE[Microsoft Word]] でも使えばよくて、今の普通の [[plain text]] で[[振り仮名]]を全く使えないという問題は8割くらい解決できればそれでいいっていう考え方もあるんじゃないかな。 [TIME[2025-08-27T09:24:27.863Z]]

[58] ([[縦中横]]も専用の[[符号位置]]がどこかにあれば、同じ方法で「実装」できそうだね。ただし[[縦書き]]は各種ソフトウェアの実装状況が[[横書き]]よりも宜しくないのがネックになるかも。) [TIME[2025-08-27T09:25:38.686Z]]

[59] [[漢文]]も難題とされてきたけど、 >>57 の手法でいいのであれば、 interlinear annotation と例の使い道のわからない[[漢文]]ブロックの文字を活かして plain text でもかなりのことができちゃうんじゃないかなあ。 [TIME[2025-08-27T09:27:09.713Z]]