[インデックス 13730] ファイルの概要
src/pkg/exp/locale/collate/maketables.go
: このファイルは、Unicode Collation Algorithm (UCA) のデータと CLDR (Common Locale Data Repository) のデータから、Go言語のロケール固有の照合(ソート)テーブルと見本文字(exemplar characters)を生成するためのツールです。src/pkg/exp/locale/collate/tables.go
: このファイルは、maketables.go
によって生成されるGo言語のソースコードの一部であり、照合テーブルの実装を含んでいます。今回のコミットでは、このファイルのコメントが更新されています。
コミット
commit 5a78e5ea4c3cd4d6029882a9e45c0c5506c2babb
Author: Marcel van Lohuizen <mpvl@golang.org>
Date: Sat Sep 1 14:15:00 2012 +0200
exp/locale/collate: Added functionality to parse and process LDML files
for both locale-specific exemplar characters and tailorings to
the collation table.
Some specifices:
- Moved stringSet to the beginning of the file and added some functionality
to parse command line files.
- openReader now modifies the input URL for localFiles to guarantee that
any http source listed in the generated file is indeed this source.
- Note that the implementation of the Tailoring API used by maketables.go
is not yet checked in. So for now adding tailorings are simply no-ops.
- The generated file of exemplar characters will be used somewhere else.
Here is a snippet of how the body of the generated file looks like:
type exemplarType int
const (
exCharacters exemplarType = iota
exContractions
exPunctuation
exAuxiliary
exCurrency
exIndex
exN
)
var exemplarCharacters = map[string][exN]string{
"af": [exN]string{
0: "a á â b c d e é è ê ë f g h i î ï j k l m n o ô ö p q r s t u û v w x y z",
3: "á à â ä ã æ ç é è ê ë í ì î ï ó ò ô ö ú ù û ü ý",
4: "a b c d e f g h i j k l m n o p q r s t u v w x y z",
},
...
}
R=r
CC=golang-dev
https://golang.org/cl/6501070
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/5a78e5ea4c3cd4d6029882a9e45c0c5506c2babb
元コミット内容
このコミットは、exp/locale/collate
パッケージに、LDML (Locale Data Markup Language) ファイルを解析および処理する機能を追加します。これにより、ロケール固有の見本文字(exemplar characters)と、照合テーブルへのテーラリング(カスタマイズ)の両方をサポートします。
主な変更点は以下の通りです。
stringSet
ユーティリティがファイルの先頭に移動され、コマンドラインファイルの解析機能が追加されました。openReader
関数が、ローカルファイルの場合にHTTPソースのURLを修正するようになりました。これにより、生成されるファイルにリストされるHTTPソースが、実際にそのソースであることを保証します。maketables.go
で使用されるテーラリングAPIの実装はまだチェックインされていません。そのため、現時点ではテーラリングの追加は単なるno-op(何もしない操作)です。- 生成される見本文字のファイルは、他の場所で使用される予定です。コミットメッセージには、生成されるファイルの本体の抜粋が示されています。
変更の背景
このコミットの背景には、Go言語の国際化(i18n)および地域化(l10n)サポートの強化があります。特に、文字列のソート順序は言語や地域によって大きく異なるため、これを正確に処理するためには、Unicode Collation Algorithm (UCA) と、各ロケールに特化したカスタマイズ(テーラリング)データが必要です。
これまでのmaketables.go
は、主にDUCET (Default Unicode Collation Element Table) から基本的な照合データを生成していましたが、より詳細なロケール固有のルール(見本文字や特定の言語のソート順の調整)を取り込むためには、CLDR (Common Locale Data Repository) のLDMLファイルを直接解析する機能が必要でした。
この変更により、Go言語のexp/locale/collate
パッケージが、より包括的で正確なロケール固有の照合機能を提供するための基盤が構築されます。特に、CLDRデータを取り込むことで、世界中の多様な言語のソート要件に対応できるようになります。
前提知識の解説
このコミットを理解するためには、以下の概念について基本的な知識が必要です。
-
Unicode Collation Algorithm (UCA):
- Unicode Consortiumによって定義された、多言語テキストを適切にソートするためのアルゴリズムです。言語や地域によって文字のソート順が異なるため、UCAはこれらの違いを考慮した標準的なソート方法を提供します。
- UCAは、各文字に「照合要素(collation element)」と呼ばれる重みを割り当てることで機能します。この重みは、プライマリ、セカンダリ、ターシャリなどのレベルに分かれており、それぞれ異なるソートの粒度(例:文字の基本形、アクセント、大文字・小文字)を表現します。
- DUCET (Default Unicode Collation Element Table): UCAのデフォルトの照合要素テーブルです。
allkeys.txt
というファイル名で提供されることが多く、すべてのUnicode文字に対する基本的な照合重みが定義されています。
-
CLDR (Common Locale Data Repository):
- Unicode Consortiumが提供する、ロケール固有のデータ(日付、時刻、通貨、数値の書式、言語名、国名、ソート順など)の標準リポジトリです。
- CLDRデータは、XML形式のLDML (Locale Data Markup Language) ファイルで構成されており、通常はZIPアーカイブ(例:
core.zip
)として配布されます。 - CLDRには、各言語・地域に特化した照合ルール(テーラリング)や、その言語で使用される代表的な文字セット(見本文字)などの情報が含まれています。
-
LDML (Locale Data Markup Language):
- CLDRデータの基盤となるXMLベースのマークアップ言語です。ロケール固有の情報を構造化して表現するために使用されます。
- 照合ルールはLDMLの
<collation>
要素内に定義され、見本文字は<exemplarCharacters>
要素内に定義されます。
-
Go言語の
exp/locale/collate
パッケージ:- Go言語の実験的なパッケージで、Unicodeの照合アルゴリズムをGoプログラムで利用するための機能を提供します。このパッケージは、文字列のソートや比較において、ロケール固有のルールを適用することを可能にします。
maketables.go
は、このパッケージが使用するデータテーブルを生成するためのツールです。
-
テーラリング (Tailoring):
- UCAのデフォルトルールを特定の言語や地域の慣習に合わせてカスタマイズすることです。例えば、ドイツ語では「ä」が「a」と「e」の間にソートされるなど、言語固有の例外ルールを定義します。LDMLファイルにはこれらのテーラリング情報が含まれています。
-
見本文字 (Exemplar Characters):
- 特定の言語やスクリプトで使用される代表的な文字のセットです。例えば、英語の見本文字はアルファベットのa-zなどです。LDMLファイルには、基本の見本文字、補助的な見本文字、句読点、通貨記号など、様々なカテゴリの見本文字が定義されています。
技術的詳細
このコミットは、maketables.go
ツールを大幅に拡張し、CLDRのLDMLファイルを直接処理できるようにすることで、Go言語の照合機能の精度と網羅性を向上させています。
-
CLDR ZIPアーカイブの処理:
archive/zip
パッケージが導入され、CLDRデータが配布されるcore.zip
のようなZIPアーカイブを直接読み込めるようになりました。openArchive
関数が追加され、指定されたURL(またはローカルファイル)からZIPファイルをダウンロードし、その内容をメモリに読み込んでzip.Reader
として提供します。
-
LDML XMLの解析:
encoding/xml
パッケージが導入され、LDMLファイルのXML構造をGoの構造体にマッピングして解析できるようになりました。LDML
,Attr
,AttrValue
,Collation
,Rules
,RuleElem
などのGo構造体が定義され、LDMLのXML要素と属性に対応しています。これにより、XMLデータをGoのオブジェクトとして簡単に操作できます。decodeXML
関数は、zip.File
からXMLを読み込み、対応するLDML
構造体にデコードします。
-
UCAデータソースの柔軟性向上:
--ducet
フラグが--root
フラグに置き換えられ、DUCETデータソースとしてallkeys.txt
だけでなく、allkeys_CLDR.txt
を含むZIPファイルも指定できるようになりました。これにより、CLDRに準拠したUCAデータソースの利用が容易になります。
-
見本文字の抽出と生成:
parseMain
関数が追加され、CLDRのmain
ディレクトリ内のXMLファイルを解析し、各ロケールの見本文字(<exemplarCharacters>
要素)を抽出します。- 抽出された見本文字は、
localeChars
というmap[string]charSets
型の変数に格納されます。 printExemplarCharacters
関数は、このlocaleChars
データを使用して、Go言語のソースコードとしてexemplarCharacters
マップを生成します。このマップは、ロケールごとに異なるカテゴリの見本文字(基本、収縮、句読点、補助、通貨、インデックス)を保持します。
-
照合テーラリングの処理:
parseCollation
関数が追加され、CLDRのcollation
ディレクトリ内のXMLファイルを解析し、各ロケールに特化した照合テーラリングルールを抽出します。- LDMLの照合ルールは複雑な構造を持つため、
RuleElem
構造体とそのrewrite
メソッドが、UnicodeエスケープシーケンスやXMLタグの正規化を行います。 insertTailoring
およびinsertCollation
関数は、抽出されたテーラリングルールをbuild.Builder
(照合テーブルを構築する内部構造)に挿入します。これにより、ロケール固有のソート順がGoの照合器に反映されます。- コミットメッセージにあるように、テーラリングAPIの実装はまだ完全ではないため、現時点では一部のテーラリングはno-opとして扱われますが、このコミットは将来的な完全なサポートのための基盤を築いています。
-
コマンドラインフラグの拡張と
stringSet
の改善:flag
パッケージの利用が大幅に拡張され、--cldr
,--short
,--draft
,--tags
,--package
,--tables
,--exclude
,--include
,--types
といった新しいフラグが追加されました。これにより、生成されるテーブルの種類や対象ロケール、出力形式を細かく制御できるようになりました。stringSet
構造体と関連メソッド(flagStringSet
,flagStringSetAllowAll
,Set
,add
,values
,contains
,compact
)が再設計され、より汎用的なコマンドライン引数のセット処理(カンマ区切りリストの解析、重複排除、ソート、許可された値の検証など)が可能になりました。これは、複数のテーブルやロケールを柔軟に指定するために不可欠な改善です。
コアとなるコードの変更箇所
主な変更はsrc/pkg/exp/locale/collate/maketables.go
ファイルに集中しています。
- インポートの追加:
import ( "archive/zip" // ZIPアーカイブの読み込み "encoding/xml" // XMLの解析 "io/ioutil" // ファイル読み込みユーティリティ "unicode/utf8" // UTF-8文字列処理 )
- 新しいコマンドラインフラグの定義:
root
,cldr
,test
,localFiles
,short
,draft
,tags
,pkg
,tables
,exclude
,include
,types
といった多数のフラグが追加されました。 stringSet
の実装の移動と拡張: ファイルの先頭に移動し、flag.Value
インターフェースを実装することで、コマンドラインフラグとして利用できるようになりました。flagStringSet
やflagStringSetAllowAll
といったヘルパー関数も追加されています。openReader
関数の変更:localFiles
フラグが設定されている場合、URLをローカルファイルパスに変換するロジックが追加されました。openArchive
関数の追加: ZIPアーカイブを開くための新しい関数です。func openArchive(url *string) *zip.Reader { f, err := openReader(url) failOnError(err) buffer, err := ioutil.ReadAll(f) f.Close() failOnError(err) archive, err := zip.NewReader(bytes.NewReader(buffer), int64(len(buffer))) failOnError(err) return archive }
parseUCA
関数の変更:--root
フラグがZIPファイルを指す場合、その中のallkeys_CLDR.txt
を読み込むように変更されました。- LDML XML構造体の定義:
LDMLファイルのXML構造に対応するGoの構造体(
LDML
,Attr
,AttrValue
,Collation
,Settings
,Rules
,RuleElem
など)が多数追加されました。 decodeXML
関数の追加: XMLファイルをGo構造体にデコードします。- 見本文字関連の関数:
charSets
,localeChars
,exemplarHeader
,printExemplarCharacters
,parseMain
,parseCharacters
といった見本文字の解析とGoコード生成のための関数が追加されました。 - 照合テーラリング関連の関数:
fileRe
,parseCollation
,lmap
,cldrIndex
,insertTailoring
,insertCollation
といった照合テーラリングの解析と適用を行う関数が追加されました。 main
関数のロジック変更: 新しいフラグに基づいて、parseUCA
,parseMain
,parseCollation
の呼び出しが条件付けされ、生成される出力もtables
フラグによって制御されるようになりました。
コアとなるコードの解説
このコミットの核心は、CLDRのLDMLファイルをGo言語の照合システムに統合するためのデータパイプラインを構築した点にあります。
-
データソースの抽象化と拡張:
- 以前はDUCETの
allkeys.txt
に限定されていたUCAデータソースが、--root
フラグによってZIPファイル内のallkeys_CLDR.txt
もサポートするようになりました。 --cldr
フラグの導入により、CLDRのcore.zip
を直接指定できるようになり、世界中のロケールデータへのアクセスが可能になりました。openArchive
関数は、HTTPまたはローカルファイルシステムからZIPファイルを透過的に読み込む役割を担い、データ取得の柔軟性を高めています。
- 以前はDUCETの
-
LDML XMLの構造化された解析:
encoding/xml
パッケージと、LDMLのXMLスキーマに厳密に対応するGo構造体(LDML
,Collation
,Rules
,RuleElem
など)の定義が、LDMLファイルの複雑な階層構造をGoプログラム内で扱いやすくしています。decodeXML
関数は、XMLデータをこれらのGo構造体にマッピングすることで、XMLのパースを簡素化し、データの整合性を保ちます。
-
見本文字の処理フロー:
parseMain
関数は、CLDRのmain
ディレクトリにあるロケールXMLファイルから<exemplarCharacters>
要素を特定し、その内容を抽出します。parseCharacters
関数は、抽出された見本文字の文字列(例:"[a b c {ch}]"
)を解析し、個々の文字や文字シーケンスのリストに変換します。この関数は、Unicodeエスケープや特殊な記号の処理も行います。- 最終的に、
printExemplarCharacters
関数が、これらの解析された見本文字データをGoのmap[string][exN]string
形式のソースコードとして出力します。これにより、Goプログラム内でロケールごとの見本文字に簡単にアクセスできるようになります。
-
照合テーラリングの処理フロー:
parseCollation
関数は、CLDRのcollation
ディレクトリにあるロケールXMLファイルから<collation>
要素を特定し、その内容を抽出します。- 抽出された照合ルール(
<rules>
要素内)は、RuleElem
構造体として表現されます。この構造体は、リセットポイント、コンテキスト、拡張、およびプライマリ/セカンダリ/ターシャリ/アイデンティティレベルでの照合要素の変更など、UCAの複雑なテーラリングルールをカプセル化します。 RuleElem.rewrite()
メソッドは、XML内のUnicodeエスケープ(例:&#xXXXX;
)や特定のタグ形式を正規化し、Goプログラムで扱いやすい文字列形式に変換します。insertTailoring
およびinsertCollation
関数は、これらの解析・正規化されたテーラリングルールをbuild.Builder
に渡し、Goの照合器が使用する内部データ構造に組み込みます。これにより、特定のロケールにおける文字のソート順序が、CLDRの定義に従ってカスタマイズされます。
-
stringSet
の汎用化:stringSet
は、コマンドライン引数として渡されるカンマ区切りの文字列リスト(例:--tables=collate,chars
)を効率的に処理するための汎用的なユーティリティとして再設計されました。- この改善により、ユーザーは生成したいテーブルの種類、含める/除外する言語、特定のデータタイプなどを柔軟に指定できるようになり、
maketables.go
の使いやすさと機能性が大幅に向上しました。
これらの変更は、Go言語がより堅牢で国際化に対応したアプリケーションを構築するための重要なステップであり、特に多言語環境での正確な文字列ソート機能の提供に貢献します。
関連リンク
- Unicode Collation Algorithm (UCA): http://www.unicode.org/reports/tr10/
- Common Locale Data Repository (CLDR): http://cldr.unicode.org/
- Locale Data Markup Language (LDML): http://www.unicode.org/reports/tr35/
- Go言語の
exp/locale
パッケージ (当時の実験的なパッケージ): https://pkg.go.dev/exp/locale (現在のGoモジュールシステムではパスが異なる場合がありますが、概念は同じです)
参考にした情報源リンク
- Unicode Collation Algorithm (UCA) - Wikipedia: https://en.wikipedia.org/wiki/Unicode_collation_algorithm
- Common Locale Data Repository (CLDR) - Wikipedia: https://en.wikipedia.org/wiki/Common_Locale_Data_Repository
- LDML - Unicode Consortium: http://www.unicode.org/reports/tr35/ (LDMLの公式仕様)
- Go
archive/zip
package documentation: https://pkg.go.dev/archive/zip - Go
encoding/xml
package documentation: https://pkg.go.dev/encoding/xml