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
22 /* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
24 void build_page (void)
30 /* unsigned char n; */
31 unsigned int n; /* 95/Jan/7 */
34 if ((link(contrib_head) == 0) || output_active)
40 p = link(contrib_head);
42 if (last_glue != max_halfword)
43 delete_glue_ref(last_glue);
48 if (type(p) == glue_node)
50 last_glue = glue_ptr(p);
51 add_glue_ref(last_glue);
55 last_glue = max_halfword;
57 if (type(p) == penalty_node)
58 last_penalty = penalty(p);
59 else if (type(p) == kern_node)
68 if (page_contents < box_there)
70 if (page_contents == 0)
71 freeze_page_specs(box_there);
73 page_contents = box_there;
75 q = new_skip_param(top_skip_code);
77 if (width(temp_ptr) > height(p))
78 width(temp_ptr) = width(temp_ptr) - height(p);
83 link(contrib_head) = q;
88 page_total = page_total + page_depth + height(p);
89 page_depth = depth(p);
99 if (page_contents < box_there)
101 else if (precedes_break(page_tail))
108 if (page_contents < box_there)
110 else if (link(p) == 0)
112 else if (type(link(p)) == glue_node)
119 if (page_contents < box_there)
131 if (page_contents == 0)
132 freeze_page_specs(inserts_only);
137 while (n >= subtype(link(r)))
144 q = get_node(page_ins_node_size);
155 height(r) = height(box(n)) + depth(box(n));
160 if (count(n) == 1000)
163 h = x_over_n(height(r), 1000) * count(n);
165 page_goal = page_goal - h - width(q);
166 page_so_far[2 + stretch_order(q)] = page_so_far[2 + stretch_order(q)] + stretch(q);
167 page_shrink = page_shrink + shrink(q);
169 if ((shrink_order(q) != normal) && (shrink(q) != 0))
171 print_err("Infinite glue shrinkage inserted from ");
174 help3("The correction glue for page breaking with insertions",
175 "must have finite shrinkability. But you may proceed,",
176 "since the offensive shrinkability has been made finite.");
181 if (type(r) == split_up)
182 insert_penalties = insert_penalties + float_cost(p);
186 delta = page_goal - page_total - page_depth + page_shrink;
188 if (count(n) == 1000)
191 h = x_over_n(height(p), 1000) * count(n);
193 if (((h <= 0) || (h <= delta)) && (height(p) + height(r) <= dimen(n)))
195 page_goal = page_goal - h;
196 height(r) = height(r) + height(p);
201 w = max_dimen; /* 2^30 - 1 */
204 w = page_goal - page_total - page_depth;
206 if (count(n) != 1000)
207 w = x_over_n(w, count(n)) * 1000;
210 if (w > dimen(n) - height(r))
211 w = dimen(n) - height(r);
213 q = vert_break(ins_ptr(p), w, depth(p));
214 height(r) = height(r) + best_height_plus_depth;
217 if (tracing_pages > 0)
225 print_scaled(best_height_plus_depth);
229 print_int(eject_penalty);
230 else if (type(q) == penalty_node)
231 print_int(penalty(q));
235 end_diagnostic(false);
238 if (count(n) != 1000)
239 best_height_plus_depth = x_over_n(best_height_plus_depth, 1000) * count(n);
241 page_goal = page_goal - best_height_plus_depth;
247 insert_penalties = insert_penalties + (eject_penalty);
248 else if (type(q) == penalty_node)
249 insert_penalties = insert_penalties + penalty(q);
259 return; // abort_flag set
264 if (pi < inf_penalty)
266 if (page_total < page_goal)
267 if ((page_so_far[3] != 0) || (page_so_far[4] != 0) || (page_so_far[5] != 0))
270 b = badness(page_goal - page_total, page_so_far[2]);
271 else if (page_total - page_goal > page_shrink)
272 b = awful_bad; /* 2^30 - 1 */
274 b = badness(page_total - page_goal, page_shrink);
276 if (b < awful_bad) /* 2^30 - 1 */
277 if (pi <= eject_penalty)
279 else if (b < inf_bad)
280 c = b + pi + insert_penalties;
286 if (insert_penalties >= 10000)
287 c = awful_bad; /* 2^30 - 1 */
290 if (tracing_pages > 0)
297 print_scaled(page_goal);
300 if (b == awful_bad) /* 2^30 - 1 */
309 if (c == awful_bad) /* 2^30 - 1 */
314 if (c <= least_page_cost)
317 end_diagnostic(false);
321 if (c <= least_page_cost)
324 best_size = page_goal;
326 r = link(page_ins_head);
328 while (r != page_ins_head)
330 best_ins_ptr(r) = last_ins_ptr(r);
335 if ((c == awful_bad) || (pi <= eject_penalty)) /* 2^30 - 1 */
346 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);
376 if (page_depth > page_max_depth)
378 page_total = page_total + page_depth - page_max_depth;
379 page_depth = page_max_depth;
384 link(contrib_head) = link(p);
388 link(contrib_head) = link(p);
393 while (!(link(contrib_head) == 0));
398 nest[0].tail_field = contrib_head;
401 void app_space (void)
405 if ((space_factor >= 2000) && (xspace_skip != zero_glue))
406 q = new_param_glue(xspace_skip_code);
409 if (space_skip != zero_glue)
413 main_p = font_glue[cur_font];
417 main_p = new_spec(zero_glue);
418 main_k = param_base[cur_font] + space_code;
419 width(main_p) = font_info[main_k].cint;
420 stretch(main_p) = font_info[main_k + 1].cint;
421 shrink(main_p) = font_info[main_k + 2].cint;
422 font_glue[cur_font] = main_p;
426 main_p = new_spec(main_p);
428 if (space_factor >= 2000)
429 width(main_p) = width(main_p) + extra_space(cur_font);
431 stretch(main_p) = xn_over_d(stretch(main_p), space_factor, 1000);
432 shrink(main_p) = xn_over_d(shrink(main_p), 1000, space_factor);
433 q = new_glue(main_p);
434 glue_ref_count(main_p) = 0;
440 /* called from tex8.c only */
442 void insert_dollar_sign (void)
445 cur_tok = math_shift_token + '$';
446 print_err("Missing $ inserted");
447 help2("I've inserted a begin-math/end-math symbol since I think",
448 "you left one out. Proceed, with fingers crossed.");
454 print_err("You can't use `");
455 print_cmd_chr(cur_cmd, cur_chr);
456 print_string("' in ");
460 void report_illegal_case (void)
463 help4("Sorry, but I'm not programmed to handle this case;",
464 "I'll just pretend that you didn't ask for it.",
465 "If you're in the wrong mode, you might be able to",
466 "return to the right one by typing `I}' or `I$' or `I\\par'.");
470 bool privileged (void)
476 report_illegal_case();
481 bool its_all_over (void)
485 if ((page_head == page_tail) && (head == cur_list.tail_field) && (dead_cycles == 0))
491 tail_append(new_null_box());
493 tail_append(new_glue(fill_glue));
494 tail_append(new_penalty(-1073741824L));
501 void append_glue (void)
522 cur_val = fil_neg_glue;
534 tail_append(new_glue(cur_val));
538 decr(glue_ref_count(cur_val));
541 subtype(tail) = mu_glue;
545 void append_kern (void)
551 scan_dimen(s == mu_glue, false, false);
552 tail_append(new_kern(cur_val));
560 if (cur_group == bottom_level)
563 print_cmd_chr(cur_cmd, cur_chr);
564 help1("Things are pretty mixed up, but I think the worst is over.");
572 print_err("Missing ");
576 case semi_simple_group:
578 info(p) = cs_token_flag + frozen_end_group;
579 print_esc("endgroup");
583 case math_shift_group:
585 info(p) = math_shift_token + '$';
590 case math_left_group:
592 info(p) = cs_token_flag + frozen_right;
593 link(p) = get_avail();
595 info(p) = other_token + '.';
602 info(p) = right_brace_token + '}';
608 print_string(" inserted");
609 ins_list(link(temp_head));
610 help5("I've inserted something that you may have forgotten.",
611 "(See the <inserted text> above.)",
612 "With luck, this will get me unwedged. But if you",
613 "really didn't forget anything, try typing `2' now; then",
614 "my insertion and my current dilemma will both disappear.");
618 /* only called from tex8.c */
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);
741 /* called only from tex8.c */
743 void begin_box_(integer box_context)
754 scan_eight_bit_int();
755 cur_box = box(cur_val);
762 scan_eight_bit_int();
763 cur_box = copy_node_list(box(cur_val));
771 if (abs(mode) == mmode)
774 help1("Sorry; this \\lastbox will be void.");
777 else if ((mode == vmode) && (head == cur_list.tail_field))
780 help2("Sorry...I usually can't take things from the current page.",
781 "This \\lastbox will therefore be void.");
786 if (!(tail >= hi_mem_min))
787 if ((type(tail) == hlist_node) || (type(tail) == vlist_node))
795 if (!(q >= hi_mem_min))
796 if (type(q) == disc_node)
798 for (m = 1; m <= replace_count(q); m++)
807 while (!(q == tail));
810 shift_amount(cur_box) = 0;
822 scan_eight_bit_int();
825 if (!scan_keyword("to"))
827 print_err("Missing `to' inserted");
828 help2("I'm working on `\\vsplit<box number> to <dimen>';",
829 "will look for the <dimen> next.");
833 scan_dimen(false, false, false);
834 cur_box = vsplit(n, cur_val);
840 k = cur_chr - vtop_code;
841 saved(0) = box_context;
844 if ((box_context < box_flag) && (abs(mode) == vmode))
845 scan_spec(adjust_hbox_group, true);
847 scan_spec(hbox_group, true);
851 scan_spec(vbox_group, true);
854 scan_spec(vtop_group, true);
862 mode = - (integer) k;
866 prev_depth = ignore_depth;
869 begin_token_list(every_vbox, every_vbox_text);
876 begin_token_list(every_hbox, every_vbox_text);
883 box_end(box_context);
886 void scan_box_(integer box_context)
892 while (!((cur_cmd != spacer) && (cur_cmd != relax)));
894 if (cur_cmd == make_box)
896 begin_box(box_context);
898 else if ((box_context >= leader_flag) && ((cur_cmd == hrule) || (cur_cmd == vrule)))
900 cur_box = scan_rule_spec();
901 box_end(box_context);
905 print_err("A <box> was supposed to be here");
906 help3("I was expecting to see \\hbox or \\vbox or \\copy or \\box or",
907 "something like that. So you might find something missing in",
908 "your output. But keep trying; you can fix this later.");
912 /****************************************************************************/
913 void package_ (small_number);
914 /****************************************************************************/
916 small_number norm_min_ (integer h)
926 void new_graf_(bool indented)
930 if ((mode == vmode) || (head != tail))
931 tail_append(new_param_glue(par_skip_code));
938 prev_graf =(norm_min(left_hyphen_min) * 64 + norm_min(right_hyphen_min)) * 65536L + cur_lang;
942 tail = new_null_box();
944 width(tail) = par_indent;
948 begin_token_list(every_par, every_par_text);
953 /* procedure indent_in_hmode; l.21058 */
955 void indent_in_hmode (void)
962 width(p) = par_indent;
964 if (abs(mode) == hmode)
969 math_type(nucleus(q)) = sub_box;
970 info(nucleus(q)) = p;
977 /* only called from tex8.c */
979 void head_for_vmode (void)
983 if (cur_cmd != hrule)
987 print_err("You can't use `");
989 print_string("' here except with leaders");
990 help2("To put a horizontal rule in an hbox or an alignment,",
991 "you should use \\leaders or \\hrulefill (see The TeXbook).");
1000 cur_input.index_field = inserted;
1004 void end_graf (void)
1011 line_break(widow_penalty);
1017 /* only called form tex8.c */
1019 void begin_insert_or_adjust (void)
1021 if (cur_cmd == vadjust)
1025 scan_eight_bit_int();
1029 print_err("You can't ");
1030 print_esc("insert");
1032 help1("I'm changing to \\insert0; box 255 is special.");
1040 new_save_level(insert_group);
1045 prev_depth = ignore_depth;
1048 void make_mark (void)
1052 p = scan_toks(false, true);
1053 p = get_node(small_node_size);
1054 type(p) = mark_node;
1056 mark_ptr(p) = def_ref;
1061 void append_penalty (void)
1064 tail_append(new_penalty(cur_val));
1069 /* only called from tex8.c */
1071 void delete_last (void)
1076 if ((mode == vmode) && (tail == head))
1078 if ((cur_chr != glue_node) || (last_glue != max_halfword))
1081 help2("Sorry...I usually can't take things from the current page.",
1082 "Try `I\\vskip-\\lastskip' instead.");
1084 if (cur_chr == kern_node)
1085 help_line[0] = "Try `I\\kern-\\last_kern' instead.";
1086 else if (cur_chr != glue_node)
1087 help_line[0] = "Perhaps you can make the output routine do it.";
1093 if (!(tail >= hi_mem_min))
1094 if (type(tail) == cur_chr)
1102 if (!(q >= hi_mem_min))
1103 if (type(q) == disc_node)
1105 for (m = 1; m <= replace_count(q); m++)
1114 while (!(q == tail));
1117 flush_node_list(tail);
1122 /* only called from tex8.c */
1123 /* procedure unpackage; l.21256 */
1125 void unpackage (void)
1131 scan_eight_bit_int();
1137 if ((abs(mode) == mmode) || ((abs(mode) == vmode) && (type(p) != vlist_node)) ||
1138 ((abs(mode) == hmode) && (type(p) != hlist_node)))
1140 print_err("Incompatible list can't be unboxed");
1141 help3("Sorry, Pandora. (You sneaky devil.)",
1142 "I refuse to unbox an \\hbox in vertical mode or vice versa.",
1143 "And I can't open any boxes in math mode.");
1149 link(tail) = copy_node_list(list_ptr(p));
1152 link(tail) = list_ptr(p);
1154 free_node(p, box_node_size);
1157 while (link(tail) != 0)
1161 void append_italic_correction (void)
1164 internal_font_number f;
1168 if ((tail >= hi_mem_min))
1170 else if (type(tail) == ligature_node)
1176 tail_append(new_kern(char_italic(f, char_info(f, character(p)))));
1177 subtype(tail) = explicit;
1181 void append_discretionary (void)
1185 tail_append(new_disc());
1189 c = hyphen_char[cur_font];
1193 pre_break(tail) = new_character(cur_font, c);
1199 new_save_level(disc_group);
1203 space_factor = 1000;
1206 /* only called form tex8.c */
1208 void build_discretionary (void)
1220 if (!(p >= hi_mem_min))
1221 if (type(p) > rule_node)
1222 if (type(p) != kern_node)
1223 if (type(p) != ligature_node)
1225 print_err("Improper discretionary list");
1226 help1("Discretionary lists must contain only boxes and kerns.");
1229 print_nl("The following discretionary sublist has been deleted:");
1231 end_diagnostic(true);
1249 pre_break(tail) = p;
1253 post_break(tail) = p;
1258 if ((n > 0) && (abs(mode) == mmode))
1260 print_err("Illegal math ");
1261 print_esc("discretionary");
1262 help2("Sorry: The third part of a discretionary break must be",
1263 "empty, in math formulas. I had to delete your third part.");
1271 if (n <= max_quarterword)
1272 replace_count(tail) = n;
1275 print_err("Discretionary list is too long");
1276 help2("Wow---I never thought anybody would tweak me here.",
1277 "You can't seriously need such a huge discretionary list?");
1291 new_save_level(disc_group);
1295 space_factor = 1000;
1297 /* called only from tex8.c */
1299 void make_accent (void)
1303 internal_font_number f;
1304 scaled a, h, x, w, delta;
1309 p = new_character(f, cur_val);
1314 s = slant(f) / ((double) 65536.0);
1315 a = char_width(f, char_info(f, character(p)));
1320 if ((cur_cmd == letter) || (cur_cmd == other_char) || (cur_cmd == char_given))
1321 q = new_character(f, cur_chr);
1322 else if (cur_cmd == char_num)
1325 q = new_character(f, cur_val);
1332 t = slant(f) / ((double) 65536.0);
1333 i = char_info(f, character(q));
1334 w = char_width(f, i);
1335 h = char_height(f, height_depth(i));
1340 shift_amount(p) = x - h;
1343 delta = round((w - a) / ((double) 2.0)+ h * t - x * s);
1344 r = new_kern(delta);
1345 subtype(r) = acc_kern;
1348 tail = new_kern(- (integer) a - delta);
1349 subtype(tail) = acc_kern;
1356 space_factor = 1000;
1360 void align_error (void)
1362 if (abs(align_state) > 2)
1364 print_err("Misplaced ");
1365 print_cmd_chr(cur_cmd, cur_chr);
1367 if (cur_tok == tab_token + '&')
1369 help6("I can't figure out why you would want to use a tab mark",
1370 "here. If you just want an ampersand, the remedy is",
1371 "simple: Just type `I\\&' now. But if some right brace",
1372 "up above has ended a previous alignment prematurely,",
1373 "you're probably due for more error messages, and you",
1374 "might try typing `S' now just to see what is salvageable.");
1378 help5("I can't figure out why you would want to use a tab mark",
1379 "or \\cr or \\span just now. If something like a right brace",
1380 "up above has ended a previous alignment prematurely,",
1381 "you're probably due for more error messages, and you",
1382 "might try typing `S' now just to see what is salvageable.");
1391 if (align_state < 0)
1393 print_err("Missing { inserted");
1395 cur_tok = left_brace_token + '{';
1399 print_err("Missing } inserted");
1401 cur_tok = right_brace_token + '}';
1404 help3("I've put in what seems to be necessary to fix",
1405 "the current column of the current alignment.",
1406 "Try to go on, since this might almost work.");
1411 void noalign_error (void)
1413 print_err("Misplaced ");
1414 print_esc("noalign");
1415 help2("I expect to see \\noalign only after the \\cr of",
1416 "an alignment. Proceed, and I'll ignore this case.");
1419 /* only called from tex8.c */
1421 void omit_error (void)
1423 print_err("Misplaced ");
1425 help2("I expect to see \\omit only after tab marks or the \\cr of",
1426 "an alignment. Proceed, and I'll ignore this case.");
1432 base_ptr = input_ptr;
1433 input_stack[base_ptr] = cur_input;
1435 while ((input_stack[base_ptr].index_field != v_template) &&
1436 (input_stack[base_ptr].loc_field == 0) &&
1437 (input_stack[base_ptr].state_field == token_list))
1440 if ((input_stack[base_ptr].index_field != v_template) ||
1441 (input_stack[base_ptr].loc_field != 0) ||
1442 (input_stack[base_ptr].state_field != token_list))
1443 fatal_error("(interwoven alignment preambles are not allowed)");
1445 if (cur_group == align_group)
1455 /* only called form tex8.c */
1457 void cs_error (void)
1459 print_err("Extra ");
1460 print_esc("endcsname");
1461 help1("I'm ignoring this, since I wasn't doing a \\csname.");
1465 void push_math_(group_code c)
1469 incompleat_noad = 0;
1473 void init_math (void)
1480 internal_font_number f;
1487 if ((cur_cmd == math_shift) && (mode > 0))
1492 w = -max_dimen; /* - (2^30 - 1) */
1496 line_break(display_widow_penalty);
1497 v = shift_amount(just_box) + 2 * quad(cur_font);
1498 w = -max_dimen; /* - (2^30 - 1) */
1499 p = list_ptr(just_box);
1504 if ((p >= hi_mem_min))
1507 d = char_width(f, char_info(f, character(p)));
1524 mem[lig_trick] = mem[lig_char(p)];
1525 link(lig_trick) = link(p);
1541 if (glue_sign(just_box) == stretching)
1543 if ((glue_order(just_box) == stretch_order(q)) && (stretch(q) != 0))
1544 v = max_dimen; /* - (2^30 - 1) */
1546 else if (glue_sign(just_box) == shrinking)
1548 if ((glue_order(just_box) == shrink_order(q)) && (shrink(q) != 0))
1549 v = max_dimen; /* - (2^30 - 1) */
1552 if (subtype(p) >= a_leaders)
1566 if (v < max_dimen) /* - (2^30 - 1) */
1571 if (v < max_dimen) /* - (2^30 - 1) */
1578 w = max_dimen; /* - (2^30 - 1) */
1587 if (par_shape_ptr == 0)
1588 if ((hang_indent != 0) && (((hang_after >= 0) &&
1589 (prev_graf + 2 > hang_after)) || (prev_graf + 1 < - (integer) hang_after)))
1591 l = hsize - abs(hang_indent);
1593 if (hang_indent > 0)
1605 n = info(par_shape_ptr);
1607 if (prev_graf + 2 >= n)
1608 p = par_shape_ptr + 2 * n;
1610 p = par_shape_ptr + 2 *(prev_graf + 2);
1612 s = mem[p - 1].cint;
1616 push_math(math_shift_group);
1618 eq_word_define(int_base + cur_fam_code, -1);
1619 eq_word_define(dimen_base + pre_display_size_code, w);
1620 eq_word_define(dimen_base + display_width_code, l);
1621 eq_word_define(dimen_base + display_indent_code, s);
1623 if (every_display != 0)
1624 begin_token_list(every_display, every_display_text);
1636 push_math(math_shift_group);
1637 eq_word_define(int_base + cur_fam_code, -1);
1639 if (every_math != 0)
1640 begin_token_list(every_math, every_math_text);
1645 void start_eq_no (void)
1651 push_math(math_shift_group);
1652 eq_word_define(int_base + cur_fam_code, -1);
1654 if (every_math != 0)
1655 begin_token_list(every_math, every_math_text);
1659 void scan_math_(halfword p)
1668 while(!((cur_cmd != spacer) && (cur_cmd != relax)));
1677 c = math_code(cur_chr);
1682 cur_cs = cur_chr + active_base;
1683 cur_cmd = eq_type(cur_cs);
1684 cur_chr = equiv(cur_cs);
1698 cur_cmd = char_given;
1705 scan_fifteen_bit_int();
1716 scan_twenty_seven_bit_int();
1727 push_math(math_group);
1733 math_type(p) = math_char;
1734 character(p) = c % 256;
1736 if ((c >= var_code) && ((cur_fam >= 0) && (cur_fam < 16)))
1739 fam(p) = (c / 256) % 16;
1742 void set_math_char_(integer c)
1748 cur_cs = cur_chr + active_base;
1749 cur_cmd = eq_type(cur_cs);
1750 cur_chr = equiv(cur_cs);
1757 math_type(nucleus(p)) = math_char;
1758 character(nucleus(p)) = c % 256;
1759 fam(nucleus(p)) = (c / 256) % 16;
1763 if (((cur_fam >= 0) && (cur_fam < 16)))
1764 fam(nucleus(p)) = cur_fam;
1769 type(p) = ord_noad + (c / 4096);
1776 void math_limit_switch (void)
1779 if (type(tail) == op_noad)
1781 subtype(tail) = cur_chr;
1785 print_err("Limit controls must follow a math operator");
1786 help1("I'm ignoring this misplaced \\limits or \\nolimits command.");
1790 void scan_delimiter_(halfword p, bool r)
1794 scan_twenty_seven_bit_int();
1802 while (!((cur_cmd != spacer) && (cur_cmd != relax)));
1808 cur_val = del_code(cur_chr);
1812 scan_twenty_seven_bit_int();
1823 print_err("Missing delimiter (. inserted)");
1824 help6("I was expecting to see something like `(' or `\\{' or",
1825 "`\\}' here. If you typed, e.g., `{' instead of `\\{', you",
1826 "should probably delete the `{' by typing `1' now, so that",
1827 "braces don't get unbalanced. Otherwise just proceed.",
1828 "Acceptable delimiters are characters whose \\delcode is",
1829 "nonnegative, or you can use `\\delimiter <delimiter code>'.");
1834 small_fam(p) = (cur_val / 1048576L) % 16;
1835 small_char(p) = (cur_val / 4096) % 256;
1836 large_fam(p) = (cur_val / 256) % 16;
1837 large_char(p) = cur_val % 256;
1840 void math_radical (void)
1842 tail_append(get_node(radical_noad_size));
1843 type(tail) = radical_noad;
1844 subtype(tail) = normal;
1845 mem[nucleus(tail)].hh = empty_field;
1846 mem[subscr(tail)].hh = empty_field;
1847 mem[supscr(tail)].hh = empty_field;
1848 scan_delimiter(left_delimiter(tail), true);
1849 scan_math(nucleus(tail));
1854 if (cur_cmd == accent)
1856 print_err("Please use ");
1857 print_esc("mathaccent");
1858 print_string(" for accents in math mode");
1859 help2("I'm changing \\accent to \\mathaccent here; wish me luck.",
1860 "(Accents are not the same in formulas as they are in text.)");
1864 tail_append(get_node(accent_noad_size));
1865 type(tail) = accent_noad;
1866 subtype(tail) = normal;
1867 mem[nucleus(tail)].hh = empty_field;
1868 mem[subscr(tail)].hh = empty_field;
1869 mem[supscr(tail)].hh = empty_field;
1870 math_type(accent_chr(tail)) = math_char;
1871 scan_fifteen_bit_int();
1872 character(accent_chr(tail)) = cur_val % 256;
1874 if ((cur_val >= var_code) && ((cur_fam >= 0) && (cur_fam < 16)))
1875 fam(accent_chr(tail)) = cur_fam;
1877 fam(accent_chr(tail)) = (cur_val / 256) % 16;
1879 scan_math(nucleus(tail));
1882 void append_choices (void)
1884 tail_append(new_choice());
1887 push_math(math_choice_group);
1891 halfword fin_mlist_(halfword p)
1895 if (incompleat_noad != 0)
1897 math_type(denominator(incompleat_noad)) = sub_mlist;
1898 info(denominator(incompleat_noad)) = link(head);
1901 q = incompleat_noad;
1904 q = info(numerator(incompleat_noad));
1906 if (type(q) != left_noad)
1909 return 0; // abort_flag set
1912 info(numerator(incompleat_noad)) = link(q);
1913 link(q) = incompleat_noad;
1914 link(incompleat_noad) = p;
1927 void build_choices (void)
1937 display_mlist(tail) = p;
1941 text_mlist(tail) = p;
1945 script_mlist(tail) = p;
1950 script_script_mlist(tail) = p;
1958 push_math(math_choice_group);
1964 /* small_number t; */
1965 int t; /* 95/Jan/7 */
1972 if (script_allowed(tail))
1974 p = supscr(tail) + cur_cmd - sup_mark;
1978 if ((p == 0) || (t != 0))
1980 tail_append(new_noad());
1981 p = supscr(tail) + cur_cmd - sup_mark;
1985 if (cur_cmd == sup_mark)
1987 print_err("Double superscript");
1988 help1("I treat `x^1^2' essentially like `x^1{}^2'.");
1992 print_err("Double subscript");
1993 help1("I treat `x_1_2' essentially like `x_1{}_2'.");
2000 /* used to continue here with math_fraction etc in tex7.c */
2001 /*****************************************************************************/
2002 /* moved down here to avoid pragma optimize questions 96/Sep/12 */
2004 void package_(small_number c)
2012 save_ptr = save_ptr - 3;
2015 cur_box = hpack(link(head), saved(2), saved(1));
2018 cur_box = vpackage(link(head), saved(2), saved(1), d);
2023 p = list_ptr(cur_box);
2026 if (type(p) <= rule_node)
2029 depth(cur_box) = depth(cur_box) - h + height(cur_box);
2030 height(cur_box) = h;
2036 //#pragma optimize ("", on) /* 96/Sep/12 */