home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Borland Programmer's Resource
/
Borland_Programmers_Resource_CD_1995.iso
/
utils
/
rtfprsr
/
trfstack.c
< prev
Wrap
Text File
|
1995-05-18
|
6KB
|
264 lines
/*
trf-stack.c - internal and written stack operations.
*/
# include <stdio.h>
# include <sys/types.h>
# include "rtf.h"
# include "rtf2troff.h"
static int iTopState = 0; /* current internal state */
static State iState[maxIStack] = /* internal state stack */
{
/*
state 0 = initial state.
*/
rtfNoDestination, /* destination */
{
0, /* landscape (0 = no) */
12240.0/rtfTpi, /* paper width = 8.5i*/
15840.0/rtfTpi, /* paper height = 11i */
1800.0/rtfTpi, /* left margin = 1.25i */
1800.0/rtfTpi, /* right margin = 1.25i */
1440.0/rtfTpi, /* top margin = 1i */
1440.0/rtfTpi, /* bottom margin = 1i */
720.0/rtfTpi /* tab width = .5i */
},
{
rtfPageBreak, /* section break type */
1, /* starting page number */
0, /* continuous page numbering */
1080.0/rtfTpi, /* header position */
1080.0/rtfTpi, /* footer position */
0 /* title page not special */
},
{
0, /* first indent */
0, /* left indent */
0, /* right indent */
0, /* space before */
0, /* space after */
.2, /* space between: 12p * 1.2 = 14.4p */
0, /* no tabs set yet */
0, /* number of tabs */
{ 0 }, /* tab positions */
{ 0 }, /* tab types */
rtfLeaderMotion, /* tab character */
rtfQuadLeft, /* justification */
rtfNoBorderType, /* no border */
0 /* draw border nowhere */
},
{
12, /* font size */
0, /* char style (plain, DON'T CHANGE) */
0, /* superscript */
0 /* subscript */
}
};
static int wTopState = 0; /* current written state */
static State wState[maxWStack]; /* written state stack */
/*
Set up pointers into internal state 0, and equate initial written
state to internal state (although written state isn't actually
written until FlushInitialState()).
Initialize the tab type array to left tabs, so that any tab
positions specified without a type will default to left-justified.
*/
void InitState ()
{
is = &iState[0];
/* initialize state 0 */
ids = &is->docState;
iss = &is->sectState;
ips = &is->parState;
ics = &is->charState;
ips->tabFlag = 0;
InitTabSet ();
/* sync written state to internal state */
bcopy ((char *) &iState[0], (char *) &wState[0], (int) sizeof (State));
ws = &wState[0];
wds = &ws->docState;
wss = &ws->sectState;
wps = &ws->parState;
wcs = &ws->charState;
}
void CheckFinalState ()
{
if (iTopState != 0)
fprintf (stderr, "Warning: unbalanced brace level\n");
if (wTopState != 0)
fprintf (stderr, "Warning: unrestored environment\n");
if (indirectionLevel > 0)
fprintf (stderr, "Warning: unrestored indirection\n");
}
/*
Push or pop internal state.
On push, initial value of new state is same as current state, so
no state *change* is involved. Indicate that no destination or
tab stops have been specified.
On pop, revert to previous state. It's just laziness to set the
state change variables on a state pop, since some or all of them
may well not have changed at all... but it's safest and easiest
to do so.
*/
void PushIState ()
{
if (iTopState >= maxIStack - 1)
{
fprintf (stderr, "Internal state stack limit exceeded");
fprintf (stderr, " maximum level (%d)\n", maxIStack);
exit (1);
}
bcopy ((char *) &iState[iTopState],
(char *) &iState[iTopState + 1], (int) sizeof (State));
is = &iState[++iTopState];
is->destination = rtfNoDestination;
is->parState.tabFlag = 0; /* no tabs set in state yet */
ids = &is->docState;
iss = &is->sectState;
ips = &is->parState;
ics = &is->charState;
}
void PopIState ()
{
if (iTopState < 1)
{
fprintf (stderr, "Pop error: no internal state to pop");
fprintf (stderr, " maximum level (%d)\n", maxIStack);
exit (1);
}
is = &iState[--iTopState];
ids = &is->docState;
iss = &is->sectState;
ips = &is->parState;
ics = &is->charState;
++docStateChanged;
++sectStateChanged;
++parStateChanged;
++charStateChanged;
}
void PushWState ()
{
if (wTopState >= maxWStack - 1)
{
fprintf (stderr, "Written state stack limit exceeded");
fprintf (stderr, " maximum level (%d)\n", maxWStack);
exit (1);
}
bcopy ((char *) &wState[wTopState],
(char *) &wState[wTopState + 1], (int) sizeof (State));
ws = &wState[++wTopState];
wds = &ws->docState;
wss = &ws->sectState;
wps = &ws->parState;
wcs = &ws->charState;
}
void PopWState ()
{
if (wTopState < 1)
{
fprintf (stderr, "Pop error: no written state to pop");
fprintf (stderr, " maximum level (%d)\n", maxWStack);
exit (1);
}
ws = &wState[--wTopState];
wds = &ws->docState;
wss = &ws->sectState;
wps = &ws->parState;
wcs = &ws->charState;
++docStateChanged;
++sectStateChanged;
++parStateChanged;
++charStateChanged;
}
/*
Environment switching routines. When commands are written
to switch environments, take snapshot of current written state.
When environment switches back, restore to snapshot state to
reflect the troff state switch.
Environment switches are saved only when diversions are collected,
not when they are written out.
*/
void BeginDiversion (name)
char *name;
{
Flush ();
fprintf (f, ".rm %s\n.di %s\n", name, name);
++indirectionLevel;
fprintf (f, ".ev 1\n");
PushWState ();
}
void EndDiversion ()
{
Flush ();
fprintf (f, ".br\n");
fprintf (f, ".ev\n");
PopWState ();
fprintf (f, ".di\n");
--indirectionLevel;
}
/*
Restore section, paragraph or character defaults, using
values stored in state 0.
Paragraph defaults are restored by using the state 0 values,
they applying the "Normal" style (style 0). The tab flag is reset
before expanding the style so any inherited tabs will be overridden
by tabs in the style, and reset after expansion so any tabs in the
paragraph itself will override inherited or style tabs.
*/
void RestoreSectDefaults ()
{
bcopy ((char *) &iState[0].sectState, (char *) iss,
(int) sizeof (SectState));
}
void RestoreParDefaults ()
{
bcopy ((char *) &iState[0].parState, (char *) ips,
(int) sizeof (ParState));
ips->tabFlag = 0;
RTFExpandStyle (0);
ips->tabFlag = 0;
}
void RestoreCharDefaults ()
{
bcopy ((char *) &iState[0].charState, (char *) ics,
(int) sizeof (CharState));
}