Skip to content

キーワード自動リンク (GLOBAL_DEFINED_WORDS.json)#977

Merged
faithandbrave merged 3 commits into
cpprefjp:masterfrom
akinomyoga:defined_words
Jun 30, 2022
Merged

キーワード自動リンク (GLOBAL_DEFINED_WORDS.json)#977
faithandbrave merged 3 commits into
cpprefjp:masterfrom
akinomyoga:defined_words

Conversation

@akinomyoga

@akinomyoga akinomyoga commented May 29, 2022

Copy link
Copy Markdown
Member

#510 特に #510 (comment) の部分実装です。今のところ変更は 4 リポジトリに亙るのですが、最終的に採用されるか分かりませんし、また、一箇所で議論したいので取り敢えずここに PR を開きます。

関連する変更一覧

他の関連するIssue

議論の項目

以下議論の余地あり。

  • このPRでは markdown_to_html で markdown.treeprocessors.Treeprocessor markdown.postprocessors.Postprocessor を実装しているが別の方針も可能かもしれない。
    • (欠点) 現在 "Python の標準 XML ライブラリ xml.etree.ElementTree" を使っているが、xml.etree.ElementTree の仕様がダメダメ。一応解説をつけたが…。
    • (代替案) Preprocessor → 当初これで実装を試みたが「コードの中やリンク中のテキストに対しては自動リンクしない」などの処理が困難。
    • (代替案) PR提出当初 Treeprocessor を使っていたが色々問題があったので効率は悪くなるが Postprocessor を使う様に変更した (e6005183 @ akinomyoga/cpprefjp-markdown_to_html )。
      • (欠点) キーワードの一部が何処かで htmlStash.store などを通して一時的に乱数に変換されている場合 (例えば < などの実体参照など) は検出できない。
    • (代替案) imgが横幅を超える場合に横スクロールを可能にする kunai#119 (comment) で提案されたようにもう一段 Node による変換を入れてそこで実装する。
    • 追記: PR提出当初 Treeprocessor を使っていたが htmlStash の内容を処理できないため Postprocessor に変更しました
  • 自動リンク抑制
    • (案) 一つの記事の中で初出のときだけ自動リンクを貼る
    • (案) 定義されているのと同じ記事の中では自動リンクを貼らない
    • 記事が長くて離れている場合があるのでやはり同じ記事内でも全て自動リンクにするのが良いかも。
    • 自動リンクを定義箇所本体に適用する (つまり自身にリンクする) のはおかしいのでそれを抑制する仕組みが必要。現在は定義箇所は明示的に <dfn> を用いて示すようにしている。
      • 追記: これは現在正しく動作していない (htmlStash(?) により dfn が置換されているため)
      • 追記2: 修正しました。Treeprocessor から Postprocessor に変更
  • defined_words, GLOBAL_DEFINED_WORDS などの名前付けセンス
  • 後、全体的に変換結果を検証する必要があるかもしれない。現状 lang/cpp17/inline_variables.mdimplementation-compliance.md の変換結果しか確認していない。
  • 追記 GLOBAL_DEFINED_WORDS.json に一言説明も含められるようにして <a> 要素のtitle属性に指定するのもありかも (マウスホバーで簡単な説明が見られる) → be3fa110 @ markdown_to_html で対応
  • 追記 アルファベットのキーワードは単語の途中で一致しないようにする。例えば "SADLY" に対して "S[ADL]Y" とリンク付けられると困る → 498b4941 @ markdown_to_html で対応

その他 cpprefjp 全体の構造に対する理解の不足から、変な点もあると思います。

@faithandbrave

Copy link
Copy Markdown
Member

ありがとうございます!ひとまず進め方としてはこれでいいと思います!

@akinomyoga

Copy link
Copy Markdown
Member Author

ありがとうございます! 引き続き細かい調整(試験的なものも含めて)は入れています。以下、機能的な変更

他にもここの実装は変だぞという御指摘や細かい振る舞いの提案・調整などに関して、忌憚なくご意見を下されば幸いです。

@akinomyoga

Copy link
Copy Markdown
Member Author

動くものがないとレビューしにくいかもしれないので、デモとして生成結果を https://akinomyoga.github.io/cpprefjp-site/ に配置してみました。(相対リンク変換 cpprefjp/site_generator#78 によってトップレベル以外でも cpprefjp を配置して kunai/crsearch も含めて正しく動作するようになったので、そのデモも兼ねています。)

サンプル ("不適格" の自動リンクが埋め込まれている頁の例)

@onihusube

Copy link
Copy Markdown
Member

個人的な話ですけど、リンクされてるキーワードの下線が点線だと違和感があります(多分ウィキペディアのせい?)

直線あるいは無しで良いのではと思いました

@akinomyoga

akinomyoga commented May 31, 2022

Copy link
Copy Markdown
Member Author

個人的な話ですけど、リンクされてるキーワードの下線が点線だと違和感があります(多分ウィキペディアのせい?)

直線あるいは無しで良いのではと思いました

ありがとうございます! これも丁度意見を伺いたかったところです。「自動リンクを通常のリンクと同じ様に表示するかあるいは少し違った表示にするかという選択肢があるなぁ」と思って、取り敢えず異なる表示にできるようにしましたがスタイルは確定ではないです。具体的なスタイルは akinomyoga/cpprefjp-kunai@852c507...defined_words で指定しているので自由に設定可能です。

何となく自動リンク = 点線みたいなイメージを持っていたので (恐らくこれははてなブログのキーワードリンクから来ている) 取り敢えず適当に点線にしていました。うーん。本当は通常のリンクよりも目立たなくしたかったのですが、現状の下線だと逆に目立ってしまっていますね。

別に自動リンクだからといって通常の明示的なリンクよりも目立たなくする必要もないのかもしれませんが、DOM インスペクタでもう少しスタイルを弄って遊んでみてもいかなと思っています。

通常リンクと同じスタイル

image

a.cpprefjp-defined-word {}

もう少し目立たなく(黒文字・点線) (以前のはてなキーワードに近い表示)

image

a.cpprefjp-defined-word {
  text-decoration: underline dotted 1px;
  text-underline-offset: 1px;
  color: black;
}
a.cpprefjp-defined-word:hover {
  background-color: #DDD;
}

下線なし (マウスホバーしない限りリンクが其処にあることを意識させない表示)

image

a.cpprefjp-defined-word {
  text-decoration: none;
  color: black;
}
a.cpprefjp-defined-word:hover {
  background-color: #DDD;
}

直線グレー

image

a.cpprefjp-defined-word {
    text-decoration: underline;
    text-underline-offset: 1px;
    color: gray;
}
a.cpprefjp-defined-word:hover {
  background-color: #EEE;
  color: black;
}

好みをお聞かせいただければ幸いです。

@onihusube

onihusube commented May 31, 2022

Copy link
Copy Markdown
Member

リンクにカーソル載せると説明がポップアップするのに気づいてませんでした・・・
それがあることを主張する意味で他のリンクと見た目を分けるのはありだと思います。

そうなると、提示されたものの中なら「もう少し目立たなく(黒文字・点線) 」のものがいいでしょうか
開発者ツールで書き換えてみてみましたが、下線が点線だとどうにもリンク切れ(Noリンク)感がありました。これがどこから来てるのか謎だし私が慣れればいいだけなのですが・・・

ポップアップの待ち時間ですが、待ち時間ゼロくらいでもいいのかなとも思いました。それならば、ポップアップが出ることにすぐ気づけるのでスタイルの差がそこまで問題にならなくなる気がしました

@akinomyoga

akinomyoga commented May 31, 2022

Copy link
Copy Markdown
Member Author

ポップアップの待ち時間ですが、待ち時間ゼロくらいでもいいのかなとも思いました。それならば、ポップアップが出ることにすぐ気づけるのでスタイルの差がそこまで問題にならなくなる気がしました

ポップアップは単に title 属性を指定しているだけなのでブラウザが勝手に表示しているのですよね。。。待ち時間を制御する方法があるのか調べてみたところ、ブラウザはそのような設定は提供していないが、jQuery UI Tooltip がブラウザのツールチップを置き換える形で設定可能な自前ツールチップを表示してくれるそうです [1]。

で、webpack で jquery-ui を使う方法がよく分からず見様見真似で実装してみたのですが (f51d2c0c @ kunai) [2,3,4]、

ツールチップが表示されなくなりました。。。開発者ツールで見るとマウスをホバーした時に <div role="tooltip" id="ui-id-..." class="..." style="position: relative; top: ...; left: ...;"> という要素が <body> 直下に追加されているのが見えるので、一応 jQuery UI Tooltip は動いているのだと思いますが何処にも表示されない…。cpprefjp の CSS とコンフリクトして何処かに隠れているかブラウザの画面外に表示されているのかも…。

@akinomyoga

akinomyoga commented May 31, 2022

Copy link
Copy Markdown
Member Author

ポップアップの待ち時間ですが、待ち時間ゼロくらいでもいいのかなとも思いました。それならば、ポップアップが出ることにすぐ気づけるのでスタイルの差がそこまで問題にならなくなる気がしました

jQuery UI Tooltip は諦めることにして、回答 [5] にある疑似要素を使ってツールチップを表示する方式に切り替えました (ceb9288f @ kunai)。

https://akinomyoga.github.io/cpprefjp-site/ の方も更新しましたので動作をご確認いただけます。

開発者ツールで書き換えてみてみましたが、下線が点線だとどうにもリンク切れ(Noリンク)感がありました。これがどこから来てるのか謎だし私が慣れればいいだけなのですが・・・

色を変えたら Noリンク 感は弱まるかもしれないと思って多少調整しました。

image

余談ですが、私の「自動リンクを下線で表示している感」はたぶん SuikaWiki [6] からだった気がします ("下線=リンク切れ" も確かにありそうな気がすると思って探していたら見つけました)。改めてWikiソースなど見たら SuikaWiki の自動リンクっぽいのは実は全部明示的に指定したリンクだったみたいですが…。

@yumetodo

yumetodo commented May 31, 2022

Copy link
Copy Markdown
Member

自分のはてなブログどうしてたっけと思って見てきたらこんなのでした

image

@onihusube

Copy link
Copy Markdown
Member

青点線+ポップアップ待ち時間なしいい感じです!!

@akinomyoga

Copy link
Copy Markdown
Member Author

自分のはてなブログどうしてたっけと思って見てきたらこんなのでした

ああ、なるほど。これは border-bottom を使っているのですね。cpprefjp は line-height を設定しているためか border-bottom だと線の位置が離れすぎ (主観) に感じたので text-decoration に切り替えてしまいました。(他にも自動リンクを貼っている辞書サイトが昔あったような気がするけれど思い出せない…)

青点線+ポップアップ待ち時間なしいい感じです!!

ご確認ありがとうございます!

ポップアップを今は「リンクの上」に表示していますが、「リンクの下」に表示するように変更しようかどうか考えています。ちょうどブラウザの表示範囲の一番上にリンクがあると、更にその上にポップアップを表示しても表示範囲外になって見えないという問題があるためです。例えば "不適格" のリンクをクリックして跳んだ先で "適格" の上にマウスをホバーしてもポップアップがスクロール範囲の外側になって表示されません (つまり、リンクが一番下にあるケースよりも一番上にあるケースの方が多そう)。

@akinomyoga

akinomyoga commented Jun 2, 2022

Copy link
Copy Markdown
Member Author

ツールチップをリンクの下に表示するように変更し以下に反映しました。

関連 commit を squash しました。

もしよろしければ折を見てそれぞれに PR を出そうと思います。

@akinomyoga

akinomyoga commented Jun 5, 2022

Copy link
Copy Markdown
Member Author
  • 他のリポジトリに関連する変更を PR として提出しました。
  • プレビュー https://akinomyoga.github.io/cpprefjp-site/ にも反映させました (今回は deploy は成功した模様)。
  • editors_doc に GLOBAL_DEFINED_WORDS について加筆しました (ec03526)。

全ページ変換に関する設定?

早とちりです。御放念下さい

editors_doc/start_editing.mdGLOBAL_QUALIFY_LIST.txt について以下のように記述されています。

反映間隔

cpprefjp/site へ push すると、すぐに反映されます。

毎日深夜0時ころに全ページの変換を行います。ページを追加したときのサイドバーの更新や、GLOBAL_QUALIFY_LIST.txtを編集した場合の適用は、そのときの変換で全ページに変更が適用されます。

具体的に上記のことがどのように処理されているのか分かっていないですが、もしかすると GLOBAL_DEFINED_WORDS についても同様に全体の変換を誘起させた方が良いかもしれません? 或いは、build.sh を見るともしかすると現時点で毎回全ページ変換していたりするでしょうか。

追記: すみません。恐らく上記部分の意味を取り違えていました。「そのときの変換」というのは「深夜0時ころの変換」のことを指しているのですね (「ページを追加したときや GLOBAL_QUALIFY_LIST を編集した場合の変換」と勘違いしてました)。


追記: より多くの用例でデザインを再考する必要性?

ふと思ったのですがもっと多くの用例を見て設計を調整する必要があるかもしれません。現在 "適格" と "不適格" の2つの例だけを元にして自動リンクの仕様を決定していますが、この際、他の様々なパターンも今の内に考えておいた方が楽かもしれません。

必要に応じてその都度設計を調整すれば良いと考えていましたが、恐らく毎回 site, site_generator, markdown_to_html のそれぞれに PR を出さなければならず少々面倒なので、すぐ思いつくものについては今の内に対応してしまっても良いような気がしてきました。

  • "未定義の動作"、"未定義動作"、"動作は未定義"、"振る舞いは未定義" などの表記ゆれにどう対応するか。
    • 案1: "未定義の動作"、"未定義動作"、"未定義" の三種類の文字列に対して自動リンクする。json には {"未定義の動作": {"link": "...", "desc": "..."}, "未定義動作": { "redirect": "未定義の動作"}, "未定義": {"redirect": "未定義の動作"}} などとする。用語集・索引ページの生成時には redirect 項目は「未定義 → 未定義の動作の項を見よ」という形に生成。
    • 案2: 親項目の中に含める。例えば {"未定義の動作":{"link":"...","desc":"...","alias":"未定義動作;未定義"}} → ✗この方法だと別表記の読みを定義できない。
  • CPO などの略語などをどのように取り扱うか。
    • 案1: これも表記揺れと同様に redirect? {"カスタマイゼーションポイントオブジェクト": {...}, "CPO": {"redirect": "カスタマイゼーションポイントオブジェクト"}}
    • 案2: 親項目の中に略語を含める。例えば {"カスタマイゼーションポイントオブジェクト": {"link":"...","desc":"...","abbr": "CPO"}}

他に意見がなければ勝手ながらどんどん思いつきで試験実装していってしまうと思います。悪しからず御容赦下さい。いつでも機能毎に revert/drop/再実装 することに吝かではありませんので、どうぞ不要・要考察な機能がありましたら御指摘下さいませ。

余談 5年前の初期案・Weblioなど

どういう用例が考えられるかと思って他の Issue #510, #774, #773 を改めて洗っていたのですが、何やら既に一番最初のコメント #493 (comment) で色々のことがカバーされていますね… (1mmも進歩してないな→自分)。で、「自動リンクを点線で表示している辞書サイト」というのが Weblio だったということも、このコメントで判明しました。Weblio より:

image

Weblio の CSS はこうでした:

image

@yumetodo

yumetodo commented Jun 6, 2022

Copy link
Copy Markdown
Member

一つの記事の中で初出のときだけ自動リンクを貼る

ルビをどれだけふるか問題に近いと思うんですが、原則全部リンクでいいと思います。

@yumetodo

yumetodo commented Jun 6, 2022

Copy link
Copy Markdown
Member

必要に応じてその都度設計を調整すれば良いと考えていましたが、恐らく毎回 site, site_generator, markdown_to_html のそれぞれに PR を出さなければならず少々面倒なので、すぐ思いつくものについては今の内に対応してしまっても良いような気がしてきました。

2つともredirectにするのが自然な気がします

@akinomyoga

Copy link
Copy Markdown
Member Author

ルビをどれだけふるか問題に近いと思うんですが、原則全部リンクでいいと思います。

なるほど、確かにルビを振るときにも似たような問題が生じるのですね。今まで意識したことありませんでした。今まで一続きのテキスト (つまり、単一の TEXT_NODE) の中に複数回同じ用語が現れたときにだけ、2回目以降の自動リンクを抑制していたのですが、その処置を revert しました: 9312b823 @ markdown_to_html.

2つともredirectにするのが自然な気がします

ご意見ありがとうございます。動作確認用に用語を追加 (fea6326) するとともにこれも実装 (7ee10927 @ markdown_to_html) しました。最新の変換結果はhttps://akinomyoga.github.io/cpprefjp-site/ にデプロイしてあります。その他に細かい調整があります:

  • ツールチップのスタイルの調整 (f1b02a43, c1cddf88 @ kunai)
    • ツールチップが最前面に来るように z-index 設定しました。
    • "カスタマイゼーションポイントオブジェクト" などのように説明が長くなるもののために、ツールチップの幅の制限 (max-width) を追加しています。
    • 文字の大きさを、ドキュメントトップレベルでの文字の大きさを基準に決めるように。
    • その他の文字の修飾などを自動リンク対象から継承しないように。
  • カスタマイゼーションポイントオブジェクトなどのように解説ページが未だない用語については、リンクは貼らずに、一言説明だけツールチップで表示。マウスホバーした時に背景色が変わる効果はリンクがある時にだけ適用。
  • 現在 GLOBAL_DEFINED_WORDS.json の設定方法に誤りがあった場合、強制的にエラーを発生させて変換を停止しています。
    • (→ エラーを無視して変換を続ける動作にした方が良いかもしれない? もしそうするならば GLOBAL_DEFINED_WORDS.json が json 形式としても誤っていた場合にもエラーを握りつぶすように書き換える必要あり。うーん、やはり現状の様にエラーがあったら変換を停止させる方が良さそう)

@onihusube #774 で挙げられていたカスタマイゼーションポイントオブジェクト (CPO) を設計検証用の例として使わせていただいたのですが、説明が適当 (fea6326) です…より良い説明があればご教示いただければ幸いです。


現在、微妙かもしれないと思っている振る舞いに、自動リンク対象がページの右端に表示されている時に、CSS擬似要素で実現しているツールチップがブラウザの画面外にはみ出て読めないという問題があります (下の画像を参照)。どうにか CSS でこういった場合の位置を調整する方法があれば良いのですが…。良い方法がなければ、取り敢えずこの問題は無視することにします (将来的に自前で JavaScript でツールチップを実装するという可能性もあるかもですがそれは out of scope of this PR)。

Hidden Friends - cpprefjp C++日本語リファレンス より
image

@yumetodo

Copy link
Copy Markdown
Member

現在、微妙かもしれないと思っている振る舞いに、自動リンク対象がページの右端に表示されている時に、CSS擬似要素で実現しているツールチップがブラウザの画面外にはみ出て読めないという問題があります (下の画像を参照)。どうにか CSS でこういった場合の位置を調整する方法があれば良いのですが…。

なかなか辛そうですね・・・。 document.body.scrollWidthとかが変化しないし、疑似要素の大きさは取れないし・・・・。
image

疑似要素をすっぱり投げ捨てて普通のDOM要素を予めHTML上で記述しておいて対象となるキーワードをhoverしたときのeventを拾って表示させるほうが筋が良さそうです。

@akinomyoga

Copy link
Copy Markdown
Member Author

疑似要素をすっぱり投げ捨てて普通のDOM要素を予めHTML上で記述しておいて対象となるキーワードをhoverしたときのeventを拾って表示させるほうが筋が良さそうです。

そうですね。。それをしてくれるのが jQuery UI Tooltip のはずなのですが何故かうまく動かず (※厳密に言うと、これは "予めDOM要素を記述する" 方式ではなく動的にDOM要素を追加する方式)。なので自前で書く必要がありますね。

@akinomyoga

Copy link
Copy Markdown
Member Author

疑似要素をすっぱり投げ捨てて普通のDOM要素を予めHTML上で記述しておいて対象となるキーワードをhoverしたときのeventを拾って表示させるほうが筋が良さそうです。

out of scope と書いていましたが結局実装しました (2bbb114a @ akinomyoga/kunai)。これで範囲外にツールチップが表示されることもありません。生成結果を akinomyoga.github.io/cpprefjp-site に反映させました。例えば 標準規格と処理系Hidden Friends を御覧ください。

image

Fade in/out (CSS Transition) はつけてみましたが、もしかしたら少し煩わしいかもしれません。

@faithandbrave faithandbrave merged commit 4844636 into cpprefjp:master Jun 30, 2022
@akinomyoga akinomyoga deleted the defined_words branch June 30, 2022 05:16
@faithandbrave

Copy link
Copy Markdown
Member

一通りマージして、ちゃんと動いてるっぽいですね!ありがとうございます!
https://cpprefjp.github.io/lang/cpp11/char16_32.html

@akinomyoga

Copy link
Copy Markdown
Member Author

元PRで mention すれば自動的に「~からメンションされました」というのが表示されるとは言え、確かにこの PR の cover に PR へのリンクを列挙しておくべきでしたね。

@akinomyoga

Copy link
Copy Markdown
Member Author

何れにしても皆様方、長らくこのPRにお付き合いいただきましてありがとうございました。お陰様で当初のPRよりも大幅に改善されたものにすることができました。またもうひとつの巨大PR cpprefjp/site_generator#81 が待ち受けていますが、もしよろしければそちらの方もよろしくお願いいたします。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants