Annotation of 43BSDTahoe/new/B/src/bed/eval.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
                      2: static char rcsid[] = "$Header: eval.c,v 2.3 84/07/19 11:47:18 guido Exp $";
                      3: 
                      4: /*
                      5:  * B editor -- Width attribute evaluation.
                      6:  */
                      7: 
                      8: #include "b.h"
                      9: #include "node.h"
                     10: #include "gram.h"
                     11: #include "eval.h"
                     12: 
                     13: 
                     14: /*
                     15:  * The following convention is used throughout the editor to indicate
                     16:  * the sizes of objects.
                     17:  * - A zero or positive `width' value means the object contains no
                     18:  *   linefeeds.  The width is counted in characters.
                     19:  * - A negative `width' means the object (or its children) contains
                     20:  *   at leasty one linefeed (return is treated as a linefeed here).
                     21:  *   The number of linefeeds is -width.
                     22:  *   There is no indication whether the object fits on that number of
                     23:  *   physical lines, as logical lines may have arbitrary length.
                     24:  *
                     25:  * For coordinates the following convention is used.
                     26:  * (Note that, in accordance to the convention in curses(3), the
                     27:  * `y' coordinate always precedes the `x' coorxdinate.)
                     28:  * - `Y' is the line number, counted from the beginning of the unit.
                     29:  *   These are logical lines rather than physical lines.
                     30:  *   The first line has line number 0.
                     31:  * - `X' is the column number.  The first column is 0.  For x < 0,
                     32:  *   see the important notice below.
                     33:  * - `Level' is the indentation level, indicating where a new line
                     34:  *   would start if inserted at the current position.
                     35:  *   The initial `x' position of such a line is `level*TABS'.
                     36:  *
                     37:  * ***** IMPORTANT NOTICE *****
                     38:  * A special case is x = -1.  This means that the current x position is
                     39:  * unknown.  Further output on the same line is suppressed, until a
                     40:  * linefeed is encountered.  This feature is necessary because while
                     41:  * calculating coordinates, when an object has width < 0, only the y
                     42:  * coordinate of the end of that object is known.  In this case, the
                     43:  * next non-empty object MUST START WITH A LINEFEED, or it will not
                     44:  * be visible on the screen (in practice, a space is sometimes present
                     45:  * in the parse tree which is not shown then).
                     46:  */
                     47: 
                     48: 
                     49: /*
                     50:  * Compute the (y, x) coordinates and indent level just before
                     51:  * the beginning of the j'th child, if the current node starts
                     52:  * at the initial values of (y, x) and level.
                     53:  */
                     54: 
                     55: Visible Procedure
                     56: evalcoord(n, jch, py, px, plevel)
                     57:        register node n;
                     58:        register int jch;
                     59:        int *py;
                     60:        int *px;
                     61:        int *plevel;
                     62: {
                     63:        node nn;
                     64:        register int i;
                     65:        register string *rp = noderepr(n);
                     66:        register int k;
                     67:        register int y = 0;
                     68:        int x = *px;
                     69:        int level = *plevel;
                     70:        int nch = Type(n) == Tex ? 0 : nchildren(n);
                     71: 
                     72:        if (jch > nch)
                     73:                jch = nch+1;
                     74:        for (i = 0; i < jch; ++i) {
                     75:                if (i) {
                     76:                        nn = child(n, i);
                     77:                        k = width(nn);
                     78:                        if (k < 0) {
                     79:                                y += -k;
                     80:                                x = k;
                     81:                        }
                     82:                        else if (x >= 0)
                     83:                                x += k;
                     84:                }
                     85:                k = Fwidth(rp[i]);
                     86:                if (k < 0) {
                     87:                        y += -k;
                     88:                        x = rp[i][0] == '\r' ? 0 : TABS*level;
                     89:                        x += strlen(rp[i]) - 1;
                     90:                }
                     91:                else {
                     92:                        if (x >= 0)
                     93:                                x += k;
                     94:                        if (rp[i]) {
                     95:                                if (rp[i][k] == '\t')
                     96:                                        ++level;
                     97:                                else if (rp[i][k] == '\b')
                     98:                                        --level;
                     99:                        }
                    100:                }
                    101:        }
                    102: 
                    103:        *py += y;
                    104:        *px = x;
                    105:        *plevel = level;
                    106: }
                    107: 
                    108: 
                    109: /*
                    110:  * Yield the width of a piece of fixed text as found in a node's repr,
                    111:  * excluding \b or \t.  If \n or \r is found, -1 is returned.
                    112:  * It assumes that \n or \r only occur as first
                    113:  * character, and \b or \t only as last.
                    114:  */
                    115: 
                    116: Visible int
                    117: fwidth(str)
                    118:        register string str;
                    119: {
                    120:        register int c;
                    121:        register int n = 0;
                    122: 
                    123:        if (!str)
                    124:                return 0;
                    125:        c = str[0];
                    126:        if (c == '\r' || c == '\n')
                    127:                return -1;
                    128:        for (; c; c = *++str)
                    129:                ++n;
                    130:        if (n > 0) {
                    131:                c = str[-1];
                    132:                if (c == '\t' || c == '\b')
                    133:                        --n;
                    134:        }
                    135:        return n;
                    136: }
                    137: 
                    138: 
                    139: /*
                    140:  * Evaluate the width of node n, assuming the widths of its children
                    141:  * have correctly been calculated.
                    142:  */
                    143: 
                    144: Visible int
                    145: evalwidth(n)
                    146:        register node n;
                    147: {
                    148:        register int w;
                    149:        register int i;
                    150:        register string *rp;
                    151:        register int y = 0;
                    152:        register int x = 0;
                    153:        register int nch;
                    154:        register node nn;
                    155: 
                    156:        rp = noderepr(n);
                    157:        nch = Type(n) == Tex ? 0 : nchildren(n);
                    158:        for (i = 0; i <= nch; ++i) {
                    159:                if (i) {
                    160:                        nn = child(n, i);
                    161:                        w = width(nn);
                    162:                        if (w < 0) {
                    163:                                y += -w;
                    164:                                x = w;
                    165:                        }
                    166:                        else
                    167:                                x += w;
                    168:                }
                    169:                w = Fwidth(rp[i]);
                    170:                if (w < 0) {
                    171:                        y += -w;
                    172:                        x = 0;
                    173:                }
                    174:                else
                    175:                        x += w;
                    176:        }
                    177:        if (y > 0)
                    178:                return -y;
                    179:        return x;
                    180: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.