Skip to content

インラインコードの自動リンクツールを開発したい #1452

Open
@faithandbrave

Description

@faithandbrave
Member

文章中のバッククォートで囲まれたコードへのリンク貼りが、けっこう大きな作業負担になりやすいので、ここの自動リンクツールを開発したいです。

作るのは私がやるつもりではありますが、まずは要件定義と懸念事項の洗い出しをしたいです。

  • 基本的にはGLOBAL_QUALIFY_LIST.txtに登録されたものを自動リンクする
  • すでに手動リンクされているものは自動リンクの対象外にする
  • std::move()のような、1引数版が<utility>、3〜4引数版が<algorithm>で定義されるようなものは、* std::move(_1)[link /reference/utility/move.md]のように記述できるようにすることを目指す

型の推論をするとかは、少なくとも初期バージョンではむずかしい気がしています。現在は、std::vectorの変数はvv1v2みたいに、グローバル修飾である程度決め打ちして対応しています。

それとこのタスクと関連して、グローバル修飾に無制限に登録できるよう、コードブロック中に登場する識別子だけ使う、という修正をどこかでやる必要があります。いまは個数の制限自体はとくにないのですが、そのうち何らかの弊害がでそうで怖いところではあります。

そのほか、考えられそうな要件と懸念があれば教えてください。

Activity

self-assigned this
on Jun 2, 2025
faithandbrave

faithandbrave commented on Jun 2, 2025

@faithandbrave
MemberAuthor

同じクラス (同じ階層) のメンバ関数へのリンクも自動化しないといけないですね。
これはもしかしたら、ファイルの探索とかしないといけないかも?

akinomyoga

akinomyoga commented on Jun 3, 2025

@akinomyoga
Member

型の推論をするとかは、少なくとも初期バージョンではむずかしい気がしています。現在は、std::vectorの変数はvv1v2みたいに、グローバル修飾である程度決め打ちして対応しています。

同じクラス (同じ階層) のメンバ関数へのリンクも自動化しないといけないですね。

v.begin() etc. .だけでなく任意のメンバ関数に対して型推論なしで自動リンクにすると、誤爆が発生する頻度が上がると思うのですが、

  • 実際に誤爆があった時にそれらを個別に抑制する方法は提供しますか?
    • 先に手動でリンクをつけてしまえば良い? → コードブロック内にある場合はどうするか? またコードブロック外でも 1つの記事内or段落内で繰り返し登場する場合に、全てリンクするのか?
  • 新しい記事の場合は編集時に誤ったリンク付けがないか確認すれば良いですが、古い記事はどうしますか?
    • 例えば新しいリンクは opt-in にして、明示的に有効化する指定を記事内に埋め込まない限りは発動しない様にする? → これだと面倒だし将来的に完全に移行した後に指定が残り続ける。
    • 逆に opt-out にして、古い記事には無効化指定を一括で追加する。確認できた記事から順番に無効化指定を外していく。
    • 或いは誤爆があるのは仕方がないことにして放置する。

これはもしかしたら、ファイルの探索とかしないといけないかも?

crsearch で使っているデータベースを流用できないでしょうか。

yohhoy

yohhoy commented on Jun 3, 2025

@yohhoy
Member

文章中のバッククォートで囲まれたコードへのリンク貼り
基本的にはGLOBAL_QUALIFY_LIST.txtに登録されたものを自動リンク

経験則として、サンプルコード中では名前空間が原則明示(例:std::tuple)され、文章中のコードブロックでは省略表記(例:tuple)が多いようです。

現時点では GLOBAL_QUALIFY_LIST.txt に何を登録すべきか/すべきでないかも曖昧ですが、以下の懸念が生まれそうです。

  • 名前空間の明示版と省略版を二重登録してゆく?(例:std::tupletuple
  • 名前空間を除く識別子名が短い一般名詞(例:std::ranges::to, std::execution::on)の場合、名前空間なしにリスト登録すると問題が生じないか?(意図しない自動リンクが張られるリスクが高い)
  • 長い名前空間名(例:std::ranges::views, std::execution)に対して、名前空間の表記ルールを明文化する必要がある?(エイリアス定義using ex = std::exectionしてよい?)

個人的には、本件については中立の立場です。執筆者の作業負担となるのは理解しつつも、その名前が何を指すかの機械判別は困難ですし、適切なリンクを張る作業を通じ仕様理解が進むという側面もあります。

安全側に倒すと、名前空間指定ありの完全修飾名のみを登録する方針となりそうですが、本文中のコードブロックでは(名前空間省略されるため)ほとんど役に立たない気がしています。

faithandbrave

faithandbrave commented on Jun 4, 2025

@faithandbrave
MemberAuthor

グローバル修飾を使う点について、安全に関する懸念があると理解しました。
全体を再確認するのも大変でしょうから、ここでは安全側に倒した方針として、以下を提案します。

  • インラインコードのリンク用にGLOBAL_INLINE_QUALIFY_LIST.txtを用意して、GLOBAL_QUALIFY_LIST.txtと分離して管理する
    • moveとかforwardとかの幅広く使うものを定義
  • ページ内にインラインコードのリンクを定義できるようにする
    • ページ先頭の[meta cpp]とかのうしろにでもbegin[inlink begin.md]みたいに指定 (主に同じクラスのメンバ関数を指定する用)
  • 指定したコード修飾の影響範囲を調べるツールを用意する (check_qualify_use.py --inline "move" (--inlineの反対は--block))
    • site_generator / markdown_to_htmlの対象コード抽出と同じコードで検出する (リポジトリが違うのでコードのコピーにはなりますが)
    • 修飾対象となるファイル名と行番号、行の内容を出力する

古い記事・新しい記事関係なく全体に適用するつもりではありますが、誤爆の懸念への対策としては、以下のような作業フローにすれば十分かなと思います。

  • GLOBAL_INLINE_QUALIFY_LIST.txtには少しずつ登録し、
  • 影響範囲をツールでチェック

これでたとえば、v.begin()に対してvalarrayのファイルが検出されたら怪しいとわかります。


また、現時点でのGLOBAL_QUALIFY_LIST.txtの運用についてですが、

  • 名前空間のありなし
    • 両方登録する
    • 名前空間ありは、主にサンプルコード用
    • 名前空間なしは、主に宣言用
  • 名前空間の別名ルール
    • namespace fs = std::filesystem;とかもしてあるので、ライブラリごとに決めてしまってよいかと思います
faithandbrave

faithandbrave commented on Jun 4, 2025

@faithandbrave
MemberAuthor

途中でコメント投稿してしまったので編集しました

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @faithandbrave@yohhoy@akinomyoga

      Issue actions

        インラインコードの自動リンクツールを開発したい · Issue #1452 · cpprefjp/site