1 /* Copyright 2014 Clerk Ma
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 void build_page (void)
29 /* unsigned char n; */
33 if ((link(contrib_head) == 0) || output_active)
39 p = link(contrib_head);
41 if (last_glue != max_halfword)
42 delete_glue_ref(last_glue);
47 if (type(p) == glue_node)
49 last_glue = glue_ptr(p);
50 add_glue_ref(last_glue);
54 last_glue = max_halfword;
56 if (type(p) == penalty_node)
57 last_penalty = penalty(p);
58 else if (type(p) == kern_node)
67 if (page_contents < box_there)
69 if (page_contents == 0)
70 freeze_page_specs(box_there);
72 page_contents = box_there;
74 q = new_skip_param(top_skip_code);
76 if (width(temp_ptr) > height(p))
77 width(temp_ptr) = width(temp_ptr) - height(p);
82 link(contrib_head) = q;
87 page_total = page_total + page_depth + height(p);
88 page_depth = depth(p);
98 if (page_contents < box_there)
100 else if (precedes_break(page_tail))
107 if (page_contents < box_there)
109 else if (link(p) == 0)
111 else if (type(link(p)) == glue_node)
118 if (page_contents < box_there)
130 if (page_contents == 0)
131 freeze_page_specs(inserts_only);
136 while (n >= subtype(link(r)))
143 q = get_node(page_ins_node_size);
154 height(r) = height(box(n)) + depth(box(n));
159 if (count(n) == 1000)
162 h = x_over_n(height(r), 1000) * count(n);
164 page_goal = page_goal - h - width(q);
165 page_so_far[2 + stretch_order(q)] = page_so_far[2 + stretch_order(q)] + stretch(q);
166 page_shrink = page_shrink + shrink(q);
168 if ((shrink_order(q) != normal) && (shrink(q) != 0))
170 print_err("Infinite glue shrinkage inserted from ");
173 help3("The correction glue for page breaking with insertions",
174 "must have finite shrinkability. But you may proceed,",
175 "since the offensive shrinkability has been made finite.");
180 if (type(r) == split_up)
181 insert_penalties = insert_penalties + float_cost(p);
185 delta = page_goal - page_total - page_depth + page_shrink;
187 if (count(n) == 1000)
190 h = x_over_n(height(p), 1000) * count(n);
192 if (((h <= 0) || (h <= delta)) && (height(p) + height(r) <= dimen(n)))
194 page_goal = page_goal - h;
195 height(r) = height(r) + height(p);
203 w = page_goal - page_total - page_depth;
205 if (count(n) != 1000)
206 w = x_over_n(w, count(n)) * 1000;
209 if (w > dimen(n) - height(r))
210 w = dimen(n) - height(r);
212 q = vert_break(ins_ptr(p), w, depth(p));
213 height(r) = height(r) + best_height_plus_depth;
216 if (tracing_pages > 0)
224 print_scaled(best_height_plus_depth);
228 print_int(eject_penalty);
229 else if (type(q) == penalty_node)
230 print_int(penalty(q));
234 end_diagnostic(false);
237 if (count(n) != 1000)
238 best_height_plus_depth = x_over_n(best_height_plus_depth, 1000) * count(n);
240 page_goal = page_goal - best_height_plus_depth;
246 insert_penalties = insert_penalties + (eject_penalty);
247 else if (type(q) == penalty_node)
248 insert_penalties = insert_penalties + penalty(q);
263 if (pi < inf_penalty)
265 if (page_total < page_goal)
266 if ((page_so_far[3] != 0) || (page_so_far[4] != 0) || (page_so_far[5] != 0))
269 b = badness(page_goal - page_total, page_so_far[2]);
270 else if (page_total - page_goal > page_shrink)
273 b = badness(page_total - page_goal, page_shrink);
276 if (pi <= eject_penalty)
278 else if (b < inf_bad)
279 c = b + pi + insert_penalties;
285 if (insert_penalties >= 10000)
289 if (tracing_pages > 0)
296 print_scaled(page_goal);
313 if (c <= least_page_cost)
316 end_diagnostic(false);
320 if (c <= least_page_cost)
323 best_size = page_goal;
325 r = link(page_ins_head);
327 while (r != page_ins_head)
329 best_ins_ptr(r) = last_ins_ptr(r);
334 if ((c == awful_bad) || (pi <= eject_penalty))
345 if ((type(p) < glue_node) || (type(p) > kern_node))
349 if (type(p) == kern_node)
354 page_so_far[2 + stretch_order(q)] = page_so_far[2 + stretch_order(q)] + stretch(q);
355 page_shrink = page_shrink + shrink(q);
357 if ((shrink_order(q) != normal) && (shrink(q) != 0))
359 print_err("Infinite glue shrinkage found on current page");
360 help4("The page about to be output contains some infinitely",
361 "shrinkable glue, e.g., `\\vss' or `\\vskip 0pt minus 1fil'.",
362 "Such glue doesn't belong there; but you can safely proceed,",
363 "since the offensive shrinkability has been made finite.");
366 shrink_order(r) = normal;
373 page_total = page_total + page_depth + width(q);
377 if (page_depth > page_max_depth)
379 page_total = page_total + page_depth - page_max_depth;
380 page_depth = page_max_depth;
385 link(contrib_head) = link(p);
390 link(contrib_head) = link(p);
395 while (!(link(contrib_head) == 0));
400 nest[0].tail_field = contrib_head;
403 void app_space (void)
407 if ((space_factor >= 2000) && (xspace_skip != zero_glue))
408 q = new_param_glue(xspace_skip_code);
411 if (space_skip != zero_glue)
415 main_p = font_glue[cur_font];
419 main_p = new_spec(zero_glue);
420 main_k = param_base[cur_font] + space_code;
421 width(main_p) = font_info[main_k].cint;
422 stretch(main_p) = font_info[main_k + 1].cint;
423 shrink(main_p) = font_info[main_k + 2].cint;
424 font_glue[cur_font] = main_p;
428 main_p = new_spec(main_p);
430 if (space_factor >= 2000)
431 width(main_p) = width(main_p) + extra_space(cur_font);
433 stretch(main_p) = xn_over_d(stretch(main_p), space_factor, 1000);
434 shrink(main_p) = xn_over_d(shrink(main_p), 1000, space_factor);
435 q = new_glue(main_p);
436 glue_ref_count(main_p) = 0;
443 void insert_dollar_sign (void)
446 cur_tok = math_shift_token + '$';
447 print_err("Missing $ inserted");
448 help2("I've inserted a begin-math/end-math symbol since I think",
449 "you left one out. Proceed, with fingers crossed.");
455 print_err("You can't use `");
456 print_cmd_chr(cur_cmd, cur_chr);
461 void report_illegal_case (void)
464 help4("Sorry, but I'm not programmed to handle this case;",
465 "I'll just pretend that you didn't ask for it.",
466 "If you're in the wrong mode, you might be able to",
467 "return to the right one by typing `I}' or `I$' or `I\\par'.");
471 boolean privileged (void)
477 report_illegal_case();
482 boolean its_all_over (void)
486 if ((page_head == page_tail) && (head == tail) && (dead_cycles == 0))
492 tail_append(new_null_box());
494 tail_append(new_glue(fill_glue));
495 tail_append(new_penalty(-1073741824L));
502 void append_glue (void)
523 cur_val = fil_neg_glue;
535 tail_append(new_glue(cur_val));
539 decr(glue_ref_count(cur_val));
542 subtype(tail) = mu_glue;
546 void append_kern (void)
552 scan_dimen((s == mu_glue), false, false);
553 tail_append(new_kern(cur_val));
561 if (cur_group == bottom_level)
564 print_cmd_chr(cur_cmd, cur_chr);
565 help1("Things are pretty mixed up, but I think the worst is over.");
573 print_err("Missing ");
577 case semi_simple_group:
579 info(p) = cs_token_flag + frozen_end_group;
580 print_esc("endgroup");
584 case math_shift_group:
586 info(p) = math_shift_token + '$';
591 case math_left_group:
593 info(p) = cs_token_flag + frozen_right;
594 link(p) = get_avail();
596 info(p) = other_token + '.';
603 info(p) = right_brace_token + '}';
610 ins_list(link(temp_head));
611 help5("I've inserted something that you may have forgotten.",
612 "(See the <inserted text> above.)",
613 "With luck, this will get me unwedged. But if you",
614 "really didn't forget anything, try typing `2' now; then",
615 "my insertion and my current dilemma will both disappear.");
620 void extra_right_brace (void)
622 print_err("Extra }, or forgotten ");
626 case semi_simple_group:
627 print_esc("endgroup");
630 case math_shift_group:
634 case math_left_group:
639 help5("I've deleted a group-closing symbol because it seems to be",
640 "spurious, as in `$x}$'. But perhaps the } is legitimate and",
641 "you forgot something else, as in `\\hbox{$x}'. In such cases",
642 "the way to recover is to insert both the forgotten and the",
643 "deleted material, e.g., by typing `I$}'.");
648 void normal_paragraph (void)
651 eq_word_define(int_base + looseness_code, 0);
653 if (hang_indent != 0)
654 eq_word_define(dimen_base + hang_indent_code, 0);
657 eq_word_define(int_base + hang_after_code, 1);
659 if (par_shape_ptr != 0)
660 eq_define(par_shape_loc, shape_ref, 0);
663 void box_end (integer box_context)
667 if (box_context < box_flag)
671 shift_amount(cur_box) = box_context;
673 if (abs(mode) == vmode)
675 append_to_vlist(cur_box);
677 if (adjust_tail != 0)
679 if (adjust_head != adjust_tail)
681 link(tail) = link(adjust_head);
693 if (abs(mode) == hmode)
698 math_type(nucleus(p)) = sub_box;
699 info(nucleus(p)) = cur_box;
703 link(tail) = cur_box;
708 else if (box_context < ship_out_flag)
709 if (box_context < (box_flag + 256))
710 eq_define((box_base - box_flag) + box_context, box_ref, cur_box);
712 geq_define((box_base - box_flag - 256) + box_context, box_ref, cur_box);
713 else if (cur_box != 0)
714 if (box_context > ship_out_flag)
720 while (!((cur_cmd != spacer) && (cur_cmd != relax)));
722 if (((cur_cmd == hskip) && (abs(mode) != vmode)) || ((cur_cmd == vskip) && (abs(mode) == vmode)))
725 subtype(tail) = box_context - (leader_flag - a_leaders);
726 leader_ptr(tail) = cur_box;
730 print_err("Leaders not followed by proper glue");
731 help3("You should say `\\leaders <box or rule><hskip or vskip>'.",
732 "I found the <box or rule>, but there's no suitable",
733 "<hskip or vskip>, so I'm ignoring these leaders.");
735 flush_node_list(cur_box);
742 void begin_box (integer box_context)
753 scan_eight_bit_int();
754 cur_box = box(cur_val);
761 scan_eight_bit_int();
762 cur_box = copy_node_list(box(cur_val));
770 if (abs(mode) == mmode)
773 help1("Sorry; this \\lastbox will be void.");
776 else if ((mode == vmode) && (head == cur_list.tail_field))
779 help2("Sorry...I usually can't take things from the current page.",
780 "This \\lastbox will therefore be void.");
785 if (!is_char_node(tail))
786 if ((type(tail) == hlist_node) || (type(tail) == vlist_node))
794 if (!is_char_node(q))
795 if (type(q) == disc_node)
797 for (m = 1; m <= replace_count(q); m++)
806 while (!(q == tail));
809 shift_amount(cur_box) = 0;
820 scan_eight_bit_int();
823 if (!scan_keyword("to"))
825 print_err("Missing `to' inserted");
826 help2("I'm working on `\\vsplit<box number> to <dimen>';",
827 "will look for the <dimen> next.");
831 scan_dimen(false, false, false);
832 cur_box = vsplit(n, cur_val);
838 k = cur_chr - vtop_code;
839 saved(0) = box_context;
842 if ((box_context < box_flag) && (abs(mode) == vmode))
843 scan_spec(adjust_hbox_group, true);
845 scan_spec(hbox_group, true);
849 scan_spec(vbox_group, true);
852 scan_spec(vtop_group, true);
860 mode = - (integer) k;
864 prev_depth = ignore_depth;
867 begin_token_list(every_vbox, every_vbox_text);
874 begin_token_list(every_hbox, every_vbox_text);
882 box_end(box_context);
885 void scan_box_(integer box_context)
891 while (!((cur_cmd != spacer) && (cur_cmd != relax)));
893 if (cur_cmd == make_box)
895 begin_box(box_context);
897 else if ((box_context >= leader_flag) && ((cur_cmd == hrule) || (cur_cmd == vrule)))
899 cur_box = scan_rule_spec();
900 box_end(box_context);
904 print_err("A <box> was supposed to be here");
905 help3("I was expecting to see \\hbox or \\vbox or \\copy or \\box or",
906 "something like that. So you might find something missing in",
907 "your output. But keep trying; you can fix this later.");
912 small_number norm_min_ (integer h)
922 void new_graf (boolean indented)
926 if ((mode == vmode) || (head != tail))
927 tail_append(new_param_glue(par_skip_code));
934 prev_graf = (norm_min(left_hyphen_min) * 64 + norm_min(right_hyphen_min)) * 65536L + cur_lang;
938 tail = new_null_box();
940 width(tail) = par_indent;
944 begin_token_list(every_par, every_par_text);
950 void indent_in_hmode (void)
957 width(p) = par_indent;
959 if (abs(mode) == hmode)
964 math_type(nucleus(q)) = sub_box;
965 info(nucleus(q)) = p;
973 void head_for_vmode (void)
977 if (cur_cmd != hrule)
981 print_err("You can't use `");
983 prints("' here except with leaders");
984 help2("To put a horizontal rule in an hbox or an alignment,",
985 "you should use \\leaders or \\hrulefill (see The TeXbook).");
1005 line_break(widow_penalty);
1012 void begin_insert_or_adjust (void)
1014 if (cur_cmd == vadjust)
1018 scan_eight_bit_int();
1022 print_err("You can't ");
1023 print_esc("insert");
1025 help1("I'm changing to \\insert0; box 255 is special.");
1033 new_save_level(insert_group);
1038 prev_depth = ignore_depth;
1041 void make_mark (void)
1045 p = scan_toks(false, true);
1046 p = get_node(small_node_size);
1047 type(p) = mark_node;
1049 mark_ptr(p) = def_ref;
1054 void append_penalty (void)
1057 tail_append(new_penalty(cur_val));
1063 void delete_last (void)
1068 if ((mode == vmode) && (tail == head))
1070 if ((cur_chr != glue_node) || (last_glue != max_halfword))
1073 help2("Sorry...I usually can't take things from the current page.",
1074 "Try `I\\vskip-\\lastskip' instead.");
1076 if (cur_chr == kern_node)
1077 help_line[0] = "Try `I\\kern-\\last_kern' instead.";
1078 else if (cur_chr != glue_node)
1079 help_line[0] = "Perhaps you can make the output routine do it.";
1085 if (!is_char_node(tail))
1086 if (type(tail) == cur_chr)
1094 if (!is_char_node(q))
1095 if (type(q) == disc_node)
1097 for (m = 1; m <= replace_count(q); m++)
1106 while (!(q == tail));
1109 flush_node_list(tail);
1115 void unpackage (void)
1121 scan_eight_bit_int();
1127 if ((abs(mode) == mmode) || ((abs(mode) == vmode) && (type(p) != vlist_node)) ||
1128 ((abs(mode) == hmode) && (type(p) != hlist_node)))
1130 print_err("Incompatible list can't be unboxed");
1131 help3("Sorry, Pandora. (You sneaky devil.)",
1132 "I refuse to unbox an \\hbox in vertical mode or vice versa.",
1133 "And I can't open any boxes in math mode.");
1139 link(tail) = copy_node_list(list_ptr(p));
1142 link(tail) = list_ptr(p);
1144 free_node(p, box_node_size);
1147 while (link(tail) != 0)
1151 void append_italic_correction (void)
1154 internal_font_number f;
1158 if (is_char_node(tail))
1160 else if (type(tail) == ligature_node)
1166 tail_append(new_kern(char_italic(f, char_info(f, character(p)))));
1167 subtype(tail) = explicit;
1171 void append_discretionary (void)
1175 tail_append(new_disc());
1179 c = hyphen_char[cur_font];
1183 pre_break(tail) = new_character(cur_font, c);
1189 new_save_level(disc_group);
1193 space_factor = 1000;
1197 void build_discretionary (void)
1209 if (!is_char_node(p))
1210 if (type(p) > rule_node)
1211 if (type(p) != kern_node)
1212 if (type(p) != ligature_node)
1214 print_err("Improper discretionary list");
1215 help1("Discretionary lists must contain only boxes and kerns.");
1218 print_nl("The following discretionary sublist has been deleted:");
1220 end_diagnostic(true);
1238 pre_break(tail) = p;
1242 post_break(tail) = p;
1247 if ((n > 0) && (abs(mode) == mmode))
1249 print_err("Illegal math ");
1250 print_esc("discretionary");
1251 help2("Sorry: The third part of a discretionary break must be",
1252 "empty, in math formulas. I had to delete your third part.");
1260 if (n <= max_quarterword)
1261 replace_count(tail) = n;
1264 print_err("Discretionary list is too long");
1265 help2("Wow---I never thought anybody would tweak me here.",
1266 "You can't seriously need such a huge discretionary list?");
1280 new_save_level(disc_group);
1284 space_factor = 1000;
1287 void make_accent (void)
1291 internal_font_number f;
1292 scaled a, h, x, w, delta;
1297 p = new_character(f, cur_val);
1302 s = slant(f) / ((double) 65536.0);
1303 a = char_width(f, char_info(f, character(p)));
1308 if ((cur_cmd == letter) || (cur_cmd == other_char) || (cur_cmd == char_given))
1309 q = new_character(f, cur_chr);
1310 else if (cur_cmd == char_num)
1313 q = new_character(f, cur_val);
1320 t = slant(f) / ((double) 65536.0);
1321 i = char_info(f, character(q));
1322 w = char_width(f, i);
1323 h = char_height(f, height_depth(i));
1328 shift_amount(p) = x - h;
1331 delta = round((w - a) / ((double) 2.0) + h * t - x * s);
1332 r = new_kern(delta);
1333 subtype(r) = acc_kern;
1336 tail = new_kern(- (integer) a - delta);
1337 subtype(tail) = acc_kern;
1344 space_factor = 1000;
1348 void align_error (void)
1350 if (abs(align_state) > 2)
1352 print_err("Misplaced ");
1353 print_cmd_chr(cur_cmd, cur_chr);
1355 if (cur_tok == tab_token + '&')
1357 help6("I can't figure out why you would want to use a tab mark",
1358 "here. If you just want an ampersand, the remedy is",
1359 "simple: Just type `I\\&' now. But if some right brace",
1360 "up above has ended a previous alignment prematurely,",
1361 "you're probably due for more error messages, and you",
1362 "might try typing `S' now just to see what is salvageable.");
1366 help5("I can't figure out why you would want to use a tab mark",
1367 "or \\cr or \\span just now. If something like a right brace",
1368 "up above has ended a previous alignment prematurely,",
1369 "you're probably due for more error messages, and you",
1370 "might try typing `S' now just to see what is salvageable.");
1379 if (align_state < 0)
1381 print_err("Missing { inserted");
1383 cur_tok = left_brace_token + '{';
1387 print_err("Missing } inserted");
1389 cur_tok = right_brace_token + '}';
1392 help3("I've put in what seems to be necessary to fix",
1393 "the current column of the current alignment.",
1394 "Try to go on, since this might almost work.");
1399 void noalign_error (void)
1401 print_err("Misplaced ");
1402 print_esc("noalign");
1403 help2("I expect to see \\noalign only after the \\cr of",
1404 "an alignment. Proceed, and I'll ignore this case.");
1408 void omit_error (void)
1410 print_err("Misplaced ");
1412 help2("I expect to see \\omit only after tab marks or the \\cr of",
1413 "an alignment. Proceed, and I'll ignore this case.");
1419 base_ptr = input_ptr;
1420 input_stack[base_ptr] = cur_input;
1422 while ((input_stack[base_ptr].index_field != v_template) &&
1423 (input_stack[base_ptr].loc_field == 0) &&
1424 (input_stack[base_ptr].state_field == token_list))
1427 if ((input_stack[base_ptr].index_field != v_template) ||
1428 (input_stack[base_ptr].loc_field != 0) ||
1429 (input_stack[base_ptr].state_field != token_list))
1430 fatal_error("(interwoven alignment preambles are not allowed)");
1432 if (cur_group == align_group)
1443 void cs_error (void)
1445 print_err("Extra ");
1446 print_esc("endcsname");
1447 help1("I'm ignoring this, since I wasn't doing a \\csname.");
1451 void push_math_(group_code c)
1455 incompleat_noad = 0;
1459 void init_math (void)
1466 internal_font_number f;
1473 if ((cur_cmd == math_shift) && (mode > 0))
1482 line_break(display_widow_penalty);
1483 v = shift_amount(just_box) + 2 * quad(cur_font);
1485 p = list_ptr(just_box);
1490 if (is_char_node(p))
1493 d = char_width(f, char_info(f, character(p)));
1510 mem[lig_trick] = mem[lig_char(p)];
1511 link(lig_trick) = link(p);
1527 if (glue_sign(just_box) == stretching)
1529 if ((glue_order(just_box) == stretch_order(q)) && (stretch(q) != 0))
1532 else if (glue_sign(just_box) == shrinking)
1534 if ((glue_order(just_box) == shrink_order(q)) && (shrink(q) != 0))
1538 if (subtype(p) >= a_leaders)
1575 if (par_shape_ptr == 0)
1576 if ((hang_indent != 0) && (((hang_after >= 0) &&
1577 (prev_graf + 2 > hang_after)) || (prev_graf + 1 < - (integer) hang_after)))
1579 l = hsize - abs(hang_indent);
1581 if (hang_indent > 0)
1593 n = info(par_shape_ptr);
1595 if (prev_graf + 2 >= n)
1596 p = par_shape_ptr + 2 * n;
1598 p = par_shape_ptr + 2 *(prev_graf + 2);
1600 s = mem[p - 1].cint;
1604 push_math(math_shift_group);
1606 eq_word_define(int_base + cur_fam_code, -1);
1607 eq_word_define(dimen_base + pre_display_size_code, w);
1608 eq_word_define(dimen_base + display_width_code, l);
1609 eq_word_define(dimen_base + display_indent_code, s);
1611 if (every_display != 0)
1612 begin_token_list(every_display, every_display_text);
1624 push_math(math_shift_group);
1625 eq_word_define(int_base + cur_fam_code, -1);
1627 if (every_math != 0)
1628 begin_token_list(every_math, every_math_text);
1633 void start_eq_no (void)
1639 push_math(math_shift_group);
1640 eq_word_define(int_base + cur_fam_code, -1);
1642 if (every_math != 0)
1643 begin_token_list(every_math, every_math_text);
1647 void scan_math_(pointer p)
1656 while (!((cur_cmd != spacer) && (cur_cmd != relax)));
1665 c = math_code(cur_chr);
1670 cur_cs = cur_chr + active_base;
1671 cur_cmd = eq_type(cur_cs);
1672 cur_chr = equiv(cur_cs);
1686 cur_cmd = char_given;
1693 scan_fifteen_bit_int();
1704 scan_twenty_seven_bit_int();
1715 push_math(math_group);
1721 math_type(p) = math_char;
1722 character(p) = c % 256;
1724 if ((c >= var_code) && ((cur_fam >= 0) && (cur_fam < 16)))
1727 fam(p) = (c / 256) % 16;
1730 void set_math_char_(integer c)
1736 cur_cs = cur_chr + active_base;
1737 cur_cmd = eq_type(cur_cs);
1738 cur_chr = equiv(cur_cs);
1745 math_type(nucleus(p)) = math_char;
1746 character(nucleus(p)) = c % 256;
1747 fam(nucleus(p)) = (c / 256) % 16;
1751 if (((cur_fam >= 0) && (cur_fam < 16)))
1752 fam(nucleus(p)) = cur_fam;
1757 type(p) = ord_noad + (c / 4096);
1764 void math_limit_switch (void)
1767 if (type(tail) == op_noad)
1769 subtype(tail) = cur_chr;
1773 print_err("Limit controls must follow a math operator");
1774 help1("I'm ignoring this misplaced \\limits or \\nolimits command.");
1778 void scan_delimiter_(pointer p, boolean r)
1782 scan_twenty_seven_bit_int();
1790 while (!((cur_cmd != spacer) && (cur_cmd != relax)));
1796 cur_val = del_code(cur_chr);
1800 scan_twenty_seven_bit_int();
1811 print_err("Missing delimiter (. inserted)");
1812 help6("I was expecting to see something like `(' or `\\{' or",
1813 "`\\}' here. If you typed, e.g., `{' instead of `\\{', you",
1814 "should probably delete the `{' by typing `1' now, so that",
1815 "braces don't get unbalanced. Otherwise just proceed.",
1816 "Acceptable delimiters are characters whose \\delcode is",
1817 "nonnegative, or you can use `\\delimiter <delimiter code>'.");
1822 small_fam(p) = (cur_val / 1048576L) % 16;
1823 small_char(p) = (cur_val / 4096) % 256;
1824 large_fam(p) = (cur_val / 256) % 16;
1825 large_char(p) = cur_val % 256;
1828 void math_radical (void)
1830 tail_append(get_node(radical_noad_size));
1831 type(tail) = radical_noad;
1832 subtype(tail) = normal;
1833 mem[nucleus(tail)].hh = empty_field;
1834 mem[subscr(tail)].hh = empty_field;
1835 mem[supscr(tail)].hh = empty_field;
1836 scan_delimiter(left_delimiter(tail), true);
1837 scan_math(nucleus(tail));
1842 if (cur_cmd == accent)
1844 print_err("Please use ");
1845 print_esc("mathaccent");
1846 prints(" for accents in math mode");
1847 help2("I'm changing \\accent to \\mathaccent here; wish me luck.",
1848 "(Accents are not the same in formulas as they are in text.)");
1852 tail_append(get_node(accent_noad_size));
1853 type(tail) = accent_noad;
1854 subtype(tail) = normal;
1855 mem[nucleus(tail)].hh = empty_field;
1856 mem[subscr(tail)].hh = empty_field;
1857 mem[supscr(tail)].hh = empty_field;
1858 math_type(accent_chr(tail)) = math_char;
1859 scan_fifteen_bit_int();
1860 character(accent_chr(tail)) = cur_val % 256;
1862 if ((cur_val >= var_code) && ((cur_fam >= 0) && (cur_fam < 16)))
1863 fam(accent_chr(tail)) = cur_fam;
1865 fam(accent_chr(tail)) = (cur_val / 256) % 16;
1867 scan_math(nucleus(tail));
1870 void append_choices (void)
1872 tail_append(new_choice());
1875 push_math(math_choice_group);
1879 pointer fin_mlist_(pointer p)
1883 if (incompleat_noad != 0)
1885 math_type(denominator(incompleat_noad)) = sub_mlist;
1886 info(denominator(incompleat_noad)) = link(head);
1889 q = incompleat_noad;
1892 q = info(numerator(incompleat_noad));
1894 if (type(q) != left_noad)
1900 info(numerator(incompleat_noad)) = link(q);
1901 link(q) = incompleat_noad;
1902 link(incompleat_noad) = p;
1916 void build_choices (void)
1926 display_mlist(tail) = p;
1930 text_mlist(tail) = p;
1934 script_mlist(tail) = p;
1939 script_script_mlist(tail) = p;
1947 push_math(math_choice_group);
1953 /* small_number t; */
1961 if (script_allowed(tail))
1963 p = supscr(tail) + cur_cmd - sup_mark;
1967 if ((p == 0) || (t != 0))
1969 tail_append(new_noad());
1970 p = supscr(tail) + cur_cmd - sup_mark;
1974 if (cur_cmd == sup_mark)
1976 print_err("Double superscript");
1977 help1("I treat `x^1^2' essentially like `x^1{}^2'.");
1981 print_err("Double subscript");
1982 help1("I treat `x_1_2' essentially like `x_1{}_2'.");
1991 void package (small_number c)
1999 save_ptr = save_ptr - 3;
2002 cur_box = hpack(link(head), saved(2), saved(1));
2005 cur_box = vpackage(link(head), saved(2), saved(1), d);
2010 p = list_ptr(cur_box);
2013 if (type(p) <= rule_node)
2016 depth(cur_box) = depth(cur_box) - h + height(cur_box);
2017 height(cur_box) = h;