home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / texmf / source / TeX / tex / math.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-08  |  32.6 KB  |  1,335 lines

  1. #define EXTERN extern
  2. #include "texd.h"
  3.  
  4. static halfword cleanbox (halfword p, smallnumber style);
  5. static void    fetch (halfword a, smallnumber size);
  6. static void    makeover (halfword q, smallnumber style, smallnumber size);
  7. static void    makeunder (halfword q, smallnumber style, smallnumber size);
  8. static void    makevcenter (halfword q, smallnumber size);
  9. static void    makeradical (halfword q, smallnumber style, smallnumber size);
  10. static void    makemathaccent (halfword q, smallnumber sty, smallnumber sz);
  11. static void    makefraction (halfword q, smallnumber style, smallnumber size);
  12. static scaled    makeop (halfword q, smallnumber style, smallnumber size);
  13. static void    makeord (halfword q, smallnumber cursize);
  14. static void    makescripts (halfword q, scaled delta, smallnumber curstyle,
  15.                     smallnumber cursize);
  16. static smallnumber makeleftright (halfword q, smallnumber style,
  17.                     scaled maxd, scaled maxh);
  18. static long_halfword
  19.         mlisttohlist (long_halfword curmlist,
  20.                   smallnumber curstyle,
  21.                   int mlistpenalties);
  22.  
  23.  
  24.    static halfword
  25. cleanbox (halfword p, smallnumber curstyle)
  26. { cleanbox_regmem 
  27.   register halfword x;
  28.   register long_halfword q;
  29.  
  30.   switch ( mathtype ( p ) ) {
  31.   case mathchar : 
  32.     q = newnoad () ; 
  33.     mem [ nucleus ( q ) ] = mem [ p ];
  34.     break;
  35.   case submlist : 
  36.     q = info ( p );
  37.     break ; 
  38.  
  39.   case subbox : 
  40.     q = info ( p );
  41.     goto lab40 ; 
  42.     break ; 
  43.   default: 
  44.     q = newnullbox();
  45.     goto lab40 ; 
  46.     break ; 
  47.   } 
  48.  
  49.   q = mlisttohlist (q, curstyle, false);
  50.   /* q = link ( temphead ); */
  51.  
  52. lab40:
  53.   if ( ischarnode(q) || (q == 0) )
  54.     x = hpack( q, 0, 1 );
  55.   else if( (link(q) == 0) && (ztype(q) <= vlistnode) && (shiftamount(q) == 0) )
  56.     x = q;
  57.   else
  58.     x = hpack( q, 0, 1 );
  59.   q = listptr ( x );
  60.   if ( ischarnode ( q ) ) {
  61.     register halfword r;
  62.  
  63.     r = link ( q );
  64.     if( (r != 0) && (link(r) == 0)
  65.     && !ischarnode(r) && (ztype(r) == kernnode) ) {
  66.       freenode( r, smallnodesize );
  67.       link ( q ) = 0;
  68.     }
  69.   }
  70.   return(x);
  71. }
  72.  
  73.  
  74.    static void
  75. fetch (halfword a, smallnumber cursize)
  76. { fetch_regmem 
  77.  
  78.   curc = character ( a ) ; 
  79.   curf = famfnt ( fam ( a ) + cursize );
  80.   if ( curf == nullfont ) {
  81.     print_err("");
  82.     printsize( cursize );  printchar( 32 );  printint( fam(a) );
  83.     c_print(" is undefined (character ");
  84.     print ( curc );  printchar ( 41 );
  85.     zhelp1( STR_H_SOMEWHERE_IN_MATH );
  86.     error();
  87.     curi = nullcharacter ; 
  88.     mathtype ( a ) = 0 ; 
  89.   } else {
  90.     if ( curc >= fontbc(curf) && curc <= fontec(curf) )
  91.       curi = zcharinfo ( curf ,  curc ) ; 
  92.     else
  93.       curi = nullcharacter;
  94.     if ( ! ( charexists ( curi ) ) ) {
  95.       charwarning ( curf , curc ) ; 
  96.       mathtype ( a ) = 0;
  97.     }
  98.   }
  99. }
  100.  
  101.    static void
  102. makeover (halfword q, smallnumber curstyle, smallnumber cursize)
  103. { makeover_regmem 
  104.  
  105.   info(nucleus(q)) = overbar( cleanbox( nucleus(q), crampedstyle(curstyle) ),
  106.             3 * defaultrulethickness, defaultrulethickness );
  107.   mathtype( nucleus(q) ) = subbox;
  108. }
  109.  
  110.  
  111.    static void
  112. makeunder (halfword q, smallnumber curstyle, smallnumber cursize)
  113. { makeunder_regmem 
  114.   register halfword p, x, y  ; 
  115.   register scaled delta  ; 
  116.  
  117.   x = cleanbox ( nucleus ( q ) , curstyle ) ; 
  118.   p = newkern ( 3 * defaultrulethickness ) ; 
  119.   link ( x ) = p ; 
  120.   link ( p ) = fractionrule ( defaultrulethickness ) ; 
  121.  
  122.   y = vpackage ( x , 0 , 1 , maxdimen ) ; 
  123.   delta = height ( y ) + depth ( y ) + defaultrulethickness ; 
  124.   height ( y ) = height ( x ) ; 
  125.   depth ( y ) = delta - height ( y ) ; 
  126.  
  127.   info ( nucleus ( q ) ) = y ; 
  128.   mathtype ( nucleus ( q ) ) = subbox ; 
  129. }
  130.  
  131.  
  132.    static void
  133. makevcenter (halfword q, smallnumber cursize)
  134. { makevcenter_regmem 
  135.   register halfword v;
  136.   register scaled delta;
  137.  
  138.   v = info ( nucleus ( q ) ) ; 
  139.   if ( ztype ( v ) != vlistnode ) 
  140.     confusion("vcenter");
  141.   delta = height ( v ) + depth ( v ) ; 
  142.   height ( v ) = axisheight ( cursize ) + half ( delta ) ; 
  143.   depth ( v ) = delta - height ( v ) ; 
  144. }
  145.  
  146.  
  147.    static void
  148. makeradical (halfword q, smallnumber curstyle, smallnumber cursize)
  149. { makeradical_regmem 
  150.   register halfword x, y;
  151.   register scaled delta, clr;
  152.  
  153.   x = cleanbox ( nucleus ( q ) , crampedstyle ( curstyle ) ) ; 
  154.   if ( curstyle < textstyle ) 
  155.     clr = defaultrulethickness + ( abs ( mathxheight ( cursize ) ) / 4 ) ; 
  156.   else {
  157.     clr = defaultrulethickness ; 
  158.     clr = clr + ( abs ( clr ) / 4 ) ; 
  159.   } 
  160.   y = vardelimiter ( leftdelimiter ( q ) , cursize ,
  161.         height ( x ) + depth ( x ) + clr + defaultrulethickness ) ;
  162.   delta = depth ( y ) - ( height ( x ) + depth ( x ) + clr ) ; 
  163.   if ( delta > 0 )
  164.     clr = clr + half ( delta ) ; 
  165.   shiftamount ( y ) = - (integer) ( height ( x ) + clr ) ; 
  166.   link ( y ) = overbar ( x , clr , height ( y ) ) ; 
  167.   info ( nucleus ( q ) ) = hpack ( y , 0 , 1 ) ; 
  168.   mathtype ( nucleus ( q ) ) = subbox ; 
  169. }
  170.  
  171.  
  172.    static void
  173. makemathaccent (halfword q, smallnumber curstyle, smallnumber cursize)
  174. { makemathaccent_regmem 
  175.   register halfword x, y  ; 
  176.   register quarterword c  ; 
  177.   register internalfontnumber f  ; 
  178.   fourquarters i  ; 
  179.   register scaled s  ; 
  180.   register scaled h  ; 
  181.   register scaled delta  ; 
  182.   register scaled w  ; 
  183.  
  184.   fetch ( accentchr ( q ), cursize ) ; 
  185.   if ( charexists ( curi ) ) {
  186.     i = curi ; 
  187.     c = curc ; 
  188.     f = curf ; 
  189.     s = 0 ; 
  190.     if ( mathtype ( nucleus ( q ) ) == mathchar ) {
  191.       fetch ( nucleus ( q ), cursize ) ; 
  192.       if ( chartag ( curi ) == ligtag ) {
  193. #ifdef FONTPTR
  194.     register SMALLmemoryword *ligp;
  195.  
  196.     ligp = zligkernstart ( curf ,  curi ) ;
  197.     curi = ligp->qqqq ;
  198.     if ( skipbyte ( curi ) > stopflag ) {
  199.       ligp = zligkernrestart ( curf ,  curi ) ; 
  200.       curi = ligp->qqqq ;
  201.     } 
  202. #else
  203.     register integer a ;
  204.  
  205.     a = zligkernstart ( curf ,  curi ) ;
  206.     curi = fontinfo [ a ] .qqqq ;
  207.     if ( skipbyte ( curi ) > stopflag ) {
  208.       a = zligkernrestart ( curf ,  curi ) ; 
  209.       curi = fontinfo [ a ] .qqqq ;
  210.     } 
  211. #endif
  212.     while ( true ) {
  213.       if ( nextchar ( curi ) == skewchar(curf) ) {
  214.         if( (opbyte(curi) >= kernflag) && (skipbyte(curi) <= stopflag) )
  215.           s = zcharkern( curf, curi );
  216.         goto lab31;
  217.       }
  218.       if ( skipbyte ( curi ) >= stopflag ) 
  219.         goto lab31 ;
  220. #ifdef FONTPTR
  221.       ligp = ligp + skipbyte ( curi ) + 1 ; 
  222.       curi = ligp->qqqq ;
  223. #else
  224.       a = a + skipbyte ( curi ) + 1 ; 
  225.       curi = fontinfo [ a ] .qqqq ;
  226. #endif
  227.     } 
  228.       }
  229.     }
  230.  
  231. lab31:
  232.     x = cleanbox ( nucleus ( q ) , crampedstyle ( curstyle ) ) ; 
  233.     w = width ( x ) ; 
  234.     h = height ( x ) ; 
  235.     while ( true ) {
  236.       if ( chartag ( i ) != listtag ) 
  237.         goto lab30 ; 
  238.       y = rembyte ( i ) ; 
  239.       i = zcharinfo ( f ,  y ) ; 
  240.       if ( ! charexists ( i ) ) 
  241.         goto lab30 ; 
  242.       if ( zcharwidth ( f ,  i ) > w ) 
  243.         goto lab30 ; 
  244.       c = y ; 
  245.     } 
  246.  
  247. lab30:
  248.     if ( h < xheight ( f ) ) 
  249.       delta = h ; 
  250.     else
  251.       delta = xheight ( f ) ; 
  252.     if( (mathtype(supscr(q)) != 0) || (mathtype(subscr(q)) != 0) )
  253.     if ( mathtype ( nucleus ( q ) ) == mathchar ) {
  254.       flushnodelist ( x ) ; 
  255.       x = newnoad () ; 
  256.       mem [ nucleus ( x ) ] = mem [ nucleus ( q ) ] ; 
  257.       mem [ supscr ( x ) ] = mem [ supscr ( q ) ] ; 
  258.       mem [ subscr ( x ) ] = mem [ subscr ( q ) ] ; 
  259.       mem [ supscr ( q ) ] .hh = emptyfield ; 
  260.       mem [ subscr ( q ) ] .hh = emptyfield ; 
  261.       mathtype ( nucleus ( q ) ) = submlist ; 
  262.       info ( nucleus ( q ) ) = x ; 
  263.       x = cleanbox ( nucleus ( q ) , curstyle ) ; 
  264.       delta = delta + height ( x ) - h ; 
  265.       h = height ( x ) ; 
  266.     }
  267.     y = charbox ( f , c ) ; 
  268.     shiftamount ( y ) = s + half ( w - width ( y ) ) ; 
  269.     width ( y ) = 0 ; 
  270.     { register long_halfword p;
  271.  
  272.       p = newkern ( - (integer) delta ) ; 
  273.       link ( p ) = x ; 
  274.       link ( y ) = p ;
  275.     }
  276.     y = vpackage ( y , 0 , 1 , maxdimen ) ; 
  277.     width ( y ) = width ( x ) ; 
  278.     if ( height ( y ) < h ) {
  279.       register long_halfword p;
  280.  
  281.       p = newkern ( h - height ( y ) ) ; 
  282.       link ( p ) = listptr ( y ) ; 
  283.       listptr ( y ) = p ; 
  284.       height ( y ) = h ; 
  285.     } 
  286.     info ( nucleus ( q ) ) = y ; 
  287.     mathtype ( nucleus ( q ) ) = subbox ; 
  288.   }
  289. }
  290.  
  291.  
  292.    static void
  293. makefraction (halfword q, smallnumber curstyle, smallnumber cursize)
  294. { makefraction_regmem 
  295.   register halfword p, v, x, z;
  296.   register scaled delta, shiftup, shiftdown;
  297.  
  298.   if ( thickness ( q ) == defaultcode ) 
  299.     thickness ( q ) = defaultrulethickness;
  300.  
  301.   x = cleanbox ( numerator ( q ) , numstyle ( curstyle ) ) ; 
  302.   z = cleanbox ( denominator ( q ) , denomstyle ( curstyle ) ) ; 
  303.   if ( width ( x ) < width ( z ) )
  304.     x = rebox ( x , width ( z ) ); 
  305.   else
  306.     z = rebox ( z , width ( x ) );
  307.  
  308.   if ( curstyle < textstyle ) {
  309.     shiftup = num1 ( cursize ) ; 
  310.     shiftdown = denom1 ( cursize ) ; 
  311.   } else {
  312.     shiftdown = denom2 ( cursize ) ; 
  313.     if ( thickness ( q ) != 0 ) 
  314.       shiftup = num2 ( cursize ) ; 
  315.     else
  316.       shiftup = num3 ( cursize ) ; 
  317.   }
  318.  
  319.   if ( thickness ( q ) == 0 ) {
  320.     register scaled clr;
  321.  
  322.     if ( curstyle < textstyle )
  323.       clr = 7 * defaultrulethickness;
  324.     else
  325.       clr = 3 * defaultrulethickness;
  326.     delta = half( clr - ( (shiftup - depth(x)) - (height(z) - shiftdown) ) );
  327.     if ( delta > 0 ) {
  328.       shiftup = shiftup + delta;
  329.       shiftdown = shiftdown + delta;
  330.     } 
  331.   } else {
  332.     register scaled clr, delta1, delta2;
  333.  
  334.     if ( curstyle < textstyle ) 
  335.       clr = 3 * thickness ( q ) ; 
  336.     else
  337.       clr = thickness ( q ) ; 
  338.     delta = half ( thickness ( q ) ) ; 
  339.     delta1 = clr - ( (shiftup - depth(x)) - (axisheight(cursize) + delta) );
  340.     delta2 = clr - ( (axisheight(cursize) - delta) - (height(z) - shiftdown) );
  341.     if ( delta1 > 0 )
  342.       shiftup = shiftup + delta1 ; 
  343.     if ( delta2 > 0 ) 
  344.       shiftdown = shiftdown + delta2 ; 
  345.   }
  346.  
  347.   v = newnullbox ();
  348.   ztype ( v ) = vlistnode;
  349.   height ( v ) = shiftup + height ( x );
  350.   depth ( v ) = depth ( z ) + shiftdown;
  351.   width ( v ) = width ( x );
  352.  
  353.   if ( thickness ( q ) == 0 ) {
  354.     p = newkern( ( shiftup - depth ( x ) ) - ( height ( z ) - shiftdown ) );
  355.     link ( p ) = z;
  356.   } else {
  357.     register halfword y;
  358.  
  359.     y = fractionrule( thickness(q) );
  360.     p = newkern( (axisheight(cursize) - delta) - (height(z) - shiftdown) );
  361.     link ( y ) = p ; 
  362.     link ( p ) = z ; 
  363.     p = newkern( (shiftup - depth(x)) - (axisheight(cursize) + delta) );
  364.     link ( p ) = y;
  365.   } 
  366.  
  367.   link ( x ) = p;
  368.   listptr ( v ) = x;
  369.  
  370.   if ( curstyle < textstyle ) 
  371.     delta = delim1 ( cursize );
  372.   else
  373.     delta = delim2 ( cursize );
  374.  
  375.   x = vardelimiter( leftdelimiter(q), cursize, delta );
  376.   link ( x ) = v;
  377.  
  378.   z = vardelimiter( rightdelimiter(q), cursize, delta );
  379.   link ( v ) = z;
  380.  
  381.   newhlist(q) = hpack( x, 0, 1 );
  382. }
  383.  
  384.  
  385.    static scaled
  386. makeop (halfword q, smallnumber curstyle, smallnumber cursize)
  387. { makeop_regmem
  388.   register scaled delta;
  389.   register halfword v, x, y, z;
  390.  
  391.   if ( ( subtype ( q ) == normal ) && ( curstyle < textstyle ) )
  392.     subtype ( q ) = limits;
  393.  
  394.   if ( mathtype ( nucleus ( q ) ) == mathchar ) {
  395.     fetch ( nucleus ( q ), cursize );
  396.     if ( ( curstyle < textstyle ) && ( chartag ( curi ) == listtag ) ) {
  397.       register quarterword c;
  398.       fourquarters i;
  399.  
  400.       c = rembyte ( curi ) ; 
  401.       i = zcharinfo ( curf ,  c ) ; 
  402.       if ( charexists ( i ) ) {
  403.     curc = c ; 
  404.     curi = i ; 
  405.     character ( nucleus ( q ) ) = c ; 
  406.       }
  407.     }
  408.     delta = zcharitalic( curf, curi );
  409.     x = cleanbox( nucleus(q), curstyle );
  410.     if( (mathtype(subscr(q)) != 0) && (subtype(q) != limits) )
  411.       width ( x ) = width ( x ) - delta;
  412.     shiftamount(x) = half( height(x) - depth(x) ) - axisheight( cursize );
  413.     mathtype ( nucleus ( q ) ) = subbox;
  414.     info ( nucleus ( q ) ) = x;
  415.   } else
  416.     delta = 0;
  417.  
  418.   if ( subtype ( q ) == limits ) {
  419.     x = cleanbox ( supscr ( q ) , supstyle ( curstyle ) ) ; 
  420.     y = cleanbox ( nucleus ( q ) , curstyle ) ; 
  421.     z = cleanbox ( subscr ( q ) , substyle ( curstyle ) ) ; 
  422.     v = newnullbox () ; 
  423.     ztype ( v ) = vlistnode ; 
  424.     width ( v ) = width ( y ) ; 
  425.     if ( width ( x ) > width ( v ) ) 
  426.       width ( v ) = width ( x ) ; 
  427.     if ( width ( z ) > width ( v ) ) 
  428.       width ( v ) = width ( z ) ;
  429.     x = rebox ( x , width ( v ) ) ; 
  430.     y = rebox ( y , width ( v ) ) ; 
  431.     z = rebox ( z , width ( v ) ) ; 
  432.     shiftamount ( x ) = half ( delta ) ; 
  433.     shiftamount ( z ) = - (integer) shiftamount ( x ) ; 
  434.     height ( v ) = height ( y ) ; 
  435.     depth ( v ) = depth ( y ) ; 
  436.  
  437.     if ( mathtype ( supscr ( q ) ) == 0 ) {
  438.       freenode ( x , boxnodesize ) ; 
  439.       listptr ( v ) = y ; 
  440.     } else {
  441.       register scaled shiftup;
  442.       register long_halfword p;
  443.  
  444.       shiftup = bigopspacing3 - depth ( x ) ; 
  445.       if ( shiftup < bigopspacing1 ) 
  446.         shiftup = bigopspacing1 ; 
  447.       p = newkern ( shiftup ) ; 
  448.       link ( p ) = y ; 
  449.       link ( x ) = p ; 
  450.       p = newkern ( bigopspacing5 ) ; 
  451.       link ( p ) = x;
  452.       listptr ( v ) = p;
  453.       height(v) = height(v) + bigopspacing5 + height(x) + depth(x) + shiftup;
  454.     }
  455.  
  456.     if ( mathtype ( subscr ( q ) ) == 0 ) 
  457.       freenode ( z, boxnodesize ) ; 
  458.     else {
  459.       register scaled shiftdown;
  460.       register long_halfword p;
  461.  
  462.       shiftdown = bigopspacing4 - height ( z ) ; 
  463.       if ( shiftdown < bigopspacing2 ) 
  464.     shiftdown = bigopspacing2 ; 
  465.       p = newkern ( shiftdown ) ; 
  466.       link ( y ) = p ; 
  467.       link ( p ) = z ; 
  468.       p = newkern ( bigopspacing5 ) ; 
  469.       link ( z ) = p ; 
  470.       depth(v) = depth(v) + bigopspacing5 + height(z) + depth(z) + shiftdown;
  471.     }
  472.  
  473.     newhlist ( q ) = v;
  474.   }
  475.  
  476.   return(delta);
  477. }
  478.  
  479.  
  480.    static void
  481. makeord (halfword q, smallnumber cursize)
  482. { makeord_regmem
  483.   register halfword p;
  484.  
  485. lab20:
  486.   if ( mathtype ( subscr ( q ) ) == 0 ) 
  487.   if ( mathtype ( supscr ( q ) ) == 0 ) 
  488.   if ( mathtype ( nucleus ( q ) ) == mathchar ) {
  489.     p = link ( q ) ; 
  490.     if ( p != 0 ) 
  491.     if ( ( ztype ( p ) >= ordnoad ) && ( ztype ( p ) <= punctnoad ) ) 
  492.     if ( mathtype ( nucleus ( p ) ) == mathchar ) 
  493.     if ( fam ( nucleus ( p ) ) == fam ( nucleus ( q ) ) ) {
  494.       mathtype ( nucleus ( q ) ) = mathtextchar ; 
  495.       fetch ( nucleus ( q ), cursize );
  496.       if ( chartag ( curi ) == ligtag ) {
  497. #ifdef FONTPTR
  498.     register SMALLmemoryword *ligp;
  499.  
  500.     curc = character ( nucleus ( p ) ) ; 
  501.     ligp = zligkernstart ( curf ,  curi ) ;
  502.     curi = ligp->qqqq ;
  503.     if ( skipbyte ( curi ) > stopflag ) {
  504.       ligp = zligkernrestart ( curf ,  curi ) ; 
  505.       curi = ligp->qqqq ;
  506.     } 
  507. #else
  508.     register integer a ;
  509.  
  510.     curc = character ( nucleus ( p ) ) ; 
  511.     a = zligkernstart ( curf ,  curi ) ; 
  512.     curi = fontinfo [ a ] .qqqq ; 
  513.     if ( skipbyte ( curi ) > stopflag ) {
  514.       a = zligkernrestart ( curf ,  curi ) ; 
  515.       curi = fontinfo [ a ] .qqqq ; 
  516.     } 
  517. #endif
  518.     while ( true ) {
  519.       if ( nextchar ( curi ) == curc ) 
  520.       if ( skipbyte ( curi ) <= stopflag ) 
  521.       if ( opbyte ( curi ) >= kernflag ) {
  522.         p = newkern ( zcharkern ( curf ,  curi ) ) ; 
  523.         link ( p ) = link ( q ) ; 
  524.         link ( q ) = p ; 
  525.         return ; 
  526.       } else {
  527.         {
  528.           if ( interrupt != 0 ) 
  529.           pauseforinstructions () ; 
  530.         } 
  531.         switch ( opbyte ( curi ) ) 
  532.         {case 1 : 
  533.         case 5 : 
  534.           character ( nucleus ( q ) ) = rembyte ( curi ) ; 
  535.           break ; 
  536.         case 2 : 
  537.         case 6 : 
  538.           character ( nucleus ( p ) ) = rembyte ( curi ) ; 
  539.           break ; 
  540.         case 3 : 
  541.         case 7 : 
  542.         case 11 : 
  543.           { register long_halfword r;
  544.  
  545.         r = newnoad () ; 
  546.         character ( nucleus ( r ) ) = rembyte ( curi ) ; 
  547.         fam ( nucleus ( r ) ) = fam ( nucleus ( q ) ) ; 
  548.         link ( q ) = r ; 
  549.         link ( r ) = p ; 
  550.         if ( opbyte ( curi ) < 11 ) 
  551.           mathtype ( nucleus ( r ) ) = mathchar ; 
  552.         else
  553.           mathtype ( nucleus ( r ) ) = mathtextchar ; 
  554.           }
  555.           break ; 
  556.         default: 
  557.           {
  558.         link ( q ) = link ( p ) ; 
  559.         character ( nucleus ( q ) ) = rembyte ( curi ) ; 
  560.         mem [ subscr ( q ) ] = mem [ subscr ( p ) ] ; 
  561.         mem [ supscr ( q ) ] = mem [ supscr ( p ) ] ; 
  562.         freenode ( p , noadsize ) ; 
  563.           } 
  564.           break ; 
  565.         } 
  566.         if ( opbyte ( curi ) > 3 ) 
  567.           return ; 
  568.         mathtype ( nucleus ( q ) ) = mathchar ; 
  569.         goto lab20 ; 
  570.       }
  571.       if ( skipbyte ( curi ) >= stopflag ) 
  572.         return ; 
  573. #ifdef FONTPTR
  574.       ligp = ligp + skipbyte ( curi ) + 1 ; 
  575.       curi = ligp->qqqq ; 
  576. #else
  577.       a = a + skipbyte ( curi ) + 1 ; 
  578.       curi = fontinfo [ a ] .qqqq ; 
  579. #endif
  580.     }
  581.       }
  582.     }
  583.   }
  584. }
  585.  
  586.  
  587.    static void
  588. makescripts (halfword q , scaled delta, smallnumber curstyle,
  589.         smallnumber cursize)
  590. { makescripts_regmem
  591.   register halfword p, x, y;
  592.   register scaled shiftup, shiftdown, clr;
  593.  
  594.   p = newhlist ( q ) ; 
  595.   if ( ischarnode ( p ) ) {
  596.     shiftup = 0 ; 
  597.     shiftdown = 0 ; 
  598.   } else {
  599.     register halfword z;
  600.     register smallnumber t;
  601.  
  602.     z = hpack ( p , 0 , 1 ) ; 
  603.     if ( curstyle < scriptstyle ) 
  604.       t = scriptsize;
  605.     else
  606.       t = scriptscriptsize;
  607.     shiftup = height ( z ) - supdrop ( t ) ; 
  608.     shiftdown = depth ( z ) + subdrop ( t ) ; 
  609.     freenode ( z , boxnodesize ) ; 
  610.   }
  611.  
  612.   if ( mathtype ( supscr ( q ) ) == 0 ) {
  613.     x = cleanbox ( subscr ( q ) , substyle ( curstyle ) ) ; 
  614.     width ( x ) = width ( x ) + scriptspace ; 
  615.     if ( shiftdown < sub1 ( cursize ) ) 
  616.       shiftdown = sub1 ( cursize ) ; 
  617.     clr = height ( x ) - ( abs ( mathxheight ( cursize ) * 4 ) / 5 ) ; 
  618.     if ( shiftdown < clr ) 
  619.       shiftdown = clr ; 
  620.     shiftamount ( x ) = shiftdown ; 
  621.   } else {
  622.     {
  623.       x = cleanbox ( supscr ( q ) , supstyle ( curstyle ) ) ; 
  624.       width ( x ) = width ( x ) + scriptspace ; 
  625.       if ( odd ( curstyle ) ) 
  626.         clr = sup3 ( cursize ) ; 
  627.       else if ( curstyle < textstyle ) 
  628.         clr = sup1 ( cursize ) ; 
  629.       else clr = sup2 ( cursize ) ; 
  630.       if ( shiftup < clr ) 
  631.         shiftup = clr ; 
  632.       clr = depth ( x ) + ( abs ( mathxheight ( cursize ) ) / 4 ) ; 
  633.       if ( shiftup < clr ) 
  634.         shiftup = clr ; 
  635.     }
  636.     if ( mathtype ( subscr ( q ) ) == 0 ) 
  637.       shiftamount ( x ) = - (integer) shiftup ; 
  638.     else {
  639.       y = cleanbox ( subscr ( q ) , substyle ( curstyle ) ) ; 
  640.       width ( y ) = width ( y ) + scriptspace ; 
  641.       if ( shiftdown < sub2 ( cursize ) ) 
  642.       shiftdown = sub2 ( cursize ) ; 
  643.       clr = 4 * defaultrulethickness - ( ( shiftup - depth ( x ) ) - ( height 
  644.       ( y ) - shiftdown ) ) ; 
  645.       if ( clr > 0 ) {
  646.     shiftdown = shiftdown + clr ; 
  647.     clr = ( abs ( mathxheight ( cursize ) * 4 ) / 5 ) - ( shiftup - depth 
  648.     ( x ) ) ; 
  649.     if ( clr > 0 ) {
  650.       shiftup = shiftup + clr ; 
  651.       shiftdown = shiftdown - clr ; 
  652.     } 
  653.       }
  654.       shiftamount ( x ) = delta ; 
  655.       p = newkern ( ( shiftup - depth ( x ) ) - ( height ( y ) - shiftdown ) );
  656.       link ( x ) = p ; 
  657.       link ( p ) = y ; 
  658.       x = vpackage ( x , 0 , 1 , maxdimen ) ; 
  659.       shiftamount ( x ) = shiftdown ; 
  660.     } 
  661.   }
  662.  
  663.   if ( newhlist ( q ) == 0 )
  664.     newhlist ( q ) = x ; 
  665.   else {
  666.     p = newhlist ( q ) ; 
  667.     while ( link ( p ) != 0 )
  668.       p = link ( p );
  669.     link ( p ) = x;
  670.   }
  671. }
  672.  
  673.  
  674.    static smallnumber
  675. makeleftright (halfword q, smallnumber style, scaled maxd, scaled maxh)
  676. { makeleftright_regmem 
  677.   register scaled delta, delta1, delta2 ;
  678.   register smallnumber cursize;
  679.  
  680.   if ( style < scriptstyle ) 
  681.     cursize = textsize ; 
  682.   else
  683.     cursize = 16 * ( ( style - textstyle ) / 2 ) ; 
  684.  
  685.   delta2 = maxd + axisheight ( cursize ) ; 
  686.   delta1 = maxh + maxd - delta2 ; 
  687.   if ( delta2 > delta1 ) 
  688.     delta1 = delta2 ; 
  689.   delta = ( delta1 / 500 ) * delimiterfactor ; 
  690.   delta2 = delta1 + delta1 - delimitershortfall ; 
  691.   if ( delta < delta2 ) 
  692.     delta = delta2 ; 
  693.   newhlist ( q ) = vardelimiter ( delimiter ( q ) , cursize , delta ) ; 
  694.  
  695.   return( ztype ( q ) - ( leftnoad - opennoad ) );
  696. }
  697.  
  698.  
  699.    static long_halfword
  700. mlisttohlist (long_halfword mlist, smallnumber curstyle, int penalties)
  701. { mlisttohlist_regmem 
  702.   smallnumber style  ; 
  703.   register halfword q  ; 
  704.   register halfword r  ; 
  705.   register smallnumber rtype  ; 
  706.   register smallnumber t  ; 
  707.   register halfword p, x, y, z  ; 
  708.   register integer pen  ; 
  709.   register smallnumber s  ; 
  710.   register scaled maxh, maxd  ; 
  711.   register scaled delta  ;
  712.  
  713.   smallnumber cursize;
  714.   scaled curmu;
  715.  
  716.   style = curstyle ; 
  717.  
  718.   q = mlist ; 
  719.   r = 0 ; 
  720.   rtype = opnoad ; 
  721.   maxh = 0 ; 
  722.   maxd = 0 ; 
  723.   {
  724.     if ( curstyle < scriptstyle ) 
  725.       cursize = textsize ; 
  726.     else
  727.       cursize = 16 * ( ( curstyle - textstyle ) / 2 ) ; 
  728.     curmu = xovern ( mathquad ( cursize ) , 18 ) ; 
  729.   }
  730.  
  731.   while ( q != 0 ) {
  732.  
  733. lab21:
  734.     delta = 0 ; 
  735.     switch ( ztype ( q ) ) {
  736.     case binnoad : 
  737.       switch ( rtype ) {
  738.       case binnoad : 
  739.       case opnoad : 
  740.       case relnoad : 
  741.       case opennoad : 
  742.       case punctnoad : 
  743.       case leftnoad : 
  744.     {
  745.       ztype ( q ) = ordnoad ; 
  746.       goto lab21 ; 
  747.     } 
  748.     break ; 
  749.       default: 
  750.     break ; 
  751.       }
  752.       break ; 
  753.     case relnoad : 
  754.     case closenoad : 
  755.     case punctnoad : 
  756.     case rightnoad : 
  757.       {
  758.     if ( rtype == binnoad )
  759.       ztype ( r ) = ordnoad ; 
  760.     if ( ztype ( q ) == rightnoad ) 
  761.       goto lab80 ; 
  762.       } 
  763.       break ; 
  764.     case leftnoad : 
  765.       goto lab80 ; 
  766.       break ; 
  767.     case fractionnoad : 
  768.       {
  769.     makefraction ( q, curstyle, cursize );
  770.     goto lab82 ; 
  771.       } 
  772.       break ; 
  773.     case opnoad : 
  774.       {
  775.     delta = makeop ( q, curstyle, cursize );
  776.     if ( subtype ( q ) == limits ) 
  777.       goto lab82 ; 
  778.       } 
  779.       break ; 
  780.     case ordnoad : 
  781.       makeord ( q, cursize );
  782.       break ; 
  783.     case opennoad : 
  784.     case innernoad : 
  785.       break ; 
  786.     case radicalnoad : 
  787.       makeradical ( q, curstyle, cursize );
  788.       break ; 
  789.     case overnoad : 
  790.       makeover ( q, curstyle, cursize ) ; 
  791.       break ; 
  792.     case undernoad : 
  793.       makeunder ( q, curstyle, cursize ) ;
  794.       break ; 
  795.     case accentnoad : 
  796.       makemathaccent ( q, curstyle, cursize );
  797.       break ; 
  798.     case vcenternoad : 
  799.       makevcenter ( q, cursize ) ; 
  800.       break ; 
  801.     case stylenode : 
  802.       {
  803.     curstyle = subtype ( q ) ; 
  804.     {
  805.       if ( curstyle < scriptstyle ) 
  806.       cursize = textsize ; 
  807.       else cursize = 16 * ( ( curstyle - textstyle ) / 2 ) ; 
  808.       curmu = xovern ( mathquad ( cursize ) , 18 ) ; 
  809.     } 
  810.     goto lab81 ; 
  811.       } 
  812.       break ; 
  813.     case choicenode : 
  814.       {
  815.     switch ( curstyle / 2 ) 
  816.     {case 0 : 
  817.       {
  818.         p = displaymlist ( q ) ; 
  819.         displaymlist ( q ) = 0 ; 
  820.       } 
  821.       break ; 
  822.     case 1 : 
  823.       {
  824.         p = textmlist ( q ) ; 
  825.         textmlist ( q ) = 0 ; 
  826.       } 
  827.       break ; 
  828.     case 2 : 
  829.       {
  830.         p = scriptmlist ( q ) ; 
  831.         scriptmlist ( q ) = 0 ; 
  832.       } 
  833.       break ; 
  834.     case 3 : 
  835.       {
  836.         p = scriptscriptmlist ( q ) ; 
  837.         scriptscriptmlist ( q ) = 0 ; 
  838.       } 
  839.       break ; 
  840.     } 
  841.     flushnodelist ( displaymlist ( q ) ) ; 
  842.     flushnodelist ( textmlist ( q ) ) ; 
  843.     flushnodelist ( scriptmlist ( q ) ) ; 
  844.     flushnodelist ( scriptscriptmlist ( q ) ) ; 
  845.     ztype ( q ) = stylenode ; 
  846.     subtype ( q ) = curstyle ; 
  847.     width ( q ) = 0 ; 
  848.     depth ( q ) = 0 ; 
  849.     if ( p != 0 ) {
  850.       z = link ( q ) ; 
  851.       link ( q ) = p ; 
  852.       while ( link ( p ) != 0 ) p = link ( p ) ; 
  853.       link ( p ) = z ; 
  854.     } 
  855.     goto lab81 ; 
  856.       } 
  857.       break ; 
  858.     case insnode : 
  859.     case marknode : 
  860.     case adjustnode : 
  861.     case whatsitnode : 
  862.     case penaltynode : 
  863.     case discnode : 
  864.       goto lab81 ; 
  865.       break ; 
  866.     case rulenode : 
  867.       {
  868.     if ( height ( q ) > maxh ) 
  869.     maxh = height ( q ) ; 
  870.     if ( depth ( q ) > maxd ) 
  871.     maxd = depth ( q ) ; 
  872.     goto lab81 ; 
  873.       } 
  874.       break ; 
  875.     case gluenode : 
  876.       {
  877.     if ( subtype ( q ) == muglue ) {
  878.       x = glueptr ( q ) ; 
  879.       y = mathglue ( x , curmu ) ; 
  880.       deleteglueref ( x ) ; 
  881.       glueptr ( q ) = y ; 
  882.       subtype ( q ) = normal ; 
  883.     } else if ( cursize != textsize && ( subtype(q) == condmathglue ) ) {
  884.       p = link ( q ) ; 
  885.       if ( p != 0 ) 
  886.       if ( ( ztype ( p ) == gluenode ) || ( ztype ( p ) == kernnode ) ) {
  887.         link ( q ) = link ( p ) ; 
  888.         link ( p ) = 0 ; 
  889.         flushnodelist ( p ) ; 
  890.       } 
  891.     } 
  892.     goto lab81 ; 
  893.       } 
  894.       break ; 
  895.     case kernnode : 
  896.       {
  897.     mathkern ( q , curmu ) ; 
  898.     goto lab81 ; 
  899.       } 
  900.       break ; 
  901.     default: 
  902.       confusion("mlist1");
  903.       break ; 
  904.     }
  905.  
  906.     switch ( mathtype ( nucleus ( q ) ) ) {
  907.     case mathchar : 
  908.     case mathtextchar : 
  909.       {
  910.     fetch ( nucleus ( q ), cursize ) ; 
  911.     if ( charexists ( curi ) ) {
  912.       delta = zcharitalic ( curf ,  curi ) ; 
  913.       p = newcharacter ( curf , curc ) ; 
  914.       if ( mathtype(nucleus(q)) == mathtextchar && space(curf) != 0 )
  915.         delta = 0 ; 
  916.       if ( ( mathtype ( subscr ( q ) ) == 0 ) && ( delta != 0 ) ) {
  917.         link ( p ) = newkern ( delta ) ; 
  918.         delta = 0 ; 
  919.       } 
  920.     } 
  921.     else p = 0 ; 
  922.       } 
  923.       break ; 
  924.     case 0 : 
  925.       p = 0 ; 
  926.       break ; 
  927.     case subbox : 
  928.       p = info ( nucleus ( q ) ) ; 
  929.       break ; 
  930.     case submlist : 
  931.       {
  932. #if 0
  933.     mlisttohlist ( info(nucleus(q)), curstyle, false);
  934.  
  935.     p = hpack ( link ( temphead ) , 0 , 1 ) ; 
  936. #else
  937.     p = hpack( mlisttohlist(info(nucleus(q)), curstyle, false), 0, 1 );
  938. #endif
  939.       } 
  940.       break ; 
  941.     default: 
  942.       confusion("mlist2");
  943.       break ; 
  944.     } 
  945.  
  946.     newhlist ( q ) = p ; 
  947.     if ( ( mathtype ( subscr(q) ) == 0 ) && ( mathtype ( supscr(q) ) == 0 ) )
  948.       goto lab82 ; 
  949.     makescripts ( q , delta, curstyle, cursize );
  950.  
  951. lab82:
  952.     z = hpack ( newhlist ( q ) , 0 , 1 ) ; 
  953.     if ( height ( z ) > maxh ) 
  954.       maxh = height ( z ) ; 
  955.     if ( depth ( z ) > maxd ) 
  956.       maxd = depth ( z ) ; 
  957.     freenode ( z , boxnodesize ) ; 
  958. lab80:
  959.     r = q ; 
  960.     rtype = ztype ( r );
  961. lab81:
  962.     q = link ( q );
  963.   }
  964.  
  965.   if ( rtype == binnoad ) 
  966.     ztype ( r ) = ordnoad ; 
  967.  
  968.   p = temphead;
  969.   link(p) = 0;
  970.   q = mlist;
  971.  
  972.   rtype = 0;
  973.   curstyle = style;
  974.   {
  975.     if ( curstyle < scriptstyle ) 
  976.       cursize = textsize ; 
  977.     else
  978.       cursize = 16 * ( ( curstyle - textstyle ) / 2 ) ; 
  979.     curmu = xovern ( mathquad ( cursize ) , 18 ) ; 
  980.   }
  981.  
  982.   while ( q != 0 ) {
  983.     t = ordnoad ; 
  984.     s = noadsize ; 
  985.     pen = infpenalty ; 
  986.     switch ( ztype ( q ) ) {
  987.     case opnoad : 
  988.     case opennoad : 
  989.     case closenoad : 
  990.     case punctnoad : 
  991.     case innernoad : 
  992.       t = ztype ( q ) ; 
  993.       break ; 
  994.     case binnoad : 
  995.       {
  996.     t = binnoad ; 
  997.     pen = binoppenalty ; 
  998.       } 
  999.       break ; 
  1000.     case relnoad : 
  1001.       {
  1002.     t = relnoad ; 
  1003.     pen = relpenalty ; 
  1004.       } 
  1005.       break ; 
  1006.     case ordnoad : 
  1007.     case vcenternoad : 
  1008.     case overnoad : 
  1009.     case undernoad : 
  1010.       break ; 
  1011.     case radicalnoad : 
  1012.       s = radicalnoadsize ; 
  1013.       break ; 
  1014.     case accentnoad : 
  1015.       s = accentnoadsize ; 
  1016.       break ; 
  1017.     case fractionnoad : 
  1018.       {
  1019.     t = innernoad ; 
  1020.     s = fractionnoadsize ; 
  1021.       } 
  1022.       break ; 
  1023.     case leftnoad : 
  1024.     case rightnoad : 
  1025.       t = makeleftright ( q , style , maxd , maxh ) ; 
  1026.       break ; 
  1027.     case stylenode : 
  1028.       {
  1029.     curstyle = subtype ( q ) ; 
  1030.     s = stylenodesize ; 
  1031.     {
  1032.       if ( curstyle < scriptstyle ) 
  1033.       cursize = textsize ; 
  1034.       else cursize = 16 * ( ( curstyle - textstyle ) / 2 ) ; 
  1035.       curmu = xovern ( mathquad ( cursize ) , 18 ) ; 
  1036.     } 
  1037.     goto lab83 ; 
  1038.       } 
  1039.       break ; 
  1040.     case whatsitnode : 
  1041.     case penaltynode : 
  1042.     case rulenode : 
  1043.     case discnode : 
  1044.     case adjustnode : 
  1045.     case insnode : 
  1046.     case marknode : 
  1047.     case gluenode : 
  1048.     case kernnode : 
  1049.       {
  1050.     link ( p ) = q ; 
  1051.     p = q ; 
  1052.     q = link ( q ) ; 
  1053.     link ( p ) = 0 ; 
  1054.     goto lab30 ; 
  1055.       } 
  1056.       break ; 
  1057.     default: 
  1058.       confusion("mlist3");
  1059.       break ; 
  1060.     } 
  1061.  
  1062.     if ( rtype > 0 ) {
  1063.     static char math_spacing[] = {
  1064.         0, 2, 3, 4, 0, 0, 0, 1,
  1065.         2, 2, 9, 4, 0, 0, 0, 1,
  1066.         3, 3, 9, 9, 3, 9, 9, 3,
  1067.         4, 4, 9, 0, 4, 0, 0, 4,
  1068.         0, 0, 9, 0, 0, 0, 0, 0,
  1069.         0, 2, 3, 4, 0, 0, 0, 1,
  1070.         1, 1, 9, 1, 1, 1, 1, 1,
  1071.         1, 2, 3, 4, 1, 0, 1, 1 };
  1072.  
  1073.       switch ( math_spacing[ rtype * 8 + t - (9 * ordnoad) ] ) {
  1074.       case 0 :
  1075.     x = 0 ; 
  1076.     break ; 
  1077.       case 1 :
  1078.     if ( curstyle < scriptstyle ) 
  1079.       x = thinmuskipcode ; 
  1080.     else
  1081.       x = 0 ; 
  1082.     break ; 
  1083.       case 2 : 
  1084.     x = thinmuskipcode ; 
  1085.     break ; 
  1086.       case 3 : 
  1087.     if ( curstyle < scriptstyle ) 
  1088.       x = medmuskipcode ; 
  1089.     else x = 0 ; 
  1090.     break ; 
  1091.       case 4 : 
  1092.     if ( curstyle < scriptstyle ) 
  1093.       x = thickmuskipcode ; 
  1094.     else x = 0 ; 
  1095.     break ;
  1096.       default:
  1097.     confusion("mlist4");
  1098.     break ; 
  1099.       }
  1100.  
  1101.       if ( x != 0 ) {
  1102.     y = mathglue ( gluepar ( x ) , curmu ) ; 
  1103.     z = newglue ( y ) ; 
  1104.     gluerefcount ( y ) = 0 ; 
  1105.     link ( p ) = z ; 
  1106.     p = z ; 
  1107.     subtype ( z ) = x + 1 ; 
  1108.       }
  1109.     }
  1110.  
  1111.     if ( newhlist ( q ) != 0 ) {
  1112.       link ( p ) = newhlist ( q ) ; 
  1113.       do {
  1114.       p = link ( p ) ; 
  1115.       } while ( ! ( link ( p ) == 0 ) ) ; 
  1116.     }
  1117.     if ( penalties ) 
  1118.     if ( link ( q ) != 0 ) 
  1119.     if ( pen < infpenalty ) {
  1120.       rtype = ztype ( link ( q ) ) ; 
  1121.       if ( rtype != penaltynode ) 
  1122.       if ( rtype != relnoad ) {
  1123.     z = newpenalty ( pen ) ; 
  1124.     link ( p ) = z ; 
  1125.     p = z ; 
  1126.       }
  1127.     }
  1128.     rtype = t ; 
  1129. lab83: r = q ; 
  1130.     q = link ( q ) ; 
  1131.     freenode ( r , s ) ; 
  1132. lab30: ;
  1133.   }
  1134.   return( link(temphead) );
  1135. }
  1136.  
  1137.  
  1138.   static int
  1139. check_font_params(void)
  1140. { aftermath_regmem
  1141.  
  1142.   if ( ( fontparams(famfnt ( 2 + textsize )) < totalmathsyparams )
  1143.     || ( fontparams(famfnt ( 2 + scriptsize )) < totalmathsyparams )
  1144.     || ( fontparams(famfnt ( 2 + scriptscriptsize )) < totalmathsyparams ) )
  1145.   {
  1146.     print_err("Math formula deleted: Insufficient symbol fonts");
  1147.     zhelp1( STR_H_SORRY_TEXTFONT2 );
  1148.     error();
  1149.     flushmath(); 
  1150.     return(true);
  1151.   } else if ( ( fontparams(famfnt( 3 + textsize )) < totalmathexparams )
  1152.     || ( fontparams(famfnt( 3 + scriptsize )) < totalmathexparams )
  1153.     || ( fontparams(famfnt( 3 + scriptscriptsize )) < totalmathexparams ) )
  1154.   {
  1155.     print_err("Math formula deleted: Insufficient extension fonts");
  1156.     zhelp1( STR_H_SORRY_TEXTFONT3 );
  1157.     error();
  1158.     flushmath();
  1159.     return(true);
  1160.   } 
  1161.  
  1162.   return(false);
  1163. }
  1164.  
  1165.  
  1166. void check_that_dollar_follows ( void )        /* added (br) */
  1167. { register eightbits r_curcmd;
  1168.  
  1169.   r_curcmd = getxtoken();
  1170.   if ( r_curcmd != 3 ) {
  1171.     print_err("Display math should end with $$");
  1172.     zhelp1( STR_H_THEDOLLARTHATI );
  1173.     backerror();
  1174.   }
  1175. }
  1176.  
  1177.  
  1178. void aftermath ( void )
  1179. { aftermath_regmem 
  1180.   boolean l  ; 
  1181.   boolean danger  ; 
  1182.   register integer m  ; 
  1183.   register halfword p  ; 
  1184.   register halfword a  ; 
  1185.   register halfword b  ; 
  1186.   register scaled w  ; 
  1187.   register scaled z  ; 
  1188.   register scaled e  ; 
  1189.   register scaled q  ; 
  1190.   register scaled d  ; 
  1191.   register scaled s  ; 
  1192.   register smallnumber g1, g2  ; 
  1193.   register halfword r  ; 
  1194.   register halfword t  ; 
  1195.  
  1196.  
  1197.   danger = check_font_params();
  1198.  
  1199.   m = curlist .modefield ; 
  1200.   l = false ; 
  1201.   p = finmlist ( 0 ) ; 
  1202.  
  1203.   if ( curlist .modefield == - (integer) m ) {
  1204.     check_that_dollar_follows();
  1205.  
  1206. #if 0
  1207.     mlisttohlist ( p, textstyle, false );
  1208.  
  1209.     a = hpack ( link ( temphead ) , 0 , 1 ) ; 
  1210. #else
  1211.     a = hpack( mlisttohlist(p, textstyle, false), 0, 1 );
  1212. #endif
  1213.     unsave () ; 
  1214.     decr ( saveptr ) ; 
  1215.     if ( saved ( 0 ) == 1 ) 
  1216.       l = true ;
  1217.  
  1218.     danger = check_font_params();
  1219.  
  1220.     m = curlist .modefield ; 
  1221.     p = finmlist ( 0 ) ; 
  1222.   } else
  1223.     a = 0 ; 
  1224.  
  1225.   if ( m < 0 ) {
  1226.     /* Finish math in text mode 1196. */
  1227.     tailappend ( newmath ( mathsurround , before ) ) ;
  1228.  
  1229. #if 0
  1230.     mlisttohlist(p, textstyle, (curlist.modefield > 0));
  1231.     link ( curlist .tailfield ) = link ( temphead ) ; 
  1232. #else
  1233.     link(curlist.tailfield) =
  1234.         mlisttohlist(p, textstyle, (curlist.modefield > 0));
  1235. #endif
  1236.  
  1237.     while ( link ( curlist .tailfield ) != 0 )
  1238.     curlist .tailfield = link ( curlist .tailfield );
  1239.     tailappend( newmath( mathsurround, after ) );
  1240.     curlist .auxfield .hh .v.LH = 1000 ; 
  1241.     unsave ();
  1242.   } else {
  1243.     if ( a == 0 ) {
  1244.       check_that_dollar_follows();
  1245.     }
  1246.  
  1247.     p = mlisttohlist(p, displaystyle, false);
  1248.     /* p = link ( temphead ); */
  1249.  
  1250.     adjusttail = adjusthead;
  1251.     b = hpack( p, 0, 1 );
  1252.     p = listptr( b );
  1253.     t = adjusttail;
  1254.     adjusttail = 0;
  1255.     w = width ( b );
  1256.     z = displaywidth;
  1257.     s = displayindent;
  1258.     if ( ( a == 0 ) || danger ) {
  1259.       e = 0 ; 
  1260.       q = 0 ; 
  1261.     } else {
  1262.       e = width ( a ) ; 
  1263.       q = e + mathquad ( textsize ) ; 
  1264.     } 
  1265.     if ( w + q > z ) {
  1266.       if ( ( e != 0 ) && ( ( w - totalshrink [ normal ] + q <= z )
  1267.             || ( totalshrink [ fil ] != 0 )
  1268.             || ( totalshrink [ fill ] != 0 )
  1269.             || ( totalshrink [ filll ] != 0 ) ) )
  1270.       {
  1271.     freenode ( b , boxnodesize ) ; 
  1272.     b = hpack ( p , z - q , 0 ) ; 
  1273.       } else {
  1274.     e = 0 ; 
  1275.     if ( w > z ) {
  1276.       freenode ( b , boxnodesize ) ; 
  1277.       b = hpack ( p , z , 0 ) ; 
  1278.     }
  1279.       }
  1280.       w = width ( b ) ; 
  1281.     }
  1282.     d = half ( z - w ) ; 
  1283.     if ( ( e > 0 ) && ( d < 2 * e ) ) {
  1284.       d = half ( z - w - e ) ; 
  1285.       if( ( p != 0 ) && ( ! ischarnode(p) ) && ( ztype(p) == gluenode ) )
  1286.     d = 0;
  1287.     }
  1288.     tailappend ( newpenalty ( predisplaypenalty ) ) ; 
  1289.     if ( ( d + s <= predisplaysize ) || l ) {
  1290.       g1 = abovedisplayskipcode ; 
  1291.       g2 = belowdisplayskipcode ; 
  1292.     } else {
  1293.       g1 = abovedisplayshortskipcode ; 
  1294.       g2 = belowdisplayshortskipcode ; 
  1295.     }
  1296.     if ( l && ( e == 0 ) ) {
  1297.       shiftamount ( a ) = s;
  1298.       appendtovlist ( a );
  1299.       tailappend ( newpenalty ( infpenalty ) );
  1300.     } else
  1301.       tailappend ( newparamglue ( g1 ) );
  1302.     if ( e != 0 ) {
  1303.       r = newkern ( z - w - e - d ) ; 
  1304.       if ( l ) {
  1305.     link ( a ) = r ; 
  1306.     link ( r ) = b ; 
  1307.     b = a ; 
  1308.     d = 0 ; 
  1309.       } else {      
  1310.     link ( b ) = r ; 
  1311.     link ( r ) = a ; 
  1312.       } 
  1313.       b = hpack ( b , 0 , 1 ) ; 
  1314.     }
  1315.     shiftamount ( b ) = s + d ; 
  1316.     appendtovlist ( b ) ; 
  1317.     if ( ( a != 0 ) && ( e == 0 ) && ! l ) {
  1318.       tailappend ( newpenalty ( infpenalty ) ) ; 
  1319.       shiftamount ( a ) = s + z - width ( a ) ; 
  1320.       appendtovlist ( a ) ; 
  1321.       g2 = 0 ; 
  1322.     } 
  1323.     if ( t != adjusthead ) {
  1324.       link ( curlist .tailfield ) = link ( adjusthead ) ; 
  1325.       curlist .tailfield = t ; 
  1326.     } 
  1327.     tailappend ( newpenalty ( postdisplaypenalty ) ) ; 
  1328.     if ( g2 > 0 ) 
  1329.       tailappend ( newparamglue ( g2 ) );
  1330.     resumeafterdisplay ();
  1331.   }
  1332. }
  1333.  
  1334. /* -- end -- */
  1335.