summaryrefslogtreecommitdiff
path: root/support/RTF-1_06a1/trf-stack.c
blob: 2179b0ddd01988237b83926d5725b4ac71800647 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
/*
	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));
}