@x {hyphen count int_pars go here} @y @d hyphen_count_state_code=69 @d three_hyphen_demerits_code=70 {demerits for three consecutive hyphens} @d four_hyphen_demerits_code=71 {demerits for four consecutive hyphens} @d five_hyphen_demerits_code=72 {demerits for five or more consecutive hyphens} @z @x @d error_context_lines==int_par(error_context_lines_code) @y @d hyphen_count_state==int_par(hyphen_count_state_code) @d hyphen_count_en==(hyphen_count_state>0) @d error_context_lines==int_par(error_context_lines_code) @d three_hyphen_demerits==int_par(three_hyphen_demerits_code) @d four_hyphen_demerits==int_par(four_hyphen_demerits_code) @d five_hyphen_demerits==int_par(five_hyphen_demerits_code) @z @x error_context_lines_code:print_esc("errorcontextlines"); @y error_context_lines_code:print_esc("errorcontextlines"); hyphen_count_state_code:print_esc("hyphencountstate"); three_hyphen_demerits_code:print_esc("threehyphendemerits"); four_hyphen_demerits_code:print_esc("fourhyphendemerits"); five_hyphen_demerits_code:print_esc("fivehyphendemerits"); @z @x primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/ @!@:error_context_lines_}{\.{\\errorcontextlines} primitive@> @y primitive("errorcontextlines",assign_int,int_base+error_context_lines_code);@/ @!@:error_context_lines_}{\.{\\errorcontextlines} primitive@> primitive("threehyphendemerits",assign_int,int_base+three_hyphen_demerits_code);@/ @!@:three_hyphen_demerits_}{\.{\\threehyphendemerits} primitive@> primitive("fourhyphendemerits",assign_int,int_base+four_hyphen_demerits_code);@/ @!@:four_hyphen_demerits_}{\.{\\fourhyphendemerits} primitive@> primitive("fivehyphendemerits",assign_int,int_base+five_hyphen_demerits_code);@/ @!@:five_hyphen_demerits_}{\.{\\fivehyphendemerits} primitive@> primitive("hyphencountstate",assign_int,int_base+hyphen_count_state_code);@/ @!@:hyphen_count_state_}{\.{\\hyphencountstate} primitive@> @z @x escape_char:="\"; end_line_char:=carriage_return; @y escape_char:="\"; end_line_char:=carriage_return; hyphen_count_state:=0; @z @x @d tight_fit=3 {fitness classification for lines shrinking 0.5 to 1.0 of their shrinkability} @y @d hyphen_count_limit=6 {treat 6 consecutive hyphens like 5} @d fitness_classes=4 {number of different fitness classes} @d line_classes=24 {|hyphen_count_limit*fitness_classes|} @d tight_fit=3 {fitness classification for lines shrinking 0.5 to 1.0 of their shrinkability} @z @x @d active_node_size=3 {number of words in active nodes} @d fitness==subtype {|very_loose_fit..tight_fit| on final line for this break} @y @d active_node_size=3 {number of words in active nodes} @d line_fitness==subtype {|very_loose_fit..tight_fit| on final line for this break; also contains information about number of consecutive hyphens} @d fitness(#)==(line_fitness(#) mod fitness_classes) @d hyphen_count(#)==(line_fitness(#) div fitness_classes) @z @x type(last_active):=hyphenated; line_number(last_active):=max_halfword; subtype(last_active):=0; {the |subtype| is never examined by the algorithm} @y type(last_active):=hyphenated; line_number(last_active):=max_halfword; line_fitness(last_active):=0; {the |fitness| is never examined by the algorithm} @z @x @!fit_class:very_loose_fit..tight_fit; {possible fitness class of test line} @y @!fit_class:very_loose_fit..tight_fit; {possible fitness class of test line} @!consec:0..5; {number of consecutive hyphens up to test line} @!line_class:small_number; {|fit_class+fitness_classes*consec|} @z % We have to insert active nodes not only for the four fitness classes, % but for each fitness class/consecutive hyphen count combination. Since % we have |fitness_classes| fitness classes and |hyphen_count_limit| different % numbers of consecutive hyphens, we end up with up to |line_classes| active % nodes. The following arrays are no longer indexed by fit_class, but by % fit_class+fitness_classes*consec, where consec (; minimal_demerits[fit_class]:=awful_bad; end; @y for fit_class:=very_loose_fit to tight_fit do for consec:=0 to hyphen_count_limit-1 do begin line_class:=fit_class+fitness_classes*consec; if minimal_demerits[line_class]<=minimum_demerits then @; minimal_demerits[line_class]:=awful_bad; end; @z @x @= begin q:=get_node(passive_node_size); link(q):=passive; passive:=q; cur_break(q):=cur_p; @!stat incr(pass_number); serial(q):=pass_number;@+tats@;@/ prev_break(q):=best_place[fit_class];@/ q:=get_node(active_node_size); break_node(q):=passive; line_number(q):=best_pl_line[fit_class]+1; fitness(q):=fit_class; type(q):=break_type; total_demerits(q):=minimal_demerits[fit_class]; link(q):=r; link(prev_r):=q; prev_r:=q; @!stat if tracing_paragraphs>0 then @; tats@;@/ end @y @= begin q:=get_node(passive_node_size); link(q):=passive; passive:=q; cur_break(q):=cur_p; @!stat incr(pass_number); serial(q):=pass_number;@+tats@;@/ prev_break(q):=best_place[line_class];@/ q:=get_node(active_node_size); break_node(q):=passive; line_number(q):=best_pl_line[line_class]+1; line_fitness(q):=line_class; type(q):=break_type; total_demerits(q):=minimal_demerits[line_class]; link(q):=r; link(prev_r):=q; prev_r:=q; @!stat if tracing_paragraphs>0 then @; tats@;@/ end @z @x if break_type=hyphenated then print_char("-"); @y if break_type=hyphenated then begin print("-("); print_int(consec); print_char(")"); end; @z @x else @; @y else @; if break_type=unhyphenated then consec:=0 else if hyphen_count(r)=hyphen_count_limit-1 then consec:=hyphen_count(r) else consec:=hyphen_count(r)+1; line_class:=fit_class+fitness_classes*consec; @z @x if d<=minimal_demerits[fit_class] then begin minimal_demerits[fit_class]:=d; best_place[fit_class]:=break_node(r); best_pl_line[fit_class]:=l; if dnull then d:=d+double_hyphen_demerits else d:=d+final_hyphen_demerits; @y if (break_type=hyphenated)and(hyphen_count(r)>0) then if cur_p=null then d:=d+final_hyphen_demerits else if not hyphen_count_en then d:=d+double_hyphen_demerits else case hyphen_count(r) of 1: d:=d+double_hyphen_demerits; 2: d:=d+three_hyphen_demerits; 3: d:=d+four_hyphen_demerits; othercases d:=d+five_hyphen_demerits; endcases; @z @x q:=get_node(active_node_size); type(q):=unhyphenated; fitness(q):=decent_fit; @y q:=get_node(active_node_size); type(q):=unhyphenated; line_fitness(q):=decent_fit+fitness_classes*0; @z