OSDN Git Service

removed libmd5.
[putex/putex.git] / src / texsourc / tex5.c
1 /* Copyright 2014 Clerk Ma\r
2 \r
3    This program is free software; you can redistribute it and/or modify\r
4    it under the terms of the GNU General Public License as published by\r
5    the Free Software Foundation; either version 2 of the License, or\r
6    (at your option) any later version.\r
7 \r
8    This program is distributed in the hope that it will be useful, but\r
9    WITHOUT ANY WARRANTY; without even the implied warranty of\r
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
11    General Public License for more details.\r
12 \r
13    You should have received a copy of the GNU General Public License\r
14    along with this program; if not, write to the Free Software\r
15    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\r
16    02110-1301 USA.  */\r
17 \r
18 #define EXTERN extern\r
19 \r
20 #include "yandytex.h"\r
21 \r
22 /* sec 0715 */\r
23 pointer rebox (pointer b, scaled w)\r
24 {\r
25   pointer p;\r
26   internal_font_number f;\r
27   scaled v;\r
28 \r
29   if ((width(b) != w) && (list_ptr(b) != 0))\r
30   {\r
31     if (type(b) == vlist_node)\r
32       b = hpack(b, 0, 1);\r
33 \r
34     p = list_ptr(b);\r
35 \r
36     if ((is_char_node(p)) && (link(p) == 0))\r
37     {\r
38       f = font(p);\r
39       v = char_width(f, char_info(f, character(p)));\r
40 \r
41       if (v != width(b))\r
42         link(p) = new_kern(width(b) - v);\r
43     }\r
44 \r
45     free_node(b, box_node_size);\r
46     b = new_glue(ss_glue);\r
47     link(b) = p;\r
48 \r
49     while (link(p) != 0)\r
50       p = link(p);\r
51 \r
52     link(p) = new_glue(ss_glue);\r
53     return hpack(b, w, exactly);\r
54   }\r
55   else\r
56   {\r
57     width(b) = w;\r
58     return b;\r
59   }\r
60 }\r
61 /* sec 0716 */\r
62 pointer math_glue (pointer g, scaled m)\r
63 {\r
64   pointer p;\r
65   integer n;\r
66   scaled f;\r
67 \r
68   n = x_over_n(m, 65536L);\r
69   f = tex_remainder;\r
70 \r
71   if (f < 0)\r
72   {\r
73     decr(n);\r
74     f = f + 65536L;\r
75   }\r
76 \r
77   p = get_node(glue_spec_size);\r
78   width(p) = mu_mult(width(g));\r
79   stretch_order(p) = stretch_order(g);\r
80 \r
81   if (stretch_order(p) == normal)\r
82     stretch(p) = mu_mult(stretch(g));\r
83   else\r
84     stretch(p) = stretch(g);\r
85 \r
86   shrink_order(p) = shrink_order(g);\r
87 \r
88   if (shrink_order(p) == normal)\r
89     shrink(p) = mu_mult(shrink(g));\r
90   else\r
91     shrink(p) = shrink(g);\r
92 \r
93   return p;\r
94 }\r
95 /* sec 0717 */\r
96 void math_kern (pointer p, scaled m)\r
97 {\r
98   integer n;\r
99   scaled f;\r
100 \r
101   if (subtype(p) == mu_glue)\r
102   {\r
103     n = x_over_n(m, 65536L);\r
104     f = tex_remainder;\r
105 \r
106     if (f < 0)\r
107     {\r
108       decr(n);\r
109       f = f + 65536L;\r
110     }\r
111 \r
112     width(p) = mu_mult(width(p));\r
113     subtype(p) = explicit;\r
114   }\r
115 }\r
116 /* sec 0718 */\r
117 void flush_math (void)\r
118 {\r
119   flush_node_list(link(head));\r
120   flush_node_list(incompleat_noad);\r
121   link(head) = 0;\r
122   tail = head;\r
123   incompleat_noad = 0;\r
124 }\r
125 /* sec 0720 */\r
126 pointer clean_box (pointer p, small_number s)\r
127 {\r
128   pointer q;\r
129   small_number save_style;\r
130   pointer x;\r
131   pointer r;\r
132 \r
133   switch (math_type(p))\r
134   {\r
135     case math_char:\r
136       {\r
137         cur_mlist = new_noad();\r
138         mem[nucleus(cur_mlist)] = mem[p];\r
139       }\r
140       break;\r
141 \r
142     case sub_box:\r
143       {\r
144         q = info(p);\r
145         goto found;\r
146       }\r
147       break;\r
148 \r
149     case sub_mlist:\r
150       cur_mlist = info(p);\r
151       break;\r
152 \r
153     default:\r
154       {\r
155         q = new_null_box();\r
156         goto found;\r
157       }\r
158     break;\r
159   }\r
160 \r
161   save_style = cur_style;\r
162   cur_style = s;\r
163   mlist_penalties = false;\r
164   mlist_to_hlist();\r
165   q = link(temp_head);\r
166   cur_style = save_style;\r
167 \r
168   {\r
169     if (cur_style < script_style)\r
170       cur_size = text_size;\r
171     else\r
172       cur_size = 16 * ((cur_style - text_style) / 2);\r
173 \r
174     cur_mu = x_over_n(math_quad(cur_size), 18);\r
175   }\r
176 \r
177 found:\r
178   if (is_char_node(q) || (q == 0))\r
179     x = hpack(q, 0, 1);\r
180   else if ((link(q) == 0) && (type(q) <= vlist_node) && (shift_amount(q) == 0))\r
181     x = q;\r
182   else\r
183     x = hpack(q, 0, 1);\r
184 \r
185   q = list_ptr(x);\r
186 \r
187   if (is_char_node(q))\r
188   {\r
189     r = link(q);\r
190 \r
191     if (r != 0)\r
192       if (link(r) == 0)\r
193         if (!is_char_node(r))\r
194           if (type(r) == kern_node)\r
195           {\r
196             free_node(r, small_node_size);\r
197             link(q) = 0;\r
198           }\r
199   }\r
200 \r
201   return x;\r
202 }\r
203 /* sec 0722 */\r
204 void fetch (pointer a)\r
205 {\r
206   cur_c = character(a);\r
207   cur_f = fam_fnt(fam(a) + cur_size);\r
208 \r
209   if (cur_f == null_font)\r
210   {\r
211     print_err("");\r
212     print_size(cur_size);\r
213     print_char(' ');\r
214     print_int(fam(a));\r
215     prints(" is undefined (character ");\r
216     print(cur_c);\r
217     print_char(')');\r
218     help4("Somewhere in the math formula just ended, you used the",\r
219         "stated character from an undefined font family. For example,",\r
220         "plain TeX doesn't allow \\it or \\sl in subscripts. Proceed,",\r
221         "and I'll try to forget that I needed that character.");\r
222     error();\r
223     cur_i = null_character;\r
224     math_type(a) = 0;\r
225   }\r
226   else\r
227   {\r
228     if ((cur_c >= font_bc[cur_f]) && (cur_c <= font_ec[cur_f]))\r
229       cur_i = char_info(cur_f, cur_c);\r
230     else\r
231       cur_i = null_character;\r
232 \r
233     if (!char_exists(cur_i))\r
234     {\r
235       char_warning(cur_f, cur_c);\r
236       math_type(a) = 0;\r
237     }\r
238   }\r
239 }\r
240 /* sec 0734 */\r
241 void make_over (pointer q)\r
242 {\r
243   info(nucleus(q)) = overbar(clean_box(nucleus(q), 2 * (cur_style / 2) + 1),\r
244       3 * default_rule_thickness, default_rule_thickness);\r
245   math_type(nucleus(q)) = sub_box;\r
246 }\r
247 /* sec 0735 */\r
248 void make_under (pointer q)\r
249 {\r
250   pointer p, x, y;\r
251   scaled delta;\r
252 \r
253   x = clean_box(nucleus(q), cur_style);\r
254   p = new_kern(3 * default_rule_thickness);\r
255   link(x) = p;\r
256   link(p) = fraction_rule(default_rule_thickness);\r
257   y = vpackage(x, 0, 1, max_dimen);\r
258   delta = height(y) + depth(y) + default_rule_thickness;\r
259   height(y) = height(x);\r
260   depth(y) = delta - height(y);\r
261   info(nucleus(q)) = y;\r
262   math_type(nucleus(q)) = sub_box;\r
263 }\r
264 /* sec 0736 */\r
265 void make_vcenter (pointer q)\r
266\r
267   pointer v;\r
268   scaled delta;\r
269 \r
270   v = info(nucleus(q));\r
271 \r
272   if (type(v) != vlist_node)\r
273   {\r
274     confusion("vcenter");\r
275     return;\r
276   }\r
277 \r
278   delta = height(v) + depth(v);\r
279   height(v) = axis_height(cur_size) + half(delta);\r
280   depth(v) = delta - height(v);\r
281 }\r
282 /* sec 0737 */\r
283 void make_radical (pointer q)\r
284 {\r
285   pointer x, y;\r
286   scaled delta, clr;\r
287 \r
288   x = clean_box(nucleus(q), 2 * (cur_style / 2) + 1);\r
289 \r
290   if (cur_style < text_style)\r
291     clr = default_rule_thickness + (abs(math_x_height(cur_size)) / 4);\r
292   else\r
293   {\r
294     clr = default_rule_thickness;\r
295     clr = clr + (abs(clr) / 4);\r
296   }\r
297 \r
298   y = var_delimiter(left_delimiter(q), cur_size, height(x) + depth(x) + clr + default_rule_thickness);\r
299   delta = depth(y) -(height(x) + depth(x) + clr);\r
300 \r
301   if (delta > 0)\r
302     clr = clr + half(delta);\r
303 \r
304   shift_amount(y) = - (integer) (height(x) + clr);\r
305   link(y) = overbar(x, clr, height(y));\r
306   info(nucleus(q)) = hpack(y, 0, 1);\r
307   math_type(nucleus(q)) = sub_box;\r
308 }\r
309 /* sec 0738 */\r
310 void make_math_accent (pointer q)\r
311 {\r
312   pointer p, x, y;\r
313   integer a;\r
314   quarterword c;\r
315   internal_font_number f;\r
316   four_quarters i;\r
317   scaled s;\r
318   scaled h;\r
319   scaled delta;\r
320   scaled w;\r
321 \r
322   fetch(accent_chr(q));\r
323 \r
324   if (char_exists(cur_i))\r
325   {\r
326     i = cur_i;\r
327     c = cur_c;\r
328     f = cur_f;\r
329     s = 0;\r
330 \r
331     if (math_type(nucleus(q)) == math_char)\r
332     {\r
333       fetch(nucleus(q));\r
334 \r
335       if (char_tag(cur_i) == lig_tag)\r
336       {\r
337         a = lig_kern_start(cur_f, cur_i);\r
338         cur_i = font_info[a].qqqq;\r
339 \r
340         if (skip_byte(cur_i) > stop_flag)\r
341         {\r
342           a = lig_kern_restart(cur_f, cur_i);\r
343           cur_i = font_info[a].qqqq;\r
344         }\r
345 \r
346         while (true)\r
347         {\r
348           if (next_char(cur_i) == skew_char[cur_f])\r
349           {\r
350             if (op_byte(cur_i) >= kern_flag)\r
351               if (skip_byte(cur_i) <= stop_flag)\r
352                 s = char_kern(cur_f, cur_i);\r
353 \r
354             goto done1;\r
355           }\r
356 \r
357           if (skip_byte(cur_i) >= stop_flag)\r
358             goto done1;\r
359 \r
360           a = a + skip_byte(cur_i) + 1;\r
361           cur_i = font_info[a].qqqq;\r
362         }\r
363       }\r
364     }\r
365 \r
366 done1:\r
367     x = clean_box(nucleus(q), cramped_style(cur_style));\r
368     w = width(x);\r
369     h = height(x);\r
370 \r
371     while (true)\r
372     {\r
373       if (char_tag(i) != list_tag)\r
374         goto done;\r
375 \r
376       y = rem_byte(i);\r
377       i = char_info(f, y);\r
378 \r
379       if (!char_exists(i))\r
380         goto done;\r
381 \r
382       if (char_width(f, i) > w)\r
383         goto done;\r
384 \r
385       c = y;\r
386     }\r
387 \r
388 done:\r
389     if (h < x_height(f))\r
390       delta = h;\r
391     else\r
392       delta = x_height(f);\r
393 \r
394     if ((math_type(supscr(q)) != 0) || (math_type(subscr(q)) != 0))\r
395       if (math_type(nucleus(q)) == math_char)\r
396       {\r
397         flush_node_list(x);\r
398         x = new_noad();\r
399         mem[nucleus(x)] = mem[nucleus(q)];\r
400         mem[supscr(x)] = mem[supscr(q)];\r
401         mem[subscr(x)] = mem[subscr(q)];\r
402         mem[supscr(q)].hh = empty_field;\r
403         mem[subscr(q)].hh = empty_field;\r
404         math_type(nucleus(q)) = sub_mlist;\r
405         info(nucleus(q)) = x;\r
406         x = clean_box(nucleus(q), cur_style);\r
407         delta = delta + height(x) - h;\r
408         h = height(x);\r
409       }\r
410 \r
411     y = char_box(f, c);\r
412     shift_amount(y) = s + half(w - width(y));\r
413     width(y) = 0;\r
414     p = new_kern(-(integer) delta);\r
415     link(p) = x;\r
416     link(y) = p;\r
417     y = vpackage(y, 0, 1, max_dimen);\r
418     width(y) = width(x);\r
419 \r
420     if (height(y) < h)\r
421     {\r
422       p = new_kern(h - height(y));\r
423       link(p) = list_ptr(y);\r
424       list_ptr(y) = p;\r
425       height(y) = h;\r
426     }\r
427 \r
428     info(nucleus(q)) = y;\r
429     math_type(nucleus(q)) = sub_box;\r
430   }\r
431 }\r
432 /* sec 0743 */\r
433 void make_fraction (pointer q)\r
434 {\r
435   pointer p, v, x, y, z;\r
436   scaled delta, delta1, delta2, shift_up, shift_down, clr;\r
437   \r
438   if (thickness(q) == default_code)\r
439     thickness(q) = default_rule_thickness;\r
440 \r
441   x = clean_box(numerator(q), num_style(cur_style));\r
442   z = clean_box(denominator(q), denom_style(cur_style));\r
443 \r
444   if (width(x) < width(z))\r
445     x = rebox(x, width(z));\r
446   else\r
447     z = rebox(z, width(x));\r
448 \r
449   if (cur_style < text_style)\r
450   {\r
451     shift_up = num1(cur_size);\r
452     shift_down = denom1(cur_size);\r
453   }\r
454   else\r
455   {\r
456     shift_down = denom2(cur_size);\r
457 \r
458     if (thickness(q) != 0)\r
459       shift_up = num2(cur_size);\r
460     else\r
461       shift_up = num3(cur_size);\r
462   }\r
463 \r
464   if (thickness(q) == 0)\r
465   {\r
466     if (cur_style < text_style)\r
467       clr = 7 * default_rule_thickness;\r
468     else\r
469       clr = 3 * default_rule_thickness;\r
470 \r
471     delta = half(clr - ((shift_up - depth(x)) - (height(z) - shift_down)));\r
472 \r
473     if (delta > 0)\r
474     {\r
475       shift_up = shift_up + delta;\r
476       shift_down = shift_down + delta;\r
477     }\r
478   }\r
479   else\r
480   {\r
481     if (cur_style < text_style)\r
482       clr = 3 * thickness(q);\r
483     else\r
484       clr = thickness(q);\r
485 \r
486     delta = half(thickness(q));\r
487     delta1 = clr - ((shift_up - depth(x)) - (axis_height(cur_size) + delta));\r
488     delta2 = clr - ((axis_height(cur_size) - delta) - (height(z) - shift_down));\r
489 \r
490     if (delta1 > 0)\r
491       shift_up = shift_up + delta1;\r
492 \r
493     if (delta2 > 0)\r
494       shift_down = shift_down + delta2;\r
495   }\r
496 \r
497   v = new_null_box();\r
498   type(v) = vlist_node;\r
499   height(v) = shift_up + height(x);\r
500   depth(v) = depth(z) + shift_down;\r
501   width(v) = width(x);\r
502 \r
503   if (thickness(q) == 0)\r
504   {\r
505     p = new_kern((shift_up - depth(x)) - (height(z) - shift_down));\r
506     link(p) = z;\r
507   }\r
508   else\r
509   {\r
510     y = fraction_rule(thickness(q));\r
511     p = new_kern((axis_height(cur_size) - delta) - (height(z) - shift_down));\r
512     link(y) = p;\r
513     link(p) = z;\r
514     p = new_kern((shift_up - depth(x)) - (axis_height(cur_size) + delta));\r
515     link(p) = y;\r
516   }\r
517 \r
518   link(x) = p;\r
519   list_ptr(v) = x;\r
520 \r
521   if (cur_style < text_style)\r
522     delta = delim1(cur_size);\r
523   else\r
524     delta = delim2(cur_size);\r
525 \r
526   x = var_delimiter(left_delimiter(q), cur_size, delta);\r
527   link(x) = v;\r
528   z = var_delimiter(right_delimiter(q), cur_size, delta);\r
529   link(v) = z;\r
530   new_hlist(q) = hpack(x, 0, 1);\r
531 }\r
532 /* sec 0752 */\r
533 void make_ord (pointer q)\r
534 {\r
535   integer a;\r
536   pointer p, r;\r
537 \r
538 restart:\r
539   if (math_type(subscr(q)) == 0)\r
540     if (math_type(supscr(q)) == 0)\r
541       if (math_type(nucleus(q)) == math_char)\r
542       {\r
543         p = link(q);\r
544 \r
545         if (p != 0)\r
546           if ((type(p) >= ord_noad) && (type(p) <= punct_noad))\r
547             if (math_type(nucleus(p)) == math_char)\r
548               if (fam(nucleus(p)) == fam(nucleus(q)))\r
549               {\r
550                 math_type(nucleus(q)) = math_text_char;\r
551                 fetch(nucleus(q));\r
552 \r
553                 if (char_tag(cur_i) == lig_tag)\r
554                 {\r
555                   a = lig_kern_start(cur_f, cur_i);\r
556                   cur_c = character(nucleus(p));\r
557                   cur_i = font_info[a].qqqq;\r
558 \r
559                   if (skip_byte(cur_i) > stop_flag)\r
560                   {\r
561                     a = lig_kern_restart(cur_f, cur_i);\r
562                     cur_i = font_info[a].qqqq;\r
563                   }\r
564 \r
565                   while (true)\r
566                   {\r
567                     if (next_char(cur_i) == cur_c)\r
568                       if (skip_byte(cur_i) <= stop_flag)\r
569                         if (op_byte(cur_i) >= kern_flag)\r
570                         {\r
571                           p = new_kern(char_kern(cur_f, cur_i));\r
572                           link(p) = link(q);\r
573                           link(q) = p;\r
574                           return;\r
575                         }\r
576                         else\r
577                         {\r
578                           check_interrupt();\r
579 \r
580                           switch (op_byte(cur_i))\r
581                           {\r
582                             case 1:\r
583                             case 5:\r
584                               character(nucleus(q)) = rem_byte(cur_i);\r
585                               break;\r
586                             case 2:\r
587                             case 6:\r
588                               character(nucleus(p)) = rem_byte(cur_i);\r
589                               break;\r
590                             case 3:\r
591                             case 7:\r
592                             case 11:\r
593                               {\r
594                                 r = new_noad();\r
595                                 character(nucleus(r)) = rem_byte(cur_i);\r
596                                 fam(nucleus(r)) = fam(nucleus(q));\r
597                                 link(q) = r;\r
598                                 link(r) = p;\r
599 \r
600                                 if (op_byte(cur_i) < 11)\r
601                                   math_type(nucleus(r)) = math_char;\r
602                                 else\r
603                                   math_type(nucleus(r)) = math_text_char;\r
604                               }\r
605                               break;\r
606 \r
607                             default:\r
608                               {\r
609                                 link(q) = link(p);\r
610                                 character(nucleus(q)) = rem_byte(cur_i);\r
611                                 mem[subscr(q)] = mem[subscr(p)];\r
612                                 mem[supscr(q)] = mem[supscr(p)];\r
613                                 free_node(p, noad_size);\r
614                               }\r
615                               break;\r
616                           }\r
617 \r
618                           if (op_byte(cur_i) > 3)\r
619                             return;\r
620 \r
621                           math_type(nucleus(q)) = math_char;\r
622                           goto restart;\r
623                         }\r
624 \r
625                     if (skip_byte(cur_i) >= stop_flag)\r
626                       return;\r
627 \r
628                     a = a + skip_byte(cur_i) + 1;\r
629                     cur_i = font_info[a].qqqq;\r
630                   }\r
631                 }\r
632               }\r
633       }\r
634 }\r
635 /* sec 0762 */\r
636 small_number make_left_right (pointer q, small_number style, scaled max_d, scaled max_h)\r
637 {\r
638   scaled delta, delta1, delta2;\r
639 \r
640   if (style < script_style)\r
641     cur_size = text_size;\r
642   else\r
643     cur_size = 16 * ((style - text_style) / 2);\r
644 \r
645   delta2 = max_d + axis_height(cur_size);\r
646   delta1 = max_h + max_d - delta2;\r
647 \r
648   if (delta2 > delta1)\r
649     delta1 = delta2;\r
650 \r
651   delta = (delta1 / 500) * delimiter_factor;\r
652   delta2 = delta1 + delta1 - delimiter_shortfall;\r
653 \r
654   if (delta < delta2)\r
655     delta = delta2;\r
656 \r
657   new_hlist(q) = var_delimiter(delimiter(q), cur_size, delta);\r
658 \r
659   return type(q) - (left_noad - open_noad);\r
660 }\r
661 /* sec 0726 */\r
662 void mlist_to_hlist (void)\r
663 {\r
664   pointer mlist;\r
665   boolean penalties;\r
666   small_number style;\r
667   small_number save_style;\r
668   pointer q;\r
669   pointer r;\r
670   /* small_number r_type; */\r
671   int r_type;\r
672   /* small_number t; */\r
673   int t;\r
674   pointer p, x, y, z;\r
675   integer pen;\r
676   small_number s;\r
677   scaled max_h, max_d;\r
678   scaled delta;\r
679 \r
680   mlist = cur_mlist;\r
681   penalties = mlist_penalties;\r
682   style = cur_style;\r
683   q = mlist;\r
684   r = 0;\r
685   r_type = op_noad;\r
686   max_h = 0;\r
687   max_d = 0;\r
688 \r
689   {\r
690     if (cur_style < script_style)\r
691       cur_size = text_size;\r
692     else\r
693       cur_size = 16 * ((cur_style - text_style) / 2);\r
694 \r
695     cur_mu = x_over_n(math_quad(cur_size), 18);\r
696   }\r
697 \r
698   while (q != 0)\r
699   {\r
700 reswitch:\r
701     delta = 0;\r
702 \r
703     switch (type(q))\r
704     {\r
705       case bin_noad:\r
706         switch (r_type)\r
707         {\r
708           case bin_noad:\r
709           case op_noad:\r
710           case rel_noad:\r
711           case open_noad:\r
712           case punct_noad:\r
713           case left_noad:\r
714             {\r
715               type(q) = ord_noad;\r
716               goto reswitch;\r
717             }\r
718             break;\r
719 \r
720           default:\r
721             do_nothing();\r
722             break;\r
723         }\r
724         break;\r
725 \r
726       case rel_noad:\r
727       case close_noad:\r
728       case punct_noad:\r
729       case right_noad:\r
730         {\r
731           if (r_type == bin_noad)\r
732             type(r) = ord_noad;\r
733 \r
734           if (type(q) == right_noad)\r
735             goto done_with_noad;\r
736         }\r
737         break;\r
738 \r
739       case left_noad:\r
740         goto done_with_noad;\r
741         break;\r
742 \r
743       case fraction_noad:\r
744         {\r
745           make_fraction(q);\r
746           goto check_dimensions;\r
747         }\r
748         break;\r
749 \r
750       case op_noad:\r
751         {\r
752           delta = make_op(q);\r
753 \r
754           if (subtype(q) == limits)\r
755             goto check_dimensions;\r
756         }\r
757         break;\r
758 \r
759       case ord_noad:\r
760         make_ord(q);\r
761         break;\r
762 \r
763       case open_noad:\r
764       case inner_noad:\r
765         do_nothing();\r
766         break;\r
767 \r
768       case radical_noad:\r
769         make_radical(q);\r
770         break;\r
771 \r
772       case over_noad:\r
773         make_over(q);\r
774         break;\r
775 \r
776       case under_noad:\r
777         make_under(q);\r
778         break;\r
779 \r
780       case accent_noad:\r
781         make_math_accent(q);\r
782         break;\r
783 \r
784       case vcenter_noad:\r
785         make_vcenter(q);\r
786         break;\r
787 \r
788       case style_node:\r
789         {\r
790           cur_style = subtype(q);\r
791 \r
792           {\r
793             if (cur_style < script_style)\r
794               cur_size = text_size;\r
795             else\r
796               cur_size = 16 * ((cur_style - text_style) / 2);\r
797 \r
798             cur_mu = x_over_n(math_quad(cur_size), 18);\r
799           }\r
800 \r
801           goto done_with_node;\r
802         }\r
803         break;\r
804 \r
805       case choice_node:\r
806         {\r
807           switch (cur_style / 2)\r
808           {\r
809             case 0:\r
810               choose_mlist(display_mlist);\r
811               break;\r
812 \r
813             case 1:\r
814               choose_mlist(text_mlist);\r
815               break;\r
816 \r
817             case 2:\r
818               choose_mlist(script_mlist);\r
819               break;\r
820 \r
821             case 3:\r
822               choose_mlist(script_script_mlist);\r
823               break;\r
824           }\r
825 \r
826           flush_node_list(display_mlist(q));\r
827           flush_node_list(text_mlist(q));\r
828           flush_node_list(script_mlist(q));\r
829           flush_node_list(script_script_mlist(q));\r
830           type(q) = style_node;\r
831           subtype(q) = cur_style;\r
832           width(q) = 0;\r
833           depth(q) = 0;\r
834 \r
835           if (p != 0)\r
836           {\r
837             z = link(q);\r
838             link(q) = p;\r
839 \r
840             while (link(p) != 0)\r
841               p = link(p);\r
842 \r
843             link(p) = z;\r
844           }\r
845 \r
846           goto done_with_node;\r
847         }\r
848         break;\r
849 \r
850       case ins_node:\r
851       case mark_node:\r
852       case adjust_node:\r
853       case whatsit_node:\r
854       case penalty_node:\r
855       case disc_node:\r
856         goto done_with_node;\r
857         break;\r
858 \r
859       case rule_node:\r
860         {\r
861           if (height(q) > max_h)\r
862             max_h = height(q);\r
863 \r
864           if (depth(q) > max_d)\r
865             max_d = depth(q);\r
866 \r
867           goto done_with_node;\r
868         }\r
869         break;\r
870 \r
871       case glue_node:\r
872         {\r
873           if (subtype(q) == mu_glue)\r
874           {\r
875             x = glue_ptr(q);\r
876             y = math_glue(x, cur_mu);\r
877             delete_glue_ref(x);\r
878             glue_ptr(q) = y;\r
879             subtype(q) = normal;\r
880           }\r
881           else if ((cur_size != text_size) && (subtype(q) == cond_math_glue))\r
882           {\r
883             p = link(q);\r
884 \r
885             if (p != 0)\r
886               if ((type(q) == glue_node) || (type(p) == kern_node))\r
887               {\r
888                 link(q) = link(p);\r
889                 link(p) = 0;\r
890                 flush_node_list(p);\r
891               }\r
892           }\r
893 \r
894           goto done_with_node;\r
895         }\r
896         break;\r
897 \r
898       case kern_node:\r
899         {\r
900           math_kern(q, cur_mu);\r
901           goto done_with_node;\r
902         }\r
903         break;\r
904 \r
905       default:\r
906         {\r
907           confusion("mlist1");\r
908           return;\r
909         }\r
910         break;\r
911     }\r
912 \r
913     switch (math_type(nucleus(q)))\r
914     {\r
915       case math_char:\r
916       case math_text_char:\r
917         {\r
918           fetch(nucleus(q));\r
919 \r
920           if (char_exists(cur_i))\r
921           {\r
922             delta = char_italic(cur_f, cur_i);\r
923             p = new_character(cur_f, cur_c);\r
924 \r
925             if ((math_type(nucleus(q)) == math_text_char) && (space(cur_f) != 0))\r
926               delta = 0;\r
927 \r
928             if ((math_type(subscr(q)) == 0) && (delta != 0))\r
929             {\r
930               link(p) = new_kern(delta);\r
931               delta = 0;\r
932             }\r
933           }\r
934           else\r
935             p = 0;\r
936         }\r
937         break;\r
938 \r
939       case 0:\r
940         p = 0;\r
941         break;\r
942 \r
943       case sub_box:\r
944         p = info(nucleus(q));\r
945         break;\r
946 \r
947       case sub_mlist:\r
948         {\r
949           cur_mlist = info(nucleus(q));\r
950           save_style = cur_style;\r
951           mlist_penalties = false;\r
952           mlist_to_hlist();\r
953           cur_style = save_style;\r
954 \r
955           {\r
956             if (cur_style < script_style)\r
957               cur_size = text_size;\r
958             else\r
959               cur_size = 16 * ((cur_style - text_style) / 2);\r
960 \r
961             cur_mu = x_over_n(math_quad(cur_size), 18);\r
962           }\r
963 \r
964           p = hpack(link(temp_head), 0, 1);\r
965         }\r
966         break;\r
967 \r
968       default:\r
969         {\r
970           confusion("mlist2");\r
971           return;\r
972         }\r
973         break;\r
974     }\r
975   \r
976     new_hlist(q) = p;\r
977 \r
978     if ((math_type(subscr(q)) == 0) && (math_type(supscr(q)) == 0))\r
979       goto check_dimensions;\r
980 \r
981     make_scripts(q, delta);\r
982 \r
983 check_dimensions:\r
984     z = hpack(new_hlist(q), 0, 1);\r
985 \r
986     if (height(z) > max_h)\r
987       max_h = height(z);\r
988 \r
989     if (depth(z) > max_d)\r
990       max_d = depth(z);\r
991 \r
992     free_node(z, box_node_size);\r
993 \r
994 done_with_noad:\r
995     r = q;\r
996     r_type = type(r);\r
997 \r
998 done_with_node:\r
999     q = link(q);\r
1000   }\r
1001 \r
1002   if (r_type == bin_noad)\r
1003     type(r) = ord_noad;\r
1004 \r
1005   p = temp_head;\r
1006   link(p) = 0;\r
1007   q = mlist;\r
1008   r_type = 0;\r
1009   cur_style = style;\r
1010 \r
1011   {\r
1012     if (cur_style < script_style)\r
1013       cur_size = text_size;\r
1014     else\r
1015       cur_size = 16 *((cur_style - text_style) / 2);\r
1016 \r
1017     cur_mu = x_over_n(math_quad(cur_size), 18);\r
1018   }\r
1019 \r
1020   while (q != 0)\r
1021   {\r
1022     t = ord_noad;\r
1023     s = noad_size;\r
1024     pen = inf_penalty;\r
1025 \r
1026     switch (type(q))\r
1027     {\r
1028       case op_noad:\r
1029       case open_noad:\r
1030       case close_noad:\r
1031       case punct_noad:\r
1032       case inner_noad:\r
1033         t = type(q);\r
1034         break;\r
1035 \r
1036       case bin_noad:\r
1037         {\r
1038           t = bin_noad;\r
1039           pen = bin_op_penalty;\r
1040         }\r
1041         break;\r
1042 \r
1043       case rel_noad:\r
1044         {\r
1045           t = rel_noad;\r
1046           pen = rel_penalty;\r
1047         }\r
1048         break;\r
1049 \r
1050       case ord_noad:\r
1051       case vcenter_noad:\r
1052       case over_noad:\r
1053       case under_noad:\r
1054         do_nothing();\r
1055         break;\r
1056 \r
1057       case radical_noad:\r
1058         s = radical_noad_size;\r
1059         break;\r
1060 \r
1061       case accent_noad:\r
1062         s = accent_noad_size;\r
1063         break;\r
1064 \r
1065       case fraction_noad:\r
1066         {\r
1067           t = inner_noad;\r
1068           s = fraction_noad_size;\r
1069         }\r
1070         break;\r
1071 \r
1072       case left_noad:\r
1073       case right_noad:\r
1074         t = make_left_right(q, style, max_d, max_h);\r
1075         break;\r
1076 \r
1077       case style_node:\r
1078         {\r
1079           cur_style = subtype(q);\r
1080           s = style_node_size;\r
1081 \r
1082           {\r
1083             if (cur_style < script_style)\r
1084               cur_size = text_size;\r
1085             else\r
1086               cur_size = 16 *((cur_style - text_style) / 2);\r
1087 \r
1088             cur_mu = x_over_n(math_quad(cur_size), 18);\r
1089           }\r
1090 \r
1091           goto delete_q;\r
1092         }\r
1093         break;\r
1094 \r
1095       case whatsit_node:\r
1096       case penalty_node:\r
1097       case rule_node:\r
1098       case disc_node:\r
1099       case adjust_node:\r
1100       case ins_node:\r
1101       case mark_node:\r
1102       case glue_node:\r
1103       case kern_node:\r
1104         {\r
1105           link(p) = q;\r
1106           p = q;\r
1107           q = link(q);\r
1108           link(p) = 0;\r
1109           goto done;\r
1110         }\r
1111         break;\r
1112 \r
1113       default:\r
1114         {\r
1115           confusion("mlist3");\r
1116           return;\r
1117         }\r
1118         break;\r
1119     }\r
1120 \r
1121     if (r_type > 0)\r
1122     {\r
1123       switch (str_pool[r_type * 8 + t + magic_offset])\r
1124       {\r
1125         case '0':\r
1126           x = 0;\r
1127           break;\r
1128 \r
1129         case '1':\r
1130           if (cur_style < script_style)\r
1131             x = thin_mu_skip_code;\r
1132           else\r
1133             x = 0;\r
1134           break;\r
1135 \r
1136         case '2':\r
1137           x = thin_mu_skip_code;\r
1138           break;\r
1139 \r
1140         case '3':\r
1141           if (cur_style < script_style)\r
1142             x = med_mu_skip_code;\r
1143           else\r
1144             x = 0;\r
1145           break;\r
1146 \r
1147         case '4':\r
1148           if (cur_style < script_style)\r
1149             x = thick_mu_skip_code;\r
1150           else\r
1151             x = 0;\r
1152           break;\r
1153 \r
1154         default:\r
1155           {\r
1156             confusion("mlist4");\r
1157             return;\r
1158           }\r
1159           break;\r
1160       }\r
1161 \r
1162       if (x != 0)\r
1163       {\r
1164         y = math_glue(glue_par(x), cur_mu);\r
1165         z = new_glue(y);\r
1166         glue_ref_count(y) = 0;\r
1167         link(p) = z;\r
1168         p = z;\r
1169         subtype(z) = x + 1;\r
1170       }\r
1171     }\r
1172 \r
1173     if (new_hlist(q) != 0)\r
1174     {\r
1175       link(p) = new_hlist(q);\r
1176 \r
1177       do\r
1178         {\r
1179           p = link(p);\r
1180         }\r
1181       while (!(link(p) == 0));\r
1182     }\r
1183 \r
1184     if (penalties)\r
1185       if (link(q) != 0)\r
1186         if (pen < inf_penalty)\r
1187         {\r
1188           r_type = type(link(q));\r
1189 \r
1190           if (r_type != penalty_node)\r
1191             if (r_type != rel_noad)\r
1192             {\r
1193               z = new_penalty(pen);\r
1194               link(p) = z;\r
1195               p = z;\r
1196             }\r
1197         }\r
1198 \r
1199     r_type = t;\r
1200 \r
1201 delete_q:\r
1202     r = q;\r
1203     q = link(q);\r
1204     free_node(r, s);\r
1205 done:;\r
1206   }\r
1207 }\r
1208 /* sec 0772 */\r
1209 void push_alignment (void)\r
1210 {\r
1211   pointer p;\r
1212 \r
1213   p = get_node(align_stack_node_size);\r
1214   link(p) = align_ptr;\r
1215   info(p) = cur_align;\r
1216   llink(p) = preamble;\r
1217   rlink(p) = cur_span;\r
1218   mem[p + 2].cint = cur_loop;\r
1219   mem[p + 3].cint = align_state;\r
1220   info(p + 4) = cur_head;\r
1221   link(p + 4) = cur_tail;\r
1222   align_ptr = p;\r
1223   cur_head = get_avail();\r
1224 }\r
1225 /* sec 0772 */\r
1226 void pop_alignment (void)\r
1227 {\r
1228   pointer p;\r
1229 \r
1230   free_avail(cur_head);\r
1231   p = align_ptr;\r
1232   cur_tail = link(p + 4);\r
1233   cur_head = info(p + 4);\r
1234   align_state = mem[p + 3].cint;\r
1235   cur_loop = mem[p + 2].cint;\r
1236   cur_span = rlink(p);\r
1237   preamble = llink(p);\r
1238   cur_align = info(p);\r
1239   align_ptr = link(p);\r
1240   free_node(p, align_stack_node_size);\r
1241 }\r
1242 /* sec 0782 */\r
1243 void get_preamble_token (void)\r
1244 {\r
1245 restart:\r
1246   get_token();\r
1247 \r
1248   while ((cur_chr == span_code) && (cur_cmd == tab_mark))\r
1249   {\r
1250     get_token();\r
1251 \r
1252     if (cur_cmd > max_command)\r
1253     {\r
1254       expand();\r
1255       get_token();\r
1256     }\r
1257   }\r
1258 \r
1259   if (cur_cmd == endv)\r
1260   {\r
1261     fatal_error("(interwoven alignment preambles are not allowed)");\r
1262     return;\r
1263   }\r
1264 \r
1265   if ((cur_cmd == assign_glue) && (cur_chr == glue_base + tab_skip_code))\r
1266   {\r
1267     scan_optional_equals();\r
1268     scan_glue(glue_val);\r
1269 \r
1270     if (global_defs > 0)\r
1271       geq_define(glue_base + tab_skip_code, glue_ref, cur_val);\r
1272     else\r
1273       eq_define(glue_base + tab_skip_code, glue_ref, cur_val);\r
1274 \r
1275     goto restart;\r
1276   }\r
1277 }\r
1278 /* sec 0774 */\r
1279 void init_align (void)\r
1280 {\r
1281   pointer save_cs_ptr;\r
1282   pointer p;\r
1283 \r
1284   save_cs_ptr = cur_cs;\r
1285   push_alignment();\r
1286   align_state = -1000000L;\r
1287 \r
1288   if ((mode == mmode) && ((tail != head) || (incompleat_noad != 0)))\r
1289   {\r
1290     print_err("Improper ");\r
1291     print_esc("halign");\r
1292     prints(" inside $$'s");\r
1293     help3("Displays can use special alignments (like \\eqalignno)",\r
1294         "only if nothing but the alignment itself is between $$'s.",\r
1295         "So I've deleted the formulas that preceded this alignment.");\r
1296     error();\r
1297     flush_math();\r
1298   }\r
1299 \r
1300   push_nest();\r
1301 \r
1302   if (mode == mmode)\r
1303   {\r
1304     mode = -vmode;\r
1305     prev_depth = nest[nest_ptr - 2].aux_field.cint;\r
1306   }\r
1307   else if (mode > 0)\r
1308     mode = - (integer) mode;\r
1309 \r
1310   scan_spec(align_group, false);\r
1311   preamble = 0;\r
1312   cur_align = align_head;\r
1313   cur_loop = 0;\r
1314   scanner_status = aligning;\r
1315   warning_index = save_cs_ptr;\r
1316   align_state = -1000000L;\r
1317 \r
1318   while (true)\r
1319   {\r
1320     link(cur_align) = new_param_glue(tab_skip_code);\r
1321     cur_align = link(cur_align);\r
1322 \r
1323     if (cur_cmd == car_ret)\r
1324       goto done;\r
1325 \r
1326     p = hold_head;\r
1327     link(p) = 0;\r
1328 \r
1329     while (true)\r
1330     {\r
1331       get_preamble_token();\r
1332 \r
1333       if (cur_cmd == mac_param)\r
1334         goto done1;\r
1335 \r
1336       if ((cur_cmd <= car_ret) && (cur_cmd >= tab_mark) && (align_state == -1000000L))\r
1337         if ((p == hold_head) && (cur_loop == 0) && (cur_cmd == tab_mark))\r
1338           cur_loop = cur_align;\r
1339         else\r
1340         {\r
1341           print_err("Missing # inserted in alignment preamble");\r
1342           help3("There should be exactly one # between &'s, when an",\r
1343               "\\halign or \\valign is being set up. In this case you had",\r
1344               "none, so I've put one in; maybe that will work.");\r
1345           back_error();\r
1346           goto done1;\r
1347         }\r
1348       else if ((cur_cmd != spacer) || (p != hold_head))\r
1349       {\r
1350         link(p) = get_avail();\r
1351         p = link(p);\r
1352         info(p) = cur_tok;\r
1353       }\r
1354     }\r
1355 \r
1356 done1:\r
1357     link(cur_align) = new_null_box();\r
1358     cur_align = link(cur_align);\r
1359     info(cur_align) = end_span;\r
1360     width(cur_align) = null_flag;\r
1361     u_part(cur_align) = link(hold_head);\r
1362     p = hold_head;\r
1363     link(p) = 0;\r
1364 \r
1365     while (true)\r
1366     {\r
1367 continu:\r
1368       get_preamble_token();\r
1369 \r
1370       if ((cur_cmd <= car_ret) && (cur_cmd >= tab_mark) && (align_state == -1000000L))\r
1371         goto done2;\r
1372 \r
1373       if (cur_cmd == mac_param)\r
1374       {\r
1375         print_err("Only one # is allowed per tab");\r
1376         help3("There should be exactly one # between &'s, when an",\r
1377             "\\halign or \\valign is being set up. In this case you had",\r
1378             "more than one, so I'm ignoring all but the first.");\r
1379         error();\r
1380         goto continu;\r
1381       }\r
1382 \r
1383       link(p) = get_avail();\r
1384       p = link(p);\r
1385       info(p) = cur_tok;\r
1386     }\r
1387 \r
1388 done2:\r
1389     link(p) = get_avail();\r
1390     p = link(p);\r
1391     info(p) = end_template_token;\r
1392     v_part(cur_align) = link(hold_head);\r
1393   }\r
1394 \r
1395 done:\r
1396   scanner_status = 0;\r
1397   new_save_level(align_group);\r
1398 \r
1399   if (every_cr != 0)\r
1400     begin_token_list(every_cr, every_cr_text);\r
1401 \r
1402   align_peek();\r
1403 }\r
1404 /* sec 0787 */\r
1405 void init_span (pointer p)\r
1406 {\r
1407   push_nest();\r
1408 \r
1409   if (mode == -hmode)\r
1410     space_factor = 1000;\r
1411   else\r
1412   {\r
1413     prev_depth = ignore_depth;\r
1414     normal_paragraph();\r
1415   }\r
1416 \r
1417   cur_span = p;\r
1418 }\r
1419 /* sec 0786 */\r
1420 void init_row (void)\r
1421 {\r
1422   push_nest();\r
1423 \r
1424   mode = (-hmode - vmode) - mode;\r
1425 \r
1426   if (mode == -hmode)\r
1427     space_factor = 0;\r
1428   else\r
1429     prev_depth = 0;\r
1430 \r
1431   tail_append(new_glue(glue_ptr(preamble)));\r
1432   subtype(tail) = tab_skip_code + 1;\r
1433   cur_align = link(preamble);\r
1434   cur_tail = cur_head;\r
1435   init_span(cur_align);\r
1436 }\r
1437 /* sec 0788 */\r
1438 void init_col (void)\r
1439 {\r
1440   extra_info(cur_align) = cur_cmd;\r
1441 \r
1442   if (cur_cmd == omit)\r
1443     align_state = 0;\r
1444   else\r
1445   {\r
1446     back_input();\r
1447     begin_token_list(u_part(cur_align), u_template);\r
1448   }\r
1449 }\r
1450 /* sec 0799 */\r
1451 void fin_row (void)\r
1452 {\r
1453   pointer p;\r
1454 \r
1455   if (mode == -hmode)\r
1456   {\r
1457     p = hpack(link(head), 0, 1);\r
1458     pop_nest();\r
1459     append_to_vlist(p);\r
1460 \r
1461     if (cur_head != cur_tail)\r
1462     {\r
1463       link(tail) = link(cur_head);\r
1464       tail = cur_tail;\r
1465     }\r
1466   }\r
1467   else\r
1468   {\r
1469     p = vpackage(link(head), 0, 1, max_dimen);\r
1470     pop_nest();\r
1471     link(tail) = p;\r
1472     tail = p;\r
1473     space_factor = 1000;\r
1474   }\r
1475 \r
1476   type(p) = unset_node;\r
1477   glue_stretch(p) = 0;\r
1478 \r
1479   if (every_cr != 0)\r
1480     begin_token_list(every_cr, every_cr_text);\r
1481 \r
1482   align_peek();\r
1483 }\r
1484 /* sec 0800 */\r
1485 void fin_align (void)\r
1486 {\r
1487   pointer p, q, r, s, u, v;\r
1488   scaled t, w;\r
1489   scaled o;\r
1490   halfword n;\r
1491   scaled rule_save;\r
1492   memory_word aux_save;\r
1493 \r
1494   if (cur_group != align_group)\r
1495   {\r
1496     confusion("align1");\r
1497     return;\r
1498   }\r
1499 \r
1500   unsave();\r
1501 \r
1502   if (cur_group != align_group)\r
1503   {\r
1504     confusion("align0");\r
1505     return;\r
1506   }\r
1507 \r
1508   unsave();\r
1509 \r
1510   if (nest[nest_ptr - 1].mode_field == mmode)\r
1511     o = display_indent;\r
1512   else\r
1513     o = 0;\r
1514 \r
1515   q = link(preamble);\r
1516 \r
1517   do\r
1518     {\r
1519       flush_list(u_part(q));\r
1520       flush_list(v_part(q));\r
1521       p = link(link(q));\r
1522 \r
1523       if (width(q) == null_flag)\r
1524       {\r
1525         width(q) = 0;\r
1526         r = link(q);\r
1527         s = glue_ptr(r);\r
1528 \r
1529         if (s != zero_glue)\r
1530         {\r
1531           add_glue_ref(zero_glue);\r
1532           delete_glue_ref(s);\r
1533           glue_ptr(c) = zero_glue;\r
1534         }\r
1535       }\r
1536 \r
1537       if (info(q) != end_span)\r
1538       {\r
1539         t = width(q) + width(glue_ptr(link(q)));\r
1540         r = info(q);\r
1541         s = end_span;\r
1542         info(s) = p;\r
1543         n = min_quarterword + 1;\r
1544 \r
1545         do\r
1546           {\r
1547             width(r) = width(r) - t;\r
1548             u = info(r);\r
1549 \r
1550             while (link(r) > n)\r
1551             {\r
1552               s = info(s);\r
1553               n = link(info(s)) + 1;\r
1554             }\r
1555 \r
1556             if (link(r) < n)\r
1557             {\r
1558               info(r) = info(s);\r
1559               info(s) = r;\r
1560               decr(link(r));\r
1561               s = r;\r
1562             }\r
1563             else\r
1564             {\r
1565               if (width(r) > width(info(s)))\r
1566                 width(info(s)) = width(r);\r
1567 \r
1568               free_node(r, span_node_size);\r
1569             }\r
1570 \r
1571             r = u;\r
1572           }\r
1573         while (!(r == end_span));\r
1574       }\r
1575 \r
1576       type(q) = unset_node;\r
1577       span_count(q) = min_quarterword;\r
1578       height(q) = 0;\r
1579       depth(q) = 0;\r
1580       glue_order(q) = normal;\r
1581       glue_sign(q) = normal;\r
1582       glue_stretch(q) = 0;\r
1583       glue_shrink(q) = 0;\r
1584       q = p;\r
1585     }\r
1586   while (!(q == 0));\r
1587 \r
1588   save_ptr = save_ptr - 2;\r
1589   pack_begin_line = - (integer) mode_line;\r
1590 \r
1591   if (mode == -vmode)\r
1592   {\r
1593     rule_save = overfull_rule;\r
1594     overfull_rule = 0;\r
1595     p = hpack(preamble, saved(1), saved(0));\r
1596     overfull_rule = rule_save;\r
1597   }\r
1598   else\r
1599   {\r
1600     q = link(preamble);\r
1601 \r
1602     do\r
1603       {\r
1604         height(q) = width(q);\r
1605         width(q) = 0;\r
1606         q = link(link(q));\r
1607       }\r
1608     while (!(q == 0));\r
1609 \r
1610     p = vpackage(preamble, saved(1), saved(0), max_dimen);\r
1611     q = link(preamble);\r
1612 \r
1613     do\r
1614       {\r
1615         width(q) = height(q);\r
1616         height(q) = 0;\r
1617         q = link(link(q));\r
1618       }\r
1619     while (!(q == 0));\r
1620   }\r
1621 \r
1622   pack_begin_line = 0;\r
1623   q = link(head);\r
1624   s = head;\r
1625 \r
1626   while (q != 0)\r
1627   {\r
1628     if (!is_char_node(q))\r
1629       if (type(q) == unset_node)\r
1630       {\r
1631         if (mode == -vmode)\r
1632         {\r
1633           type(q) = hlist_node;\r
1634           width(q) = width(p);\r
1635         }\r
1636         else\r
1637         {\r
1638           type(q) = vlist_node;\r
1639           height(q) = height(p);\r
1640         }\r
1641 \r
1642         glue_order(q) = glue_order(p);\r
1643         glue_sign(q) = glue_sign(p);\r
1644         glue_set(q) = glue_set(p);\r
1645         shift_amount(q) = o;\r
1646         r = link(list_ptr(q));\r
1647         s = link(list_ptr(p));\r
1648 \r
1649         do\r
1650           {\r
1651             n = span_count(r);\r
1652             t = width(s);\r
1653             w = t;\r
1654             u = hold_head;\r
1655 \r
1656             while (n > min_quarterword)\r
1657             {\r
1658               decr(n);\r
1659               s = link(s);\r
1660               v = glue_ptr(s);\r
1661               link(u) = new_glue(v);\r
1662               u = link(u);\r
1663               subtype(u) = tab_skip_code + 1;\r
1664               t = t + width(v);\r
1665 \r
1666               if (glue_sign(p) == stretching)\r
1667               {\r
1668                 if (stretch_order(v) == glue_order(p))\r
1669                   t = t + round(glue_set(p) * stretch(v));\r
1670               }\r
1671               else if (glue_sign(p) == shrinking)\r
1672               {\r
1673                 if (shrink_order(v) == glue_order(p))\r
1674                   t = t - round(glue_set(p) * shrink(v));\r
1675               }\r
1676 \r
1677               s = link(s);\r
1678               link(u) = new_null_box();\r
1679               u = link(u);\r
1680               t = t + width(s);\r
1681 \r
1682               if (mode == -vmode)\r
1683                 width(u) = width(s);\r
1684               else\r
1685               {\r
1686                 type(u) = vlist_node;\r
1687                 height(u) = width(s);\r
1688               }\r
1689             }\r
1690             \r
1691 \r
1692             if (mode == -vmode)\r
1693             {\r
1694               height(r) = height(q);\r
1695               depth(r) = depth(q);\r
1696 \r
1697               if (t == width(r))\r
1698               {\r
1699                 glue_sign(r) = normal;\r
1700                 glue_order(r) = normal;\r
1701                 glue_set(r) = 0.0;\r
1702               }\r
1703               else if (t > width(r))\r
1704               {\r
1705                 glue_sign(r) = stretching;\r
1706 \r
1707                 if (glue_stretch(r) == 0)\r
1708                   glue_set(r) = 0.0;\r
1709                 else\r
1710                   glue_set(r) = (t - width(r)) / ((double) glue_stretch(r));\r
1711               }\r
1712               else\r
1713               {\r
1714                 glue_order(r) = glue_sign(r);\r
1715                 glue_sign(r) = shrinking;\r
1716 \r
1717                 if (glue_shrink(r) == 0)\r
1718                   glue_set(r) = 0.0;\r
1719                 else if ((glue_order(r) == normal) && (width(r) - t > glue_shrink(r)))\r
1720                   glue_set(r) = 1.0;\r
1721                 else\r
1722                   glue_set(r) = (width(r) - t)/ ((double) glue_shrink(r));\r
1723               }\r
1724 \r
1725               width(r) = w;\r
1726               type(r) = hlist_node;\r
1727             }\r
1728             else\r
1729             {\r
1730               width(r) = width(q);\r
1731 \r
1732               if (t == height(r))\r
1733               {\r
1734                 glue_sign(r) = normal;\r
1735                 glue_order(r) = normal;\r
1736                 glue_set(r) = 0.0;\r
1737               }\r
1738               else if (t > height(r))\r
1739               {\r
1740                 glue_sign(r) = stretching;\r
1741 \r
1742                 if (glue_stretch(r) == 0)\r
1743                   glue_set(r) = 0.0;\r
1744                 else\r
1745                   glue_set(r) = (t - height(r)) / ((double) glue_stretch(r));\r
1746               }\r
1747               else\r
1748               {\r
1749                 glue_order(r) = glue_sign(r);\r
1750                 glue_sign(r) = shrinking;\r
1751 \r
1752                 if (glue_shrink(r) == 0)\r
1753                   glue_set(r) = 0.0;\r
1754                 else if ((glue_order(r) == normal) && (height(r) - t > glue_shrink(r)))\r
1755                   glue_set(r) = 1.0;\r
1756                 else\r
1757                   glue_set(r) = (height(r) - t) / ((double) glue_shrink(r));\r
1758               }\r
1759 \r
1760               height(r) = w;\r
1761               type(r) = vlist_node;\r
1762             }\r
1763 \r
1764             shift_amount(r) = 0;\r
1765 \r
1766             if (u != hold_head)\r
1767             {\r
1768               link(u) = link(r);\r
1769               link(r) = link(hold_head);\r
1770               r = u;\r
1771             }\r
1772 \r
1773             r = link(link(r));\r
1774             s = link(link(s));\r
1775           }\r
1776         while (!(r == 0));\r
1777       }\r
1778       else if (type(q) == rule_node)\r
1779       {\r
1780         if (is_running(width(q)))\r
1781           width(q) = width(p);\r
1782 \r
1783         if (is_running(height(q)))\r
1784           height(q) = height(p);\r
1785 \r
1786         if (is_running(depth(q)))\r
1787           depth(q) = depth(p);\r
1788 \r
1789         if (o != 0)\r
1790         {\r
1791           r = link(q);\r
1792           link(q) = 0;\r
1793           q = hpack(q, 0, 1);\r
1794           shift_amount(q) = o;\r
1795           link(q) = r;\r
1796           link(s) = q;\r
1797         }\r
1798       }\r
1799     s = q;\r
1800     q = link(q);\r
1801   }\r
1802 \r
1803   flush_node_list(p);\r
1804   pop_alignment();\r
1805   aux_save = cur_list.aux_field;\r
1806   p = link(head);\r
1807   q = tail;\r
1808   pop_nest();\r
1809 \r
1810   if (mode == mmode)\r
1811   {\r
1812     do_assignments();\r
1813 \r
1814     if (cur_cmd != math_shift)\r
1815     {\r
1816       print_err("Missing $$ inserted");\r
1817       help2("Displays can use special alignments (like \\eqalignno)",\r
1818           "only if nothing but the alignment itself is between $$'s.");\r
1819       back_error();\r
1820     }\r
1821     else\r
1822     {\r
1823       get_x_token();\r
1824 \r
1825       if (cur_cmd != math_shift)\r
1826       {\r
1827         print_err("Display math should end with $$");\r
1828         help2("The `$' that I just saw supposedly matches a previous `$$'.",\r
1829             "So I shall assume that you typed `$$' both times.");\r
1830         back_error();\r
1831       }\r
1832     }\r
1833 \r
1834     pop_nest();\r
1835     tail_append(new_penalty(pre_display_penalty));\r
1836     tail_append(new_param_glue(above_display_skip_code));\r
1837     link(tail) = p;\r
1838 \r
1839     if (p != 0)\r
1840       tail = q;\r
1841 \r
1842     tail_append(new_penalty(post_display_penalty));\r
1843     tail_append(new_param_glue(below_display_skip_code));\r
1844     prev_depth = aux_save.cint;\r
1845     resume_after_display();\r
1846   }\r
1847   else\r
1848   {\r
1849     cur_list.aux_field = aux_save;\r
1850     link(tail) = p;\r
1851 \r
1852     if (p != 0)\r
1853       tail = q;\r
1854 \r
1855     if (mode == vmode)\r
1856       build_page();\r
1857   }\r
1858 }\r
1859 /* sec 0791 */\r
1860 boolean fin_col (void)\r
1861 {\r
1862   pointer p;\r
1863   pointer q, r;\r
1864   pointer s;\r
1865   pointer u;\r
1866   scaled w;\r
1867   glue_ord o;\r
1868   halfword n;\r
1869 \r
1870   if (cur_align == 0)\r
1871   {\r
1872     confusion("endv");\r
1873     return 0;\r
1874   }\r
1875 \r
1876   q = link(cur_align);\r
1877 \r
1878   if (q == 0)\r
1879   {\r
1880     confusion("endv");\r
1881     return 0;\r
1882   }\r
1883 \r
1884   if (align_state < 500000L)\r
1885   {\r
1886     fatal_error("(interwoven alignment preambles are not allowed)");\r
1887     return 0;\r
1888   }\r
1889 \r
1890   p = link(q);\r
1891 \r
1892   if ((p == 0) && (extra_info(cur_align) < cr_code))\r
1893     if (cur_loop != 0)\r
1894     {\r
1895       link(q) = new_null_box();\r
1896       p = link(q);\r
1897       info(p) = end_span;\r
1898       width(p) = null_flag;\r
1899       cur_loop = link(cur_loop);\r
1900       q = hold_head;\r
1901       r = u_part(cur_loop);\r
1902 \r
1903       while (r != 0)\r
1904       {\r
1905         link(q) = get_avail();\r
1906         q = link(q);\r
1907         info(q) = info(r);\r
1908         r = link(r);\r
1909       }\r
1910 \r
1911       link(q) = 0;\r
1912       u_part(p) = link(hold_head);\r
1913       q = hold_head;\r
1914       r = v_part(cur_loop);\r
1915 \r
1916       while (r != 0)\r
1917       {\r
1918         link(q) = get_avail();\r
1919         q = link(q);\r
1920         info(q) = info(r);\r
1921         r = link(r);\r
1922       }\r
1923 \r
1924       link(q) = 0;\r
1925       v_part(p) = link(hold_head);\r
1926       cur_loop = link(cur_loop);\r
1927       link(p) = new_glue(glue_ptr(cur_loop));\r
1928     }\r
1929     else\r
1930     {\r
1931       print_err("Extra alignment tab has been changed to ");\r
1932       print_esc("cr");\r
1933       help3("You have given more \\span or & marks than there were",\r
1934           "in the preamble to the \\halign or \\valign now in progress.",\r
1935           "So I'll assume that you meant to type \\cr instead.");\r
1936       extra_info(cur_align) = cr_code;\r
1937       error();\r
1938     }\r
1939 \r
1940   if (extra_info(cur_align) != span_code)\r
1941   {\r
1942     unsave();\r
1943     new_save_level(align_group);\r
1944 \r
1945     {\r
1946       if (mode == -hmode)\r
1947       {\r
1948         adjust_tail = cur_tail;\r
1949         u = hpack(link(head), 0, 1);\r
1950         w = width(u);\r
1951         cur_tail = adjust_tail;\r
1952         adjust_tail = 0;\r
1953       }\r
1954       else\r
1955       {\r
1956         u = vpackage(link(head), 0, 1, 0);\r
1957         w = height(u);\r
1958       }\r
1959 \r
1960       n = min_quarterword;\r
1961 \r
1962       if (cur_span != cur_align)\r
1963       {\r
1964         q = cur_span;\r
1965 \r
1966         do\r
1967           {\r
1968             incr(n);\r
1969             q = link(link(q));\r
1970           }\r
1971         while (!(q == cur_align));\r
1972 \r
1973         if (n > max_quarterword)\r
1974         {\r
1975           confusion("256 spans");\r
1976           return 0;\r
1977         }\r
1978 \r
1979         q = cur_span;\r
1980 \r
1981         while (link(info(q)) < n)\r
1982           q = info(q);\r
1983 \r
1984         if (link(info(q)) > n)\r
1985         {\r
1986           s = get_node(span_node_size);\r
1987           info(s) = info(q);\r
1988           link(s) = n;\r
1989           info(q) = s;\r
1990           width(s) = w;\r
1991         }\r
1992         else if (width(info(q)) < w)\r
1993           width(info(q)) = w;\r
1994       }\r
1995       else if (w > width(cur_align))\r
1996         width(cur_align) = w;\r
1997 \r
1998       type(u) = unset_node;\r
1999       span_count(u) = n;\r
2000 \r
2001       if (total_stretch[filll] != 0)\r
2002         o = filll;\r
2003       else if (total_stretch[fill] != 0)\r
2004         o = fill;\r
2005       else if (total_stretch[fil] != 0)\r
2006         o = fil;\r
2007       else\r
2008         o = normal;\r
2009 \r
2010       glue_order(u) = o;\r
2011       glue_stretch(u) = total_stretch[o];\r
2012 \r
2013       if (total_shrink[filll] != 0)\r
2014         o = filll;\r
2015       else if (total_shrink[fill] != 0)\r
2016         o = fill;\r
2017       else if (total_shrink[fil] != 0)\r
2018         o = fil;\r
2019       else\r
2020         o = normal;\r
2021 \r
2022       glue_sign(u) = o;\r
2023       glue_shrink(u) = total_shrink[o];\r
2024       pop_nest();\r
2025       link(tail) = u;\r
2026       tail = u;\r
2027     }\r
2028 \r
2029     tail_append(new_glue(glue_ptr(link(cur_align))));\r
2030     subtype(tail) = tab_skip_code + 1;\r
2031 \r
2032     if (extra_info(cur_align) >= cr_code)\r
2033     {\r
2034       return true;\r
2035     }\r
2036 \r
2037     init_span(p);\r
2038   }\r
2039 \r
2040   align_state = 1000000L;\r
2041 \r
2042   do\r
2043     {\r
2044       get_x_token();\r
2045     }\r
2046   while (!(cur_cmd != spacer));\r
2047 \r
2048   cur_align = p;\r
2049   init_col();\r
2050 \r
2051   return false;\r
2052 }\r
2053 /* sec 0749 */\r
2054 scaled make_op (pointer q)\r
2055 {\r
2056   scaled delta;\r
2057   pointer p, v, x, y, z;\r
2058   quarterword c;\r
2059   four_quarters i;\r
2060   scaled shift_up, shift_down;\r
2061 \r
2062   if ((subtype(q) == normal) && (cur_style < text_style))\r
2063     subtype(q) = limits;\r
2064 \r
2065   if (math_type(nucleus(q)) == math_char)\r
2066   {\r
2067     fetch(nucleus(q));\r
2068 \r
2069     if ((cur_style < text_style) && (char_tag(cur_i) == list_tag))\r
2070     {\r
2071       c = rem_byte(cur_i);\r
2072       i = char_info(cur_f, c);\r
2073 \r
2074       if (char_exists(i))\r
2075       {\r
2076         cur_c = c;\r
2077         cur_i = i;\r
2078         character(nucleus(q)) = c;\r
2079       }\r
2080     }\r
2081 \r
2082     delta = char_italic(cur_f, cur_i);\r
2083     x = clean_box(nucleus(q), cur_style);\r
2084 \r
2085     if ((math_type(subscr(q)) != 0) && (subtype(q) != limits))\r
2086       width(x) = width(x) - delta;\r
2087 \r
2088     shift_amount(x) = half(height(x) - depth(x)) - axis_height(cur_size);\r
2089     math_type(nucleus(q)) = sub_box;\r
2090     info(nucleus(q)) = x;\r
2091   }\r
2092   else\r
2093     delta = 0;\r
2094 \r
2095   if (subtype(q) == limits)\r
2096   {\r
2097     x = clean_box(supscr(q), sup_style(cur_style));\r
2098     y = clean_box(nucleus(q), cur_style);\r
2099     z = clean_box(subscr(q), sub_style(cur_style));\r
2100     v = new_null_box();\r
2101     type(v) = vlist_node;\r
2102     width(v) = width(y);\r
2103 \r
2104     if (width(x) > width(v))\r
2105       width(v) = width(x);\r
2106 \r
2107     if (width(z) > width(v))\r
2108       width(v) = width(z);\r
2109 \r
2110     x = rebox(x, width(v));\r
2111     y = rebox(y, width(v));\r
2112     z = rebox(z, width(v));\r
2113     shift_amount(x) = half(delta);\r
2114     shift_amount(z) = - (integer) shift_amount(x);\r
2115     height(v) = height(y);\r
2116     depth(v) = depth(y);\r
2117 \r
2118     if (math_type(supscr(q)) == 0)\r
2119     {\r
2120       free_node(x, box_node_size);\r
2121       list_ptr(v) = y;\r
2122     }\r
2123     else\r
2124     {\r
2125       shift_up = big_op_spacing3 - depth(x);\r
2126 \r
2127       if (shift_up < big_op_spacing1)\r
2128         shift_up = big_op_spacing1;\r
2129 \r
2130       p = new_kern(shift_up);\r
2131       link(p) = y;\r
2132       link(x) = p;\r
2133       p = new_kern(big_op_spacing5);\r
2134       link(p) = x;\r
2135       list_ptr(v) = p;\r
2136       height(v) = height(v) + big_op_spacing5 + height(x) + depth(x) + shift_up;\r
2137     }\r
2138 \r
2139     if (math_type(subscr(q)) == 0)\r
2140       free_node(z, box_node_size);\r
2141     else\r
2142     {\r
2143       shift_down = big_op_spacing4 - height(z);\r
2144 \r
2145       if (shift_down < big_op_spacing2)\r
2146         shift_down = big_op_spacing2;\r
2147 \r
2148       p = new_kern(shift_down);\r
2149       link(y) = p;\r
2150       link(p) = z;\r
2151       p = new_kern(big_op_spacing5);\r
2152       link(z) = p;\r
2153       depth(v) = depth(v) + big_op_spacing5 + height(z) + depth(z) + shift_down;\r
2154     }\r
2155 \r
2156     new_hlist(q) = v;\r
2157   }\r
2158 \r
2159   return delta;\r
2160 }\r
2161 /* sec 0756 */\r
2162 void make_scripts (pointer q, scaled delta)\r
2163 {\r
2164   pointer p, x, y, z;\r
2165   scaled shift_up, shift_down, clr;\r
2166   small_number t;\r
2167 \r
2168   p = new_hlist(q);\r
2169 \r
2170   if (is_char_node(p))\r
2171   {\r
2172     shift_up = 0;\r
2173     shift_down = 0;\r
2174   }\r
2175   else\r
2176   {\r
2177     z = hpack(p, 0, 1);\r
2178 \r
2179     if (cur_style < script_style)\r
2180       t = script_size;\r
2181     else\r
2182       t = script_script_size;\r
2183 \r
2184     shift_up = height(z) - sup_drop(t);\r
2185     shift_down = depth(z) + sub_drop(t);\r
2186     free_node(z, box_node_size);\r
2187   }\r
2188 \r
2189   if (math_type(supscr(q)) == 0)\r
2190   {\r
2191     x = clean_box(subscr(q), sub_style(cur_style));\r
2192     width(x) = width(x) + script_space;\r
2193 \r
2194     if (shift_down < sub1(cur_size))\r
2195       shift_down = sub1(cur_size);\r
2196 \r
2197     clr = height(x) -(abs(math_x_height(cur_size) * 4) / 5);\r
2198 \r
2199     if (shift_down < clr)\r
2200       shift_down = clr;\r
2201 \r
2202     shift_amount(x) = shift_down;\r
2203   }\r
2204   else\r
2205   {\r
2206     {\r
2207       x = clean_box(supscr(q), sup_style(cur_style));\r
2208       width(x) = width(x) + script_space;\r
2209 \r
2210       if (odd(cur_style))\r
2211         clr = sup3(cur_size);\r
2212       else if (cur_style < text_style)\r
2213         clr = sup1(cur_size);\r
2214       else\r
2215         clr = sup2(cur_size);\r
2216 \r
2217       if (shift_up < clr)\r
2218         shift_up = clr;\r
2219 \r
2220       clr = depth(x) +(abs(math_x_height(cur_size)) / 4);\r
2221 \r
2222       if (shift_up < clr)\r
2223         shift_up = clr;\r
2224     }\r
2225 \r
2226     if (math_type(subscr(q)) == 0)\r
2227       shift_amount(x) = - (integer) shift_up;\r
2228     else\r
2229     {\r
2230       y = clean_box(subscr(q), sub_style(cur_style));\r
2231       width(y) = width(y) + script_space;\r
2232 \r
2233       if (shift_down < sub2(cur_size))\r
2234         shift_down = sub2(cur_size);\r
2235 \r
2236       clr = 4 * default_rule_thickness - ((shift_up - depth(x)) - (height(y) - shift_down));\r
2237 \r
2238       if (clr > 0)\r
2239       {\r
2240         shift_down = shift_down + clr;\r
2241 \r
2242         clr = (abs(math_x_height(cur_size) * 4) / 5) - (shift_up - depth(x));\r
2243 \r
2244         if (clr > 0)\r
2245         {\r
2246           shift_up = shift_up + clr;\r
2247           shift_down = shift_down - clr;\r
2248         }\r
2249       }\r
2250 \r
2251       shift_amount(x) = delta;\r
2252       p = new_kern((shift_up - depth(x)) - (height(y) - shift_down));\r
2253       link(x) = p;\r
2254       link(p) = y;\r
2255       x = vpackage(x, 0, 1, max_dimen);\r
2256       shift_amount(x) = shift_down;\r
2257     }\r
2258   }\r
2259 \r
2260   if (new_hlist(q) == 0)\r
2261     new_hlist(q) = x;\r
2262   else\r
2263   {\r
2264     p = new_hlist(q);\r
2265 \r
2266     while (link(p) != 0)\r
2267       p = link(p);\r
2268 \r
2269     link(p) = x;\r
2270   }\r
2271 }