home *** CD-ROM | disk | FTP | other *** search
- /*
- trf-table.c - table writing functions
-
- Ugly ugly ugly.
- */
-
- # include <stdio.h>
- # include <sys/types.h>
- # include "rtf.h"
- # include "rtf2troff.h"
-
-
- static int CellBorderLocIndex ();
- static int VCellBorderType ();
- static char *VCellBorderStr ();
- static char *HCellBorderStr ();
-
-
- /*
- Border type tokens *follow* cell border location specifiers.
- */
-
- void TblAttr ()
- {
- double inch = (double) rtfParam / (double) rtfTpi;
- int i, j, loc;
-
- switch (rtfMinor)
- {
- case rtfCellBordBottom:
- case rtfCellBordTop:
- case rtfCellBordLeft:
- case rtfCellBordRight:
- if (its->nCells >= maxCell)
- {
- fprintf (stderr,
- "Borders specified for too many cells\n");
- break;
- }
- loc = CellBorderLocIndex (rtfMinor);
- /*
- Get border type tokens until non-type token seen,
- then route non-type token normally.
- */
- for (;;)
- {
- (void) RTFGetToken ();
- if (!RTFCheckCM (rtfControl, rtfParAttr)
- || (rtfMinor != rtfBorderSingle
- && rtfMinor != rtfBorderThick
- && rtfMinor != rtfBorderShadow
- && rtfMinor != rtfBorderDouble
- && rtfMinor != rtfBorderDot
- && rtfMinor != rtfBorderHair))
- break;
- if (its->nCells < maxCell)
- its->border[its->nCells][loc] = rtfMinor;
- }
- RTFRouteToken (); /* send non-border through router */
- break;
- case rtfRowDef:
- its->tableHeader = 0;
- its->nCells = 0;
- its->curCell = 0;
- for (i = 0; i < maxCell; i++)
- {
- its->cellPos[i] = 0;
- for (j = 0; j < 4; j++)
- its->border[i][j] = rtfNoBorderType;
- }
- its->tableLeft = 0;
- its->cellGap = 0;
- break;
- case rtfRowLeft:
- break;
- case rtfRowRight:
- break;
- case rtfRowCenter:
- break;
- case rtfRowGapH:
- its->cellGap = inch;
- break;
- case rtfRowHt:
- break;
- case rtfRowLeftEdge:
- its->tableLeft = inch;
- break;
- case rtfCellPos:
- if (its->nCells >= maxCell)
- fprintf (f, "max. table row cell count (%d) exceeded\n",
- maxCell);
- else
- its->cellPos[its->nCells++] = inch;
- break;
- case rtfMergeRngFirst:
- break;
- case rtfMergePrevious:
- break;
- }
- }
-
-
- void BeginTbl ()
- {
- int i, n;
- double cwid;
- char *p;
-
- Flush ();
- FlushState ();
- SaveTblFPV (); /* save current font, ps, vs */
- fprintf (f, ".TS\n");
- fprintf (f, "center tab(^);\n");
- for (i = 0; i < its->nCells; i++)
- {
- if ((p = VCellBorderStr (VCellBorderType (i))) != NULL)
- fprintf (f, "%s ", p);
- cwid = its->cellPos[i];
- if (i > 0)
- cwid -= its->cellPos[i-1];
- cwid -= EnWidth ();
- fprintf (f, "l1w(%gi) ", cwid);
- }
- if ((p = VCellBorderStr (VCellBorderType (its->nCells))) != NULL)
- fprintf (f, "%s ", p);
- fprintf (f, ".\n");
- ++its->tableHeader;
-
- /* print top borders */
- n = 0;
- for (i = 0; i < its->nCells; i++)
- {
- if (its->border[i][topIndex] != rtfNoBorderType)
- ++n;
- }
- if (n > 0)
- {
- for (i = 0; i < its->nCells; i++)
- {
- if (i > 0)
- fprintf (f, "^");
- if ((p = HCellBorderStr (its->border[i][topIndex]))
- != NULL)
- fprintf (f, "%s", p);
- }
- fprintf (f, "\n");
- }
- }
-
-
- void EndTbl ()
- {
- int i, n;
- char *p;
-
- /* print bottom borders */
- n = 0;
- for (i = 0; i < its->nCells; i++)
- {
- if (its->border[i][bottomIndex] != rtfNoBorderType)
- ++n;
- }
- if (n > 0)
- {
- for (i = 0; i < its->nCells; i++)
- {
- if (i > 0)
- fprintf (f, "^");
- if ((p = HCellBorderStr (its->border[i][bottomIndex]))
- != NULL)
- fprintf (f, "%s", p);
- }
- fprintf (f, "\n");
- }
- fprintf (f, ".TE\n"); /* this undoes ps/vs... */
- FlushTblFPV (); /* so redo it. ugh. */
- FlushState ();
- its->tableHeader = 0;
- its->curCell = 0;
- }
-
-
- /*
- BeginCell() called when first \intbl in row is seen and after
- each \cell; EndCell() called whenever \cell or \row are seen.
- These do nothing if the cell number is greater than would be
- expected given the number of cell positions found in the table
- layout information. (It *is* possible to find information
- beyond the last cell; Word for Macintosh, at least, seems to put an
- empty cell at the end of each row.)
- */
-
- void BeginCell ()
- {
- /* accept cells 0..nCells-1 */
- if (its->curCell < its->nCells)
- {
- Flush ();
- fprintf (f, "T{\n");
- /*FlushState ();*/
- FlushTblFPV (); /* set up correct font, ps, vs */
- }
- inTable = 1;
- }
-
-
- void EndCell ()
- {
- Flush ();
- /* accept cells 0..nCells-1 */
- if (its->curCell < its->nCells)
- {
- fprintf (f, "T}");
- }
- ++its->curCell;
- if (its->curCell < its->nCells)
- fprintf (f, "^"); /* more cells to go */
- else if (its->curCell == its->nCells)
- fprintf (f, "\n"); /* no more cells to go */
- inTable = 0;
- }
-
-
- static int CellBorderLocIndex (loc)
- int loc;
- {
- switch (loc)
- {
- case rtfCellBordLeft: return (leftIndex);
- case rtfCellBordRight: return (rightIndex);
- case rtfCellBordTop: return (topIndex);
- case rtfCellBordBottom: return (bottomIndex);
- }
- fprintf (stderr, "CellBorderLocIndex: bad argument (%d)\n", loc);
- exit (1);
- }
-
-
- /*
- Determine vertical border for left of cell i. Takes into account
- right border of i-1 and left border of i, with the latter taking
- precedence. Two special cases are handled implicitly in code
- below. When i = 0, return left border of cell 0. When i = nCells,
- return right border of cell nCells-1.
- */
-
- static int VCellBorderType (i)
- int i;
- {
- int border = rtfNoBorderType;
-
- if (i >= 0 && i < its->nCells)
- border = its->border[i][leftIndex];
- if (i > 0 && i <= its->nCells && border == rtfNoBorderType)
- border = its->border[i-1][rightIndex];
- return (border);
- }
-
-
- static char *VCellBorderStr (type)
- int type;
- {
- switch (type)
- {
- case rtfBorderShadow:
- case rtfBorderThick:
- case rtfBorderDot:
- case rtfBorderHair:
- case rtfBorderSingle: return ("|");
- case rtfBorderDouble: return ("||");
- }
- return (NULL);
- }
-
-
- static char *HCellBorderStr (type)
- int type;
- {
- switch (type)
- {
- case rtfBorderShadow:
- case rtfBorderThick:
- case rtfBorderDot:
- case rtfBorderHair:
- case rtfBorderSingle: return ("_");
- case rtfBorderDouble: return ("=");
- }
- return (NULL);
- }
-