Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 17869] ファイルの概要

このコミットは、Go言語のドキュメンテーションツールである go/doc パッケージにおける、ドキュメントの概要(synopsis)生成ロジックの改善に関するものです。特に、日本語、中国語、韓国語の句読点(全角の句点「。」やピリオド「.」)を適切に認識し、それらの言語におけるパッケージ概要の表示を改善することを目的としています。

コミット

commit df03aeb67cab0f5ac153752607ef8f2c91983a6e
Author: Ato Araki <ato.araki@gmail.com>
Date:   Tue Nov 5 15:13:50 2013 +1100

    go/doc: add full stop of Japanese, Chinese and Korean.
    
    This fix will show a good synopsis on package listings in that languages.
    
    R=adg, r
    CC=golang-dev
    https://golang.org/cl/21130043

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/df03aeb67cab0f5ac153752607ef8f2c91983a6e

元コミット内容

日本語、中国語、韓国語の句点(ピリオド)を追加します。 この修正により、これらの言語でのパッケージリスト表示において、適切な概要が表示されるようになります。

変更の背景

Go言語のドキュメンテーションツール go/doc は、Goのソースコードからドキュメントを生成し、godoc コマンドや pkg.go.dev のようなオンラインサービスで利用されます。このツールは、パッケージの概要(synopsis)を生成する際に、コメントの最初の文を抽出するロジックを持っています。

従来のロジックでは、英語のピリオド(.)を文の区切りとして認識していました。しかし、日本語、中国語、韓国語といった東アジア言語では、文の終わりに全角の句点「。」や、場合によっては全角のピリオド「.」が使用されます。これらの句読点が適切に認識されない場合、go/doc が生成するパッケージ概要が意図せず長くなったり、不自然な位置で途切れたりする問題がありました。

このコミットは、これらの言語の句読点を明示的に認識することで、多言語対応を強化し、より正確で自然なパッケージ概要を生成することを目的としています。これにより、これらの言語で書かれたGoパッケージのドキュメントが、godocpkg.go.dev でより適切に表示されるようになります。

前提知識の解説

Go言語の go/doc パッケージ

go/doc パッケージは、Goのソースコードからドキュメンテーションを抽出・解析するための標準ライブラリです。Goのツールチェインの一部として提供され、godoc コマンドや pkg.go.dev などのドキュメンテーションサービスで利用されています。このパッケージは、Goのソースファイル内のコメントを解析し、パッケージ、関数、型、変数などのドキュメントを構造化された形式で提供します。

パッケージ概要(Synopsis)

go/doc パッケージは、各Goパッケージの「概要」(synopsis)を生成する機能を持っています。これは通常、パッケージコメントの最初の文から抽出されます。この概要は、パッケージリストや検索結果などで簡潔な説明として表示され、ユーザーがパッケージの目的を素早く理解するのに役立ちます。概要の抽出ロジックは、文の区切りを正確に識別することが重要です。

Unicodeと多言語対応

Go言語はUnicodeを完全にサポートしており、多言語対応が可能です。しかし、テキスト処理においては、各言語の特性(句読点、文字の分類、書字方向など)を考慮する必要があります。特に、日本語、中国語、韓国語(CJK言語)は、英語とは異なる句読点や文字の特性を持つため、これらの言語のテキストを正確に処理するには、Unicodeの文字プロパティや特定の文字コードを認識するロジックが必要となります。

  • 日本語の句点: 主に全角の「。」(U+3002 IDEOGRAPHIC FULL STOP)が使用されます。
  • 中国語の句点: 日本語と同様に全角の「。」(U+3002 IDEOGRAPHIC FULL STOP)が使用されます。
  • 韓国語の句点: 全角の「。」(U+3002 IDEOGRAPHIC FULL STOP)が使用されることもありますが、英語のピリオド「.」(U+002E FULL STOP)も一般的に使用されます。このコミットでは、全角のピリオド「.」(U+FF0E FULLWIDTH FULL STOP)も対象としています。

unicode パッケージ

Goの標準ライブラリ unicode パッケージは、Unicode文字のプロパティ(カテゴリ、スクリプトなど)を扱うための機能を提供します。unicode.IsUpper のような関数は、特定の文字が大文字であるかどうかを判定するために使用されます。

技術的詳細

このコミットは、src/pkg/go/doc/synopsis.go ファイル内の firstSentenceLen 関数に修正を加えています。この関数は、与えられた文字列(通常はGoのコメント)の最初の文の長さを計算し、その長さを返します。これにより、go/doc はコメントの最初の文を抽出し、パッケージの概要として使用します。

変更前は、この関数は主に英語の句読点(ピリオド .) とその前後の文字の組み合わせ(例: P. Q. のような略語ではないことを確認するロジック)に基づいて文の終わりを判断していました。

変更後、以下の2つの全角句読点が文の区切りとして追加で認識されるようになりました。

  1. p == '。' (U+3002 IDEOGRAPHIC FULL STOP): 日本語、中国語、韓国語で一般的に使用される全角の句点。
  2. p == '.' (U+FF0E FULLWIDTH FULL STOP): 全角のピリオド。特に韓国語などで使用されることがあります。

これにより、firstSentenceLen 関数は、これらの全角句読点が出現した場合にも、そこで文が終了すると判断し、より正確な概要の長さを返すようになります。

また、src/pkg/go/doc/synopsis_test.go には、この変更を検証するための新しいテストケースが追加されています。これらのテストケースは、日本語と韓国語のコメントが適切に処理され、正しい概要が抽出されることを確認しています。

  • "Package こんにちは。世界": 日本語の句点「。」を含むケース。
  • "Package 안녕.世界": 韓国語で使われる全角ピリオド「.」を含むケース。

これらのテストケースは、変更が意図通りに機能し、多言語の句読点に対応できるようになったことを保証します。

コアとなるコードの変更箇所

diff --git a/src/pkg/go/doc/synopsis.go b/src/pkg/go/doc/synopsis.go
index d1ad86c741..c90080b7cc 100644
--- a/src/pkg/go/doc/synopsis.go
+++ b/src/pkg/go/doc/synopsis.go
@@ -22,6 +22,9 @@ func firstSentenceLen(s string) int {
 		if q == ' ' && p == '.' && (!unicode.IsUpper(pp) || unicode.IsUpper(ppp)) {
 			return i
 		}
+		if p == '。' || p == '.' {
+			return i
+		}
 		ppp, pp, p = pp, p, q
 	}
 	return len(s)
diff --git a/src/pkg/go/doc/synopsis_test.go b/src/pkg/go/doc/synopsis_test.go
index fd7081a07c..59b253cb8d 100644
--- a/src/pkg/go/doc/synopsis_test.go
+++ b/src/pkg/go/doc/synopsis_test.go
@@ -28,6 +28,8 @@ var tests = []struct {
 	{"P. Q.   ", 8, "P. Q."},\
 	{"Package Καλημέρα κόσμε.", 36, "Package Καλημέρα κόσμε."},\
 	{"Package こんにちは 世界\n", 31, "Package こんにちは 世界"},\
+\t{"Package こんにちは。世界", 26, "Package こんにちは。\"},\
+\t{"Package 안녕.世界", 17, "Package 안녕."},\
 	{"Package foo does bar.", 21, "Package foo does bar."},\
 	{"Copyright 2012 Google, Inc. Package foo does bar.", 27, ""},\
 	{"All Rights reserved. Package foo does bar.", 20, ""},\

コアとなるコードの解説

src/pkg/go/doc/synopsis.go の変更

firstSentenceLen 関数は、文字列 s の最初の文の長さをルーン(Unicodeコードポイント)単位で計算します。

func firstSentenceLen(s string) int {
	// ... (既存のロジック) ...

	// 既存の英語ピリオドの処理
	if q == ' ' && p == '.' && (!unicode.IsUpper(pp) || unicode.IsUpper(ppp)) {
		return i
	}

	// 追加された日本語、中国語、韓国語の句読点の処理
	if p == '。' || p == '.' {
		return i
	}

	// ... (既存のロジック) ...
}
  • p は現在のルーン、q は次のルーン、pp は2つ前のルーン、ppp は3つ前のルーンを表します。
  • i は現在のルーンのインデックスです。
  • 追加された if p == '。' || p == '.' の行は、現在のルーン p が全角の句点「。」または全角のピリオド「.」である場合に、その位置 i を文の終わりとして返します。これにより、これらの文字が文の区切りとして認識されるようになります。

src/pkg/go/doc/synopsis_test.go の変更

tests 変数に新しいテストケースが追加されました。

var tests = []struct {
	// ... (既存のテストケース) ...

	{"Package こんにちは 世界\n", 31, "Package こんにちは 世界"},
	{"Package こんにちは。世界", 26, "Package こんにちは。"}, // 新しいテストケース (日本語)
	{"Package 안녕.世界", 17, "Package 안녕."},       // 新しいテストケース (韓国語)
	{"Package foo does bar.", 21, "Package foo does bar."},

	// ... (既存のテストケース) ...
}
  • {"Package こんにちは。世界", 26, "Package こんにちは。"}:

    • 入力文字列は「Package こんにちは。世界」です。
    • 期待される長さは 26 です。これは「Package こんにちは。」までのバイト数(またはルーン数)に対応します。
    • 期待される概要は「Package こんにちは。」です。
    • このテストケースは、日本語の句点「。」が文の区切りとして正しく認識されることを確認します。
  • {"Package 안녕.世界", 17, "Package 안녕."}:

    • 入力文字列は「Package 안녕.世界」です。
    • 期待される長さは 17 です。これは「Package 안녕.」までのバイト数(またはルーン数)に対応します。
    • 期待される概要は「Package 안녕.」です。
    • このテストケースは、韓国語で使われる全角ピリオド「.」が文の区切りとして正しく認識されることを確認します。

これらのテストケースは、firstSentenceLen 関数が多言語の句読点を正しく処理し、期待される概要を生成できることを保証します。

関連リンク

参考にした情報源リンク