OSDN Git Service

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