POD2::JA::Unicode::LineBreak(3pm) | User Contributed Perl Documentation | POD2::JA::Unicode::LineBreak(3pm) |
Unicode::LineBreak~[ja] - UAX #14 Unicode 行分割アルゴリズム
use Unicode::LineBreak; $lb = Unicode::LineBreak->new(); $broken = $lb->break($string);
Unicode::LineBreak は、Unicode 標準の附属書14 [UAX #14] で述べる Unicode 行分割アルゴリズムを実行する。 分割位置を決定する際に、附属書11 [UAX #11] で定義される East_Asian_Width 参考特性も考慮する。
便宜的に以下の用語を使う。
強制分割〔mandatory break〕は、基本規則で定められており、周囲の文字に関係なく義務的に実行される行分割動作。 任意分割は、基本規則で認められており、ユーザが実行すると決めた場合に行われる行分割動作。 [UAX #14] で定義される任意分割には直接分割〔direct break〕と間接分割〔indirect break〕とがある。
音素文字的な文字〔alphabetic characters〕は、通常、他の文字が分割の機会を与えないかぎり、文字同士の間で行分割できない文字。 表語文字的な文字〔ideographic characters〕は、通常、その前後で行分割できる文字。 [UAX #14] では音素文字的な文字のほとんどを AL に、表語文字的な文字のほとんどを ID に分類している (これらの用語は文字学の観点からすれば不正確である)。 若干の用字系では、個々の文字からは分割位置が明確にならないため、辞書による発見的方法を用いる。
文字列の桁数は、文字列に含まれる文字の数と等しいとはかぎらない。 個々の文字は広い〔wide〕か、狭い〔narrow〕か、前進を伴わない〔nonspacing〕かのいずれかであり、各々 2 桁、1 桁、0 桁を占める。 若干の文字は、使われる文脈によって広くも狭くもなり得る。 カスタマイズによって、文字はより多様な幅を持ちうる。
注: このメソッドは、行分割のおおまかな動作を表す値を返すにすぎない。 実際のテキストを行折りするには、break() 等のメソッドを使ってほしい。
"new"、"config" の両メソッドには以下の対を指定できる。 桁数の算出 ([E])、書記素クラスタ分節 ([G]) (Unicode::GCString~[ja] も参照)、行分割動作 ([L]) に影響するものがある。
注: このオプションはリリース 1.011 で導入された。
"Urgent" オプションおよび "ユーザ定義の行分割動作" も参照。
"EASTASIAN" 文脈では、East_Asian_Width 特性が曖昧 (A) であれば「広い」文字とみなし、行分割特性が AI であれば表語文字的 (ID) とみなす。
"NONEASTASIAN" 文脈では、East_Asian_Width 特性が曖昧 (A) であれば「狭い」文字とみなし、行分割特性が AI であれば音素文字的 (AL) とみなす。
初期値では、East_Asian_width 特性の手直しはしない。 "文字の特性の手直し" も参照。
初期値では、行分割特性の手直しはしない。 "文字の特性の手直し" も参照。
"ColMax"、"ColMin"、"EAWidth" オプションも参照。
注: この「前進を伴わない」値は当モジュールによる拡張であり、 [UAX #11] の一部ではない。
注: 特性値 CP はUnicode 5.2.0版で導入された。 特性値 HL と CJ はUnicode 6.1.0版で導入された。 特性値 RI は Unicode 6.2.0版で導入された。
注: 現リリースでは現代タイ語のタイ文字にのみ対応している。
"Format" オプションにサブルーチンへの参照を指定する場合、そのサブルーチンは 3 つの引数を取らなければならない。
$修正後 = &サブルーチン(SELF, EVENT, STR);
SELF は Unicode::LineBreak オブジェクト、EVENT はサブルーチンが呼ばれた文脈を表す文字列、STR は分割位置の前または後の Unicode 文字列の断片。
EVENT |駆動の契機 |STR ----------------------------------------------------------------- "sot" |テキスト先頭 |最初の行の断片 "sop" |強制分割の後 |次の行の断片 "sol" |任意分割の後 |続きの行の断片 "" |分割の直前 |行全体 (終端の空白文字を除く) "eol" |任意分割 |分割位置の前の空白文字 "eop" |強制分割 |改行とその前の空白文字 "eot" |テキスト終端 |テキスト終端の空白文字 (と改行) -----------------------------------------------------------------
サブルーチンは、テキストの断片を修正して返さなければならない。なにも修正しなかったことを示すには、"undef" を返せばよい。 なお、"sot"、"sop"、"sol" の文脈での修正はその後の分割位置の決定に影響するが、ほかの文脈での修正は影響しない。
注意: 文字列の引数は実際には書記素クラスタ列である。 Unicode::GCString~[ja] 参照。
たとえば次のコードは、行末の空白を取り除いて行折りをする。
sub fmt { if ($_[1] =~ /^eo/) { return "\n"; } return undef; } my $lb = Unicode::LineBreak->new(Format => \&fmt); $output = $lb->break($text);
任意分割によって生じる行が CharMax、ColMax、ColMin のいずれかの制限を超えると見込まれるときは、引き続く文字列に対して緊急分割を実行できる。 "Urgent" オプションにサブルーチンへの参照を指定する場合、そのサブルーチンは 2 つの引数を取らなければならない。
@分割後 = &サブルーチン(SELF, STR);
SELF は Unicode::LineBreak オブジェクト、STR は分割すべき Unicode 文字列。
サブルーチンは、文字列 STR を分割した結果の配列を返さなければならない。
注意: 文字列の引数は実際には書記素クラスタ列である。 Unicode::GCString~[ja] 参照。
たとえば次のコードは、若干の化学物質 (チチンのような) の名称にハイフンを挿入し、行折りできるようにする。
sub hyphenize { return map {$_ =~ s/yl$/yl-/; $_} split /(\w+?yl(?=\w))/, $_[1]; } my $lb = Unicode::LineBreak->new(Urgent => \&hyphenize); $output = $lb->break("Methionylthreonylthreonylglutaminylarginyl...");
"Prep" オプションに [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(Prep => [$url, \&breakurl]); $output = $lb->break($string);
状態の保存
Unicode::LineBreak オブジェクトはハッシュ参照としてふるまう。 任意の要素を、オブジェクトの存在期間中保存できる。
たとえば次のコードは、段落を空行で分ける。
sub paraformat { my $self = shift; my $action = shift; my $str = shift; if ($action eq 'sot' or $action eq 'sop') { $self->{'line'} = ''; } elsif ($action eq '') { $self->{'line'} = $str; } elsif ($action eq 'eol') { return "\n"; } elsif ($action eq 'eop') { if (length $self->{'line'}) { return "\n\n"; } else { return "\n"; } } elsif ($action eq 'eot') { return "\n"; } return undef; } my $lb = Unicode::LineBreak->new(Format => \¶format); $output = $lb->break($string);
"Sizing" オプションにサブルーチンへの参照を指定する場合、そのサブルーチンは 5 つの引数を取らなければならない。
$桁数 = &サブルーチン(SELF, LEN, PRE, SPC, STR);
SELF は Unicode::LineBreak オブジェクト、LEN は先行する文字列の長さ、PRE は先行する Unicode 文字列、SPC は追加される空白文字、STR は処理する Unicode 文字列。
サブルーチンは "PRE.SPC.STR" の桁数を算出して返さなければならない。 桁数は整数でなくてもよい。桁数の単位は随意に選べるが、"ColMin" オプションおよび "ColMax" オプションのそれと一致させなければならない。
注意: 文字列の引数は実際には書記素クラスタ列である。 Unicode::GCString~[ja] 参照。
たとえば次のコードは、行に 8 桁ごとのタブストップがあるものとして処理する。
sub tabbedsizing { my ($self, $cols, $pre, $spc, $str) = @_; my $spcstr = $spc.$str; while ($spcstr->lbc == LB_SP) { my $c = $spcstr->item(0); if ($c eq "\t") { $cols += 8 - $cols % 8; } else { $cols += $c->columns; } $spcstr = $spcstr->substr(1); } $cols += $spcstr->columns; return $cols; }; my $lb = Unicode::LineBreak->new(LBClass => [ord("\t") => LB_SP], Sizing => \&tabbedsizing); $output = $lb->break($string);
"LBClass" オプションおよび "EAWidth" オプションで個々の文字の行分割特性 (分類) や East_Asian_Width 特性を手直しできる。その際に便利な定数をいくつか定義してある。
行分割特性
仮名などの行頭禁則文字
初期値では、若干の仮名や仮名に準ずるものを行頭禁則文字 (NS または CJ) と扱う。 以下の対を LBClass オプションに指定すれば、これらの文字を通常の表語文字的な文字 (ID) と扱える。
注。仮名ではないものもある。
長音記号。 U+30FC 長音記号、U+FF70 長音記号 (代替名称)。
注。これらの文字は行頭禁則文字と扱われることも、通常の表語文字的な文字と扱われることもある。[JIS X 4051] 6.1.1、[JLREQ] 3.1.7 や [UAX14] を参照。
注。U+3095 ゕ, U+3096 ゖ, U+30F5 ヵ, U+30F6 ヶ は仮名ではないとされる。
注。この文字は仮名ではないが、通常 "ます" や "マス" の略記として用いられる。
注。この文字は [UAX #14] では行頭禁則文字 (NS) に分類されるが、[JIS X 4051] や [JLREQ] では文字クラス (13) や cl-19 (ID に相当) に分類される。
曖昧な引用符
初期値では、若干の記号を曖昧な引用符 (QU) と扱う。
デーン語、フィン語、ノルウェー語、スウェーデン語では、9 の形状の引用符や 右向きのギュメ (’ ” » ›) を開き記号にも閉じ記号にも用いる。
和字間隔
East_Asian_Width 特性
ラテン、ギリシア、キリルの各用字系では、特定の文字が曖昧 (A) の East_Asian_Width 特性を持っている。このため、こういった文字は "EASTASIAN" 文脈で広い文字と扱われる。 "EAWidth => [ AMBIGUOUS_"*"() => EA_N ]" と指定することで、そのような文字を常に狭い文字と扱う。
いっぽう、東アジアの符号化文字集合に対する多くの実装でたびたび広い文字に描画されてきたにもかかわらず、Unicode 標準では全角 (F) の互換文字を持つがゆえに狭い (Na) 文字とされている文字が若干ある。EAWidth オプションに以下のように指定することで、これらの文字を "EASTASIAN" 文脈で広い文字と扱える。
"new" メソッドおよび "config" メソッドのオプション引数の組み込み初期値は、 設定ファイルで上書きできる。 Unicode/LineBreak/Defaults.pm。 詳細は Unicode/LineBreak/Defaults.pm.sample を読んでほしい。
バグやバグのような動作は、開発者に教えてください。
CPAN Request Tracker: <http://rt.cpan.org/Public/Dist/Display.html?Name=Unicode-LineBreak>.
$VERSION 変数を参照してほしい。
このモジュールで用いている文字の特性値は、Unicode 標準 8.0.0版による。
このモジュールでは、実装水準 UAX14-C2 を実装しているつもり。
範囲 | UAX #14 | UAX #11 | 説明 ------------------------------------------------------------- U+20A0..U+20CF | PR [*1] | N [*2] | 通貨記号 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 | 古漢字 U+F0000..U+FFFFD | AL (XX) | F か N (A) | 私用領域 U+100000..U+10FFFD | AL (XX) | F か N (A) | 私用領域 その他未割り当て | AL (XX) | N | 未割り当て、 | | | 予約、非文字 ------------------------------------------------------------- [*1] U+20A7 ペセタ記号 (PO)、U+20B6 トゥール・リーヴル記号 (PO)、U+20BB スカンディナヴィア・マルク記号 (PO)、U+20BE ラリ記号 (PO) を除く。 [*2] U+20A9 ウォン記号 (H)、U+20AC ユーロ記号 (F か N (A)) を 除く。
Text::LineFold~[ja], Text::Wrap, Unicode::GCString~[ja].
Copyright (C) 2009-2018 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.
2020-11-09 | perl v5.32.0 |