1 /* Copyright 2014 Clerk Ma
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 pointer rebox_(pointer b, scaled w)
26 internal_font_number f;
29 if ((width(b) != w) && (list_ptr(b) != 0))
31 if (type(b) == vlist_node)
36 if ((is_char_node(p)) && (link(p) == 0))
39 v = char_width(f, char_info(f, character(p)));
42 link(p) = new_kern(width(b) - v);
45 free_node(b, box_node_size);
46 b = new_glue(ss_glue);
52 link(p) = new_glue(ss_glue);
53 return hpack(b, w, exactly);
61 /* This is to be the start of tex5.c */
63 pointer math_glue_(pointer g, scaled m)
69 n = x_over_n(m, 65536L);
78 p = get_node(glue_spec_size);
79 width(p) = mu_mult(width(g));
80 stretch_order(p) = stretch_order(g);
82 if (stretch_order(p) == normal)
83 stretch(p) = mu_mult(stretch(g));
85 stretch(p) = stretch(g);
87 shrink_order(p) = shrink_order(g);
89 if (shrink_order(p) == normal)
90 shrink(p) = mu_mult(shrink(g));
92 shrink(p) = shrink(g);
97 void math_kern_ (pointer p, scaled m)
102 if (subtype(p) == mu_glue)
104 n = x_over_n(m, 65536L);
113 width(p) = mu_mult(width(p));
114 subtype(p) = explicit;
118 void flush_math (void)
120 flush_node_list(link(head));
121 flush_node_list(incompleat_noad);
127 halfword clean_box_(halfword p, small_number s)
130 small_number save_style;
134 switch (math_type(p))
138 cur_mlist = new_noad();
139 mem[nucleus(cur_mlist)] = mem[p];
162 save_style = cur_style;
164 mlist_penalties = false;
167 cur_style = save_style;
170 if (cur_style < script_style)
171 cur_size = text_size;
173 cur_size = 16 * ((cur_style - text_style) / 2);
175 cur_mu = x_over_n(math_quad(cur_size), 18);
179 if (is_char_node(q) || (q == 0))
181 else if ((link(q) == 0) && (type(q) <= vlist_node) && (shift_amount(q) == 0))
194 if (!is_char_node(r))
195 if (type(r) == kern_node)
197 free_node(r, small_node_size);
205 void fetch_(pointer a)
207 cur_c = character(a);
208 cur_f = fam_fnt(fam(a) + cur_size);
210 if (cur_f == null_font)
213 print_size(cur_size);
216 prints(" is undefined (character ");
219 help4("Somewhere in the math formula just ended, you used the",
220 "stated character from an undefined font family. For example,",
221 "plain TeX doesn't allow \\it or \\sl in subscripts. Proceed,",
222 "and I'll try to forget that I needed that character.");
224 cur_i = null_character;
229 if ((cur_c >= font_bc[cur_f]) && (cur_c <= font_ec[cur_f]))
230 cur_i = char_info(cur_f, cur_c);
232 cur_i = null_character;
234 if (!char_exists(cur_i))
236 char_warning(cur_f, cur_c);
242 void make_over_(pointer q)
244 info(nucleus(q)) = overbar(clean_box(nucleus(q), 2 * (cur_style / 2) + 1),
245 3 * default_rule_thickness, default_rule_thickness);
246 math_type(nucleus(q)) = sub_box;
249 void make_under_(pointer q)
254 x = clean_box(nucleus(q), cur_style);
255 p = new_kern(3 * default_rule_thickness);
257 link(p) = fraction_rule(default_rule_thickness);
258 y = vpackage(x, 0, 1, 1073741823L); /* 2^30 - 1 */
259 delta = height(y) + depth(y) + default_rule_thickness;
260 height(y) = height(x);
261 depth(y) = delta - height(y);
262 info(nucleus(q)) = y;
263 math_type(nucleus(q)) = sub_box;
266 void make_vcenter_(pointer q)
271 v = info(nucleus(q));
273 if (type(v) != vlist_node)
275 confusion("vcenter");
279 delta = height(v) + depth(v);
280 height(v) = axis_height(cur_size) + half(delta);
281 depth(v) = delta - height(v);
284 void make_radical_(pointer q)
289 x = clean_box(nucleus(q), 2 * (cur_style / 2) + 1);
291 if (cur_style < text_style)
292 clr = default_rule_thickness + (abs(math_x_height(cur_size)) / 4);
295 clr = default_rule_thickness;
296 clr = clr + (abs(clr) / 4);
299 y = var_delimiter(left_delimiter(q), cur_size, height(x) + depth(x) + clr + default_rule_thickness);
300 delta = depth(y) -(height(x) + depth(x) + clr);
303 clr = clr + half(delta);
305 shift_amount(y) = - (integer) (height(x) + clr);
306 link(y) = overbar(x, clr, height(y));
307 info(nucleus(q)) = hpack(y, 0, 1);
308 math_type(nucleus(q)) = sub_box;
311 void make_math_accent_(pointer q)
316 internal_font_number f;
323 fetch(accent_chr(q));
325 if (char_exists(cur_i))
332 if (math_type(nucleus(q)) == math_char)
336 if (char_tag(cur_i) == lig_tag)
338 a = lig_kern_start(cur_f, cur_i);
339 cur_i = font_info[a].qqqq;
341 if (skip_byte(cur_i) > stop_flag)
343 a = lig_kern_restart(cur_f, cur_i);
344 cur_i = font_info[a].qqqq;
349 if (next_char(cur_i) == skew_char[cur_f])
351 if (op_byte(cur_i) >= kern_flag)
352 if (skip_byte(cur_i) <= stop_flag)
353 s = char_kern(cur_f, cur_i);
358 if (skip_byte(cur_i) >= stop_flag)
361 a = a + skip_byte(cur_i) + 1;
362 cur_i = font_info[a].qqqq;
368 x = clean_box(nucleus(q), cramped_style(cur_style));
374 if (char_tag(i) != list_tag)
383 if (char_width(f, i) > w)
395 if ((math_type(supscr(q)) != 0) || (math_type(subscr(q)) != 0))
396 if (math_type(nucleus(q)) == math_char)
400 mem[nucleus(x)] = mem[nucleus(q)];
401 mem[supscr(x)] = mem[supscr(q)];
402 mem[subscr(x)] = mem[subscr(q)];
403 mem[supscr(q)].hh = empty_field;
404 mem[subscr(q)].hh = empty_field;
405 math_type(nucleus(q)) = sub_mlist;
406 info(nucleus(q)) = x;
407 x = clean_box(nucleus(q), cur_style);
408 delta = delta + height(x) - h;
413 shift_amount(y) = s + half(w - width(y));
415 p = new_kern(-(integer) delta);
418 y = vpackage(y, 0, 1, 1073741823L); /* 2^30 - 1 */
423 p = new_kern(h - height(y));
424 link(p) = list_ptr(y);
429 info(nucleus(q)) = y;
430 math_type(nucleus(q)) = sub_box;
434 void make_fraction_(pointer q)
436 pointer p, v, x, y, z;
437 scaled delta, delta1, delta2, shift_up, shift_down, clr;
439 if (thickness(q) == default_code)
440 thickness(q) = default_rule_thickness;
442 x = clean_box(numerator(q), num_style(cur_style));
443 z = clean_box(denominator(q), denom_style(cur_style));
445 if (width(x) < width(z))
446 x = rebox(x, width(z));
448 z = rebox(z, width(x));
450 if (cur_style < text_style)
452 shift_up = num1(cur_size);
453 shift_down = denom1(cur_size);
457 shift_down = denom2(cur_size);
459 if (thickness(q) != 0)
460 shift_up = num2(cur_size);
462 shift_up = num3(cur_size);
465 if (thickness(q) == 0)
467 if (cur_style < text_style)
468 clr = 7 * default_rule_thickness;
470 clr = 3 * default_rule_thickness;
472 delta = half(clr - ((shift_up - depth(x)) - (height(z) - shift_down)));
476 shift_up = shift_up + delta;
477 shift_down = shift_down + delta;
482 if (cur_style < text_style)
483 clr = 3 * thickness(q);
487 delta = half(thickness(q));
488 delta1 = clr - ((shift_up - depth(x)) - (axis_height(cur_size) + delta));
489 delta2 = clr -((axis_height(cur_size) - delta) - (height(z) - shift_down));
492 shift_up = shift_up + delta1;
495 shift_down = shift_down + delta2;
499 type(v) = vlist_node;
500 height(v) = shift_up + height(x);
501 depth(v) = depth(z) + shift_down;
504 if (thickness(q) == 0)
506 p = new_kern((shift_up - depth(x)) - (height(z) - shift_down));
511 y = fraction_rule(thickness(q));
512 p = new_kern((axis_height(cur_size) - delta) - (height(z) - shift_down));
515 p = new_kern((shift_up - depth(x)) - (axis_height(cur_size) + delta));
522 if (cur_style < text_style)
523 delta = delim1(cur_size);
525 delta = delim2(cur_size);
527 x = var_delimiter(left_delimiter(q), cur_size, delta);
529 z = var_delimiter(right_delimiter(q), cur_size, delta);
531 new_hlist(q) = hpack(x, 0, 1);
534 void make_ord_(pointer q)
540 if (math_type(subscr(q)) == 0)
541 if (math_type(supscr(q)) == 0)
542 if (math_type(nucleus(q)) == math_char)
547 if ((type(p) >= ord_noad) && (type(p) <= punct_noad))
548 if (math_type(nucleus(p)) == math_char)
549 if (fam(nucleus(p)) == fam(nucleus(q)))
551 math_type(nucleus(q)) = math_text_char;
554 if (char_tag(cur_i) == lig_tag)
556 a = lig_kern_start(cur_f, cur_i);
557 cur_c = character(nucleus(p));
558 cur_i = font_info[a].qqqq;
560 if (skip_byte(cur_i) > stop_flag)
562 a = lig_kern_restart(cur_f, cur_i);
563 cur_i = font_info[a].qqqq;
568 if (next_char(cur_i) == cur_c)
569 if (skip_byte(cur_i) <= stop_flag)
570 if (op_byte(cur_i) >= kern_flag)
572 p = new_kern(char_kern(cur_f, cur_i));
582 pause_for_instructions();
586 switch (op_byte(cur_i))
590 character(nucleus(q)) = rem_byte(cur_i);
594 character(nucleus(p)) = rem_byte(cur_i);
601 character(nucleus(r)) = rem_byte(cur_i);
602 fam(nucleus(r)) = fam(nucleus(q));
606 if (op_byte(cur_i) < 11)
607 math_type(nucleus(r)) = math_char;
609 math_type(nucleus(r)) = math_text_char;
616 character(nucleus(q)) = rem_byte(cur_i);
617 mem[subscr(q)] = mem[subscr(p)];
618 mem[supscr(q)] = mem[supscr(p)];
619 free_node(p, noad_size);
624 if (op_byte(cur_i) > 3)
627 math_type(nucleus(q)) = math_char;
631 if (skip_byte(cur_i) >= stop_flag)
634 a = a + skip_byte(cur_i) + 1;
635 cur_i = font_info[a].qqqq;
642 small_number make_left_right_(pointer q, small_number style, scaled max_d, scaled max_h)
644 scaled delta, delta1, delta2;
646 if (style < script_style)
647 cur_size = text_size;
649 cur_size = 16 * ((style - text_style) / 2);
651 delta2 = max_d + axis_height(cur_size);
652 delta1 = max_h + max_d - delta2;
657 delta = (delta1 / 500) * delimiter_factor;
658 delta2 = delta1 + delta1 - delimiter_shortfall;
663 new_hlist(q) = var_delimiter(delimiter(q), cur_size, delta);
664 return type(q) - (left_noad - open_noad);
667 void mlist_to_hlist (void)
672 small_number save_style;
675 /* small_number r_type; */
677 /* small_number t; */
686 penalties = mlist_penalties;
695 if (cur_style < script_style)
696 cur_size = text_size;
698 cur_size = 16 * ((cur_style - text_style) / 2);
700 cur_mu = x_over_n(math_quad(cur_size), 18);
736 if (r_type == bin_noad)
739 if (type(q) == right_noad)
751 goto check_dimensions;
759 if (subtype(q) == limits)
760 goto check_dimensions;
795 cur_style = subtype(q);
798 if (cur_style < script_style)
799 cur_size = text_size;
801 cur_size = 16 * ((cur_style - text_style) / 2);
803 cur_mu = x_over_n(math_quad(cur_size), 18);
812 switch (cur_style / 2)
815 choose_mlist(display_mlist);
819 choose_mlist(text_mlist);
823 choose_mlist(script_mlist);
827 choose_mlist(script_script_mlist);
831 flush_node_list(display_mlist(q));
832 flush_node_list(text_mlist(q));
833 flush_node_list(script_mlist(q));
834 flush_node_list(script_script_mlist(q));
835 type(q) = style_node;
836 subtype(q) = cur_style;
866 if (height(q) > max_h)
869 if (depth(q) > max_d)
878 if (subtype(q) == mu_glue)
881 y = math_glue(x, cur_mu);
886 else if ((cur_size != text_size) && (subtype(q) == cond_math_glue))
891 if ((type(q) == glue_node) || (type(p) == kern_node))
905 math_kern(q, cur_mu);
918 switch (math_type(nucleus(q)))
925 if (char_exists(cur_i))
927 delta = char_italic(cur_f, cur_i);
928 p = new_character(cur_f, cur_c);
930 if ((math_type(nucleus(q)) == math_text_char) && (space(cur_f) != 0))
933 if ((math_type(subscr(q)) == 0) && (delta != 0))
935 link(p) = new_kern(delta);
949 p = info(nucleus(q));
954 cur_mlist = info(nucleus(q));
955 save_style = cur_style;
956 mlist_penalties = false;
958 cur_style = save_style;
961 if (cur_style < script_style)
962 cur_size = text_size;
964 cur_size = 16 * ((cur_style - text_style) / 2);
966 cur_mu = x_over_n(math_quad(cur_size), 18);
969 p = hpack(link(temp_head), 0, 1);
983 if ((math_type(subscr(q)) == 0) && (math_type(supscr(q)) == 0))
984 goto check_dimensions;
986 make_scripts(q, delta);
989 z = hpack(new_hlist(q), 0, 1);
991 if (height(z) > max_h)
994 if (depth(z) > max_d)
997 free_node(z, box_node_size);
1007 if (r_type == bin_noad)
1017 if (cur_style < script_style)
1018 cur_size = text_size;
1020 cur_size = 16 *((cur_style - text_style) / 2);
1022 cur_mu = x_over_n(math_quad(cur_size), 18);
1044 pen = bin_op_penalty;
1063 s = radical_noad_size;
1067 s = accent_noad_size;
1073 s = fraction_noad_size;
1079 t = make_left_right(q, style, max_d, max_h);
1084 cur_style = subtype(q);
1085 s = style_node_size;
1088 if (cur_style < script_style)
1089 cur_size = text_size;
1091 cur_size = 16 *((cur_style - text_style) / 2);
1093 cur_mu = x_over_n(math_quad(cur_size), 18);
1120 confusion("mlist3");
1128 switch (str_pool[r_type * 8 + t + magic_offset])
1135 if (cur_style < script_style)
1136 x = thin_mu_skip_code;
1142 x = thin_mu_skip_code;
1146 if (cur_style < script_style)
1147 x = med_mu_skip_code;
1153 if (cur_style < script_style)
1154 x = thick_mu_skip_code;
1161 confusion("mlist4");
1169 y = math_glue(glue_par(x), cur_mu);
1171 glue_ref_count(y) = 0;
1178 if (new_hlist(q) != 0)
1180 link(p) = new_hlist(q);
1186 while (!(link(p) == 0));
1191 if (pen < inf_penalty)
1193 r_type = type(link(q));
1195 if (r_type != penalty_node)
1196 if (r_type != rel_noad)
1198 z = new_penalty(pen);
1214 void push_alignment (void)
1218 p = get_node(align_stack_node_size);
1219 link(p) = align_ptr;
1220 info(p) = cur_align;
1221 llink(p) = preamble;
1222 rlink(p) = cur_span;
1223 mem[p + 2].cint = cur_loop;
1224 mem[p + 3].cint = align_state;
1225 info(p + 4) = cur_head;
1226 link(p + 4) = cur_tail;
1228 cur_head = get_avail();
1231 void pop_alignment (void)
1235 free_avail(cur_head);
1237 cur_tail = link(p + 4);
1238 cur_head = info(p + 4);
1239 align_state = mem[p + 3].cint;
1240 cur_loop = mem[p + 2].cint;
1241 cur_span = rlink(p);
1242 preamble = llink(p);
1243 cur_align = info(p);
1244 align_ptr = link(p);
1245 free_node(p, align_stack_node_size);
1248 void get_preamble_token (void)
1253 while ((cur_chr == span_code) && (cur_cmd == tab_mark))
1257 if (cur_cmd > max_command)
1264 if (cur_cmd == endv)
1266 fatal_error("(interwoven alignment preambles are not allowed)");
1270 if ((cur_cmd == assign_glue) && (cur_chr == glue_base + tab_skip_code))
1272 scan_optional_equals();
1273 scan_glue(glue_val);
1275 if (global_defs > 0)
1276 geq_define(glue_base + tab_skip_code, glue_ref, cur_val);
1278 eq_define(glue_base + tab_skip_code, glue_ref, cur_val);
1284 void init_align (void)
1286 pointer save_cs_ptr;
1289 save_cs_ptr = cur_cs;
1291 align_state = -1000000L;
1293 if ((mode == mmode) && ((tail != cur_list.head_field) || (incompleat_noad != 0)))
1295 print_err("Improper ");
1296 print_esc("halign");
1297 prints(" inside $$'s");
1298 help3("Displays can use special alignments (like \\eqalignno)",
1299 "only if nothing but the alignment itself is between $$'s.",
1300 "So I've deleted the formulas that preceded this alignment.");
1310 prev_depth = nest[nest_ptr - 2].aux_field.cint;
1313 mode = - (integer) mode;
1315 scan_spec(align_group, false);
1317 cur_align = align_head;
1319 scanner_status = aligning;
1320 warning_index = save_cs_ptr;
1321 align_state = -1000000L;
1325 link(cur_align) = new_param_glue(tab_skip_code);
1326 cur_align = link(cur_align);
1328 if (cur_cmd == car_ret)
1336 get_preamble_token();
1338 if (cur_cmd == mac_param)
1341 if ((cur_cmd <= car_ret) && (cur_cmd >= tab_mark) && (align_state == -1000000L))
1342 if ((p == hold_head) && (cur_loop == 0) && (cur_cmd == tab_mark))
1343 cur_loop = cur_align;
1346 print_err("Missing # inserted in alignment preamble");
1347 help3("There should be exactly one # between &'s, when an",
1348 "\\halign or \\valign is being set up. In this case you had",
1349 "none, so I've put one in; maybe that will work.");
1353 else if ((cur_cmd != spacer) || (p != hold_head))
1355 link(p) = get_avail();
1362 link(cur_align) = new_null_box();
1363 cur_align = link(cur_align);
1364 info(cur_align) = end_span;
1365 width(cur_align) = null_flag;
1366 u_part(cur_align) = link(hold_head);
1373 get_preamble_token();
1375 if ((cur_cmd <= car_ret) && (cur_cmd >= tab_mark) && (align_state == -1000000L))
1378 if (cur_cmd == mac_param)
1380 print_err("Only one # is allowed per tab");
1381 help3("There should be exactly one # between &'s, when an",
1382 "\\halign or \\valign is being set up. In this case you had",
1383 "more than one, so I'm ignoring all but the first.");
1388 link(p) = get_avail();
1394 link(p) = get_avail();
1396 info(p) = end_template_token;
1397 v_part(cur_align) = link(hold_head);
1402 new_save_level(align_group);
1405 begin_token_list(every_cr, every_cr_text);
1410 void init_span_ (pointer p)
1415 space_factor = 1000;
1418 prev_depth = ignore_depth;
1425 void init_row (void)
1429 mode = (-hmode - vmode) - mode;
1436 tail_append(new_glue(glue_ptr(preamble)));
1437 subtype(tail) = tab_skip_code + 1;
1438 cur_align = link(preamble);
1439 cur_tail = cur_head;
1440 init_span(cur_align);
1443 void init_col (void)
1445 extra_info(cur_align) = cur_cmd;
1447 if (cur_cmd == omit)
1452 begin_token_list(u_part(cur_align), u_template);
1462 p = hpack(link(head), 0, 1);
1466 if (cur_head != cur_tail)
1468 link(tail) = link(cur_head);
1474 p = vpackage(link(head), 0, 1, 1073741823L); /* 2^30 - 1 */
1478 space_factor = 1000;
1481 type(p) = unset_node;
1482 glue_stretch(p) = 0;
1485 begin_token_list(every_cr, every_cr_text);
1490 void fin_align (void)
1492 pointer p, q, r, s, u, v;
1497 memory_word aux_save;
1499 if (cur_group != align_group)
1501 confusion("align1");
1507 if (cur_group != align_group)
1509 confusion("align0");
1515 if (nest[nest_ptr - 1].mode_field == mmode)
1524 flush_list(u_part(q));
1525 flush_list(v_part(q));
1528 if (width(q) == null_flag)
1536 add_glue_ref(zero_glue);
1538 glue_ptr(c) = zero_glue;
1542 if (info(q) != end_span)
1544 t = width(q) + width(glue_ptr(link(q)));
1548 n = min_quarterword + 1;
1552 width(r) = width(r) - t;
1558 n = link(info(s)) + 1;
1570 if (width(r) > width(info(s)))
1571 width(info(s)) = width(r);
1573 free_node(r, span_node_size);
1578 while (!(r == end_span));
1581 type(q) = unset_node;
1582 span_count(q) = min_quarterword;
1585 glue_order(q) = normal;
1586 glue_sign(q) = normal;
1587 glue_stretch(q) = 0;
1593 save_ptr = save_ptr - 2;
1594 pack_begin_line = - (integer) mode_line;
1598 rule_save = overfull_rule;
1600 p = hpack(preamble, saved(1), saved(0));
1601 overfull_rule = rule_save;
1609 height(q) = width(q);
1615 p = vpackage(preamble, saved(1), saved(0), 1073741823L); /* 2^30 - 1 */
1620 width(q) = height(q);
1627 pack_begin_line = 0;
1633 if (!is_char_node(q))
1634 if (type(q) == unset_node)
1638 type(q) = hlist_node;
1639 width(q) = width(p);
1643 type(q) = vlist_node;
1644 height(q) = height(p);
1647 glue_order(q) = glue_order(p);
1648 glue_sign(q) = glue_sign(p);
1649 glue_set(q) = glue_set(p);
1650 shift_amount(q) = o;
1651 r = link(list_ptr(q));
1652 s = link(list_ptr(p));
1661 while (n > min_quarterword)
1666 link(u) = new_glue(v);
1668 subtype(u) = tab_skip_code + 1;
1671 if (glue_sign(p) == stretching)
1673 if (stretch_order(v) == glue_order(p))
1674 t = t + round(glue_set(p) * stretch(v));
1676 else if (glue_sign(p) == shrinking)
1678 if (shrink_order(v) == glue_order(p))
1679 t = t - round(glue_set(p) * shrink(v));
1683 link(u) = new_null_box();
1688 width(u) = width(s);
1691 type(u) = vlist_node;
1692 height(u) = width(s);
1699 height(r) = height(q);
1700 depth(r) = depth(q);
1704 glue_sign(r) = normal;
1705 glue_order(r) = normal;
1708 else if (t > width(r))
1710 glue_sign(r) = stretching;
1712 if (glue_stretch(r) == 0)
1715 glue_set(r) = (t - width(r)) / ((double) glue_stretch(r));
1719 glue_order(r) = glue_sign(r);
1720 glue_sign(r) = shrinking;
1722 if (glue_shrink(r) == 0)
1724 else if ((glue_order(r) == normal) && (width(r) - t > glue_shrink(r)))
1727 glue_set(r) = (width(r) - t)/ ((double) glue_shrink(r));
1731 type(r) = hlist_node;
1735 width(r) = width(q);
1739 glue_sign(r) = normal;
1740 glue_order(r) = normal;
1743 else if (t > height(r))
1745 glue_sign(r) = stretching;
1747 if (glue_stretch(r) == 0)
1750 glue_set(r) = (t - height(r)) / ((double) glue_stretch(r));
1754 glue_order(r) = glue_sign(r);
1755 glue_sign(r) = shrinking;
1757 if (glue_shrink(r) == 0)
1759 else if ((glue_order(r) == normal) && (height(r) - t > glue_shrink(r)))
1762 glue_set(r) = (height(r) - t) / ((double) glue_shrink(r));
1766 type(r) = vlist_node;
1769 shift_amount(r) = 0;
1774 link(r) = link(hold_head);
1783 else if (type(q) == rule_node)
1785 if (is_running(width(q)))
1786 width(q) = width(p);
1788 if (is_running(height(q)))
1789 height(q) = height(p);
1791 if (is_running(depth(q)))
1792 depth(q) = depth(p);
1799 shift_amount(q) = o;
1810 aux_save = cur_list.aux_field;
1819 if (cur_cmd != math_shift)
1821 print_err("Missing $$ inserted");
1822 help2("Displays can use special alignments (like \\eqalignno)",
1823 "only if nothing but the alignment itself is between $$'s.");
1830 if (cur_cmd != math_shift)
1832 print_err("Display math should end with $$");
1833 help2("The `$' that I just saw supposedly matches a previous `$$'.",
1834 "So I shall assume that you typed `$$' both times.");
1840 tail_append(new_penalty(pre_display_penalty));
1841 tail_append(new_param_glue(above_display_skip_code));
1847 tail_append(new_penalty(post_display_penalty));
1848 tail_append(new_param_glue(below_display_skip_code));
1849 prev_depth = aux_save.cint;
1850 resume_after_display();
1854 cur_list.aux_field = aux_save;
1865 boolean fin_col (void)
1881 q = link(cur_align);
1889 if (align_state < 500000L)
1891 fatal_error("(interwoven alignment preambles are not allowed)");
1897 if ((p == 0) && (extra_info(cur_align) < cr_code))
1900 link(q) = new_null_box();
1903 width(p) = null_flag;
1904 cur_loop = link(cur_loop);
1906 r = u_part(cur_loop);
1910 link(q) = get_avail();
1917 u_part(p) = link(hold_head);
1919 r = v_part(cur_loop);
1923 link(q) = get_avail();
1930 v_part(p) = link(hold_head);
1931 cur_loop = link(cur_loop);
1932 link(p) = new_glue(glue_ptr(cur_loop));
1936 print_err("Extra alignment tab has been changed to ");
1938 help3("You have given more \\span or & marks than there were",
1939 "in the preamble to the \\halign or \\valign now in progress.",
1940 "So I'll assume that you meant to type \\cr instead.");
1941 extra_info(cur_align) = cr_code;
1945 if (extra_info(cur_align) != span_code)
1948 new_save_level(align_group);
1953 adjust_tail = cur_tail;
1954 u = hpack(link(head), 0, 1);
1956 cur_tail = adjust_tail;
1961 u = vpackage(link(head), 0, 1, 0);
1965 n = min_quarterword;
1967 if (cur_span != cur_align)
1976 while (!(q == cur_align));
1978 if (n > max_quarterword)
1980 confusion("256 spans");
1986 while (link(info(q)) < n)
1989 if (link(info(q)) > n)
1991 s = get_node(span_node_size);
1997 else if (width(info(q)) < w)
2000 else if (w > width(cur_align))
2001 width(cur_align) = w;
2003 type(u) = unset_node;
2006 if (total_stretch[filll] != 0)
2008 else if (total_stretch[fill] != 0)
2010 else if (total_stretch[fil] != 0)
2016 glue_stretch(u) = total_stretch[o];
2018 if (total_shrink[filll] != 0)
2020 else if (total_shrink[fill] != 0)
2022 else if (total_shrink[fil] != 0)
2028 glue_shrink(u) = total_shrink[o];
2034 tail_append(new_glue(glue_ptr(link(cur_align))));
2035 subtype(tail) = tab_skip_code + 1;
2037 if (extra_info(cur_align) >= cr_code)
2045 align_state = 1000000L;
2051 while (!(cur_cmd != spacer));
2059 scaled make_op_(pointer q)
2062 pointer p, v, x, y, z;
2065 scaled shift_up, shift_down;
2067 if ((subtype(q) == normal) && (cur_style < text_style))
2068 subtype(q) = limits;
2070 if (math_type(nucleus(q)) == math_char)
2074 if ((cur_style < text_style) && (char_tag(cur_i) == list_tag))
2076 c = rem_byte(cur_i);
2077 i = char_info(cur_f, c);
2083 character(nucleus(q)) = c;
2087 delta = char_italic(cur_f, cur_i);
2088 x = clean_box(nucleus(q), cur_style);
2090 if ((math_type(subscr(q)) != 0) && (subtype(q) != limits))
2091 width(x) = width(x) - delta;
2093 shift_amount(x) = half(height(x) - depth(x)) - axis_height(cur_size);
2094 math_type(nucleus(q)) = sub_box;
2095 info(nucleus(q)) = x;
2100 if (subtype(q) == limits)
2102 x = clean_box(supscr(q), sup_style(cur_style));
2103 y = clean_box(nucleus(q), cur_style);
2104 z = clean_box(subscr(q), sub_style(cur_style));
2106 type(v) = vlist_node;
2107 width(v) = width(y);
2109 if (width(x) > width(v))
2110 width(v) = width(x);
2112 if (width(z) > width(v))
2113 width(v) = width(z);
2115 x = rebox(x, width(v));
2116 y = rebox(y, width(v));
2117 z = rebox(z, width(v));
2118 shift_amount(x) = half(delta);
2119 shift_amount(z) = - (integer) shift_amount(x);
2120 height(v) = height(y);
2121 depth(v) = depth(y);
2123 if (math_type(supscr(q)) == 0)
2125 free_node(x, box_node_size);
2130 shift_up = big_op_spacing3 - depth(x);
2132 if (shift_up < big_op_spacing1)
2133 shift_up = big_op_spacing1;
2135 p = new_kern(shift_up);
2138 p = new_kern(big_op_spacing5);
2141 height(v) = height(v) + big_op_spacing5 + height(x) + depth(x) + shift_up;
2144 if (math_type(subscr(q)) == 0)
2145 free_node(z, box_node_size);
2148 shift_down = big_op_spacing4 - height(z);
2150 if (shift_down < big_op_spacing2)
2151 shift_down = big_op_spacing2;
2153 p = new_kern(shift_down);
2156 p = new_kern(big_op_spacing5);
2158 depth(v) = depth(v) + big_op_spacing5 + height(z) + depth(z) + shift_down;
2167 void make_scripts_(pointer q, scaled delta)
2170 scaled shift_up, shift_down, clr;
2175 if (is_char_node(p))
2184 if (cur_style < script_style)
2187 t = script_script_size;
2189 shift_up = height(z) - sup_drop(t);
2190 shift_down = depth(z) + sub_drop(t);
2191 free_node(z, box_node_size);
2194 if (math_type(supscr(q)) == 0)
2196 x = clean_box(subscr(q), sub_style(cur_style));
2197 width(x) = width(x) + script_space;
2199 if (shift_down < sub1(cur_size))
2200 shift_down = sub1(cur_size);
2202 clr = height(x) -(abs(math_x_height(cur_size) * 4) / 5);
2204 if (shift_down < clr)
2207 shift_amount(x) = shift_down;
2212 x = clean_box(supscr(q), sup_style(cur_style));
2213 width(x) = width(x) + script_space;
2216 clr = sup3(cur_size);
2217 else if (cur_style < text_style)
2218 clr = sup1(cur_size);
2220 clr = sup2(cur_size);
2225 clr = depth(x) +(abs(math_x_height(cur_size)) / 4);
2231 if (math_type(subscr(q)) == 0)
2232 shift_amount(x) = - (integer) shift_up;
2235 y = clean_box(subscr(q), sub_style(cur_style));
2236 width(y) = width(y) + script_space;
2238 if (shift_down < sub2(cur_size))
2239 shift_down = sub2(cur_size);
2241 clr = 4 * default_rule_thickness - ((shift_up - depth(x)) - (height(y) - shift_down));
2245 shift_down = shift_down + clr;
2247 clr = (abs(math_x_height(cur_size) * 4) / 5) - (shift_up - depth(x));
2251 shift_up = shift_up + clr;
2252 shift_down = shift_down - clr;
2256 shift_amount(x) = delta;
2257 p = new_kern((shift_up - depth(x)) - (height(y) - shift_down));
2260 x = vpackage(x, 0, 1, 1073741823L); /* 2^30 - 1 */
2261 shift_amount(x) = shift_down;
2265 if (new_hlist(q) == 0)
2271 while (link(p) != 0)