use utf8;

=encoding utf-8

=head1 NAME

Unicode::LineBreak::JA_JP - UAX #14 Unicode 行分割アルゴリズム

=head1 SYNOPSIS

    use Unicode::LineBreak;
    $lb = Unicode::LineBreak->new();
    $broken = $lb->break($string);

=head1 DESCRIPTION

Unicode::LineBreak は、Unicode 標準の附属書14 [UAX #14] で述べる Unicode 行分割アルゴリズムを実行する。
分割位置を決定する際に、附属書11 [UAX #11] で定義される East_Asian_Width 参考特性も考慮する。

=head2 用語

便宜的に以下の用語を使う。

B<強制分割>〔mandatory break〕は、基本規則で定められており、周囲の文字に関係なく義務的に実行される行分割動作。
B<任意分割>は、基本規則で認められており、ユーザが実行すると決めた場合に行われる行分割動作。
[UAX #14] で定義される任意分割にはB<直接分割>〔direct break〕とB<間接分割>〔indirect break〕とがある。

B<音素文字的な文字>〔alphabetic characters〕は、通常、他の文字が分割の機会を与えないかぎり、文字同士の間で行分割できない文字。
B<表語文字的な文字>〔ideographic characters〕は、通常、その前後で行分割できる文字。
[UAX #14] では音素文字的な文字のほとんどを AL に、表語文字的な文字のほとんどを ID に分類している
(これらの用語は文字学の観点からすれば不正確である)。
若干の用字系では、個々の文字からは分割位置が明確にならないため、辞書による発見的方法を用いる。

文字列のB<桁数>は、文字列に含まれる文字の数と等しいとはかぎらない。
個々の文字はB<広い>〔wide〕か、B<狭い>〔narrow〕か、前進を伴わない〔nonspacing〕かのいずれかであり、各々 2 桁、1 桁、0 桁を占める。
若干の文字は、使われる文脈によって広くも狭くもなり得る。
カスタマイズによって、文字はより多様な幅を持ちうる。

=head1 PUBLIC INTERFACE

=head2 行の分割

=over 4

=item new ([KEY => VALUE, ...])

I<コンストラクタ>。
KEY => VALUE の対については L</オプション> を参照。

=item $self->break (STRING)

I<インスタンスメソッド>。
Unicode 文字列 STRING を分割し、それを返す。

=item $self->break_partial (STRING)

I<インスタンスメソッド>。
break() と同じだが、文字列を少しずつ追加して入力する場合。
入力が完了したことを示すには、STRING 引数に C<undef> を与える。

=item $self->config (KEY)

=item $self->config (KEY => VALUE, ...)

I<インスタンスメソッド>。
設定を取得または変更する。
KEY => VALUE の対については L</オプション> を参照。

=item $self->copy

I<コピーコンストラクタ>。
オブジェクトインスタンスの複製をつくる。

=begin comment

=item $self->reset

I<Undocumented>.

=end comment

=back

=head2 情報の取得

=over 4

=item context ([Charset => CHARSET], [Language => LANGUAGE])

I<関数>。
キャラクタセット CHARSET および言語コード LANGUAGE から、それを使う言語/地域の文脈を得る。

=item $self->eawidth (STRING)

I<インスタンスメソッド>。
Unicode 文字列 STRING の最初の文字の East_Asian_Width 特性を得る。
返値については L</定数> を参照。
EA_Z は前進を伴わない (幅のない) ことを意味する。
特性値 A (曖昧) は適切な値に解決する。

=item $self->lbclass (STRING)

I<インスタンスメソッド>。
Unicode 文字列 STRING の最初の文字の行分割特性 (分類) を得る。
返値については L</定数> を参照。
AI、SA、SG、XX の各分類は他の適切な分類に解決する。
ただし、東南アジアの表記体系のための単語分節が有効になっているときは、対応している用字系 (現在はタイ文字のみ) の文字の特性を SA のまま解決しない。

=item $self->lbrule (BEFORE, AFTER)

I<インスタンスメソッド>。
分類 BEFORE と分類 AFTER の間での行分割動作を得る。
返値については L</定数> を参照。

B<注>:
このメソッドは、BK、CM、CR、LF、NL、SP の各分類に関わる規則については適切な値を返せないかもしれない。
また、AI、SA、SG、XX の各分類に関わる規則については意味のある値を返さない。

=item $self->strsize (LEN, PRE, SPC, STR)

=item $self->strsize (LEN, PRE, SPC, STR, MAX)

I<インスタンスメソッド>。
MAX を指定しないと、[UAX #11] で定義された文字幅に基づいて、Unicode 文字列 PRE.SPC.STR のI<桁数>を算出する。
正の値 MAX を指定すると、PRE.SPC.SUBSTR の桁数が MAX を超えないような STR の最長の部分文字列 SUBSTR のI<文字数>を返す。

=back

=head2 オプション

L</new>、L</config> の両メソッドには以下の対を指定できる。

=over 4

=item CharactersMax => NUMBER

行に含みうる最大の文字数。行末の空白文字と改行の文字列を除く。
文字数は一般に行の長さを表さないことに注意。
初期値は C<998>。
C<0> にはできない。

=item ColumnsMin => NUMBER

任意分割された行の、改行の文字列と行末の空白文字を含めない最小桁数。
初期値は C<0>。

=item ColumnsMax => NUMBER

行の、改行の文字列と行末の空白文字を含めない最大桁数。つまり、行の最大長。
初期値は C<76>。

=back

L</UrgentBreaking> オプションおよび L</ユーザ定義の行分割動作> も参照。

=over 4

=item Context => CONTEXT

言語/地域の文脈を指定する。
現在使える文脈は C<"EASTASIAN"> か C<"NONEASTASIAN">。
初期の文脈は C<"NONEASTASIAN">。

=item Format => METHOD

分割した行を整形する方法を指定する。

=over 4

=item C<"DEFAULT">

初期の方法。
任意分割の位置に改行を挿入するだけ。

=item C<"NEWLINE">

L</Newline> オプションで指定したもので改行を置き換える。
改行の前とテキスト終端の空白文字を除去する。
テキスト終端に改行がなければ追加する。

=item C<"TRIM">

任意分割の位置に改行を挿入する。
改行の前の空白文字を除去する。

=item サブルーチンへの参照

L</行の整形> を参照。

=back

=item HangulAsAL => C<"YES"> | C<"NO">

ハングル音節とハングル連結チャモ〔conjoining jamo〕を音素文字的な文字 (AL) と扱う。
初期値は C<"NO">。

=item LegacyCM => C<"YES"> | C<"NO">

前に空白文字がついた結合文字を単独の結合文字 (ID) と扱う。
Unicode 5.0 版からは、空白文字のこのような使いかたは推奨されない。
初期値は C<"YES">。

=item Newline => STRING

改行の文字列とする Unicode 文字列。
初期値は C<"\n">。

=item SizingMethod => METHOD

文字列の長さを算出する方法を指定する。
以下のオプションが使える。

=over 4

=item C<"DEFAULT">

初期の方法。
strsize() を使う。

=item サブルーチンへの参照

L</文字列長の算出> を参照。

=back

L</TailorEA> オプションも参照。

=item TailorEA => C<[> ORD C<=E<gt>> CLASS, ... C<]>

個々の文字の East_Asian_Width 特性を手直しする。
ORD は文字の UCS インデクス値か、それらの配列への参照。
CLASS は East_Asian_Width 特性のいずれか (L</定数> を参照)。

初期値では、East_Asian_width 特性の手直しはしない。
L</文字の特性の手直し> も参照。

=item TailorLB => C<[> ORD C<=E<gt>> CLASS, ... C<]>

個々の文字の行分割特性 (分類) を手直しする。
ORD は文字の UCS インデクス値か、それらの配列への参照。
CLASS は行分割特性のいずれか (L</定数> を参照)。

初期値では、行分割特性の手直しはしない。
L</文字の特性の手直し> も参照。

=item UrgentBreaking => METHOD

長すぎる行の扱いかたを指定する。
以下のオプションが使える。

=over 4

=item C<"CROAK">

エラーメッセージを出力して死ぬ。

=item C<"FORCE">

長すぎる文字列を無理やり分割する。

=item C<"NONBREAK">

初期の方法。
長すぎる文字列も分割しない。

=item サブルーチンへの参照

L</ユーザ定義の行分割動作> を参照。

=back

=item UserBreaking => C<[>METHOD, ...C<]>

ユーザ定義の行分割動作を指定する。
METHOD には以下のものを指定できる。

=over 4

=item C<"NONBREAKURI">

URI を分割しない。

=item C<"BREAKURI">

URI を、印刷物に適した規則で分割する。
詳しくは [CMOS] の 6.17 節と 7.11 節を参照。

=item C<[> REGEX, SUBREF C<]>

正規表現 REGEX にマッチする文字列を、SUBREF で参照されるサブルーチンで分割する。
詳細は L</ユーザ定義の行分割動作> を参照。

=back

=back

=head2 定数

=over 4

=item C<EA_Na>, C<EA_N>, C<EA_A>, C<EA_W>, C<EA_H>, C<EA_F>, C<EA_Z>

[UAX #11] で定義される 6 つの East_Asian_Width 特性を表す値と、前進を伴わないことを表す EA_Z。

=item C<LB_BK>, C<LB_CR>, C<LB_LF>, C<LB_NL>, C<LB_SP>, C<LB_OP>, C<LB_CL>, C<LB_CP>, C<LB_QU>, C<LB_GL>, C<LB_NS>, C<LB_EX>, C<LB_SY>, C<LB_IS>, C<LB_PR>, C<LB_PO>, C<LB_NU>, C<LB_AL>, C<LB_ID>, C<LB_IN>, C<LB_HY>, C<LB_BA>, C<LB_BB>, C<LB_B2>, C<LB_CB>, C<LB_ZW>, C<LB_CM>, C<LB_WJ>, C<LB_H2>, C<LB_H3>, C<LB_JL>, C<LB_JV>, C<LB_JT>, C<LB_SG>, C<LB_AI>, C<LB_SA>, C<LB_XX>

[UAX #14] で定義される 37 の行分割特性 (分類) を表す値。

B<注>:
特性値 CP はUnicode 5.2.0版で導入された。

=item C<MANDATORY>, C<DIRECT>, C<INDIRECT>, C<PROHIBITED>

行分割動作を表す 4 つの値。

強制分割。直接分割も間接分割も認める。間接分割を認めるが直接分割は禁ずる。分割を禁ずる。

=item C<Unicode::LineBreak::SouthEastAsian::supported>

東南アジアの表記体系のための単語分節機能が有効かどうかを示すフラグ。
この機能が有効になっていれば、空でない文字列。
そうでなければ C<undef>。

B<注>: 現リリースでは現代タイ語のタイ文字にのみ対応している。

=item C<UNICODE_VERSION>

このモジュールが参照する Unicode 標準の版を示す文字列。

=back

=head1 CUSTOMIZATION

=head2 行の整形

L</Format> オプションにサブルーチンへの参照を指定する場合、そのサブルーチンは 3 つの引数を取らなければならない。

    修正後 = &サブルーチン(SELF, EVENT, STR);

SELF は Unicode::LineBreak オブジェクト、EVENT はサブルーチンが呼ばれた文脈を表す文字列、STR は分割位置の前または後の Unicode 文字列の断片。

    EVENT |駆動の契機           |STR
    -----------------------------------------------------------------
    "sot" |テキスト先頭         |最初の行の断片
    "sop" |強制分割の後         |次の行の断片
    "sol" |任意分割の後         |続きの行の断片
    ""    |分割の直前           |行全体 (終端の空白文字を除く)
    "eol" |任意分割             |分割位置の前の空白文字
    "eop" |強制分割             |改行とその前の空白文字
    "eot" |テキスト終端         |テキスト終端の空白文字 (と改行)
    -----------------------------------------------------------------

サブルーチンは、テキストの断片を修正して返さなければならない。なにも修正しなかったことを示すには、C<undef> を返せばよい。
なお、C<"sot">、C<"sop">、C<"sol"> の文脈での修正はその後の分割位置の決定に影響するが、ほかの文脈での修正は影響しない。

B<注意>:
リリース 1.003 以降は、文字列の引数は Unicode::GCString オブジェクトである。
L<Unicode::GCString::JA_JP/CAVEAT> 参照。

たとえば次のコードは、行末の空白を取り除いて行折りをする。

    sub fmt {
        if ($_[1] =~ /^eo/) {
            return "\n";
      	}
        return undef;
    }
    my $lb = Unicode::LineBreak->new(Format => \&fmt);
    $output = $lb->break($text);

=head2 ユーザ定義の行分割動作

任意分割によって生じる行が CharactersMax、ColumnsMin、ColumnsMax のいずれかの制限を超えると見込まれるときは、引き続く文字列に対してB<緊急分割>を実行できる。
L</UrgentBreaking> オプションにサブルーチンへの参照を指定する場合、そのサブルーチンは 5 つの引数を取らなければならない。

    分割後 = &サブルーチン(SELF, LEN, PRE, SPC, STR);

SELF は Unicode::LineBreak オブジェクト、LEN は先立つ行の長さ、PRE はその行の Unicode 文字列、SPC は追加される空白文字、STR は分割すべき Unicode 文字列。

サブルーチンは、文字列 STR を分割した結果の配列を返さなければならない。

B<注意>:
リリース 1.003 以降は、文字列の引数は Unicode::GCString オブジェクトである。
L<Unicode::GCString::JA_JP/CAVEAT> 参照。

たとえば次のコードは、若干の化学物質 (チチンのような) の名称にハイフンを挿入し、行折りできるようにする。

    sub hyphenize {
	return map {$_ =~ s/yl$/yl-/; $_} split /(\w+?yl(?=\w))/, $_[4];
    }
    my $lb = Unicode::LineBreak->new(UrgentBreaking => \&hyphenize);
    $output = $lb->break("Methionylthreonylthreonylglutaminylarginyl...");

L</UserBreaking> オプションの要素に [REGEX, SUBREF] の配列参照を指定する場合、サブルーチンは 2 つの引数を取らなければならない。

    分割後 = &サブルーチン(SELF, STR);

SELF は Unicode::LineBreak オブジェクト、STR は REGEX にマッチする分割すべき Unicode 文字列。

サブルーチンは、文字列 STR を分割した結果の配列を返さなければならない。

たとえば次のコードは、HTTP URL を [CMOS] の規則を用いて分割する。

    my $url = qr{http://[\x21-\x7E]+}i;
    sub breakurl {
        my $self = shift;
        my $str = shift;
        return split m{(?<=[/]) (?=[^/]) |
                       (?<=[^-.]) (?=[-~.,_?\#%=&]) |
        	       (?<=[=&]) (?=.)}x, $str;
    }
    my $lb = Unicode::LineBreak->new(UserBreaking => [$url, \&breakurl]);
    $output = $lb->break($string);

=head2 文字列長の算出

L</SizingMethod> オプションにサブルーチンへの参照を指定する場合、そのサブルーチンは 5 つか 6 つの引数を取らなければならない。

    桁数 = &サブルーチン(SELF, LEN, PRE, SPC, STR);

    文字数 = &サブルーチン(SELF, LEN, PRE, SPC, STR, MAX);

SELF は Unicode::LineBreak オブジェクト、LEN は先行する文字列の長さ、PRE は先行する Unicode 文字列、SPC は追加される空白文字、STR は処理する Unicode 文字列。

ひとつめの形式では、サブルーチンは C<PRE.SPC.STR> の桁数を算出して返さなければならない。
桁数は整数でなくてもよい。桁数の単位は随意に選べるが、L</ColumnsMin> オプションおよび L</ColumnsMax> オプションのそれと一致させなければならない。

ふたつめの形式では、サブルーチンは STR の部分文字列の I<Unicode 文字の数>の最大値を返さなければならない。部分文字列 SUBSTR は PRE.SPC.SUBSTR の桁数が MAX を超えないように取る。この形式は L</UrgentBreaking> オプションを C<"FORCE"> に設定した場合に使う。後の形式を実装したくなければ、C<undef> を返さなければならない。

B<注意>:
リリース 1.003 以降は、文字列の引数は Unicode::GCString オブジェクトである。
L<Unicode::GCString::JA_JP/CAVEAT> 参照。

たとえば次のコードは、行に 8 桁ごとのタブストップがあるものとして処理する。

    sub tabbedsizing {
        my ($self, $cols, $pre, $spc, $str, $max) = @_;
        return undef if $max;

	my $spcstr = $spc.$str;
        while ($spcstr =~ s/^( *)(\t+)//) {
            $cols += length($1);
            $cols += length($2) * 8 - $cols % 8;
        }
        $cols += $self->strsize(0, '', '', $spcstr);
        return $cols;
    };
    my $lb = Unicode::LineBreak->new(TailorLB => [ord("\t") => LB_SP],
                                     SizingMethod => \&tabbedsizing);
    $output = $lb->break($string);

=head2 文字の特性の手直し

L</TailorLB> オプションおよび L</TailorEA> オプションで個々の文字の行分割特性 (分類) や East_Asian_Width 特性を手直しできる。その際に便利な定数をいくつか定義してある。

=head3 行分割特性

初期値では、若干の仮名や仮名に準ずるものを行頭禁則文字 (NS) と扱う。
以下の対を L<TailorLB> オプションに指定すれば、これらの文字を通常の表語文字的な文字 (ID) と扱える。

=over 4

=item C<KANA_NONSTARTERS() =E<gt> LB_ID>

下記の文字すべて。

=item C<IDEOGRAPHIC_ITERATION MARKS() =E<gt> LB_ID>

表語文字的な繰り返し記号。
U+3005 繰返し記号、U+303B ゆすり点、U+309D 平仮名繰返し記号、U+309E 平仮名繰返し記号 (濁点)、U+30FD 片仮名繰返し記号、U+30FE 片仮名繰返し記号 (濁点)。

注。仮名ではないものもある。

=item C<KANA_SMALL_LETTERS() =E<gt> LB_ID>

=item C<KANA_PROLONGED_SOUND_MARKS() =E<gt> LB_ID>

小書き仮名。
小書き平仮名 U+3041 ぁ, U+3043 ぃ, U+3045 ぅ, U+3047 ぇ, U+3049 ぉ, U+3063 っ, U+3083 ゃ, U+3085 ゅ, U+3087 ょ, U+308E ゎ, U+3095 E<0x3095>, U+3096 E<0x3096>。
小書き片仮名 U+30A1 ァ, U+30A3 ィ, U+30A5 ゥ, U+30A7 ェ, U+30A9 ォ, U+30C3 ッ, U+30E3 ャ, U+30E5 ュ, U+30E7 ョ, U+30EE ヮ, U+30F5 ヵ, U+30F6 ヶ。
片仮名表音拡張 U+31F0 E<0x31F0> - U+31FF E<0x31FF>。
小書き片仮名 (代替名称) U+FF67 E<0xFF67> - U+FF6F E<0xFF6F>。

長音記号。
U+30FC 長音記号、U+FF70 長音記号 (代替名称)。

注。これらの文字は行頭禁則文字と扱われることも、通常の表語文字的な文字と扱われることもある。[JIS X 4051] 6.1.1 参照。

注。U+3095 E<0x3095>, U+3096 E<0x3096>, U+30F5 ヵ, U+30F6 ヶ は仮名ではないとされる。

=item C<MASU_MARK() =E<gt> LB_ID>

U+303C ます記号。

注。この文字は仮名ではないが、通常 C<"ます"> や C<"マス"> の略記として用いられる。

注。この文字は [UAX #14] では行頭禁則文字 (NS) に分類されるが、[JIS X 4051] では文字クラス (13) (ID に相当) に分類される。

=back

=head3 East_Asian_Width 特性

ラテン、ギリシア、キリルの各用字系では、特定の文字が曖昧 (A) の East_Asian_Width 特性を持っている。このため、こういった文字は C<"EASTASIAN"> 文脈で広い文字と扱われる。
C<TailorEA =E<gt> [ AMBIGUOUS_>*C<() =E<gt> EA_N ]> と指定することで、そのような文字を常に狭い文字と扱う。

=over 4

=item C<AMBIGUOUS_ALPHABETICS() =E<gt> EA_N>

下記の文字すべてを East_Asian_Width 特性 N (中立) の文字と扱う。

=item C<AMBIGUOUS_CYRILLIC() =E<gt> EA_N>

=item C<AMBIGUOUS_GREEK() =E<gt> EA_N>

=item C<AMBIGUOUS_LATIN() =E<gt> EA_N>

曖昧 (A) の幅を持つキリル、ギリシア、ラテン用字系の文字を中立 (N) の文字と扱う。

=back

いっぽう、東アジアの符号化文字集合に対する多くの実装でたびたび広い文字に描画されてきたにもかかわらず、Unicode 標準では全角 (F) の互換文字を持つがゆえに狭い (Na) 文字とされている文字が若干ある。L<TailorEA> オプションに以下のように指定することで、これらの文字を C<"EASTASIAN"> 文脈で広い文字と扱える。

=over 4

=item C<QUESTIONABLE_NARROW_SIGNS() =E<gt> EA_A>

U+00A2 セント記号、U+00A3 ポンド記号、U+00A5 円記号 (または元記号)、U+00A6 破断線、U+00AC 否定、U+00AF マクロン。

=back

=head2 設定ファイル

L</new> メソッドおよび L</config> メソッドのオプション引数の組み込み初期値は、 設定ファイルで上書きできる。
F<Unicode/LineBreak/Defaults.pm>。
詳細は F<Unicode/LineBreak/Defaults.pm.sample> を読んでほしい。

=head1 BUGS

バグやバグのような動作は、開発者に教えてください。

CPAN Request Tracker:
L<http://rt.cpan.org/Public/Dist/Display.html?Name=Unicode-LineBreak>.

=head1 VERSION

$VERSION 変数を参照してほしい。

このモジュールの開発版が
L<http://hatuka.nezumi.nu/repos/Unicode-LineBreak/>
にある。

=head2 標準への適合性

このモジュールで用いている文字の特性値は、Unicode 標準 6.0.0 版による。

このモジュールでは、実装水準 UAX14-C2 を実装しているつもり。

=over 4

=item *

一部の表語文字的な文字を NS として扱うか ID として扱うかを選べる。

=item *

ハングル音節およびハングル連結チャモを ID として扱うか AL として扱うかを選べる。

=item *

AI に分類される文字を AL と ID のどちらに解決するかを選べる。

=item *

CB に分類される文字は解決しない。

=item *

東南アジアの表記体系の単語分節に対応しない場合は、
SA に分類される文字は AL に解決する。
ただし、Grapheme_Cluster_Break 特性の値が Extend か SpacingMark である文字は CM に解決する。

=item *

SG や XX に分類される文字は AL に解決する。

=item *

以下の UCS の範囲にあるコードポイントは、文字が割り当てられていなくても決まった特性値を持つ。

    範囲               | lbclass()  | eawidth()  | 説明
    -------------------------------------------------------------
    U+3400..U+4DBF     | ID         | W          | CJK漢字
    U+4E00..U+9FFF     | ID         | W          | CJK漢字
    U+D800..U+DFFF     | AL (SG)    | N          | サロゲート
    U+E000..U+F8FF     | AL (XX)    | F か N (A) | 私用領域
    U+F900..U+FAFF     | ID         | W          | CJK漢字
    U+20000..U+2FFFD   | ID         | W          | CJK漢字
    U+30000..U+3FFFD   | ID         | W          | CJK漢字
    U+F0000..U+FFFFD   | AL (XX)    | F か N (A) | 私用領域
    U+100000..U+10FFFD | AL (XX)    | F か N (A) | 私用領域
    その他未割り当て   | AL (XX)    | N          | 未割り当て
    -------------------------------------------------------------

=item *

一般カテゴリ特性が Mn、Me、Cc、Cf、Zl、Zp のいずれかである文字は、[UAX #11] で割り当てられた East_Asian_Width 特性の値に関わらず、当モジュールで定義した特性値 Z (前進を伴わない) を持つ。

=back

=head1 REFERENCES

=over 4

=item [CMOS]

I<The Chicago Manual of Style>, 15th edition.
Chicago University Press, 2003.

=item [JIS X 4051]

JIS X 4051:2004
I<日本語文書の組版方法>.
日本規格協会, 2004.

=item [UAX #11]

A. Freytag (2008-2009).
I<Unicode Standard Annex #11: East Asian Width>, Revision 17-19.
L<http://unicode.org/reports/tr11/>.

=item [UAX #14]

A. Freytag and A. Heninger (2008-2010).
I<Unicode Standard Annex #14: Unicode Line Breaking Algorithm>, Revision 22-25.
L<http://unicode.org/reports/tr14/>.

=back

=head1 SEE ALSO

L<Text::LineFold::JA_JP>, L<Text::Wrap>.

=head1 AUTHOR

Copyright (C) 2009, 2010 Hatuka*nezumi - IKEDA Soji <hatuka(at)nezumi.nu>.

This program is free software; you can redistribute it and/or modify it 
under the same terms as Perl itself.
