2 Copyright 2014 Clerk Ma
\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
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
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
20 #define EXTERN extern
\r
22 #include "yandytex.h"
\r
25 void math_fraction (void)
\r
31 if (incompleat_noad != 0)
\r
33 if (c >= delimited_code)
\r
35 scan_delimiter(garbage, false);
\r
36 scan_delimiter(garbage, false);
\r
39 if (c % delimited_code == 0)
\r
40 scan_dimen(false, false, false);
\r
42 print_err("Ambiguous; you need another { and }");
\r
43 help3("I'm ignoring this fraction specification, since I don't",
\r
44 "know whether a construction like `x \\over y \\over z'",
\r
45 "means `{x \\over y} \\over z' or `x \\over {y \\over z}'.");
\r
50 incompleat_noad = get_node(fraction_noad_size);
\r
51 type(incompleat_noad) = fraction_noad;
\r
52 subtype(incompleat_noad) = normal;
\r
53 math_type(numerator(incompleat_noad)) = sub_mlist;
\r
54 info(numerator(incompleat_noad)) = link(head);
\r
55 mem[denominator(incompleat_noad)].hh = empty_field;
\r
56 mem[left_delimiter(incompleat_noad)].qqqq = null_delimiter;
\r
57 mem[right_delimiter(incompleat_noad)].qqqq = null_delimiter;
\r
61 if (c >= delimited_code)
\r
63 scan_delimiter(left_delimiter(incompleat_noad), false);
\r
64 scan_delimiter(right_delimiter(incompleat_noad), false);
\r
67 switch (c % delimited_code)
\r
70 scan_dimen(false, false, false);
\r
71 thickness(incompleat_noad) = cur_val;
\r
75 thickness(incompleat_noad) = default_code;
\r
79 thickness(incompleat_noad) = 0;
\r
85 void math_left_right (void)
\r
92 if ((t == right_noad) && (cur_group != math_left_group))
\r
94 if (cur_group == math_shift_group)
\r
96 scan_delimiter(garbage, false);
\r
97 print_err("Extra ");
\r
99 help1("I'm ignoring a \\right that had no matching \\left.");
\r
109 scan_delimiter(delimiter(p), false);
\r
111 if (t == left_noad)
\r
113 push_math(math_left_group);
\r
121 tail_append(new_noad());
\r
122 type(tail) = inner_noad;
\r
123 math_type(nucleus(tail)) = sub_mlist;
\r
124 info(nucleus(tail)) = p;
\r
129 void after_math (void)
\r
143 small_number g1, g2;
\r
149 if ((font_params[fam_fnt(2 + text_size)] < total_mathsy_params) ||
\r
150 (font_params[fam_fnt(2 + script_size)] < total_mathsy_params) ||
\r
151 (font_params[fam_fnt(2 + script_script_size)] < total_mathsy_params))
\r
153 print_err("Math formula deleted: Insufficient symbol fonts");
\r
154 help3("Sorry, but I can't typeset math unless \\textfont 2",
\r
155 "and \\scriptfont 2 and \\scriptscriptfont 2 have all",
\r
156 "the \\fontdimen values needed in math symbol fonts.");
\r
161 else if ((font_params[fam_fnt(3 + text_size)] < total_mathex_params) ||
\r
162 (font_params[fam_fnt(3 + script_size)] < total_mathex_params) ||
\r
163 (font_params[fam_fnt(3 + script_script_size)] < total_mathex_params))
\r
165 print_err("Math formula deleted: Insufficient extension fonts");
\r
166 help3("Sorry, but I can't typeset math unless \\textfont 3",
\r
167 "and \\scriptfont 3 and \\scriptscriptfont 3 have all",
\r
168 "the \\fontdimen values needed in math extension fonts.");
\r
183 if (cur_cmd != math_shift)
\r
185 print_err("Display math should end with $$");
\r
186 help2("The `$' that I just saw supposedly matches a previous `$$'.",
\r
187 "So I shall assume that you typed `$$' both times.");
\r
193 cur_style = text_style;
\r
194 mlist_penalties = false;
\r
196 a = hpack(link(temp_head), 0, 1);
\r
205 if ((font_params[fam_fnt(2 + text_size)] < total_mathsy_params) ||
\r
206 (font_params[fam_fnt(2 + script_size)] < total_mathsy_params) ||
\r
207 (font_params[fam_fnt(2 + script_script_size)] < total_mathsy_params))
\r
209 print_err("Math formula deleted: Insufficient symbol fonts");
\r
210 help3("Sorry, but I can't typeset math unless \\textfont 2",
\r
211 "and \\scriptfont 2 and \\scriptscriptfont 2 have all",
\r
212 "the \\fontdimen values needed in math symbol fonts.");
\r
217 else if ((font_params[fam_fnt(3 + text_size)] < total_mathex_params) ||
\r
218 (font_params[fam_fnt(3 + script_size)] < total_mathex_params) ||
\r
219 (font_params[fam_fnt(3 + script_script_size)] < total_mathex_params))
\r
221 print_err("Math formula deleted: Insufficient extension fonts");
\r
222 help3("Sorry, but I can't typeset math unless \\textfont 3",
\r
223 "and \\scriptfont 3 and \\scriptscriptfont 3 have all",
\r
224 "the \\fontdimen values needed in math extension fonts.");
\r
238 tail_append(new_math(math_surround, before));
\r
240 cur_style = text_style;
\r
241 mlist_penalties = (mode > 0);
\r
243 link(tail) = link(temp_head);
\r
245 while (link(tail) != 0)
\r
248 tail_append(new_math(math_surround, after));
\r
249 space_factor = 1000;
\r
258 if (cur_cmd != math_shift)
\r
260 print_err("Display math should end with $$");
\r
261 help2("The `$' that I just saw supposedly matches a previous `$$'.",
\r
262 "So I shall assume that you typed `$$' both times.");
\r
268 cur_style = display_style;
\r
269 mlist_penalties = false;
\r
271 p = link(temp_head);
\r
272 adjust_tail = adjust_head;
\r
273 b = hpack(p, 0, 1);
\r
279 s = display_indent;
\r
281 if ((a == 0) || danger)
\r
289 q = e + math_quad(text_size);
\r
294 if ((e != 0) && ((w - total_shrink[normal] + q <= z) || (total_shrink[fil] != 0) ||
\r
295 (total_shrink[fill] != 0) || (total_shrink[filll] != 0)))
\r
297 free_node(b, box_node_size);
\r
298 b = hpack(p, z - q, 0);
\r
306 free_node(b, box_node_size);
\r
307 b = hpack(p, z, 0);
\r
315 if ((e > 0) && (d < 2 * e))
\r
317 d = half(z - w - e);
\r
320 if (!is_char_node(p))
\r
321 if (type(p) == glue_node)
\r
325 tail_append(new_penalty(pre_display_penalty));
\r
327 if ((d + s <= pre_display_size) || l)
\r
329 g1 = above_display_skip_code;
\r
330 g2 = below_display_skip_code;
\r
334 g1 = above_display_short_skip_code;
\r
335 g2 = below_display_short_skip_code;
\r
339 shift_amount(a) = s;
\r
340 append_to_vlist(a);
\r
341 tail_append(new_penalty(10000));
\r
345 tail_append(new_param_glue(g1));
\r
350 r = new_kern(z - w - e - d);
\r
364 b = hpack(b, 0, 1);
\r
367 shift_amount(b) = s + d;
\r
368 append_to_vlist(b);
\r
370 if ((a != 0) && (e == 0) && !l)
\r
372 tail_append(new_penalty(10000));
\r
373 shift_amount(a) = s + z - width(a);
\r
374 append_to_vlist(a);
\r
378 if (t != adjust_head)
\r
380 link(tail) = link(adjust_head);
\r
384 tail_append(new_penalty(post_display_penalty));
\r
388 tail_append(new_param_glue(g2));
\r
391 resume_after_display();
\r
395 void resume_after_display (void)
\r
397 if (cur_group != math_shift_group)
\r
399 confusion("display");
\r
404 prev_graf = prev_graf + 3;
\r
407 space_factor = 1000;
\r
410 prev_graf =(norm_min(left_hyphen_min) * 64 + norm_min(right_hyphen_min)) * 65536L + cur_lang;
\r
415 if (cur_cmd != spacer)
\r
423 void get_r_token (void)
\r
430 while (!(cur_tok != space_token));
\r
432 if ((cur_cs == 0) || (cur_cs > frozen_control_sequence))
\r
434 print_err("Missing control sequence inserted");
\r
435 help5("Please don't say `\\def cs{...}', say `\\def\\cs{...}'.",
\r
436 "I've inserted an inaccessible control sequence so that your",
\r
437 "definition will be completed without mixing me up too badly.",
\r
438 "You can recover graciously from this error, if you're",
\r
439 "careful; see exercise 27.2 in The TeXbook.");
\r
444 cur_tok = cs_token_flag + frozen_protection;
\r
450 void trap_zero_glue (void)
\r
452 if ((width(cur_val) == 0) && (stretch(cur_val) == 0) && (shrink(cur_val) == 0))
\r
454 add_glue_ref(zero_glue);
\r
455 delete_glue_ref(cur_val);
\r
460 void do_register_command (small_number a)
\r
462 pointer l, q, r, s;
\r
468 if (q != tex_register)
\r
472 if ((cur_cmd >= assign_int) && (cur_cmd <= assign_mu_glue))
\r
475 p = cur_cmd - assign_int;
\r
479 if (cur_cmd != tex_register)
\r
481 print_err("You can't use `");
\r
482 print_cmd_chr(cur_cmd, cur_chr);
\r
483 prints("' after ");
\r
484 print_cmd_chr(q, 0);
\r
485 help1("I'm forgetting what you said and not changing anything.");
\r
492 scan_eight_bit_int();
\r
497 l = cur_val + count_base;
\r
501 l = cur_val + scaled_base;
\r
505 l = cur_val + skip_base;
\r
509 l = cur_val + mu_skip_base;
\r
515 if (q == tex_register)
\r
516 scan_optional_equals();
\r
517 else if (scan_keyword("by"))
\r
520 arith_error = false;
\r
528 scan_dimen(false, false, false);
\r
531 cur_val = cur_val + eqtb[l].cint;
\r
539 q = new_spec(cur_val);
\r
541 delete_glue_ref(cur_val);
\r
542 width(q) = width(q) + width(r);
\r
544 if (stretch(q) == 0)
\r
545 stretch_order(q) = normal;
\r
547 if (stretch_order(q) == stretch_order(r))
\r
548 stretch(q) = stretch(q) + stretch(r);
\r
549 else if ((stretch_order(q) < stretch_order(r)) && (stretch(r) != 0))
\r
551 stretch(q) = stretch(r);
\r
552 stretch_order(q) = stretch_order(r);
\r
555 if (shrink(q) == 0)
\r
556 shrink_order(q) = normal;
\r
558 if (shrink_order(q) == shrink_order(r))
\r
559 shrink(q) = shrink(q) + shrink(r);
\r
560 else if ((shrink_order(q) < shrink_order(r)) && (shrink(r) != 0))
\r
562 shrink(q) = shrink(r);
\r
563 shrink_order(q) = shrink_order(r);
\r
575 cur_val = mult_integers(eqtb[l].cint, cur_val);
\r
577 cur_val = nx_plus_y(eqtb[l].cint, cur_val, 0);
\r
579 cur_val = x_over_n(eqtb[l].cint, cur_val);
\r
587 width(r) = nx_plus_y(width(s), cur_val, 0);
\r
588 stretch(r) = nx_plus_y(stretch(s), cur_val, 0);
\r
589 shrink(r) = nx_plus_y(shrink(s), cur_val, 0);
\r
593 width(r) = x_over_n(width(s), cur_val);
\r
594 stretch(r) = x_over_n(stretch(s), cur_val);
\r
595 shrink(r) = x_over_n(shrink(s), cur_val);
\r
603 print_err("Arithmetic overflow");
\r
604 help2("I can't carry out that multiplication or division,",
\r
605 "since the result is out of range.");
\r
608 delete_glue_ref(cur_val);
\r
615 word_define(l, cur_val);
\r
619 define(l, glue_ref, cur_val);
\r
623 void alter_aux (void)
\r
627 if (cur_chr != abs(mode))
\r
628 report_illegal_case();
\r
632 scan_optional_equals();
\r
636 scan_dimen(false, false, false);
\r
637 prev_depth = cur_val;
\r
643 if ((cur_val <= 0) || (cur_val > 32767))
\r
645 print_err("Bad space factor");
\r
646 help1("I allow only values in the range 1..32767 here.");
\r
647 int_error(cur_val);
\r
650 space_factor = cur_val;
\r
655 void alter_prev_graf (void)
\r
659 nest[nest_ptr] = cur_list;
\r
662 while (abs(nest[p].mode_field) != vmode)
\r
665 scan_optional_equals();
\r
671 print_esc("prevgraf");
\r
672 help1("I allow only nonnegative values here.");
\r
673 int_error(cur_val);
\r
677 nest[p].pg_field = cur_val;
\r
678 cur_list = nest[nest_ptr];
\r
682 void alter_page_so_far (void)
\r
687 scan_optional_equals();
\r
688 scan_dimen(false, false, false);
\r
689 page_so_far[c] = cur_val;
\r
692 void alter_integer (void)
\r
697 scan_optional_equals();
\r
701 dead_cycles = cur_val;
\r
703 insert_penalties = cur_val;
\r
706 void alter_box_dimen (void)
\r
712 scan_eight_bit_int();
\r
714 scan_optional_equals();
\r
715 scan_dimen(false, false, false);
\r
718 mem[box(b) + c].cint = cur_val;
\r
721 void new_font (small_number a)
\r
725 internal_font_number f;
\r
728 str_number flushable_string;
\r
736 if (u >= hash_base)
\r
738 else if (u >= single_base)
\r
740 t = 1213; /* FONT */
\r
742 t = u - single_base;
\r
745 old_setting = selector;
\r
746 selector = new_string;
\r
748 print(u - active_base);
\r
749 selector = old_setting;
\r
754 define(u, set_font, null_font);
\r
755 scan_optional_equals();
\r
758 name_in_progress = true;
\r
760 if (scan_keyword("at"))
\r
762 scan_dimen(false, false, false);
\r
765 if ((s <= 0) || (s >= 134217728L)) /* 2^27 */
\r
767 print_err("Improper `at' size (");
\r
769 prints("pt), replaced by 10pt");
\r
770 help2("I can only handle fonts at positive sizes that are",
\r
771 "less than 2048pt, so I've changed what you said to 10pt.");
\r
776 else if (scan_keyword("scaled"))
\r
781 if ((cur_val <= 0) || (cur_val > 32768L))
\r
783 print_err("Illegal magnification has been changed to 1000");
\r
784 help1("The magnification ratio must be between 1 and 32768.");
\r
785 int_error(cur_val);
\r
792 name_in_progress = false;
\r
794 flushable_string = str_ptr - 1;
\r
798 int i, k1, k2, l1, l2;
\r
799 char *sch = log_line;
\r
800 k1 = str_start[cur_area];
\r
801 k2 = str_start[cur_name];
\r
802 l1 = length(cur_area);
\r
803 l2 = length(cur_name);
\r
807 for (i = 0; i < l1; i++)
\r
809 *sch++ = str_pool[i + k1];
\r
812 for (i = 0; i < l2; i++)
\r
814 *sch++ = str_pool[i + k2];
\r
819 show_line(log_line, 0);
\r
822 for (f = font_base + 1; f < font_ptr; f++)
\r
824 if (str_eq_str(font_name[f], cur_name) && str_eq_str(font_area[f], cur_area))
\r
826 if (cur_name == flushable_string)
\r
829 cur_name = font_name[f];
\r
834 if (s == font_size[f])
\r
836 if (ignore_frozen == 0 || f > frozen_font_ptr)
\r
839 printf("SKIPPING %lld ", s);
\r
841 goto common_ending;
\r
845 else if (font_size[f] == xn_over_d(font_dsize[f], - (integer) s, 1000))
\r
847 if (ignore_frozen == 0 || f > frozen_font_ptr)
\r
850 printf("SKIPPING %lld ", s);
\r
851 goto common_ending;
\r
858 show_line("READING ", 0);
\r
860 f = read_font_info(u, cur_name, cur_area, s);
\r
864 printf("NEW FONT %lld ", f);
\r
867 eqtb[font_id_base + f] = eqtb[u];
\r
868 font_id_text(f) = t;
\r
871 void new_interaction (void)
\r
874 interaction = cur_chr;
\r
876 if (interaction == batch_mode)
\r
877 selector = no_print;
\r
879 selector = term_only;
\r
882 selector = selector + 2;
\r
885 void do_assignments (void)
\r
893 while (!((cur_cmd != spacer) && (cur_cmd != relax)));
\r
895 if (cur_cmd <= max_non_prefixed_command)
\r
898 set_box_allowed = false;
\r
899 prefixed_command();
\r
900 set_box_allowed = true;
\r
904 void open_or_close_in (void)
\r
910 scan_four_bit_int();
\r
913 if (read_open[n] != closed)
\r
915 a_close(read_file[n]);
\r
916 read_open[n] = closed;
\r
921 scan_optional_equals();
\r
923 pack_file_name(cur_name, cur_area, cur_ext);
\r
925 if ((cur_ext != 335) && a_open_in(read_file[n], kpse_tex_format))
\r
927 else if ((cur_ext != 785) && (name_length + 5 < file_name_size))
\r
929 strncpy((char *) name_of_file + name_length + 1, ".tex ", 5);
\r
930 name_length = name_length + 4;
\r
932 if (a_open_in(read_file[n], kpse_tex_format))
\r
933 read_open[n] = just_open;
\r
936 name_length = name_length - 4;
\r
937 name_of_file[name_length + 1] = ' ';
\r
939 if ((cur_ext == 335) && a_open_in(read_file[n], kpse_tex_format))
\r
940 read_open[n] = just_open;
\r
946 void issue_message (void)
\r
953 link(garbage) = scan_toks(false, true);
\r
954 old_setting = selector;
\r
955 selector = new_string;
\r
956 token_show(def_ref);
\r
957 selector = old_setting;
\r
958 flush_list(def_ref);
\r
964 if (term_offset + length(s) > max_print_line - 2)
\r
966 else if ((term_offset > 0) || (file_offset > 0))
\r
978 use_err_help = true;
\r
979 else if (long_help_seen)
\r
980 help1("(That was another \\errmessage.)");
\r
983 if (interaction < error_stop_mode)
\r
984 long_help_seen = true;
\r
986 help4("This error message was generated by an \\errmessage",
\r
987 "command, so I can't give any explicit help.",
\r
988 "Pretend that you're Hercule Poirot: Examine all clues,",
\r
989 "and deduce the truth by order and method.");
\r
993 use_err_help = false;
\r
999 void shift_case (void)
\r
1007 p = scan_toks(false, false);
\r
1008 p = link(def_ref);
\r
1014 if (t < cs_token_flag + single_base)
\r
1018 if (equiv(b + c) != 0)
\r
1019 info(p) = t - c + equiv(b + c);
\r
1025 begin_token_list(link(def_ref), 3);
\r
1026 free_avail(def_ref);
\r
1029 void show_whatever (void)
\r
1037 begin_diagnostic();
\r
1038 show_activities();
\r
1042 case show_box_code:
\r
1044 scan_eight_bit_int();
\r
1045 begin_diagnostic();
\r
1046 print_nl("> \\box");
\r
1047 print_int(cur_val);
\r
1050 if (box(cur_val) == 0)
\r
1053 show_box(box(cur_val));
\r
1061 if (interaction == error_stop_mode)
\r
1068 sprint_cs(cur_cs);
\r
1073 goto common_ending;
\r
1081 if (interaction == error_stop_mode)
\r
1085 token_show(temp_head);
\r
1086 flush_list(link(temp_head));
\r
1087 goto common_ending;
\r
1092 end_diagnostic(true);
\r
1095 if (selector == term_and_log)
\r
1096 if (tracing_online <= 0)
\r
1098 selector = term_only;
\r
1099 prints(" (see the transcript file)");
\r
1100 selector = term_and_log;
\r
1105 if (interaction < error_stop_mode)
\r
1108 decr(error_count);
\r
1110 else if (tracing_online > 0)
\r
1112 help3("This isn't an error message; I'm just \\showing something.",
\r
1113 "Type `I\\show...' to show more (e.g., \\show\\cs,",
\r
1114 "\\showthe\\count10, \\showbox255, \\showlists).");
\r
1118 help5("This isn't an error message; I'm just \\showing something.",
\r
1119 "Type `I\\show...' to show more (e.g., \\show\\cs,",
\r
1120 "\\showthe\\count10, \\showbox255, \\showlists).",
\r
1121 "And type `I\\tracingonline=1\\show...' to show boxes and",
\r
1122 "lists on your terminal as well as in the transcript file.");
\r
1128 void new_whatsit_(small_number s, small_number w)
\r
1133 type(p) = whatsit_node;
\r
1139 void new_write_whatsit (small_number w)
\r
1141 new_whatsit(cur_chr, w);
\r
1143 if (w != write_node_size)
\r
1144 scan_four_bit_int();
\r
1151 else if (cur_val > 15)
\r
1155 write_stream(tail) = cur_val;
\r
1158 void do_extension (void)
\r
1167 new_write_whatsit(open_node_size);
\r
1168 scan_optional_equals();
\r
1170 open_name(tail) = cur_name;
\r
1171 open_area(tail) = cur_area;
\r
1172 open_ext(tail) = cur_ext;
\r
1179 new_write_whatsit(write_node_size);
\r
1181 p = scan_toks(false, false);
\r
1182 write_tokens(tail) = def_ref;
\r
1188 new_write_whatsit(write_node_size);
\r
1189 write_tokens(tail) = 0;
\r
1193 case special_node:
\r
1195 new_whatsit(special_node, write_node_size);
\r
1196 write_stream(tail) = 0;
\r
1197 p = scan_toks(false, true);
\r
1198 write_tokens(tail) = def_ref;
\r
1202 case immediate_code:
\r
1206 if ((cur_cmd == extension) && (cur_chr <= close_node))
\r
1211 flush_node_list(tail);
\r
1220 case set_language_code:
\r
1221 if (abs(mode) != hmode)
\r
1223 report_illegal_case();
\r
1227 new_whatsit(language_node, small_node_size);
\r
1232 else if (cur_val > 255)
\r
1237 what_lang(tail) = clang;
\r
1238 what_lhm(tail) = norm_min(left_hyphen_min);
\r
1239 what_rhm(tail) = norm_min(right_hyphen_min);
\r
1245 confusion("ext1");
\r
1252 void fix_language (void)
\r
1254 /* ASCII_code l; */
\r
1257 if (language <= 0)
\r
1259 else if (language > 255)
\r
1266 new_whatsit(language_node, small_node_size);
\r
1267 what_lang(tail) = l;
\r
1269 what_lhm(tail) = norm_min(left_hyphen_min);
\r
1270 what_rhm(tail) = norm_min(right_hyphen_min);
\r
1274 void handle_right_brace (void)
\r
1280 switch (cur_group)
\r
1282 case simple_group:
\r
1286 case bottom_level:
\r
1288 print_err("Too many }'s");
\r
1289 help2("You've closed more groups than you opened.",
\r
1290 "Such booboos are generally harmless, so keep going.");
\r
1295 case semi_simple_group:
\r
1296 case math_shift_group:
\r
1297 case math_left_group:
\r
1298 extra_right_brace();
\r
1305 case adjust_hbox_group:
\r
1307 adjust_tail = adjust_head;
\r
1322 package(vtop_code);
\r
1326 case insert_group:
\r
1329 q = split_top_skip;
\r
1331 d = split_max_depth;
\r
1332 f = floating_penalty;
\r
1335 p = vpackage(link(head), 0, 1, max_dimen);
\r
1338 if (saved(0) < 255)
\r
1340 tail_append(get_node(ins_node_size));
\r
1341 type(tail) = ins_node;
\r
1342 subtype(tail) = saved(0);
\r
1343 height(tail) = height(p) + depth(p);
\r
1344 ins_ptr(tail) = list_ptr(p);
\r
1345 split_top_ptr(tail) = q;
\r
1347 float_cost(tail) = f;
\r
1351 tail_append(get_node(small_node_size));
\r
1352 type(tail) = adjust_node;
\r
1353 subtype(tail) = 0;
\r
1354 adjust_ptr(tail) = list_ptr(p);
\r
1355 delete_glue_ref(q);
\r
1357 free_node(p, box_node_size);
\r
1359 if (nest_ptr == 0)
\r
1364 case output_group:
\r
1366 if ((loc != 0) || ((token_type != output_text) && (token_type != backed_up)))
\r
1368 print_err("Unbalanced output routine");
\r
1369 help2("Your sneaky output routine has problematic {'s and/or }'s.",
\r
1370 "I can't handle that very well; good luck.");
\r
1377 while (!(loc == 0));
\r
1383 output_active = false;
\r
1384 insert_penalties = 0;
\r
1386 if (box(255) != 0)
\r
1388 print_err("Output routine didn't use all of ");
\r
1391 help3("Your \\output commands should empty \\box255,",
\r
1392 "e.g., by saying `\\shipout\\box255'.",
\r
1393 "Proceed; I'll discard its present contents.");
\r
1399 link(page_tail) = link(head);
\r
1403 if (link(page_head) != 0)
\r
1405 if (link(contrib_head) == 0)
\r
1406 nest[0].tail_field = page_tail;
\r
1408 link(page_tail) = link(contrib_head);
\r
1409 link(contrib_head) = link(page_head);
\r
1410 link(page_head) = 0;
\r
1411 page_tail = page_head;
\r
1420 build_discretionary();
\r
1426 cur_tok = cs_token_flag + frozen_cr;
\r
1427 print_err("Missing ");
\r
1429 prints("inserted");
\r
1430 help1("I'm guessing that you meant to end an alignment here.");
\r
1435 case no_align_group:
\r
1443 case vcenter_group:
\r
1447 save_ptr = save_ptr - 2;
\r
1448 p = vpackage(link(head), saved(1), saved(0), max_dimen);
\r
1450 tail_append(new_noad());
\r
1451 type(tail) = vcenter_noad;
\r
1452 math_type(nucleus(tail)) = sub_box;
\r
1453 info(nucleus(tail)) = p;
\r
1457 case math_choice_group:
\r
1465 math_type(saved(0)) = sub_mlist;
\r
1467 info(saved(0)) = p;
\r
1471 if (type(p) == ord_noad)
\r
1473 if (math_type(subscr(p)) == 0)
\r
1474 if (math_type(supscr(p)) == 0)
\r
1476 mem[saved(0)].hh = mem[nucleus(p)].hh;
\r
1477 free_node(p, noad_size);
\r
1480 else if (type(p) == accent_noad)
\r
1481 if (saved(0) == nucleus(tail))
\r
1482 if (type(tail) == ord_noad)
\r
1486 while (link(q) != tail)
\r
1490 free_node(tail, noad_size);
\r
1497 confusion("rightbrace");
\r
1504 void main_control (void)
\r
1507 boolean bSuppress;
\r
1509 if (every_job != 0)
\r
1510 begin_token_list(every_job, every_job_text);
\r
1516 if (interrupt != 0)
\r
1517 if (OK_to_interrupt)
\r
1520 check_interrupt();
\r
1529 if (tracing_commands > 0)
\r
1530 show_cur_cmd_chr();
\r
1532 switch (abs(mode) + cur_cmd)
\r
1534 case hmode + letter:
\r
1535 case hmode + other_char:
\r
1536 case hmode + char_given:
\r
1540 case hmode + char_num:
\r
1543 cur_chr = cur_val;
\r
1548 case hmode + no_boundary:
\r
1552 if ((cur_cmd == letter) || (cur_cmd == other_char) ||
\r
1553 (cur_cmd == char_given) || (cur_cmd == char_num))
\r
1554 cancel_boundary = true;
\r
1559 case hmode + spacer:
\r
1560 if (space_factor == 1000)
\r
1561 goto append_normal_space;
\r
1566 case hmode + ex_space:
\r
1567 case mmode + ex_space:
\r
1568 goto append_normal_space;
\r
1571 case any_mode(relax):
\r
1572 case vmode + spacer:
\r
1573 case mmode + spacer:
\r
1574 case mmode + no_boundary:
\r
1578 case any_mode(ignore_spaces):
\r
1584 while (!(cur_cmd != spacer));
\r
1589 case vmode + stop:
\r
1590 if (its_all_over())
\r
1594 case vmode + vmove:
\r
1595 case hmode + hmove:
\r
1596 case mmode + hmove:
\r
1597 case any_mode(last_item):
\r
1598 case vmode + vadjust:
\r
1599 case vmode + ital_corr:
\r
1600 case non_math(eq_no):
\r
1601 case any_mode(mac_param):
\r
1602 report_illegal_case();
\r
1605 case non_math(sup_mark):
\r
1606 case non_math(sub_mark):
\r
1607 case non_math(math_char_num):
\r
1608 case non_math(math_given):
\r
1609 case non_math(math_comp):
\r
1610 case non_math(delim_num):
\r
1611 case non_math(left_right):
\r
1612 case non_math(above):
\r
1613 case non_math(radical):
\r
1614 case non_math(math_style):
\r
1615 case non_math(math_choice):
\r
1616 case non_math(vcenter):
\r
1617 case non_math(non_script):
\r
1618 case non_math(mkern):
\r
1619 case non_math(limit_switch):
\r
1620 case non_math(mskip):
\r
1621 case non_math(math_accent):
\r
1622 case mmode + endv:
\r
1623 case mmode + par_end:
\r
1624 case mmode + stop:
\r
1625 case mmode + vskip:
\r
1626 case mmode + un_vbox:
\r
1627 case mmode + valign:
\r
1628 case mmode + hrule:
\r
1629 insert_dollar_sign();
\r
1632 case vmode + hrule:
\r
1633 case hmode + vrule:
\r
1634 case mmode + vrule:
\r
1636 tail_append(scan_rule_spec());
\r
1638 if (abs(mode) == vmode)
\r
1639 prev_depth = ignore_depth;
\r
1640 else if (abs(mode) == hmode)
\r
1641 space_factor = 1000;
\r
1645 case vmode + vskip:
\r
1646 case hmode + hskip:
\r
1647 case mmode + hskip:
\r
1648 case mmode + mskip:
\r
1652 case any_mode(kern):
\r
1653 case mmode + mkern:
\r
1657 case non_math(left_brace):
\r
1658 new_save_level(simple_group);
\r
1661 case any_mode(begin_group):
\r
1662 new_save_level(semi_simple_group);
\r
1665 case any_mode(end_group):
\r
1666 if (cur_group == semi_simple_group)
\r
1672 case any_mode(right_brace):
\r
1673 handle_right_brace();
\r
1676 case vmode + hmove:
\r
1677 case hmode + vmove:
\r
1678 case mmode + vmove:
\r
1681 scan_dimen(false, false, false);
\r
1684 scan_box(cur_val);
\r
1686 scan_box(- (integer) cur_val);
\r
1690 case any_mode(leader_ship):
\r
1691 scan_box(leader_flag - a_leaders + cur_chr);
\r
1694 case any_mode(make_box):
\r
1698 case vmode + start_par:
\r
1699 new_graf(cur_chr > 0);
\r
1702 case vmode + letter:
\r
1703 case vmode + other_char:
\r
1704 case vmode + char_num:
\r
1705 case vmode + char_given:
\r
1706 case vmode + math_shift:
\r
1707 case vmode + un_hbox:
\r
1708 case vmode + vrule:
\r
1709 case vmode + accent:
\r
1710 case vmode + discretionary:
\r
1711 case vmode + hskip:
\r
1712 case vmode + valign:
\r
1713 case vmode + ex_space:
\r
1714 case vmode + no_boundary:
\r
1721 case hmode + start_par:
\r
1722 case mmode + start_par:
\r
1723 indent_in_hmode();
\r
1726 case vmode + par_end:
\r
1728 normal_paragraph();
\r
1735 case hmode + par_end:
\r
1737 if (align_state < 0)
\r
1747 case hmode + stop:
\r
1748 case hmode + vskip:
\r
1749 case hmode + hrule:
\r
1750 case hmode + un_vbox:
\r
1751 case hmode + halign:
\r
1755 case any_mode(insert):
\r
1756 case hmode + vadjust:
\r
1757 case mmode + vadjust:
\r
1758 begin_insert_or_adjust();
\r
1761 case any_mode(mark):
\r
1765 case any_mode(break_penalty):
\r
1769 case any_mode(remove_item):
\r
1773 case vmode + un_vbox:
\r
1774 case hmode + un_hbox:
\r
1775 case mmode + un_hbox:
\r
1779 case hmode + ital_corr:
\r
1780 append_italic_correction();
\r
1783 case mmode + ital_corr:
\r
1784 tail_append(new_kern(0));
\r
1787 case hmode + discretionary:
\r
1788 case mmode + discretionary:
\r
1789 append_discretionary();
\r
1792 case hmode + accent:
\r
1796 case any_mode(car_ret):
\r
1797 case any_mode(tab_mark):
\r
1801 case any_mode(no_align):
\r
1805 case any_mode(omit):
\r
1809 case vmode + halign:
\r
1810 case hmode + valign:
\r
1814 case mmode + halign:
\r
1815 if (privileged ())
\r
1816 if (cur_group == math_shift_group)
\r
1822 case vmode + endv:
\r
1823 case hmode + endv:
\r
1827 case any_mode(end_cs_name):
\r
1831 case hmode + math_shift:
\r
1835 case mmode + eq_no:
\r
1836 if (privileged ())
\r
1837 if (cur_group == math_shift_group)
\r
1843 case mmode + left_brace:
\r
1845 tail_append(new_noad());
\r
1847 scan_math(nucleus(tail));
\r
1851 case mmode + letter:
\r
1852 case mmode + other_char:
\r
1853 case mmode + char_given:
\r
1854 set_math_char(math_code(cur_chr));
\r
1857 case mmode + char_num:
\r
1860 cur_chr = cur_val;
\r
1861 set_math_char(math_code(cur_chr));
\r
1865 case mmode + math_char_num:
\r
1867 scan_fifteen_bit_int();
\r
1868 set_math_char(cur_val);
\r
1872 case mmode + math_given:
\r
1873 set_math_char(cur_chr);
\r
1876 case mmode + delim_num:
\r
1878 scan_twenty_seven_bit_int();
\r
1879 set_math_char(cur_val / 4096);
\r
1883 case mmode + math_comp:
\r
1885 tail_append(new_noad());
\r
1886 type(tail) = cur_chr;
\r
1887 scan_math(nucleus(tail));
\r
1891 case mmode + limit_switch:
\r
1892 math_limit_switch();
\r
1895 case mmode + radical:
\r
1899 case mmode + accent:
\r
1900 case mmode + math_accent:
\r
1904 case mmode + vcenter:
\r
1906 scan_spec(vcenter_group, false);
\r
1907 normal_paragraph();
\r
1910 prev_depth = ignore_depth;
\r
1912 if (every_vbox != 0)
\r
1913 begin_token_list(every_vbox, every_vbox_text);
\r
1917 case mmode + math_style:
\r
1918 tail_append(new_style(cur_chr));
\r
1921 case mmode + non_script:
\r
1923 tail_append(new_glue(zero_glue));
\r
1924 subtype(tail) = cond_math_glue;
\r
1928 case mmode + math_choice:
\r
1932 case mmode + sub_mark:
\r
1933 case mmode + sup_mark:
\r
1937 case mmode + above:
\r
1941 case mmode + left_right:
\r
1942 math_left_right();
\r
1945 case mmode + math_shift:
\r
1946 if (cur_group == math_shift_group)
\r
1952 case any_mode(toks_register):
\r
1953 case any_mode(assign_toks):
\r
1954 case any_mode(assign_int):
\r
1955 case any_mode(assign_dimen):
\r
1956 case any_mode(assign_glue):
\r
1957 case any_mode(assign_mu_glue):
\r
1958 case any_mode(assign_font_dimen):
\r
1959 case any_mode(assign_font_int):
\r
1960 case any_mode(set_aux):
\r
1961 case any_mode(set_prev_graf):
\r
1962 case any_mode(set_page_dimen):
\r
1963 case any_mode(set_page_int):
\r
1964 case any_mode(set_box_dimen):
\r
1965 case any_mode(set_shape):
\r
1966 case any_mode(def_code):
\r
1967 case any_mode(def_family):
\r
1968 case any_mode(set_font):
\r
1969 case any_mode(def_font):
\r
1970 case any_mode(tex_register):
\r
1971 case any_mode(advance):
\r
1972 case any_mode(multiply):
\r
1973 case any_mode(divide):
\r
1974 case any_mode(prefix):
\r
1975 case any_mode(let):
\r
1976 case any_mode(shorthand_def):
\r
1977 case any_mode(read_to_cs):
\r
1978 case any_mode(def):
\r
1979 case any_mode(set_box):
\r
1980 case any_mode(hyph_data):
\r
1981 case any_mode(set_interaction):
\r
1982 prefixed_command();
\r
1985 case any_mode(after_assignment):
\r
1988 after_token = cur_tok;
\r
1992 case any_mode(after_group):
\r
1995 save_for_after(cur_tok);
\r
1999 case any_mode(in_stream):
\r
2000 open_or_close_in();
\r
2003 case any_mode(message):
\r
2007 case any_mode(case_shift):
\r
2011 case any_mode(xray):
\r
2015 case any_mode(extension):
\r
2023 adjust_space_factor();
\r
2024 main_f = cur_font;
\r
2025 bchar = font_bchar[main_f];
\r
2026 false_bchar = font_false_bchar[main_f];
\r
2029 if (language != clang)
\r
2032 fast_get_avail(lig_stack);
\r
2033 font(lig_stack) = main_f;
\r
2035 character(lig_stack) = cur_l;
\r
2038 if (cancel_boundary)
\r
2040 cancel_boundary = false;
\r
2041 main_k = non_address;
\r
2044 main_k = bchar_label[main_f];
\r
2046 if (main_k == non_address)
\r
2047 goto main_loop_move_2;
\r
2051 goto main_lig_loop_1;
\r
2053 main_loop_wrapup:
\r
2057 if (lig_stack == 0)
\r
2061 cur_l = character(lig_stack);
\r
2064 if (!is_char_node(lig_stack))
\r
2065 goto main_loop_move_lig;
\r
2068 if ((cur_chr < font_bc[main_f]) || (cur_chr > font_ec[main_f]))
\r
2070 char_warning(main_f, cur_chr);
\r
2071 free_avail(lig_stack);
\r
2075 main_i = char_info(main_f, cur_l);
\r
2077 if (!char_exists(main_i))
\r
2079 char_warning(main_f, cur_chr);
\r
2080 free_avail(lig_stack);
\r
2084 link(tail) = lig_stack;
\r
2087 main_loop_lookahead:
\r
2090 if (cur_cmd == letter)
\r
2091 goto main_loop_lookahead_1;
\r
2093 if (cur_cmd == other_char)
\r
2094 goto main_loop_lookahead_1;
\r
2096 if (cur_cmd == char_given)
\r
2097 goto main_loop_lookahead_1;
\r
2101 if (cur_cmd == letter)
\r
2102 goto main_loop_lookahead_1;
\r
2104 if (cur_cmd == other_char)
\r
2105 goto main_loop_lookahead_1;
\r
2107 if (cur_cmd == char_given)
\r
2108 goto main_loop_lookahead_1;
\r
2110 if (cur_cmd == char_num)
\r
2113 cur_chr = cur_val;
\r
2114 goto main_loop_lookahead_1;
\r
2117 if (cur_cmd == no_boundary)
\r
2122 goto main_lig_loop;
\r
2124 main_loop_lookahead_1:
\r
2125 adjust_space_factor();
\r
2126 fast_get_avail(lig_stack);
\r
2127 font(lig_stack) = main_f;
\r
2129 character(lig_stack) = cur_r;
\r
2131 if (cur_r == false_bchar)
\r
2135 if (char_tag(main_i) != lig_tag)
\r
2136 goto main_loop_wrapup;
\r
2138 if (cur_r == non_char)
\r
2139 goto main_loop_wrapup;
\r
2141 main_k = lig_kern_start(main_f, main_i);
\r
2142 main_j = font_info[main_k].qqqq;
\r
2144 if (skip_byte(main_j) <= stop_flag)
\r
2145 goto main_lig_loop_2;
\r
2147 main_k = lig_kern_restart(main_f, main_j);
\r
2150 main_j = font_info[main_k].qqqq;
\r
2153 bSuppress = false;
\r
2155 if (suppress_f_ligs && next_char(main_j) == cur_r && op_byte(main_j) == no_tag)
\r
2161 if (next_char(main_j) == cur_r && bSuppress == false)
\r
2162 if (skip_byte(main_j) <= stop_flag)
\r
2164 if (op_byte(main_j) >= kern_flag)
\r
2167 tail_append(new_kern(char_kern(main_f, main_j)));
\r
2168 goto main_loop_move;
\r
2171 if (cur_l == non_char)
\r
2173 else if (lig_stack == 0)
\r
2176 check_interrupt();
\r
2178 switch (op_byte(main_j))
\r
2183 cur_l = rem_byte(main_j);
\r
2184 main_i = char_info(main_f, cur_l);
\r
2185 ligature_present = true;
\r
2191 cur_r = rem_byte(main_j);
\r
2193 if (lig_stack == 0)
\r
2195 lig_stack = new_lig_item(cur_r);
\r
2198 else if (is_char_node(lig_stack))
\r
2200 main_p = lig_stack;
\r
2201 lig_stack = new_lig_item(cur_r);
\r
2202 lig_ptr(lig_stack) = main_p;
\r
2205 character(lig_stack) = cur_r;
\r
2210 cur_r = rem_byte(main_j);
\r
2211 main_p = lig_stack;
\r
2212 lig_stack = new_lig_item(cur_r);
\r
2213 link(lig_stack) = main_p;
\r
2221 cur_l = rem_byte(main_j);
\r
2222 main_i = char_info(main_f, cur_l);
\r
2223 ligature_present = true;
\r
2228 cur_l = rem_byte(main_j);
\r
2229 ligature_present = true;
\r
2231 if (lig_stack == 0)
\r
2232 goto main_loop_wrapup;
\r
2234 goto main_loop_move_1;
\r
2239 if (op_byte(main_j) > 4)
\r
2240 if (op_byte(main_j) != 7)
\r
2241 goto main_loop_wrapup;
\r
2243 if (cur_l < non_char)
\r
2244 goto main_lig_loop;
\r
2246 main_k = bchar_label[main_f];
\r
2247 goto main_lig_loop_1;
\r
2250 if (skip_byte(main_j) == 0)
\r
2254 if (skip_byte(main_j) >= stop_flag)
\r
2255 goto main_loop_wrapup;
\r
2257 main_k = main_k + skip_byte(main_j) + 1;
\r
2260 goto main_lig_loop_1;
\r
2262 main_loop_move_lig:
\r
2263 main_p = lig_ptr(lig_stack);
\r
2266 tail_append(main_p);
\r
2268 temp_ptr = lig_stack;
\r
2269 lig_stack = link(temp_ptr);
\r
2270 free_node(temp_ptr, small_node_size);
\r
2271 main_i = char_info(main_f, cur_l);
\r
2272 ligature_present = true;
\r
2274 if (lig_stack == 0)
\r
2276 goto main_loop_lookahead;
\r
2280 cur_r = character(lig_stack);
\r
2282 goto main_lig_loop;
\r
2284 append_normal_space:
\r
2285 if (space_skip == 0)
\r
2288 main_p = font_glue[cur_font];
\r
2292 main_p = new_spec(zero_glue);
\r
2293 main_k = param_base[cur_font] + space_code;
\r
2294 width(main_p) = font_info[main_k].cint;
\r
2295 stretch(main_p) = font_info[main_k + 1].cint;
\r
2296 shrink(main_p) = font_info[main_k + 2].cint;
\r
2297 font_glue[cur_font] = main_p;
\r
2301 temp_ptr = new_glue(main_p);
\r
2304 temp_ptr = new_param_glue(space_skip_code);
\r
2306 link(tail) = temp_ptr;
\r