summaryrefslogtreecommitdiff
path: root/support/RTF-1_06a1/trf-table.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /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.c289
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);
+}