home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Tex / Tex29 / StTeXsrc.zoo / src / mathlists.c < prev    next >
C/C++ Source or Header  |  1988-03-13  |  20KB  |  754 lines

  1.  
  2. /*
  3.  * @(#)mathlists.c 2.6 EPA
  4.  *
  5.  * Copyright 1987,1988 Pat J Monardo
  6.  *
  7.  * Redistribution of this file is permitted through
  8.  * the specifications in the file COPYING.
  9.  *
  10.  * 
  11.  */
  12.  
  13. #include "tex.h"
  14. #include "eqstack.h"
  15. #include "evalstack.h"
  16. #include "token.h"
  17. #include "tokenstack.h"
  18. #include "scan.h"
  19. #include "tfm.h"
  20. #include "box.h"
  21. #include "pack.h"
  22. #include "math.h"
  23. #include "mlst-hlst.h"
  24. #include "par.h"
  25. #include "page.h"
  26. #include "mathlists.h"
  27.  
  28. push_math (c)
  29.     group   c;
  30. {
  31.     push_nest();
  32.     mode = -MMODE;
  33.     incompleat_noad = NULL;
  34.     new_save_level(c);
  35. }
  36.  
  37. init_math ()
  38. {
  39.     scal    d;
  40.     fnt     f;
  41.     scal    l;
  42.     int     n;
  43.     ptr     p;
  44.     ptr     q;
  45.     scal    s;
  46.     scal    v;
  47.     scal    w;
  48.  
  49.     get_token();
  50.     if (cur_cmd == MATH_SHIFT && mode > 0) {
  51.         if (head == tail) {
  52.             pop_nest();
  53.             w = -MAX_DIMEN;
  54.         } else {
  55.             line_break(display_widow_penalty);
  56.             v = shift_amount(just_box) + 2 * quad(cur_font);
  57.             w = -MAX_DIMEN;
  58.             p = list_ptr(just_box);
  59.             while (p != NULL) {
  60.         reswitch:
  61.                 if (is_char_node(p)) {
  62.                     f = font(p);
  63.                     d = char_width(f, char_info(f, character(p)));
  64.                     goto found;
  65.                 }
  66.                 switch (type(p))
  67.                 {
  68.                 case HLIST_NODE:
  69.                 case VLIST_NODE:
  70.                 case RULE_NODE:
  71.                     d = width(p);
  72.                     goto found;
  73.                 
  74.                 case LIGATURE_NODE:
  75.                     make_char_from_lig();
  76.                     goto reswitch;
  77.                 
  78.                 case KERN_NODE:
  79.                 case MATH_NODE:
  80.                     d = width(p);
  81.                     break;
  82.  
  83.                 case GLUE_NODE:
  84.                     q = glue_ptr(p);
  85.                     d = width(q);
  86.                     if (glue_sign(just_box) == STRETCHING) {
  87.                         if (glue_order(just_box) == stretch_order(q) &&
  88.                             stretch(q) != 0)
  89.                             v = MAX_DIMEN;
  90.                     } else if (glue_sign(just_box) == SHRINKING)  {
  91.                         if (glue_order(just_box) == shrink_order(q) &&
  92.                             shrink(q) != 0) 
  93.                             v = MAX_DIMEN;
  94.                     }
  95.                     if (subtype(p) >= A_LEADERS)    
  96.                         goto found;
  97.                     break;
  98.  
  99.                 case WHATSIT_NODE: 
  100.                     d = 0;
  101.                     break;
  102.  
  103.                 default:
  104.                     d = 0;
  105.                     break;
  106.                 }
  107.                 if (v < MAX_DIMEN)
  108.                     v += d;
  109.                 goto not_found;
  110.             
  111.             found:
  112.                 if (v < MAX_DIMEN) {
  113.                     v += d;
  114.                     w = v;
  115.                 } else {
  116.                     w = MAX_DIMEN;
  117.                     break;
  118.                 }
  119.  
  120.             not_found:
  121.                 p = link(p);
  122.             }
  123.         }
  124.         if (par_shape_ptr == NULL) {
  125.             if (hang_indent != 0 &&
  126.                 (hang_after >= 0 &&
  127.                 prev_graf + 2 > hang_after ||
  128.                 prev_graf + 1 < -hang_after)) {
  129.                 l = hsize - abs(hang_indent);
  130.                 s = (hang_indent > 0) ? hang_indent : 0;
  131.             } else {
  132.                 l = hsize;
  133.                 s = 0;
  134.             }
  135.         } else {
  136.             n = info(par_shape_ptr);
  137.             if (prev_graf + 2 >= n)
  138.                 p = par_shape_ptr + 2 * n;
  139.             else p = par_shape_ptr + 2 * (prev_graf + 2);
  140.             s = mem[p - 1].sc;
  141.             l = mem[p].sc;
  142.         }
  143.         push_math(MATH_SHIFT_GROUP);
  144.         mode = MMODE;
  145.         eq_word_define(INT_BASE + CUR_FAM_CODE, -1L);
  146.         eq_word_define(DIMEN_BASE + PRE_DISPLAY_SIZE_CODE, w);
  147.         eq_word_define(DIMEN_BASE + DISPLAY_WIDTH_CODE, l);
  148.         eq_word_define(DIMEN_BASE + DISPLAY_INDENT_CODE, s);
  149.         if (every_display != NULL)
  150.             begin_token_list(every_display, EVERY_DISPLAY_TEXT);
  151.         if (nest_ptr == 1)
  152.             build_page();
  153.     } else {
  154.         back_input(); 
  155.         push_math(MATH_SHIFT_GROUP);
  156.         eq_word_define(INT_BASE + CUR_FAM_CODE, -1L);
  157.         if (every_math != NULL)
  158.             begin_token_list(every_math, EVERY_MATH_TEXT);
  159.     }
  160. }
  161.  
  162. start_eq_no ()
  163. {
  164.     saved(0) = cur_chr;
  165.     incr(save_ptr);
  166.     push_math(MATH_SHIFT_GROUP);
  167.     eq_word_define(INT_BASE + CUR_FAM_CODE, -1L);
  168.     if (every_math != NULL)
  169.         begin_token_list(every_math, EVERY_MATH_TEXT);
  170. }
  171.  
  172. #define fam_in_range()   (cur_fam >= 0 && cur_fam < 16)
  173.  
  174. scan_math (p)
  175.     ptr     p;
  176. {
  177.     int     c;
  178.  
  179. restart:
  180.     get_nbrx_token();
  181.  
  182. reswitch:
  183.     switch (cur_cmd)
  184.     {
  185.     case LETTER:
  186.     case OTHER_CHAR:
  187.     case CHAR_GIVEN:
  188.         if (cur_chr >= 128) {
  189.             c = cur_chr;
  190.         } else {
  191.             c = ho(math_code(cur_chr));
  192.             if (c == 0100000) {
  193.                 cur_cs = cur_chr + ACTIVE_BASE;
  194.                 cur_cmd = eq_type(cur_cs);
  195.                 cur_chr = equiv(cur_cs);
  196.                 x_token();
  197.                 back_input();
  198.                 goto restart;
  199.             }
  200.         }
  201.         break;
  202.     
  203.     case CHAR_NUM:
  204.         scan_char_num();
  205.         cur_chr = cur_val;
  206.         cur_cmd = CHAR_GIVEN;
  207.         goto reswitch;
  208.         break;
  209.     
  210.     case MATH_CHAR_NUM:
  211.         scan_fifteen_bit_int();
  212.         c = cur_val;
  213.         break;
  214.  
  215.     case MATH_GIVEN:
  216.         c = cur_chr;
  217.         break;
  218.         
  219.     case DELIM_NUM:
  220.         scan_twenty_seven_bit_int();
  221.         c = (cur_val>>12);
  222.         break;
  223.  
  224.     default:
  225.         back_input();
  226.         scan_left_brace();
  227.         saved(0) = p;
  228.         incr(save_ptr);
  229.         push_math(MATH_GROUP);
  230.         return;
  231.         break;
  232.     }
  233.     math_type(p) = MATH_CHAR;
  234.     character(p) = (c&255);
  235.     if (c >= VAR_CODE && fam_in_range())
  236.         fam(p) = cur_fam;
  237.     else fam(p) = ((c>>8)&15);
  238. }
  239.  
  240. set_math_char (c)
  241.     int     c;
  242. {
  243.     ptr     p;
  244.  
  245.     if (c >= 0100000) {
  246.         cur_cs = cur_chr + ACTIVE_BASE;
  247.         cur_cmd = eq_type(cur_cs);
  248.         cur_chr = equiv(cur_cs);
  249.         x_token();
  250.         back_input();
  251.     } else {
  252.         p = new_noad();
  253.         math_type(nucleus(p)) = MATH_CHAR;
  254.         character(nucleus(p)) = c%256;
  255.         fam(nucleus(p)) = (c/256)%16;
  256.         if (c >= VAR_CODE) {
  257.             if (fam_in_range())
  258.                 fam(nucleus(p)) = cur_fam;
  259.             type(p) = ORD_NOAD;
  260.         } else type(p) = ORD_NOAD + (c>>12);
  261.         link(tail) = p;
  262.         tail = p;
  263.     }
  264. }
  265.  
  266. math_limit_switch ()
  267. {
  268.     if (head != tail && type(tail) == OP_NOAD) {
  269.         subtype(tail) = cur_chr;
  270.         return;
  271.     }
  272.     print_err("Limit controls must follow a math operator");
  273.     help_limits();
  274.     error();
  275. }
  276.  
  277. scan_delimiter (p, r)
  278.     ptr     p;
  279.     bool    r;
  280. {
  281.     if (r) {
  282.         scan_twenty_seven_bit_int();
  283.     } else {
  284.         get_nbrx_token();
  285.         switch (cur_cmd) 
  286.         {
  287.         case LETTER:
  288.         case OTHER_CHAR:
  289.             cur_val = del_code(cur_chr);
  290.             break;
  291.  
  292.         case DELIM_NUM:
  293.             scan_twenty_seven_bit_int();
  294.             break;
  295.  
  296.         default:
  297.             cur_val = -1;
  298.             break;
  299.         }
  300.     }
  301.     if (cur_val < 0) {
  302.         print_err("Missing delimiter (. inserted)");
  303.         help_delimiter();
  304.         back_error();
  305.         cur_val =  0;
  306.     }
  307.     small_fam(p) = (cur_val>>20)&15;
  308.     small_char(p) = qi((cur_val>>12)&255);
  309.     large_fam(p) = (cur_val>>8)&15;
  310.     large_char(p) = qi(cur_val&255);
  311. }
  312.  
  313. math_radical ()
  314. {
  315.     tail_append(get_node(RADICAL_NOAD_SIZE));
  316.     type(tail) = RADICAL_NOAD;
  317.     subtype(tail) = NORMAL;
  318.     mem[nucleus(tail)].hh = empty_field;
  319.     mem[supscr(tail)].hh = empty_field;
  320.     mem[subscr(tail)].hh = empty_field;
  321.     scan_delimiter(left_delimiter(tail), TRUE);
  322.     scan_math(nucleus(tail));
  323. }
  324.  
  325. math_ac ()
  326. {
  327.     if (cur_cmd == ACCENT) {
  328.         print_err("Please use ");
  329.         print_esc("mathaccent");
  330.         print(" for accents in math mode");
  331.         help_math_accent();
  332.         error();
  333.     }
  334.     tail_append(get_node(ACCENT_NOAD_SIZE));
  335.     type(tail) = ACCENT_NOAD;
  336.     subtype(tail) = NORMAL;
  337.     mem[nucleus(tail)].hh = empty_field;
  338.     mem[subscr(tail)].hh = empty_field;
  339.     mem[supscr(tail)].hh = empty_field;
  340.     math_type(accent_chr(tail)) = MATH_CHAR;
  341.     scan_fifteen_bit_int();
  342.     character(accent_chr(tail)) = qi(cur_val&255);
  343.     if (cur_val >= VAR_CODE && fam_in_range())
  344.         fam(accent_chr(tail)) = cur_fam;
  345.     else fam(accent_chr(tail)) = (cur_val>>8)&15;
  346.     scan_math(nucleus(tail));
  347. }
  348.  
  349. append_choices ()
  350. {
  351.     tail_append(new_choice());
  352.     incr(save_ptr);
  353.     saved(-1) = 0;
  354.     scan_left_brace();
  355.     push_math(MATH_CHOICE_GROUP);
  356. }
  357.  
  358. build_choices ()
  359. {
  360.     ptr     p;
  361.  
  362.     unsave();
  363.     p = fin_mlist(NULL);
  364.     switch ((int) saved(-1)) {
  365.     case 0: display_mlist(tail) = p; break;
  366.     case 1: text_mlist(tail) = p; break;
  367.     case 2: script_mlist(tail) = p; break;
  368.     case 3: script_script_mlist(tail) = p; decr(save_ptr); return;
  369.     }
  370.     incr(saved(-1));
  371.     scan_left_brace();
  372.     push_math(MATH_CHOICE_GROUP);
  373. }
  374.  
  375. sub_sup ()
  376. {
  377.     ptr     p = NULL;
  378.     int     t = EMPTY;
  379.  
  380.     if (tail != head && scripts_allowed(tail)) {
  381.         p = supscr(tail) + cur_cmd - SUP_MARK;
  382.         t = math_type(p);
  383.     }
  384.     if (p == NULL || t != EMPTY) {
  385.         tail_append(new_noad());
  386.         p = supscr(tail) + cur_cmd - SUP_MARK;
  387.         if (t != EMPTY) {
  388.             if (cur_cmd == SUP_MARK) {
  389.                 print_err("Double superscript");
  390.                 help_double_sup();
  391.             } else {
  392.                 print_err("Double subscript");
  393.                 help_double_sub();
  394.             }
  395.             error();
  396.         }
  397.     }
  398.     scan_math(p);
  399. }
  400.  
  401. math_fraction ()
  402. {
  403.     int     c;
  404.  
  405.     c = cur_chr;
  406.     if (incompleat_noad != NULL) {
  407.         if (c >= DELIMITED_CODE) {
  408.             scan_delimiter(garbage, FALSE);
  409.             scan_delimiter(garbage, FALSE);
  410.         }
  411.         if (c % DELIMITED_CODE == ABOVE_CODE)
  412.             scan_normal_dimen();
  413.         print_err("Ambiguous; you need another { and }");
  414.         help_fraction();
  415.         error();
  416.     } else {
  417.         incompleat_noad = get_node(FRACTION_NOAD_SIZE);
  418.         type(incompleat_noad) = FRACTION_NOAD;
  419.         subtype(incompleat_noad) = NORMAL;
  420.         math_type(numerator(incompleat_noad)) = SUB_MLIST;
  421.         info(numerator(incompleat_noad)) = link(head);
  422.         mem[denominator(incompleat_noad)].hh = empty_field;
  423.         mem[left_delimiter(incompleat_noad)].qqqq = null_delimiter;
  424.         mem[right_delimiter(incompleat_noad)].qqqq = null_delimiter;
  425.         link(head) = NULL;
  426.         tail = head;
  427.         if (c >= DELIMITED_CODE) {
  428.             scan_delimiter(left_delimiter(incompleat_noad), FALSE);
  429.             scan_delimiter(right_delimiter(incompleat_noad), FALSE);
  430.         }
  431.         switch (c % DELIMITED_CODE)
  432.         {
  433.         case ABOVE_CODE:
  434.             scan_normal_dimen();
  435.             thickness(incompleat_noad) = cur_val;
  436.             break;
  437.  
  438.         case OVER_CODE:
  439.             thickness(incompleat_noad) = DEFAULT_CODE;
  440.             break;
  441.  
  442.         case ATOP_CODE:
  443.             thickness(incompleat_noad) = 0;
  444.             break;
  445.         }
  446.     }
  447. }
  448.  
  449. ptr
  450. fin_mlist (p)
  451.     ptr     p;
  452. {
  453.     ptr     q;
  454.  
  455.     if (incompleat_noad != NULL) {
  456.         math_type(denominator(incompleat_noad)) = SUB_MLIST;
  457.         info(denominator(incompleat_noad)) = link(head);
  458.         if (p == NULL) {
  459.             q = incompleat_noad;
  460.         } else {
  461.             q = info(numerator(incompleat_noad));
  462.             if (type(q) != LEFT_NOAD)
  463.                 confusion("right");
  464.             info(numerator(incompleat_noad)) = link(q);
  465.             link(q) = incompleat_noad;
  466.             link(incompleat_noad) = p;
  467.         }
  468.     } else {
  469.         link(tail) = p;
  470.         q = link(head);
  471.     }
  472.     pop_nest();
  473.     return q;
  474. }
  475.  
  476. math_left_right ()
  477. {
  478.     ptr     p;
  479.     int     t;
  480.  
  481.     t = cur_chr;
  482.     if (t == RIGHT_NOAD && cur_group != MATH_LEFT_GROUP) {
  483.         if (cur_group == MATH_SHIFT_GROUP) {
  484.             scan_delimiter(garbage, FALSE);
  485.             print_err("Extra ");
  486.             print_esc("right");
  487.             help_xtra_right();
  488.             error();
  489.         } else
  490.             off_save();
  491.     } else {
  492.         p = new_noad();
  493.         type(p) = t;
  494.         scan_delimiter(delimiter(p), FALSE);
  495.         if (t == LEFT_NOAD) {
  496.             push_math(MATH_LEFT_GROUP);
  497.             link(head) = p;
  498.             tail = p;
  499.         } else {
  500.             p = fin_mlist(p);
  501.             unsave();
  502.             tail_append(new_noad());
  503.             type(tail) = INNER_NOAD;
  504.             math_type(nucleus(tail)) = SUB_MLIST;
  505.             info(nucleus(tail)) = p;
  506.         }
  507.     }
  508. }
  509.  
  510. after_math ()
  511. {
  512.     ptr     a;
  513.     ptr     b;
  514.     scal    d;
  515.     scal    e;
  516.     bool    l;
  517.     int     m;
  518.     ptr     p;
  519.     scal    q;
  520.     ptr     r;
  521.     scal    s;
  522.     scal    t;
  523.     scal    w;
  524.     scal    z;
  525.     int     g1;
  526.     int     g2;
  527.     bool    danger;
  528.  
  529.     danger = FALSE;
  530.     if (font_params[fam_fnt(2 + TEXT_SIZE)] < TOTAL_MATHSY_PARAMS ||
  531.         font_params[fam_fnt(2 + SCRIPT_SIZE)] < TOTAL_MATHSY_PARAMS ||
  532.         font_params[fam_fnt(2 + SCRIPT_SCRIPT_SIZE)] < TOTAL_MATHSY_PARAMS) {
  533.         print_err("Math formula deleted: Insufficient symbol fonts");
  534.         help_math_sy();
  535.         error();
  536.         flush_math();
  537.         danger = TRUE;
  538.     } else if (font_params[fam_fnt(3 + TEXT_SIZE)] < TOTAL_MATHEX_PARAMS ||
  539.         font_params[fam_fnt(3 + SCRIPT_SIZE)] < TOTAL_MATHEX_PARAMS ||
  540.         font_params[fam_fnt(3 + SCRIPT_SCRIPT_SIZE)] < TOTAL_MATHEX_PARAMS) {
  541.         print_err("Math formula deleted: Insufficient extension fonts");
  542.         help_math_ex();
  543.         error();
  544.         flush_math();
  545.         danger = TRUE;
  546.     }
  547.     m = mode;
  548.     l = FALSE;
  549.     p = fin_mlist(NULL);
  550.     if (mode == -m) {
  551.         cur_mlist = p;
  552.         cur_style = TEXT_STYLE;
  553.         mlist_penalties = FALSE;
  554.         mlist_to_hlist();
  555.         a = hpack(link(temp_head), NATURAL);
  556.         unsave();
  557.         decr(save_ptr);
  558.         if (saved(0) == 1)
  559.             l = TRUE;
  560.         if (danger)
  561.             flush_math();
  562.         m = mode;
  563.         p = fin_mlist(NULL);
  564.     } else {
  565.         a = NULL;
  566.     }
  567.     if (m < 0) {
  568.         tail_append(new_math(math_surround, BEFORE));
  569.         cur_mlist = p;
  570.         cur_style = TEXT_STYLE;
  571.         mlist_penalties = (mode > 0);
  572.         mlist_to_hlist();
  573.         link(tail) = link(temp_head);
  574.         while (link(tail) != NULL)
  575.             tail = link(tail);
  576.         tail_append(new_math(math_surround, AFTER));
  577.         space_factor = 1000;
  578.         unsave();
  579.     } else {
  580.         get_x_token();
  581.         if (cur_cmd != MATH_SHIFT) {
  582.             print_err("Display math should end with $$");
  583.             help_doldol();
  584.             back_error();
  585.         }
  586.         cur_mlist = p;
  587.         cur_style = DISPLAY_STYLE;
  588.         mlist_penalties = FALSE;
  589.         mlist_to_hlist();
  590.         p = link(temp_head);
  591.         adjust_tail = adjust_head;
  592.         b = hpack(p, NATURAL);
  593.         t = adjust_tail;
  594.         adjust_tail = NULL;
  595.         w = width(b);
  596.         z = display_width;
  597.         s = display_indent;
  598.         if (a == NULL || danger)
  599.             e = q = 0;
  600.         else {
  601.             e = width(a);
  602.             q = e + math_quad(TEXT_SIZE);
  603.         }
  604.         if (w + q > z) {
  605.             if (e != 0 &&
  606.                 (w - total_shrink[NORMAL] + q <= z ||
  607.                 total_shrink[FIL] != 0 ||
  608.                 total_shrink[FILL] != 0 ||
  609.                 total_shrink[FILLL] != 0)) {
  610.                 free_node(b, BOX_NODE_SIZE);
  611.                 b = hpack(p, z - q, EXACTLY);
  612.             } else {
  613.                 e = 0;
  614.                 if (w > z) {
  615.                     free_node(b, BOX_NODE_SIZE);
  616.                     b = hpack(p, z, EXACTLY);
  617.                 }
  618.             }
  619.             w = width(b);
  620.         }
  621.         d = half(z - w);
  622.         if (e > 0 && d < 2 * e) {
  623.             d = half(z - w - e);
  624.             if (p != NULL && type(p) == GLUE_NODE)
  625.                 d = 0;
  626.         }
  627.         tail_append(new_penalty(pre_display_penalty));
  628.         if (d + s <= pre_display_size || l) {
  629.             g1 = ABOVE_DISPLAY_SKIP_CODE;
  630.             g2 = BELOW_DISPLAY_SKIP_CODE;
  631.         } else {
  632.             g1 = ABOVE_DISPLAY_SHORT_SKIP_CODE;
  633.             g2 = BELOW_DISPLAY_SHORT_SKIP_CODE;
  634.         }
  635.         if (l && e == 0) {
  636.             shift_amount(a) = s;
  637.             append_to_vlist(a);
  638.             tail_append(new_penalty(INF_PENALTY));
  639.         } else {
  640.             tail_append(new_param_glue(g1));
  641.         }
  642.         if (e != 0) {
  643.             r = new_kern(z - w - e - d);
  644.             if (l) {
  645.                 link(a) = r;
  646.                 link(r) = b;
  647.                 b = a;
  648.                 d = 0;
  649.             } else {
  650.                 link(b) = r;
  651.                 link(r) = a;
  652.             }
  653.             b = hpack(b, NATURAL);
  654.         }
  655.         shift_amount(b) = s + d;
  656.         append_to_vlist(b);
  657.         if (t != adjust_head) {
  658.             link(tail) = link(adjust_head);
  659.             tail = t;
  660.         }
  661.         if (a != NULL && e == 0 && !l) {
  662.             tail_append(new_penalty(INF_PENALTY));
  663.             shift_amount(a) = s + z - width(a);
  664.             append_to_vlist(a);
  665.             tail_append(new_penalty(post_display_penalty));
  666.         } else {
  667.             tail_append(new_penalty(post_display_penalty));
  668.             tail_append(new_param_glue(g2));
  669.         }
  670.         resume_after_display();
  671.     }
  672. }
  673.  
  674. resume_after_display ()
  675. {
  676.     if (cur_group != MATH_SHIFT_GROUP)
  677.         confusion("display");
  678.     unsave();
  679.     prev_graf += 3;
  680.     push_nest();
  681.     mode = HMODE;
  682.     space_factor = 1000;
  683.     scan_optional_space();
  684.     if (nest_ptr == 1) 
  685.         build_page();
  686. }
  687.  
  688. /*
  689.  *  Help text
  690.  */
  691.  
  692. help_math_accent ()
  693. {
  694.     help2("I'm changing \\accent to \\mathaccent here; wish me luck.",
  695.     "(Accents are not the same in formulas as they are in text.)" );
  696. }
  697.  
  698. help_math_sy ()
  699. {
  700.     help3("Sorry, but I can't typeset math unless \\textfont 2",
  701.     "and \\scriptfont 2 and \\scriptscriptfont 2 have all",
  702.     "the \\fontdimen values needed in math symbol fonts." );
  703. }
  704.  
  705. help_math_ex ()
  706. {
  707.     help3("Sorry, but I can't typeset math unless \\textfont 3",
  708.     "and \\scriptfont 3 and \\scriptscriptfont 3 have all",
  709.     "the \\fontdimen values needed in math extension fonts." );
  710. }
  711.  
  712. help_limits ()
  713. {
  714.     help1("I'm ignoring this misplaced \\limits or \\nolimits command.");
  715. }
  716.  
  717. help_delimiter ()
  718. {
  719.     help6("I was expecting to see something like `(' or `\\{' or",
  720.     "`\\}' here. If you typed, e.g., `{' instead of `\\{', you",
  721.     "should probably delete the `{' by typing `1' now, so that",
  722.     "braces don't get unbalanced. Otherwise just proceed.",
  723.     "Acceptable delimiters are characters whose \\delcode is",
  724.     "nonnegative, or you can use `\\delimiter <delimiter code>'.");
  725. }
  726.  
  727. help_fraction ()
  728. {
  729.     help3("I'm ignoring this fraction specification, since I don't",
  730.     "know whether a construction like `x \\over y \\over z'",
  731.     "means `{x \\over y} \\over z' or `x \\over {y \\over z}'.");
  732. }
  733.  
  734. help_xtra_right ()
  735. {
  736.     help1("I'm ignoring a \\right that had no matching \\left.");
  737. }
  738.  
  739. help_doldol ()
  740. {
  741.     help2("The `$' that I just saw supposedly matches a previous `$$'.",
  742.     "So I shall assume that you typed `$$' both times.");
  743. }
  744.  
  745. help_double_sub ()
  746. {
  747.     help1("I treat `x_1_2' essentially like `x_1{}_2'.");
  748. }
  749.  
  750. help_double_sup ()
  751. {
  752.     help1("I treat `x^1^2' essentially like `x^1{}^2'.");
  753. }
  754.