[インデックス 10570] ファイルの概要
このコミットは、Go言語のドキュメンテーションツール(go doc
コマンドが利用するgo/doc
パッケージ)において、コメント内の見出しを検出し、生成されるHTMLドキュメントでh3
タグとしてフォーマットする機能を追加するものです。これにより、大規模なコメントセクションの構造化と可読性が向上します。
コミット
commit a6729b3085d764b845de505606008311860512b7
Author: Volker Dobler <dr.volker.dobler@gmail.com>
Date: Thu Dec 1 09:49:58 2011 -0800
go/doc: Detect headings in comments and format them as h3 in html.
To structure larger sections of comments in html output headings
are detected in comments and formated as h3 in the generated html.
A simple heuristic is used to detect headings in comments:
A heading is a non-blank, non-indented line preceded by a blank
line. It is followed by a blank and a non-blank, non-indented line.
A heading must start with an uppercase letter and end with a letter,
digit or a colon. A heading may not contain punctuation characters.
R=jan.mercl, gri, adg, rsc, r
CC=golang-dev
https://golang.org/cl/5437056
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/a6729b3085d764b845de505606008311860512b7
元コミット内容
go/doc: コメント内の見出しを検出し、HTMLでh3としてフォーマットする。
HTML出力でコメントのより大きなセクションを構造化するために、
コメント内の見出しが検出され、生成されたHTMLでh3としてフォーマットされる。
コメント内の見出しを検出するために単純なヒューリスティックが使用される:
見出しは、空白行に先行され、空白行と非空白でインデントされていない行に続く、
非空白でインデントされていない行である。
見出しは大文字で始まり、文字、数字、またはコロンで終わる必要がある。
見出しには句読点を含めることはできない。
R=jan.mercl, gri, adg, rsc, r
CC=golang-dev
https://golang.org/cl/5437056
変更の背景
Go言語のドキュメンテーションシステムは、ソースコード内のコメントから自動的にドキュメントを生成します。しかし、長いコメントブロックや複雑な説明を含む場合、単なるプレーンテキストでは構造が分かりにくく、読みにくいという課題がありました。特に、複数のセクションに分かれた説明をコメント内に記述する際、視覚的な区切りや階層を示す手段が不足していました。
このコミットは、この課題を解決するために導入されました。コメント内に特定の見出しパターンを認識し、それをHTML出力時に<h3>
タグとしてレンダリングすることで、ドキュメントの可読性と構造を大幅に向上させることを目的としています。これにより、開発者はより整理された形でドキュメントを記述できるようになり、利用者はより効率的に情報を把握できるようになります。
前提知識の解説
この変更を理解するためには、以下の知識が役立ちます。
- Go言語のドキュメンテーションシステム: Go言語には、
go doc
コマンドやgodoc
ツールを通じて、ソースコードのコメントから自動的にドキュメントを生成する仕組みがあります。これは、Goのコードベースで広く利用されており、コードとドキュメントの一貫性を保つ上で重要な役割を果たしています。go/doc
パッケージは、このドキュメント生成の中核を担うライブラリです。 - HTMLとCSS: 生成されるドキュメントがHTML形式であるため、
<h3>
タグがHTMLにおける見出し要素であり、all.css
ファイルがそのスタイルを定義するCSSファイルであるという基本的な理解が必要です。 - テキスト処理とパターン認識: コメント内の見出しを検出するために、特定のルールに基づいたテキスト処理とパターン認識が行われます。これは、正規表現に似た概念ですが、このコミットではよりシンプルなヒューリスティックが採用されています。
- Go言語のバイトスライスとUnicode: Go言語では文字列がバイトスライスとして扱われることが多く、Unicode文字の処理には
unicode
およびunicode/utf8
パッケージが使用されます。見出しの検出ロジックでは、これらのパッケージが文字のプロパティ(大文字かどうか、文字種など)を判断するために利用されています。 - Makefile:
Makefile
は、ソフトウェアのビルドプロセスを自動化するためのツールです。このコミットでは、見出し検出のテストユーティリティをビルドするためにMakefile
が更新されています。
技術的詳細
このコミットの主要な技術的変更点は、go/doc
パッケージにおけるコメントのHTML変換ロジックに、見出し検出のヒューリスティックとそれに基づくHTMLタグの挿入機能が追加されたことです。
-
見出し検出ヒューリスティック (
heading
関数):- 見出しと認識される行は、以下の条件を満たす必要があります。
- 空白ではない行であること。
- インデントされていない行であること。
- 直前に空白行があること。
- 直後に空白行があり、さらにその後に非空白でインデントされていない行が続くこと(これにより、見出しが独立したブロックとして認識される)。
- 大文字で始まること。
- 文字、数字、またはコロンで終わること。
- 句読点(
,.;:!?+*/=()[]{}_^°&§~%#@<>\"\\
)を含まないこと。ただし、所有格の's
は例外的に許可されます。
- このヒューリスティックは、正規表現ではなく、バイトスライス操作と
unicode
パッケージの関数を組み合わせて実装されています。これにより、パフォーマンスと制御の柔軟性が確保されています。
- 見出しと認識される行は、以下の条件を満たす必要があります。
-
HTML変換ロジックの変更 (
ToHTML
関数):ToHTML
関数は、コメントブロックをHTMLに変換する主要な関数です。- この関数に、見出し検出のロジックが組み込まれました。行を処理する際に、上記のヒューリスティックに基づいて見出しであると判断された場合、その行は
<p>
タグではなく<h3>
タグで囲まれて出力されます。 - 見出しが検出された場合、その見出し行とそれに続く空白行がスキップされ、次の非空白行から通常の段落処理が再開されます。
-
CSSの追加 (
doc/all.css
):- 生成された
<h3>
タグが適切に表示されるように、doc/all.css
にh3
要素のスタイルが追加されました。具体的には、font-size: 100%;
が設定されており、これはデフォルトのブラウザスタイルを上書きし、見出しが過度に大きく表示されないように調整されています。
- 生成された
-
テストの追加 (
src/pkg/go/doc/comment_test.go
):- 見出し検出ヒューリスティックの正確性を検証するために、
comment_test.go
に新しいテストケースが追加されました。これにより、様々な文字列が見出しとして正しく認識されるか、または認識されないかがテストされます。
- 見出し検出ヒューリスティックの正確性を検証するために、
-
ユーティリティツールの追加 (
src/pkg/go/doc/headscan.go
):headscan.go
は、Goのソースコードをスキャンし、コメント内で検出された見出しをログに出力するスタンドアロンのユーティリティです。これは、見出し検出ロジックが意図した通りに機能しているかを確認するためのデバッグおよび検証ツールとして機能します。Makefile
が更新され、このheadscan
ツールをビルドするためのルールが追加されました。
コアとなるコードの変更箇所
このコミットのコアとなるコードの変更箇所は、主に以下のファイルに集中しています。
src/pkg/go/doc/comment.go
: 見出し検出ロジック (heading
関数) と、コメントをHTMLに変換する主要な関数 (ToHTML
関数) が変更されています。src/pkg/go/doc/comment_test.go
:heading
関数の単体テストが追加されています。doc/all.css
:h3
タグのスタイルが追加されています。
コアとなるコードの解説
src/pkg/go/doc/comment.go
このファイルには、コメントをHTMLに変換する主要なロジックが含まれています。
-
heading(line []byte) []byte
関数: この関数は、与えられたバイトスライス(コメントの1行)が見出しのヒューリスティックを満たすかどうかを判断します。- 行の先頭と末尾の空白をトリムします。
- 行が空であれば
nil
を返します。 utf8.DecodeRune
とunicode.IsLetter
,unicode.IsUpper
を使って、行の最初の文字が大文字のアルファベットであることを確認します。utf8.DecodeLastRune
とunicode.IsLetter
,unicode.IsDigit
を使って、行の最後の文字がアルファベット、数字、またはコロンであることを確認します。- 末尾のコロンがあれば削除します。
bytes.IndexAny
を使って、特定の句読点文字(,.;:!?+*/=()[]{}_^°&§~%#@<>\"\\
)が含まれていないことを確認します。- 所有格の
's
のみを許可する特殊なロジックが含まれています。'
が見つかった場合、それが's
の形式であるかをチェックし、そうでなければnil
を返します。 - すべての条件を満たせば、トリムされた行を返します。
-
ToHTML(w io.Writer, s []byte, words map[string]string)
関数: この関数は、コメントのバイトスライスs
を読み込み、HTML形式でw
に書き込みます。 変更点として、行を処理するループ内で見出し検出ロジックが追加されました。if lastWasBlank && !lastNonblankWasHeading && i+2 < len(lines) && isBlank(lines[i+1]) && !isBlank(lines[i+2]) && indentLen(lines[i+2]) == 0 { // current line is non-blank, sourounded by blank lines // and the next non-blank line is not indented: this // might be a heading. if head := heading(line); head != nil { close() // 現在の段落を閉じる w.Write(html_h) // <h3>タグを出力 template.HTMLEscape(w, head) // 見出しテキストをエスケープして出力 w.Write(html_endh) // </h3>タグを出力 i += 2 // 見出し行とそれに続く空白行をスキップ lastNonblankWasHeading = true continue } }
このコードブロックは、現在の行が空白行に囲まれており、かつ次の非空白行がインデントされていない場合に、
heading
関数を呼び出して見出しであるかをチェックします。見出しと判断された場合、現在のHTML段落を閉じ、<h3>
タグで囲んで見出しを出力し、見出し行とそれに続く空白行をスキップして処理を続行します。
src/pkg/go/doc/comment_test.go
このファイルには、heading
関数の動作を検証するためのテストケースが定義されています。headingTests
という構造体のスライスに、入力文字列と期待される結果(見出しとして認識されるか否か)が格納されており、TestIsHeading
関数がこれらを順にテストします。
doc/all.css
このファイルには、生成されるHTMLドキュメントのスタイルが定義されています。
h3 {
font-size: 100%;
}
このCSSルールは、<h3>
要素のフォントサイズを親要素の100%に設定することで、ブラウザのデフォルトスタイル(通常はより大きなフォントサイズ)を上書きし、ドキュメント内の見出しが過度に目立ちすぎないように調整しています。
関連リンク
- Go言語の公式ドキュメント: https://go.dev/doc/
go/doc
パッケージのドキュメント: https://pkg.go.dev/go/doc
参考にした情報源リンク
- コミットメッセージ自体
- Go言語のソースコード(特に
go/doc
パッケージ) - Go言語のドキュメンテーションに関する一般的な情報