1cdf0e10cSrcweir# Copyright (c) 2002-2006  International Business Machines Corporation and
2cdf0e10cSrcweir# others. All Rights Reserved.
3cdf0e10cSrcweir#
4cdf0e10cSrcweir#  file:  line.txt
5cdf0e10cSrcweir#
6cdf0e10cSrcweir#         Line Breaking Rules
7cdf0e10cSrcweir#         Implement default line breaking as defined by Unicode Standard Annex #14 version 5.0.0
8cdf0e10cSrcweir#         http://www.unicode.org/reports/tr14/
9cdf0e10cSrcweir
10cdf0e10cSrcweir
11cdf0e10cSrcweir
12cdf0e10cSrcweir#
13cdf0e10cSrcweir#  Character Classes defined by TR 14.
14cdf0e10cSrcweir#
15cdf0e10cSrcweir
16cdf0e10cSrcweir!!chain;
17cdf0e10cSrcweir!!LBCMNoChain;
18cdf0e10cSrcweir
19cdf0e10cSrcweir
20cdf0e10cSrcweir!!lookAheadHardBreak;
21cdf0e10cSrcweir#
22cdf0e10cSrcweir#  !!lookAheadHardBreak    Described here because it is (as yet) undocumented elsewhere
23cdf0e10cSrcweir#                          and only used for the line break rules.
24cdf0e10cSrcweir#
25cdf0e10cSrcweir#           It is used in the implementation of the incredibly annoying rule LB 10
26cdf0e10cSrcweir#           which says to treat any combining mark that is not attached to a base
27cdf0e10cSrcweir#           character as if it were of class AL  (alphabetic).
28cdf0e10cSrcweir#
29cdf0e10cSrcweir#           The problem occurs in the reverse rules.
30cdf0e10cSrcweir#
31cdf0e10cSrcweir#           Consider a sequence like, with correct breaks as shown
32cdf0e10cSrcweir#               LF  ID  CM  AL  AL
33cdf0e10cSrcweir#                  ^       ^       ^
34cdf0e10cSrcweir#           Then consider the sequence without the initial ID (ideographic)
35cdf0e10cSrcweir#                 LF  CM  AL  AL
36cdf0e10cSrcweir#                    ^           ^
37cdf0e10cSrcweir#           Our CM, which in the first example was attached to the ideograph,
38cdf0e10cSrcweir#           is now unattached, becomes an alpha, and joins in with the other
39cdf0e10cSrcweir#           alphas.
40cdf0e10cSrcweir#
41cdf0e10cSrcweir#           When iterating forwards, these sequences do not present any problems
42cdf0e10cSrcweir#           When iterating backwards, we need to look ahead when encountering
43cdf0e10cSrcweir#           a CM to see whether it attaches to something further on or not.
44cdf0e10cSrcweir#           (Look-ahead in a reverse rule is looking towards the start)
45cdf0e10cSrcweir#
46cdf0e10cSrcweir#           If the CM is unattached, we need to force a break.
47cdf0e10cSrcweir#
48cdf0e10cSrcweir#           !!lookAheadHardBreak forces the run time state machine to
49cdf0e10cSrcweir#           stop immediately when a look ahead rule ( '/' operator) matches,
50cdf0e10cSrcweir#           and set the match position to that of the look-ahead operator,
51cdf0e10cSrcweir#           no matter what other rules may be in play at the time.
52cdf0e10cSrcweir#
53cdf0e10cSrcweir#           See rule LB 19 for an example.
54cdf0e10cSrcweir#
55cdf0e10cSrcweir
56cdf0e10cSrcweir$AI = [:LineBreak =  Ambiguous:];
57cdf0e10cSrcweir$DG = \u00B0;
58cdf0e10cSrcweir$AL = [[:LineBreak =  Alphabetic:] $DG];
59cdf0e10cSrcweir$BA = [:LineBreak =  Break_After:];
60cdf0e10cSrcweir$BB = [:LineBreak =  Break_Before:];
61cdf0e10cSrcweir$BK = [:LineBreak =  Mandatory_Break:];
62cdf0e10cSrcweir$B2 = [:LineBreak =  Break_Both:];
63cdf0e10cSrcweir$CB = [:LineBreak =  Contingent_Break:];
64cdf0e10cSrcweir$CL = [:LineBreak =  Close_Punctuation:] ;
65cdf0e10cSrcweir$CM = [:LineBreak =  Combining_Mark:];
66cdf0e10cSrcweir$CR = [:LineBreak =  Carriage_Return:];
67cdf0e10cSrcweir$EX = [:LineBreak =  Exclamation:];
68cdf0e10cSrcweir$GL = [:LineBreak =  Glue:];
69cdf0e10cSrcweir$HY = [:LineBreak =  Hyphen:];
70cdf0e10cSrcweir$H2 = [:LineBreak =  H2:];
71cdf0e10cSrcweir$H3 = [:LineBreak =  H3:];
72cdf0e10cSrcweir$ID = [[:LineBreak =  Ideographic:] - [\ufe30]];
73cdf0e10cSrcweir$IN = [:LineBreak =  Inseperable:];
74cdf0e10cSrcweir$IS = [[:LineBreak =  Infix_Numeric:] [\ufe30]];
75cdf0e10cSrcweir$JL = [:LineBreak =  JL:];
76cdf0e10cSrcweir$JV = [:LineBreak =  JV:];
77cdf0e10cSrcweir$JT = [:LineBreak =  JT:];
78cdf0e10cSrcweir$LF = [:LineBreak =  Line_Feed:];
79cdf0e10cSrcweir$NL = [:LineBreak =  Next_Line:];
80cdf0e10cSrcweir$NS = [:LineBreak =  Nonstarter:];
81cdf0e10cSrcweir$NU = [:LineBreak =  Numeric:];
82cdf0e10cSrcweir$OP = [[:LineBreak =  Open_Punctuation:] - $DG];
83cdf0e10cSrcweir$PO = [:LineBreak =  Postfix_Numeric:];
84cdf0e10cSrcweir$BS = \u005C;
85cdf0e10cSrcweir$PR = [[:LineBreak =  Prefix_Numeric:] - $BS];
86cdf0e10cSrcweir$QU = [:LineBreak =  Quotation:];
87cdf0e10cSrcweir$SA = [:LineBreak =  Complex_Context:];
88cdf0e10cSrcweir$SG = [:LineBreak =  Surrogate:];
89cdf0e10cSrcweir$SP = [:LineBreak =  Space:];
90cdf0e10cSrcweir$SY = [[:LineBreak =  Break_Symbols:] $BS];
91cdf0e10cSrcweir$WJ = [:LineBreak =  Word_Joiner:];
92cdf0e10cSrcweir$XX = [:LineBreak =  Unknown:];
93cdf0e10cSrcweir$ZW = [:LineBreak =  ZWSpace:];
94cdf0e10cSrcweir
95cdf0e10cSrcweir#   Dictionary character set, for triggering language-based break engines. Currently
96cdf0e10cSrcweir#   limited to LineBreak=Complex_Context. Note that this set only works in Unicode
97cdf0e10cSrcweir#   5.0 or later as the definition of Complex_Context was corrected to include all
98cdf0e10cSrcweir#   characters requiring dictionary break.
99cdf0e10cSrcweir
100cdf0e10cSrcweir$dictionary = [:LineBreak = Complex_Context:];
101cdf0e10cSrcweir
102cdf0e10cSrcweir#
103cdf0e10cSrcweir#  Rule LB1.  By default, treat AI  (characters with ambiguous east Asian width),
104cdf0e10cSrcweir#                               SA  (South East Asian: Thai, Lao, Khmer)
105cdf0e10cSrcweir#                               SG  (Unpaired Surrogates)
106cdf0e10cSrcweir#                               XX  (Unknown, unassigned)
107cdf0e10cSrcweir#                         as $AL  (Alphabetic)
108cdf0e10cSrcweir#
109cdf0e10cSrcweir$ALPlus = [$AL $AI $SA $SG $XX];
110cdf0e10cSrcweir
111cdf0e10cSrcweir#
112cdf0e10cSrcweir#  Combining Marks.   X $CM*  behaves as if it were X.  Rule LB6.
113cdf0e10cSrcweir#
114cdf0e10cSrcweir$ALcm = $ALPlus $CM*;
115cdf0e10cSrcweir$BAcm = $BA $CM*;
116cdf0e10cSrcweir$BBcm = $BB $CM*;
117cdf0e10cSrcweir$B2cm = $B2 $CM*;
118cdf0e10cSrcweir$CLcm = $CL $CM*;
119cdf0e10cSrcweir$EXcm = $EX $CM*;
120cdf0e10cSrcweir$GLcm = $GL $CM*;
121cdf0e10cSrcweir$HYcm = $HY $CM*;
122cdf0e10cSrcweir$H2cm = $H2 $CM*;
123cdf0e10cSrcweir$H3cm = $H3 $CM*;
124cdf0e10cSrcweir$IDcm = $ID $CM*;
125cdf0e10cSrcweir$INcm = $IN $CM*;
126cdf0e10cSrcweir$IScm = $IS $CM*;
127cdf0e10cSrcweir$JLcm = $JL $CM*;
128cdf0e10cSrcweir$JVcm = $JV $CM*;
129cdf0e10cSrcweir$JTcm = $JT $CM*;
130cdf0e10cSrcweir$NScm = $NS $CM*;
131cdf0e10cSrcweir$NUcm = $NU $CM*;
132cdf0e10cSrcweir$OPcm = $OP $CM*;
133cdf0e10cSrcweir$POcm = $PO $CM*;
134cdf0e10cSrcweir$PRcm = $PR $CM*;
135cdf0e10cSrcweir$QUcm = $QU $CM*;
136cdf0e10cSrcweir$SYcm = $SY $CM*;
137cdf0e10cSrcweir$WJcm = $WJ $CM*;
138cdf0e10cSrcweir
139cdf0e10cSrcweir## -------------------------------------------------
140cdf0e10cSrcweir
141cdf0e10cSrcweir!!forward;
142cdf0e10cSrcweir
143cdf0e10cSrcweir#
144cdf0e10cSrcweir#  Each class of character can stand by itself as an unbroken token, with trailing combining stuff
145cdf0e10cSrcweir#
146cdf0e10cSrcweir$ALPlus $CM+;
147cdf0e10cSrcweir$BA $CM+;
148cdf0e10cSrcweir$BB $CM+;
149cdf0e10cSrcweir$B2 $CM+;
150cdf0e10cSrcweir$CL $CM+;
151cdf0e10cSrcweir$EX $CM+;
152cdf0e10cSrcweir$GL $CM+;
153cdf0e10cSrcweir$HY $CM+;
154cdf0e10cSrcweir$H2 $CM+;
155cdf0e10cSrcweir$H3 $CM+;
156cdf0e10cSrcweir$ID $CM+;
157cdf0e10cSrcweir$IN $CM+;
158cdf0e10cSrcweir$IS $CM+;
159cdf0e10cSrcweir$JL $CM+;
160cdf0e10cSrcweir$JV $CM+;
161cdf0e10cSrcweir$JT $CM+;
162cdf0e10cSrcweir$NS $CM+;
163cdf0e10cSrcweir$NU $CM+;
164cdf0e10cSrcweir$OP $CM+;
165cdf0e10cSrcweir$PO $CM+;
166cdf0e10cSrcweir$PR $CM+;
167cdf0e10cSrcweir$QU $CM+;
168cdf0e10cSrcweir$SY $CM+;
169cdf0e10cSrcweir$WJ $CM+;
170cdf0e10cSrcweir
171cdf0e10cSrcweir#
172cdf0e10cSrcweir# CAN_CM  is the set of characters that may combine with CM combining chars.
173cdf0e10cSrcweir#         Note that Linebreak UAX 14's concept of a combining char and the rules
174cdf0e10cSrcweir#         for what they can combine with are _very_ different from the rest of Unicode.
175cdf0e10cSrcweir#
176cdf0e10cSrcweir#         Note that $CM itself is left out of this set.  If CM is needed as a base
177cdf0e10cSrcweir#         it must be listed separately in the rule.
178cdf0e10cSrcweir#
179cdf0e10cSrcweir$CAN_CM  = [^$SP $BK $CR $LF $NL $ZW $CM];       # Bases that can   take CMs
180cdf0e10cSrcweir$CANT_CM = [ $SP $BK $CR $LF $NL $ZW $CM];       # Bases that can't take CMs
181cdf0e10cSrcweir
182cdf0e10cSrcweir#
183cdf0e10cSrcweir# AL_FOLLOW  set of chars that can unconditionally follow an AL
184cdf0e10cSrcweir#            Needed in rules where stand-alone $CM s are treated as AL.
185cdf0e10cSrcweir#            Chaining is disabled with CM because it causes other failures,
186cdf0e10cSrcweir#            so for this one case we need to manually list out longer sequences.
187cdf0e10cSrcweir#
188cdf0e10cSrcweir$AL_FOLLOW_NOCM = [$BK $CR $LF $NL $ZW $SP];
189cdf0e10cSrcweir$AL_FOLLOW_CM   = [$CL $EX $IS $SY $WJ $GL $QU $BA $HY $NS $IN $NU $ALPlus $OP];
190cdf0e10cSrcweir$AL_FOLLOW      = [$AL_FOLLOW_NOCM $AL_FOLLOW_CM];
191cdf0e10cSrcweir
192cdf0e10cSrcweir
193cdf0e10cSrcweir#
194cdf0e10cSrcweir#  Rule LB 4, 5    Mandatory (Hard) breaks.
195cdf0e10cSrcweir#
196cdf0e10cSrcweir$LB4Breaks    = [$BK $CR $LF $NL];
197cdf0e10cSrcweir$LB4NonBreaks = [^$BK $CR $LF $NL];
198cdf0e10cSrcweir$CR $LF {100};
199cdf0e10cSrcweir
200cdf0e10cSrcweir#
201cdf0e10cSrcweir#  LB 6    Do not break before hard line breaks.
202cdf0e10cSrcweir#
203cdf0e10cSrcweir$LB4NonBreaks?  $LB4Breaks {100};    # LB 5  do not break before hard breaks.
204cdf0e10cSrcweir$CAN_CM $CM*    $LB4Breaks {100};
205cdf0e10cSrcweir$CM+            $LB4Breaks {100};
206cdf0e10cSrcweir
207cdf0e10cSrcweir# LB 7         x SP
208cdf0e10cSrcweir#              x ZW
209cdf0e10cSrcweir$LB4NonBreaks [$SP $ZW];
210cdf0e10cSrcweir$CAN_CM $CM*  [$SP $ZW];
211cdf0e10cSrcweir$CM+          [$SP $ZW];
212cdf0e10cSrcweir
213cdf0e10cSrcweir#
214cdf0e10cSrcweir# LB 8         Break after zero width space
215cdf0e10cSrcweir#
216cdf0e10cSrcweir$LB8Breaks    = [$LB4Breaks $ZW];
217cdf0e10cSrcweir$LB8NonBreaks = [[$LB4NonBreaks] - [$ZW]];
218cdf0e10cSrcweir
219cdf0e10cSrcweir
220cdf0e10cSrcweir# LB 9     Combining marks.      X   $CM needs to behave like X, where X is not $SP, $BK $CR $LF $NL
221cdf0e10cSrcweir#                                $CM not covered by the above needs to behave like $AL
222cdf0e10cSrcweir#                                See definition of $CAN_CM.
223cdf0e10cSrcweir
224cdf0e10cSrcweir$CAN_CM $CM+;                   #  Stick together any combining sequences that don't match other rules.
225cdf0e10cSrcweir$CM+;
226cdf0e10cSrcweir
227cdf0e10cSrcweir#
228cdf0e10cSrcweir# LB 11  Do not break before or after WORD JOINER & related characters.
229cdf0e10cSrcweir#
230cdf0e10cSrcweir$CAN_CM $CM*  $WJcm;
231cdf0e10cSrcweir$LB8NonBreaks $WJcm;
232cdf0e10cSrcweir$CM+          $WJcm;
233cdf0e10cSrcweir
234cdf0e10cSrcweir$WJcm [^$CAN_CM];
235cdf0e10cSrcweir$WJcm $CAN_CM $CM*;
236cdf0e10cSrcweir
237cdf0e10cSrcweir#
238cdf0e10cSrcweir# LB 12  Do not break before or after NBSP and related characters.
239cdf0e10cSrcweir#
240cdf0e10cSrcweir#         (!SP) x GL
241cdf0e10cSrcweir[$LB8NonBreaks-$SP] $CM* $GLcm;
242cdf0e10cSrcweir$CM+               $GLcm;
243cdf0e10cSrcweir
244cdf0e10cSrcweir#         GL  x
245cdf0e10cSrcweir$GLcm ($LB8Breaks | $SP);
246cdf0e10cSrcweir$GLcm [$LB8NonBreaks-$SP] $CM*;     # Don't let a combining mark go onto $CR, $BK, etc.
247cdf0e10cSrcweir                              #  TODO:  I don't think we need this rule.
248cdf0e10cSrcweir                              #         All but $CM will chain off of preceding rule.
249cdf0e10cSrcweir                              #         $GLcm will pick up the CM case by itself.
250cdf0e10cSrcweir
251cdf0e10cSrcweir
252cdf0e10cSrcweir
253cdf0e10cSrcweir
254cdf0e10cSrcweir#
255cdf0e10cSrcweir# LB 13   Don't break before ']' or '!' or ';' or '/', even after spaces.
256cdf0e10cSrcweir#
257cdf0e10cSrcweir$LB8NonBreaks $CL;
258cdf0e10cSrcweir$CAN_CM $CM*  $CL;
259cdf0e10cSrcweir$CM+          $CL;              # by rule 10, stand-alone CM behaves as AL
260cdf0e10cSrcweir
261cdf0e10cSrcweir$LB8NonBreaks $EX;
262cdf0e10cSrcweir$CAN_CM $CM*  $EX;
263cdf0e10cSrcweir$CM+          $EX;              # by rule 10, stand-alone CM behaves as AL
264cdf0e10cSrcweir
265cdf0e10cSrcweir$LB8NonBreaks $IS;
266cdf0e10cSrcweir$CAN_CM $CM*  $IS;
267cdf0e10cSrcweir$CM+          $IS;              # by rule 10, stand-alone CM behaves as AL
268cdf0e10cSrcweir
269cdf0e10cSrcweir$LB8NonBreaks $SY;
270cdf0e10cSrcweir$CAN_CM $CM*  $SY;
271cdf0e10cSrcweir$CM+          $SY;              # by rule 10, stand-alone CM behaves as AL
272cdf0e10cSrcweir
273cdf0e10cSrcweir
274cdf0e10cSrcweir#
275cdf0e10cSrcweir# LB 14  Do not break after OP, even after spaced
276cdf0e10cSrcweir#
277cdf0e10cSrcweir$OPcm $SP* $CAN_CM $CM*;
278cdf0e10cSrcweir$OPcm $SP* $CANT_CM;
279cdf0e10cSrcweir
280cdf0e10cSrcweir$OPcm $SP+ $CM+ $AL_FOLLOW?;    # by rule 10, stand-alone CM behaves as AL
281cdf0e10cSrcweir
282cdf0e10cSrcweir# LB 15
283cdf0e10cSrcweir# $QUcm $SP* $OPcm;
284cdf0e10cSrcweir
285cdf0e10cSrcweir# LB 16
286cdf0e10cSrcweir$CLcm $SP* $NScm;
287cdf0e10cSrcweir
288cdf0e10cSrcweir# LB 17
289cdf0e10cSrcweir$B2cm $SP* $B2cm;
290cdf0e10cSrcweir
291cdf0e10cSrcweir#
292cdf0e10cSrcweir# LB 18  Break after spaces.
293cdf0e10cSrcweir#
294cdf0e10cSrcweir$LB18NonBreaks = [$LB8NonBreaks - [$SP]];
295cdf0e10cSrcweir$LB18Breaks    = [$LB8Breaks $SP];
296cdf0e10cSrcweir
297cdf0e10cSrcweir
298cdf0e10cSrcweir# LB 19
299cdf0e10cSrcweir#         x QU
300cdf0e10cSrcweir$LB18NonBreaks $CM* $QUcm;
301cdf0e10cSrcweir$CM+                $QUcm;
302cdf0e10cSrcweir
303cdf0e10cSrcweir#         QU  x
304cdf0e10cSrcweir$QUcm .?;
305cdf0e10cSrcweir$QUcm $LB18NonBreaks $CM*;    # Don't let a combining mark go onto $CR, $BK, etc.
306cdf0e10cSrcweir                              #  TODO:  I don't think this rule is needed.
307cdf0e10cSrcweir
308cdf0e10cSrcweir
309cdf0e10cSrcweir# LB 20
310cdf0e10cSrcweir#        <break>  $CB
311cdf0e10cSrcweir#        $CB   <break>
312cdf0e10cSrcweir
313cdf0e10cSrcweir$LB20NonBreaks = [$LB18NonBreaks - $CB];
314cdf0e10cSrcweir
315cdf0e10cSrcweir# LB 21        x   (BA | HY | NS)
316cdf0e10cSrcweir#           BB x
317cdf0e10cSrcweir#
318cdf0e10cSrcweir$LB20NonBreaks $CM* ($BAcm | $HYcm | $NScm);
319cdf0e10cSrcweir
320cdf0e10cSrcweir$BBcm [^$CB];                                  #  $BB  x
321cdf0e10cSrcweir$BBcm $LB20NonBreaks $CM*;
322cdf0e10cSrcweir
323cdf0e10cSrcweir# LB 22
324cdf0e10cSrcweir$ALcm    $INcm;
325cdf0e10cSrcweir$CM+     $INcm;     #  by rule 10, any otherwise unattached CM behaves as AL
326cdf0e10cSrcweir$IDcm    $INcm;
327cdf0e10cSrcweir$INcm    $INcm;
328cdf0e10cSrcweir$NUcm    $INcm;
329cdf0e10cSrcweir
330cdf0e10cSrcweir
331cdf0e10cSrcweir# $LB 23
332cdf0e10cSrcweir$IDcm  $POcm;
333cdf0e10cSrcweir$ALcm  $NUcm;       # includes $LB19
334cdf0e10cSrcweir$CM+   $NUcm;       # Rule 10, any otherwise unattached CM behaves as AL
335cdf0e10cSrcweir$NUcm  $ALcm;
336cdf0e10cSrcweir
337cdf0e10cSrcweir#
338cdf0e10cSrcweir# LB 24
339cdf0e10cSrcweir#
340cdf0e10cSrcweir$PRcm $IDcm;
341cdf0e10cSrcweir$ALcm $PRcm;
342cdf0e10cSrcweir$PRcm $ALcm;
343cdf0e10cSrcweir$POcm $ALcm;
344cdf0e10cSrcweir
345cdf0e10cSrcweir#
346cdf0e10cSrcweir# LB 25   Numbers.
347cdf0e10cSrcweir#
348cdf0e10cSrcweir($PRcm | $POcm)? ($OPcm)? $NUcm ($NUcm | $SYcm | $IScm)* $CLcm? ($PRcm | $POcm)?;
349cdf0e10cSrcweir
350cdf0e10cSrcweir# LB 26  Do not break a Korean syllable
351cdf0e10cSrcweir#
352cdf0e10cSrcweir$JLcm ($JLcm | $JVcm | $H2cm | $H3cm);
353cdf0e10cSrcweir($JVcm | $H2cm) ($JVcm | $JTcm);
354cdf0e10cSrcweir($JTcm | $H3cm) $JTcm;
355cdf0e10cSrcweir
356cdf0e10cSrcweir# LB 27  Treat korean Syllable Block the same as ID  (don't break it)
357cdf0e10cSrcweir($JLcm | $JVcm | $JTcm | $H2cm | $H3cm) $INcm;
358cdf0e10cSrcweir($JLcm | $JVcm | $JTcm | $H2cm | $H3cm) $POcm;
359cdf0e10cSrcweir$PRcm ($JLcm | $JVcm | $JTcm | $H2cm | $H3cm);
360cdf0e10cSrcweir
361cdf0e10cSrcweir
362cdf0e10cSrcweir# LB 28   Do not break between alphabetics
363cdf0e10cSrcweir#
364cdf0e10cSrcweir$ALcm $ALcm;
365cdf0e10cSrcweir$CM+ $ALcm;      # The $CM+ is from rule 10, and unattached CM is treated as AL
366cdf0e10cSrcweir
367cdf0e10cSrcweir# LB 29
368cdf0e10cSrcweir$IScm ($ALcm | $NUcm);
369cdf0e10cSrcweir
370cdf0e10cSrcweir#
371cdf0e10cSrcweir# Rule 30   Do not break between letters, numbers or ordinary symbols
372cdf0e10cSrcweir#           and opening or closing punctuation
373cdf0e10cSrcweir#
374cdf0e10cSrcweir($ALcm | $NUcm) $OPcm;
375cdf0e10cSrcweir$CM+ $OPcm;
376cdf0e10cSrcweir$CLcm ($ALcm | $NUcm);
377cdf0e10cSrcweir
378cdf0e10cSrcweir
379cdf0e10cSrcweir
380cdf0e10cSrcweir#
381cdf0e10cSrcweir#  Reverse Rules.
382cdf0e10cSrcweir#
383cdf0e10cSrcweir## -------------------------------------------------
384cdf0e10cSrcweir
385cdf0e10cSrcweir!!reverse;
386cdf0e10cSrcweir
387cdf0e10cSrcweir$CM+ $ALPlus;
388cdf0e10cSrcweir$CM+ $BA;
389cdf0e10cSrcweir$CM+ $BB;
390cdf0e10cSrcweir$CM+ $B2;
391cdf0e10cSrcweir$CM+ $CL;
392cdf0e10cSrcweir$CM+ $EX;
393cdf0e10cSrcweir$CM+ $GL;
394cdf0e10cSrcweir$CM+ $HY;
395cdf0e10cSrcweir$CM+ $H2;
396cdf0e10cSrcweir$CM+ $H3;
397cdf0e10cSrcweir$CM+ $ID;
398cdf0e10cSrcweir$CM+ $IN;
399cdf0e10cSrcweir$CM+ $IS;
400cdf0e10cSrcweir$CM+ $JL;
401cdf0e10cSrcweir$CM+ $JV;
402cdf0e10cSrcweir$CM+ $JT;
403cdf0e10cSrcweir$CM+ $NS;
404cdf0e10cSrcweir$CM+ $NU;
405cdf0e10cSrcweir$CM+ $OP;
406cdf0e10cSrcweir$CM+ $PO;
407cdf0e10cSrcweir$CM+ $PR;
408cdf0e10cSrcweir$CM+ $QU;
409cdf0e10cSrcweir$CM+ $SY;
410cdf0e10cSrcweir$CM+ $WJ;
411cdf0e10cSrcweir$CM+;
412cdf0e10cSrcweir
413cdf0e10cSrcweir
414cdf0e10cSrcweir#
415cdf0e10cSrcweir#  Sequences of the form  (shown forwards)
416cdf0e10cSrcweir#      [CANT_CM]  <break>  [CM]  [whatever]
417cdf0e10cSrcweir#  The CM needs to behave as an AL
418cdf0e10cSrcweir#
419cdf0e10cSrcweir$AL_FOLLOW $CM+ / (
420cdf0e10cSrcweir          [$BK $CR $LF $NL $ZW {eof}] |
421cdf0e10cSrcweir          $SP+ $CM+ $SP |
422*30acf5e8Spfg          $SP+ $CM* ([^$OP $CM $SP] | [$AL {eof}]));   # if LB 14 will match, need to suppress this break.
423cdf0e10cSrcweir                                               #  LB14 says    OP SP* x .
424cdf0e10cSrcweir                                               #    becomes    OP SP* x AL
425cdf0e10cSrcweir                                               #    becomes    OP SP* x CM+ AL_FOLLOW
426cdf0e10cSrcweir                                               #
427cdf0e10cSrcweir                                               # Further note:  the $AL in [$AL {eof}] is only to work around
428cdf0e10cSrcweir                                               #                a rule compiler bug which complains about
429cdf0e10cSrcweir                                               #                empty sets otherwise.
430cdf0e10cSrcweir
431cdf0e10cSrcweir#
432cdf0e10cSrcweir#  Sequences of the form  (shown forwards)
433cdf0e10cSrcweir#      [CANT_CM]  <break> [CM]  <break>  [PR]
434cdf0e10cSrcweir#  The CM needs to behave as an AL
435cdf0e10cSrcweir#  This rule is concerned about getting the second of the two <breaks> in place.
436cdf0e10cSrcweir#
437cdf0e10cSrcweir
438cdf0e10cSrcweir[$PR   ] / $CM+ [$BK $CR $LF $NL $ZW $SP {eof}];
439cdf0e10cSrcweir
440cdf0e10cSrcweir
441cdf0e10cSrcweir
442cdf0e10cSrcweir# LB 4, 5, 5
443cdf0e10cSrcweir
444cdf0e10cSrcweir$LB4Breaks [$LB4NonBreaks-$CM];
445cdf0e10cSrcweir$LB4Breaks $CM+ $CAN_CM;
446cdf0e10cSrcweir$LF $CR;
447cdf0e10cSrcweir
448cdf0e10cSrcweir
449cdf0e10cSrcweir# LB 7         x SP
450cdf0e10cSrcweir#              x ZW
451cdf0e10cSrcweir[$SP $ZW] [$LB4NonBreaks-$CM];
452cdf0e10cSrcweir[$SP $ZW] $CM+ $CAN_CM;
453cdf0e10cSrcweir
454cdf0e10cSrcweir# LB 8 Break after zero width space
455cdf0e10cSrcweir
456cdf0e10cSrcweir
457cdf0e10cSrcweir# LB 9,10  Combining marks.
458cdf0e10cSrcweir#    X   $CM needs to behave like X, where X is not $SP or controls.
459cdf0e10cSrcweir#    $CM not covered by the above needs to behave like $AL
460cdf0e10cSrcweir# Stick together any combining sequences that don't match other rules.
461cdf0e10cSrcweir$CM+ $CAN_CM;
462cdf0e10cSrcweir
463cdf0e10cSrcweir
464cdf0e10cSrcweir# LB 11
465cdf0e10cSrcweir$CM* $WJ $CM* $CAN_CM;
466cdf0e10cSrcweir$CM* $WJ      [$LB8NonBreaks-$CM];
467cdf0e10cSrcweir
468cdf0e10cSrcweir     $CANT_CM $CM* $WJ;
469cdf0e10cSrcweir$CM* $CAN_CM  $CM* $WJ;
470cdf0e10cSrcweir
471cdf0e10cSrcweir# LB 12
472cdf0e10cSrcweir#         x GL
473cdf0e10cSrcweir#
474cdf0e10cSrcweir$CM* $GL $CM* [$LB8NonBreaks-$CM-$SP];
475cdf0e10cSrcweir
476cdf0e10cSrcweir#
477cdf0e10cSrcweir#     GL  x
478cdf0e10cSrcweir#
479cdf0e10cSrcweir$CANT_CM $CM* $GL;
480cdf0e10cSrcweir$CM* $CAN_CM $CM* $GL;
481cdf0e10cSrcweir
482cdf0e10cSrcweir
483cdf0e10cSrcweir# LB 13
484cdf0e10cSrcweir$CL $CM+ $CAN_CM;
485cdf0e10cSrcweir$EX $CM+ $CAN_CM;
486cdf0e10cSrcweir$IS $CM+ $CAN_CM;
487cdf0e10cSrcweir$SY $CM+ $CAN_CM;
488cdf0e10cSrcweir
489cdf0e10cSrcweir$CL [$LB8NonBreaks-$CM];
490cdf0e10cSrcweir$EX [$LB8NonBreaks-$CM];
491cdf0e10cSrcweir$IS [$LB8NonBreaks-$CM];
492cdf0e10cSrcweir$SY [$LB8NonBreaks-$CM];
493cdf0e10cSrcweir
494cdf0e10cSrcweir# Rule 13 & 14 taken together for an edge case.
495cdf0e10cSrcweir#   Match this, shown forward
496cdf0e10cSrcweir#     OP SP+  ($CM+ behaving as $AL) (CL | EX | IS | IY)
497cdf0e10cSrcweir#   This really wants to chain at the $CM+ (which is acting as an $AL)
498cdf0e10cSrcweir#   except for $CM chaining being disabled.
499cdf0e10cSrcweir[$CL $EX $IS $SY] $CM+ $SP+ $CM* $OP;
500cdf0e10cSrcweir
501cdf0e10cSrcweir# LB 14    OP SP* x
502cdf0e10cSrcweir#
503cdf0e10cSrcweir$CM* $CAN_CM    $SP* $CM* $OP;
504cdf0e10cSrcweir     $CANT_CM   $SP* $CM* $OP;
505cdf0e10cSrcweir$AL_FOLLOW? $CM+  $SP $SP* $CM* $OP;     #  by LB 10, behaves like $AL_FOLLOW? $AL $SP* $CM* $OP
506cdf0e10cSrcweir
507cdf0e10cSrcweir     $AL_FOLLOW_NOCM $CM+ $SP+ $CM* $OP;
508cdf0e10cSrcweir$CM* $AL_FOLLOW_CM   $CM+ $SP+ $CM* $OP;
509cdf0e10cSrcweir$SY $CM $SP+ $OP;   # TODO:  Experiment.  Remove.
510cdf0e10cSrcweir
511cdf0e10cSrcweir
512cdf0e10cSrcweir
513cdf0e10cSrcweir# LB 15
514cdf0e10cSrcweir# $CM* $OP $SP* $CM* $QU;
515cdf0e10cSrcweir
516cdf0e10cSrcweir# LB 16
517cdf0e10cSrcweir$CM* $NS $SP* $CM* $CL;
518cdf0e10cSrcweir
519cdf0e10cSrcweir# LB 17
520cdf0e10cSrcweir$CM* $B2 $SP* $CM* $B2;
521cdf0e10cSrcweir
522cdf0e10cSrcweir# LB 18  break after spaces
523cdf0e10cSrcweir#        Nothing explicit needed here.
524cdf0e10cSrcweir
525cdf0e10cSrcweir
526cdf0e10cSrcweir#
527cdf0e10cSrcweir# LB 19
528cdf0e10cSrcweir#
529cdf0e10cSrcweir$CM* $QU $CM* $CAN_CM;                                #   . x QU
530cdf0e10cSrcweir$CM* $QU      $LB18NonBreaks;
531cdf0e10cSrcweir
532cdf0e10cSrcweir
533cdf0e10cSrcweir$CM* $CAN_CM  $CM* $QU;                               #   QU x .
534cdf0e10cSrcweir     $CANT_CM $CM* $QU;
535cdf0e10cSrcweir
536cdf0e10cSrcweir#
537cdf0e10cSrcweir#  LB 20  Break before and after CB.
538cdf0e10cSrcweir#         nothing needed here.
539cdf0e10cSrcweir#
540cdf0e10cSrcweir
541cdf0e10cSrcweir# LB 21
542cdf0e10cSrcweir$CM* ($BA | $HY | $NS) $CM* [$LB20NonBreaks-$CM];     #  . x (BA | HY | NS)
543cdf0e10cSrcweir
544cdf0e10cSrcweir$CM* [$LB20NonBreaks-$CM] $CM* $BB;                   #  BB x .
545cdf0e10cSrcweir[^$CB] $CM* $BB;                                      #
546cdf0e10cSrcweir
547cdf0e10cSrcweir
548cdf0e10cSrcweir
549cdf0e10cSrcweir# LB 22
550cdf0e10cSrcweir$CM* $IN $CM* $ALPlus;
551cdf0e10cSrcweir$CM* $IN $CM* $ID;
552cdf0e10cSrcweir$CM* $IN $CM* $IN;
553cdf0e10cSrcweir$CM* $IN $CM* $NU;
554cdf0e10cSrcweir
555cdf0e10cSrcweir# LB 23
556cdf0e10cSrcweir$CM* $PO $CM* $ID;
557cdf0e10cSrcweir$CM* $NU $CM* $ALPlus;
558cdf0e10cSrcweir$CM* $ALPlus $CM* $NU;
559cdf0e10cSrcweir
560cdf0e10cSrcweir# LB 24
561cdf0e10cSrcweir$CM* $ID $CM* $PR;
562cdf0e10cSrcweir$CM* $PR $CM* $ALPlus;
563cdf0e10cSrcweir$CM* $ALPlus $CM* $PR;
564cdf0e10cSrcweir$CM* $ALPlus $CM* $PO;
565cdf0e10cSrcweir
566cdf0e10cSrcweir$CM* $ALPlus $CM* ($IS | $SY | $HY)+ / $SP;
567cdf0e10cSrcweir$CM* $NU+ $CM* $HY+ / $SP;
568cdf0e10cSrcweir
569cdf0e10cSrcweir# LB 25
570cdf0e10cSrcweir($CM* ($PR | $PO))? ($CM* $CL)? ($CM* ($NU | $IS | $SY))* $CM* $NU ($CM* ($OP))? ($CM* ($PR | $PO))?;
571cdf0e10cSrcweir
572cdf0e10cSrcweir# LB 26
573cdf0e10cSrcweir$CM* ($H3 | $H2 | $JV | $JL) $CM* $JL;
574cdf0e10cSrcweir$CM* ($JT | $JV) $CM* ($H2 | $JV);
575cdf0e10cSrcweir$CM* $JT $CM* ($H3 | $JT);
576cdf0e10cSrcweir
577cdf0e10cSrcweir# LB 27
578cdf0e10cSrcweir$CM* $IN $CM* ($H3 | $H2 | $JT | $JV | $JL);
579cdf0e10cSrcweir$CM* $PO $CM* ($H3 | $H2 | $JT | $JV | $JL);
580cdf0e10cSrcweir$CM* ($H3 | $H2 | $JT | $JV | $JL) $CM* $PR;
581cdf0e10cSrcweir
582cdf0e10cSrcweir# LB 28
583cdf0e10cSrcweir$CM* $ALPlus $CM* $ALPlus;
584cdf0e10cSrcweir
585cdf0e10cSrcweir
586cdf0e10cSrcweir# LB 29
587cdf0e10cSrcweir$CM* ($NU | $ALPlus) $CM* $IS+ [^$SP];
588cdf0e10cSrcweir
589cdf0e10cSrcweir# LB 30
590cdf0e10cSrcweir$CM* $OP $CM* ($NU | $ALPlus);
591cdf0e10cSrcweir$CM* ($NU | $ALPlus) $CM* ($CL | $SY)+ [^$SP];
592cdf0e10cSrcweir
593cdf0e10cSrcweir
594cdf0e10cSrcweir## -------------------------------------------------
595cdf0e10cSrcweir
596cdf0e10cSrcweir!!safe_reverse;
597cdf0e10cSrcweir
598cdf0e10cSrcweir# LB 7
599cdf0e10cSrcweir$CM+ [^$CM $BK $CR $LF $NL $ZW $SP];
600cdf0e10cSrcweir$CM+ $SP / .;
601cdf0e10cSrcweir
602cdf0e10cSrcweir# LB 9
603cdf0e10cSrcweir$SP+ $CM* $OP;
604cdf0e10cSrcweir
605cdf0e10cSrcweir# LB 10
606cdf0e10cSrcweir$SP+ $CM* $QU;
607cdf0e10cSrcweir
608cdf0e10cSrcweir# LB 11
609cdf0e10cSrcweir$SP+ $CM* $CL;
610cdf0e10cSrcweir$SP+ $CM* $B2;
611cdf0e10cSrcweir
612cdf0e10cSrcweir# LB 18
613cdf0e10cSrcweir($CM* ($IS | $SY))+ $CM* $NU;
614cdf0e10cSrcweir$CL $CM* ($NU | $IS | $SY);
615cdf0e10cSrcweir
616cdf0e10cSrcweir# For dictionary-based break
617cdf0e10cSrcweir$dictionary $dictionary;
618cdf0e10cSrcweir
619cdf0e10cSrcweir## -------------------------------------------------
620cdf0e10cSrcweir
621cdf0e10cSrcweir!!safe_forward;
622cdf0e10cSrcweir
623cdf0e10cSrcweir# Skip forward over all character classes that are involved in
624cdf0e10cSrcweir#   rules containing patterns with possibly more than one char
625cdf0e10cSrcweir#   of context.
626cdf0e10cSrcweir#
627cdf0e10cSrcweir#  It might be slightly more efficient to have specific rules
628cdf0e10cSrcweir#  instead of one generic one, but only if we could
629cdf0e10cSrcweir#  turn off rule chaining.  We don't want to move more
630cdf0e10cSrcweir#  than necessary.
631cdf0e10cSrcweir#
632cdf0e10cSrcweir[$CM $OP $QU $CL $B2 $PR $HY $SP $dictionary]+ [^$CM $OP $QU $CL $B2 $PR $HY $dictionary];
633cdf0e10cSrcweir$dictionary $dictionary;
634cdf0e10cSrcweir
635