summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/hitexdir/hitex.w
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/hitexdir/hitex.w')
-rw-r--r--Build/source/texk/web2c/hitexdir/hitex.w126
1 files changed, 111 insertions, 15 deletions
diff --git a/Build/source/texk/web2c/hitexdir/hitex.w b/Build/source/texk/web2c/hitexdir/hitex.w
index e037b7f847b..a81005cf8c3 100644
--- a/Build/source/texk/web2c/hitexdir/hitex.w
+++ b/Build/source/texk/web2c/hitexdir/hitex.w
@@ -5175,8 +5175,9 @@ that will be defined later.
@d tracing_scan_tokens_code (etex_int_base+3) /*show pseudo file open and close*/
@d tracing_nesting_code (etex_int_base+4) /*show incomplete groups and ifs within files*/
@d saving_vdiscards_code (etex_int_base+5) /*save items discarded from vlists*/
-@d expand_depth_code (etex_int_base+6) /*maximum depth for expansion---\eTeX*/
-@d eTeX_state_code (etex_int_base+7) /*\eTeX\ state variables*/
+@d saving_hyph_codes_code (etex_int_base+6) /*save hyphenation codes for languages*/
+@d expand_depth_code (etex_int_base+7) /*maximum depth for expansion---\eTeX*/
+@d eTeX_state_code (etex_int_base+8) /*\eTeX\ state variables*/
@d etex_int_pars (eTeX_state_code+eTeX_states) /*total number of \eTeX's integer parameters*/
@#
@d int_pars etex_int_pars /*total number of integer parameters*/
@@ -5248,8 +5249,9 @@ that will be defined later.
@d tracing_ifs int_par(tracing_ifs_code)
@d tracing_scan_tokens int_par(tracing_scan_tokens_code)
@d tracing_nesting int_par(tracing_nesting_code)
-@d expand_depth int_par(expand_depth_code)
@d saving_vdiscards int_par(saving_vdiscards_code)
+@d saving_hyph_codes int_par(saving_hyph_codes_code)
+@d expand_depth int_par(expand_depth_code)
@<Assign the values |depth_threshold:=show_box_depth|...@>=
depth_threshold=show_box_depth;
@@ -18137,6 +18139,7 @@ if (trie_not_ready) init_trie();
#endif
@;@/
cur_lang=init_cur_lang;l_hyf=init_l_hyf;r_hyf=init_r_hyf;
+set_hyph_index;
}
@ The letters $c_1\ldots c_n$ that are candidates for hyphenation are placed
@@ -18210,8 +18213,9 @@ loop@+{@+if (is_char_node(s))
goto resume;
}
else goto done1;
- if (lc_code(c)!=0)
- if ((lc_code(c)==c)||(uc_hyph > 0)) goto done2;
+ set_lc_code(c);
+ if (hc[0]!=0)
+ if ((hc[0]==c)||(uc_hyph > 0)) goto done2;
else goto done1;
resume: prev_s=s;s=link(prev_s);
}
@@ -18227,9 +18231,10 @@ hn=0;
loop@+{@+if (is_char_node(s))
{@+if (font(s)!=hf) goto done3;
hyf_bchar=character(s);c=qo(hyf_bchar);
- if (lc_code(c)==0) goto done3;
+ set_lc_code(c);
+ if (hc[0]==0) goto done3;
if (hn==63) goto done3;
- hb=s;incr(hn);hu[hn]=c;hc[hn]=lc_code(c);hyf_bchar=non_char;
+ hb=s;incr(hn);hu[hn]=c;hc[hn]=hc[0];hyf_bchar=non_char;
}
else if (type(s)==ligature_node)
@<Move the characters of a ligature node to |hu| and |hc|; but |goto done3|
@@ -18253,9 +18258,10 @@ to get to |done3| with |hn==0| and |hb| not set to any value.
j=hn;q=lig_ptr(s);@+if (q > null) hyf_bchar=character(q);
while (q > null)
{@+c=qo(character(q));
- if (lc_code(c)==0) goto done3;
+ set_lc_code(c);
+ if (hc[0]==0) goto done3;
if (j==63) goto done3;
- incr(j);hu[j]=c;hc[j]=lc_code(c);@/
+ incr(j);hu[j]=c;hc[j]=hc[0];@/
q=link(q);
}
hb=s;hn=j;
@@ -18907,6 +18913,13 @@ str_number @!s, @!t; /*strings being compared or stored*/
pool_pointer @!u, @!v; /*indices into |str_pool|*/
scan_left_brace(); /*a left brace must follow \.{\\hyphenation}*/
set_cur_lang;
+#ifdef @!INIT
+if (trie_not_ready)
+ {@+hyph_index=0;goto not_found1;
+ }
+#endif
+set_hyph_index;
+not_found1:
@<Enter as many hyphenation exceptions as are listed, until coming to a right
brace; then |return|@>;
}
@@ -18939,7 +18952,8 @@ error();
@ @<Append a new letter or hyphen@>=
if (cur_chr=='-') @<Append the value |n| to list |p|@>@;
-else{@+if (lc_code(cur_chr)==0)
+else{@+set_lc_code(cur_chr);
+ if (hc[0]==0)
{@+print_err("Not a letter");
@.Not a letter@>
help2("Letters in \\hyphenation words must have \\lccode>0.",@/
@@ -18947,7 +18961,7 @@ else{@+if (lc_code(cur_chr)==0)
error();
}
else if (n < 63)
- {@+incr(n);hc[n]=lc_code(cur_chr);
+ {@+incr(n);hc[n]=hc[0];
}
}
@@ -19243,6 +19257,7 @@ because we finish with the former just before we need the latter.
@<Get ready to compress the trie@>=
@<Sort \(t)the hyphenation...@>;
for (p=0; p<=trie_size; p++) trie_hash[p]=0;
+hyph_root=compress_trie(hyph_root);
trie_root=compress_trie(trie_root); /*identify equivalent subtries*/
for (p=0; p<=trie_ptr; p++) trie_ref[p]=0;
for (p=0; p<=255; p++) trie_min[p]=p+1;
@@ -19331,11 +19346,12 @@ value~0, which properly implements an ``empty'' family.
@<Move the data into |trie|@>=
h.rh=0;h.b0=min_quarterword;h.b1=min_quarterword; /*|trie_link=0|,
|trie_op=min_quarterword|, |trie_char=qi(0)|*/
-if (trie_root==0) /*no patterns were given*/
+if (trie_max==0) /*no patterns were given*/
{@+for (r=0; r<=256; r++) trie[r]=h;
trie_max=256;
}
-else{@+trie_fix(trie_root); /*this fixes the non-holes in |trie|*/
+else{@+if (hyph_root > 0) trie_fix(hyph_root);
+ if (trie_root > 0) trie_fix(trie_root); /*this fixes the non-holes in |trie|*/
r=0; /*now we will zero out all the holes*/
@/do@+{s=trie_link(r);trie[r]=h;r=s;
}@+ while (!(r > trie_max));
@@ -19374,11 +19390,13 @@ bool @!digit_sensed; /*should the next digit be treated as a letter?*/
quarterword @!v; /*trie op code*/
trie_pointer @!p, @!q; /*nodes of trie traversed during insertion*/
bool @!first_child; /*is |p==trie_l[q]|?*/
-ASCII_code @!c; /*character being inserted*/
+int @!c; /*character being inserted*/
if (trie_not_ready)
{@+set_cur_lang;scan_left_brace(); /*a left brace must follow \.{\\patterns}*/
@<Enter all of the patterns into a linked trie, until coming to a right
brace@>;
+ if (saving_hyph_codes > 0)
+ @<Store hyphenation codes for current language@>;
}
else{@+print_err("Too late for ");print_esc("patterns");
help1("All patterns must be given before typesetting begins.");
@@ -19484,6 +19502,7 @@ two_halves @!h; /*template used to zero out |trie|'s holes*/
if (trie_root!=0)
{@+first_fit(trie_root);trie_pack(trie_root);
}
+if (hyph_root!=0) @<Pack all stored |hyph_codes|@>;
@<Move the data into |trie|@>;
trie_not_ready=false;
}
@@ -24932,6 +24951,7 @@ print_ln();print_int(hyph_count);print(" hyphenation exception");
if (hyph_count!=1) print_char('s');
if (trie_not_ready) init_trie();
dump_int(trie_max);
+dump_int(hyph_start);
for (k=0; k<=trie_max; k++) dump_hh(trie[k]);
dump_int(trie_op_ptr);
for (k=1; k<=trie_op_ptr; k++)
@@ -24963,6 +24983,7 @@ undump_size(0, trie_size,"trie size", j);
#ifdef @!INIT
trie_max=j;
#endif
+undump(0, j, hyph_start);
for (k=0; k<=j; k++) undump_hh(trie[k]);
undump_size(0, trie_op_size,"trie op size", j);
#ifdef @!INIT
@@ -26267,7 +26288,9 @@ goto done;
@ @<Let |d| be the width of the whatsit |p|@>=d=0
@ @d adv_past(A) @+if (subtype(A)==language_node)
- {@+cur_lang=what_lang(A);l_hyf=what_lhm(A);r_hyf=what_rhm(A);@+}
+ {@+cur_lang=what_lang(A);l_hyf=what_lhm(A);r_hyf=what_rhm(A);
+ set_hyph_index;
+ }
@<Advance \(p)past a whatsit node in the \(l)|line_break| loop@>=@+
adv_past(cur_p)
@@ -26583,6 +26606,8 @@ primitive("tracingnesting", assign_int, int_base+tracing_nesting_code);@/
@!@:tracing\_nesting\_}{\.{\\tracingnesting} primitive@>
primitive("savingvdiscards", assign_int, int_base+saving_vdiscards_code);@/
@!@:saving\_vdiscards\_}{\.{\\savingvdiscards} primitive@>
+primitive("savinghyphcodes", assign_int, int_base+saving_hyph_codes_code);@/
+@!@:saving\_hyph\_codes\_}{\.{\\savinghyphcodes} primitive@>
@ @d every_eof equiv(every_eof_loc)
@@ -26596,6 +26621,7 @@ case tracing_ifs_code: print_esc("tracingifs");@+break;
case tracing_scan_tokens_code: print_esc("tracingscantokens");@+break;
case tracing_nesting_code: print_esc("tracingnesting");@+break;
case saving_vdiscards_code: print_esc("savingvdiscards");@+break;
+case saving_hyph_codes_code: print_esc("savinghyphcodes");@+break;
@ In order to handle \.{\\everyeof} we need an array |eof_seen| of
boolean variables.
@@ -28489,6 +28515,76 @@ else free_node(p, pointer_node_size);
}@+ while (!(sa_chain==null));
}
+@ When reading \.{\\patterns} while \.{\\savinghyphcodes} is positive
+the current |lc_code| values are stored together with the hyphenation
+patterns for the current language. They will later be used instead of
+the |lc_code| values for hyphenation purposes.
+
+The |lc_code| values are stored in the linked trie analogous to patterns
+$p_1$ of length~1, with |hyph_root==trie_r[0]| replacing |trie_root| and
+|lc_code(p_1)| replacing the |trie_op| code. This allows to compress
+and pack them together with the patterns with minimal changes to the
+existing code.
+
+@d hyph_root trie_r[0] /*root of the linked trie for |hyph_codes|*/
+
+@<Initialize table entries...@>=
+hyph_root=0;hyph_start=0;
+
+@ @<Store hyphenation codes for current language@>=
+{@+c=cur_lang;first_child=false;p=0;
+@/do@+{q=p;p=trie_r[q];
+}@+ while (!((p==0)||(c <= so(trie_c[p]))));
+if ((p==0)||(c < so(trie_c[p])))
+ @<Insert a new trie node between |q| and |p|, and make |p| point to it@>;
+q=p; /*now node |q| represents |cur_lang|*/
+@<Store all current |lc_code| values@>;
+}
+
+@ We store all nonzero |lc_code| values, overwriting any previously
+stored values (and possibly wasting a few trie nodes that were used
+previously and are not needed now). We always store at least one
+|lc_code| value such that |hyph_index| (defined below) will not be zero.
+
+@<Store all current |lc_code| values@>=
+p=trie_l[q];first_child=true;
+for (c=0; c<=255; c++)
+ if ((lc_code(c) > 0)||((c==255)&&first_child))
+ {@+if (p==0)
+ @<Insert a new trie node between |q| and |p|, and make |p| point to
+it@>@;
+ else trie_c[p]=si(c);
+ trie_o[p]=qi(lc_code(c));
+ q=p;p=trie_r[q];first_child=false;
+ }
+if (first_child) trie_l[q]=0;@+else trie_r[q]=0
+
+@ We must avoid to ``take'' location~1, in order to distinguish between
+|lc_code| values and patterns.
+
+@<Pack all stored |hyph_codes|@>=
+{@+if (trie_root==0) for (p=0; p<=255; p++) trie_min[p]=p+2;
+first_fit(hyph_root);trie_pack(hyph_root);
+hyph_start=trie_ref[hyph_root];
+}
+
+@ The global variable |hyph_index| will point to the hyphenation codes
+for the current language.
+
+@d set_hyph_index /*set |hyph_index| for current language*/
+ if (trie_char(hyph_start+cur_lang)!=qi(cur_lang)
+ ) hyph_index=0; /*no hyphenation codes for |cur_lang|*/
+ else hyph_index=trie_link(hyph_start+cur_lang)
+@#
+@d set_lc_code(A) /*set |hc[0]| to hyphenation or lc code for |A|*/
+ if (hyph_index==0) hc[0]=lc_code(A);
+ else if (trie_char(hyph_index+A)!=qi(A)) hc[0]=0;
+ else hc[0]=qo(trie_op(hyph_index+A))
+
+@<Glob...@>=
+static trie_pointer @!hyph_start; /*root of the packed trie for |hyph_codes|*/
+static trie_pointer @!hyph_index; /*pointer to hyphenation codes for |cur_lang|*/
+
@ When |saving_vdiscards| is positive then the glue, kern, and penalty
nodes removed by the page builder or by \.{\\vsplit} from the top of a
vertical list are saved in special lists instead of being discarded.