バグ…という認識でいいのでしょうか

「->」を入力すると、オートコレクト機能により「→」に自動変換されます。

C++言語のアロー演算子を入力しようとしているときに勝手に変換されても困りますので、ツール→オートコレクトオプション→オプションのチェックリストをいろいろいじってみたところ、どうも「置換リスト」のチェックを外すと自動変換されなくなるようです。

しかし、置換リストを上から下まで見ても「->」→「→」という設定は見当たりません。

何らかのバグと言う認識でよろしいのでしょうか。

(その他にも、置換リストを使用するよう設定すると.*(C)が©になるなずなのにならなかったり、abotuはaboutになるのにabboutはaboutにならなかったりするようです)

1 Like

回答にならないメモ:

  • 日本語とアルファベットが混ざっているとき、アルファベットの部分は英語としてスペルチェックされるかもしれない
  • Writerの[ツール] - [オートコレクト] - [オートコレクトオプション]で開かれる[オートコレクト]ダイアログには、一番上に[置換と例外扱いの言語]というコンボボックスがあり、ここで言語を選択できるようになっているため、これを「英語(米国)」にする。ロードに多少時間がかかるかもしれないが、「–>」が「→」になるような項目が存在している。(置換前ハイフン2本。このサイトのDiscourseで使われている文法なのか、手元のブラウザでは、その2本を別に選択することが出来ないっぽい)
  • ところで、おそらくそのリストはDocumentList.xmlから取得されている。このリストを眺めると、一部には正規表現で表記されているものが存在しており、おそらくこれらはリストに表示されていない。著作権マークもカッコの前後に.*が存在しているから、リストに表示されていないのかもしれない。
  • 正規表現を除外した一覧を取得しているのだろうか?それともこれらのリストボックスで弾きながら追加しているのだろうか…
  • UIのコードはautocdlg.cxxだと思うのだが…

手元でも現象再現してて。
「->」のハイフンは1本でも置換されるもよう。
…謎。

ハイフンは1本でも置換される

DocumentList.xmlでは、2本の方は正規表現ではないため(理由は推測)、英語(米国)のリストボックスに含まれるが、1本の方は正規表現になっている。

あ、なるほど…。著作権マークなどと似た扱いになっていて隠れてる、ということか…。

余談だが、ソース上はDocumentList.xmlになっているけど、ビルドの過程でzipファイルを生成し、datファイルにリネームされている。

https://opengrok.libreoffice.org/xref/core/extras/CustomTarget_autocorr.mk?r=d18f03a5#266

ここで取り出しているようだね。
svxacorr.cxx (revision e3206e67) - OpenGrok cross reference for /core/editeng/source/misc/svxacorr.cxx

https://opengrok.libreoffice.org/xref/core/editeng/source/misc/svxacorr.cxx?r=e3206e67#2325

7.3.0/7.2.5のCalcで試してみましたが、「->」のみを入力すると「=-」に変換されて警告のダイアログが出て、いいえを選べば「->」として入力できました。
Screenshot from 2022-02-22 21-21-36

Writerでは「–>」が「→」になりました。これはオートコレクトダイアログのオプションタブで「置き換えリストを使う」のTのチェックを外せば、「–>」を入力できました。

Version: 7.2.5.2 / LibreOffice Community
Build ID: 499f9727c189e6ef3471021d6132d4c694f357e5
CPU threads: 8; OS: Linux 5.16; UI render: default; VCL: gtk3
Locale: ja-JP (ja_JP.UTF-8); UI: ja-JP
Calc: threaded

再現しました。「a->」は「a→」になりました。

確かに、メニューの「ツール」→「オートコレクトプション」で「オプション」タブの置換リストをオフにすれば、変換されなくなりますね。

バグとまで言えるかはわかりませんが、期待する動作と違うように思います。

みなさん、返答をありがとうございます。

上記の通り、「.(C)」→©になりませんでしたが、
「(C)」だと©になりました。
(置換リストにあるのは「.
(C)」で、仮に正規表現だとしても「任意の0文字以上+(C)」なので「.*(C)」もヒットするはずですが…)

次に「ツール」→「オートコレクトオプション」→「置換と例外扱いの言語」で言語を「英語(米国)」にセットしてみました。
確かに「–>」→「→」、「.->.」→「→」があり、「abbout」→「about」はありませんでした。

https://opengrok.libreoffice.org/xref/core/extras/source/autocorr/lang/en-US/DocumentList.xml?r=7c1bad41
を見ると全く同様のリストのようです。

まあ、わざわざ「.*(C)」と入れる人の中で「©」や「.*©」を望む人はいないと思いますのでそれは無視するとすると、
(ちなみに「…(C)」だとちゃんと?「…©」になりました)
「オートコレクトのリストとして常に英語用のものを参照しており言語設定が機能していない」
という現象が疑われますね。

1 Like

調査完了しました。

  • 前述の通り、元となったXMLでは、置換前の項目として-->.*->.*が存在している。
  • オートコレクトのリストボックスの項目は、ソートされる
  • ソートの結果、ハイフンは、最初の方に配置される。
  • ソートの結果、ピリオドは、コロンよりも後ろ且つU+0061(a)よりも前にある
  • 結果として、-->の変換に利用される項目と-> の変換に用いられる項目は、似たような項目に見えても隣接しないが、両方ともリスト内に存在している。全数調査を面倒くさがった結果の見落としということになる。
  • なお、本オートコレクトにおいて、.*正規表現ではない。(editeng/source/misc/svxacorr.cxx#2938)
  • 当方の検証では段落区切りの入力直後にオートコレクトが発動した。
1 Like

返答ありがとうございます。

ここで「(C)」から「©」に変換されない、と記述していましたが、誤って小文字「c」を入力していたからでした。謝罪し撤回します。
ただし、「.*(C)」は相変わらず変換されません(こんな珍妙な表現を正規表現そのものor正規表現の説明以外で使用する人はいないと思うので変換されなくて正解だと思いますが…)

当方の検証では段落区切りの入力直後にオートコレクトが発動した。

Wordだと「段落区切り」と「行区切り」は区別されますが、LibreOffice calcにはそんな区別はないようです(というか、もし存在したらcalcにおける入力完了等の処理と重複します)。「セル内改行」のことだとして検証しましたが入力完了の時と全く同様です(入力完了の時に変換されないのにセル内改行の時に変換されるというのは常識的に考え難いです…)。

まあ「正規表現として扱われていない」とのことでしたのでそういうコードなのでしょう(C++は詳しくない)。少なくとも私がわざわざ「.*(C)」と入力することはないので(正規表現の研究者ではないので…)、これについては気にしなくて構いません。

なるほど…。改めて「英語(米国)」の置換リスト見てみると、確かにありますね。置換リストの検索はインクリメンタルサーチで、「->」の入力では「.\*->.\*」を引っかけくれなくて気づかなかった、ということですか。


-->」と「.\*->.\*」の挙動の違いを疑問に思いましたが、「-->」の方は前後に空白でない文字があると変換されない(「.*->.*」が有効になって「-→」に変換される)ようですね。空白区切りの「単語」と認識された場合にだけ有効になる置換ということですかね。一方の「.*->.*」は前後に文字が続いていてもいなくても変換されるようです。「.*」は独自表現のワイルドカードで、正規表現ではないのですね…(謎)。
ただしセルの先頭から書き始めると変換は機能してくれないようです。最初に半角スペースとか入れると変換してくれるっぽい。(数式と認識されるせい?)


ちなみに手元では、変換は入力完了やセル内改行を待たず、空白文字の入力タイミングで行われているようです。

1 Like

WIP(あってるか不明。単なる戯言。)

オートコレクトの表は以下のような項目を列挙するリストになっている。
[誤] cat [正] kitten
例えば、scatterをskittenterと変換することをエンドユーザーは期待するだろうか?自分は否定的。
とすると、ワイルドカードがないcatというのが指定された場合、catを探した上で、その直前直後が空白等の語区切りでないかどうかを確認しなければならない。
ワイルドカードの指定は、まさに「skittenterと置き換えて良い」という意思表示をするものではないだろうか?

考えなければならないことはまだある。
.* car.*vehicleに変更する設定があったとする。
"He bought a new sportscar, but sadly it was stolen yesterday."を変換したら、どうなるべきだろう?
"He bought a new vehicle, but sadly it was stolen yesterday."か、"vehicle"か。

なお、設問文にCalcでやった、とはないため、検証はWriterでやっている。仮にWriterやCalc独自の処理があったとしても、機能の目的把握などは使い回せるだろう、と考えている。再現手順を示せれば良いと考えていたので詳細な条件については検討しなかった。

言われてみれば設問にはCalcの言及がないですね。タグが付いてるだけで。
まぁ、動作に大きな違いがないことを期待しつつ…。


.*」の扱いについてはhimajin100000さんの理解のとおりなのでしょうね。「scatter」は変換して欲しくないかも知れない、と。
.*car.*」⇒「vehicle」のケースは、今の動作だと「.*」はワイルドカードは変換対象には含まれないようなので、"He bought a new sportsvehicle, but sadly it was stolen yesterday."になります。


昨夜のHackfestで確認されたんですが、Calcの場合、「a->」⇒「a→」となりますが、「あ->」は変換されません。この変換は日本語のリストで定義されていないためと思われ、したがってどうやら、「オートコレクトのリストとして常に英語用のものを参照しており言語設定が機能していない」というわけでもなさそうです。
また、「aあ->」は変換されますが、「あa->」は変換されません。Hackfestでは「先頭文字だけで判断してるのだろうか?」という話になりましたが、その後「あ ->」や「あ -->」(「あ」の後ろにスペース)は変換されることに気づきました。今のところ法則性を見いだせてません。フォントのWestern/Asianの識別とはアルゴリズムが違っているのでしょうか…。
このあたりWriterとは挙動が違っていて、Writerでは全て変換されます。半角文字は英語として扱われているのでしょう。


ちなみに、このサイトでの「-->」や「.*」などの表示は、前後を「`」で括ることで行えるようです(Markdownのコードスパン表現)。

ただし、「.*(C)」は相変わらず変換されません

どうやらバグのようです。
内部では、std::unordered_mapというものを使って以下のようなリストを管理しています。(厳密にはvallueは SvxAutocorrWord型)
[誤] cat [正] kitten
[誤] dog [正] puppy
[誤].*->.*[正]
このunordered_mapは 「誤」に同じものがあってはいけない というルールがあります。

先頭にワイルドカードがないものにしかマッチしない場合、その組み合わせを取ってくればよく大した問題は起きません。
今回のように先頭にワイルドカードがあるものにマッチするp->qという文字列が存在したとき、この管理機構への登録が行われ、以下のようになります。
[誤] cat [正] kitten
[誤] dog [正] puppy
[誤]p->q[正]p→q
[誤].*->.*[正]
次からp->qに出会ったときは「ワイルドカードなし」で扱われます。
ところが、マッチする物自体が.*->.*自体である場合は以下のようになってしまいます

[誤] cat [正] kitten
[誤] dog [正] puppy
[誤].*->.*[正].*→.*
[誤].*->.*[正]
ところが、これは、「誤」に同じものがあってはいけない というルールに抵触するため、無効なデータ(nullptr)を返すようにしているようです。

https://opengrok.libreoffice.org/xref/core/editeng/source/misc/svxacorr.cxx?r=14f6700f#3041

https://opengrok.libreoffice.org/xref/core/editeng/source/misc/svxacorr.cxx?r=14f6700f#2853
https://opengrok.libreoffice.org/xref/core/editeng/source/misc/svxacorr.cxx?r=14f6700f#3048
https://opengrok.libreoffice.org/xref/core/editeng/source/misc/svxacorr.cxx?r=14f6700f#3056

結果、置換処理が行われません。
https://opengrok.libreoffice.org/xref/core/sw/source/core/edit/acorrect.cxx?r=6b147d33#400

ううむ、C++自体に詳しくないということで、プログラミング用語を避けようとした結果、自分でもちょっと読みにくいと感じるコメントになってしまった。

返答ありがとうございます。

また、Calcでの挙動における質問であることを省略してしまい申し訳ありません。

.*(C)についてはC++のライブラリの仕様に由来するものであることを了解しました。

さて、->について、JO3EMCさんのコメント(特に「あ ->」や「あ -->」(「あ」の後ろにスペース)は変換される」)により、またこちらでもテストとして日本語のリストに「生江」→「名前」の変換を設定したところ変換されたので、
「オートコレクトのリストとして常に英語用のものを参照しており言語設定が機能していない」
ではなく、
「Calcのオートコレクト処理において単語の先頭がアルファベットだと英語と判定される」という現象だと考えました。

しかし、Writerの場合はまた話が違うようです。
JO3EMCさんが指摘された「 あa->」のケースのほか、 「あ->b」でも変換されますが、「あ->い」だと変換されないようです。

PS
->.*の記法について指摘していただきありがとうございます。
確かに、入力しようとするとき「Type here.Use Markdown, BBCode, or HTML to format. Drag or paste images.」
と出ますね。

どうも、「nEndPosの位置により、言語が日本語と判定され、日本語の置換リストを利用している」からのようです。
https://opengrok.libreoffice.org/xref/core/sw/source/core/edit/acorrect.cxx?r=6b147d33#387
https://opengrok.libreoffice.org/xref/core/sw/source/core/edit/acorrect.cxx?r=6b147d33#397

ありがとうございます。バグということで間違いなさそうです。