diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/RTF-1_06a1/trf-table.c |
Initial commit
Diffstat (limited to 'support/RTF-1_06a1/trf-table.c')
-rw-r--r-- | support/RTF-1_06a1/trf-table.c | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/support/RTF-1_06a1/trf-table.c b/support/RTF-1_06a1/trf-table.c new file mode 100644 index 0000000000..1b2164e5e9 --- /dev/null +++ b/support/RTF-1_06a1/trf-table.c @@ -0,0 +1,289 @@ +/* + 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); +} |