1 /* $Id: reader.h,v 1.23 1997/04/17 15:38:19 dps Exp $ */
2 /* header file for the reader */
3 
4 #ifndef __w6_reader_h__
5 #define __w6_reader_h__
6 #ifdef HAVE_CONFIG_H
7 #include "config.h"
8 #endif /* HAVE_CONFIG_H */
9 #include <stdlib.h>
10 #ifdef HAVE_STRING_H
11 #include <string.h>
12 #endif /* HAVE_STRING_H */
13 #ifdef HAVE_STRINGS_H
14 #include <strings.h>
15 #endif /* HAVE_STRINGS_H */
16 #include <iostream>
17 using namespace std;
18 #include "tblock.h"
19 #include "interface.h"
20 #include "fifo.h"
21 #include "word6.h"
22 
23 /* Raw reader output */
24 typedef enum
25 {
26     CH_PAR=0, CH_FIELD, CH_ROW, CH_SPEC, CH_ENDSPEC, CH_OTHER,
27     CH_HDRTN, CH_EOF, CH_PAGE, CH_FOOTNOTE,
28     CONTROL_FLAG=(1<<17), PART_FLAG=(1<<18)
29 } chunk_type;
30 
31 #define CH_NONL 255
32 #define CH_SUSPECT 127
33 
34 /*
35  * Anything shorter than in totla this is word abuse an all spec
36  * paragraph. This should be kept *very* small.
37  */
38 #define DISPL_TRESHOLD 3
39 #define PAR_ITEM_SEP_LIMIT 4
40 #define TEXT_ITEM_SEP_LIMIT 1024
41 
42 #ifndef __EXCLUDE_READER_CLASSES
43 
44 struct chunk_rtn
45 {
46     tblock txt;
47     int type;
48 };
49 
50 /* This class converts raw word 6 into chunks for easier digestion */
51 class chunk_reader
52 {
53  private:
54     tblock text;
55     istream *in;		/* Maybe should use istream here */
56     const char *tptr;		/* Points to tblock text */
57     int type;			/* Type */
58 
59     void read_chunk_raw(void);	/* Reads a lot */
60  protected:
61     struct chunk_rtn read_chunk(void); /* Returns the next bit */
62 
chunk_reader(istream * f)63     inline chunk_reader(istream *f)
64     {
65 	tptr=NULL;
66 	in=f;
67     }
~chunk_reader(void)68     inline ~chunk_reader(void) {}; /* Avoids compiler bug */
69 };
70 
71 
72 /*
73  * This class interpolates stuff not in the chunks, for example the
74  * the start and statistics of tables.
75  */
76 class tok_seq: private chunk_reader
77 {
78     /* Classes used here */
79 public:
80     /* Public token class */
81     class tok
82     {
83     private:
84 	enum {TABLE=0, TEXT} dtype;
85 
86     public:
87 	enum { TOK_START=0, TOK_END };
88 	token tokval;
89 	union
90 	{
91 	    struct
92 	    {
93 		int rows;
94 		int cols;
95 	    } table;
96 	    const char *d;
97 	} data;
98 	int end;
99 
100 	friend ostream &operator <<(ostream &, const tok *f);
101 	tok &operator=(const tok &d);
102 
103 	/* Avoid the need to cast NULL everywhere  for NULL defined as
104 	   (void *) 0 */
tok(token t,void * d,int e)105 	inline tok(token t, void *d, int e)
106 	{
107 	    tokval=t;
108 	    data.d=(const char *) d;
109 	    dtype=TEXT;
110 	    end=e;
111 	}
112 	/* Avoid the need to cast NULL everywhere for NULL defined as 0 */
tok(token t,int d,int e)113 	inline tok(token t, int d, int e)
114 	{
115 	    d=d;
116 	    tokval=t;
117 	    data.d=(const char *) NULL;
118 	    dtype=TEXT;
119 	    end=e;
120 	}
121 	/* Avoid the need to cast NULL everywhere for NULL defined as 0L */
tok(token t,long int d,int e)122 	inline tok(token t, long int d, int e)
123 	{
124 	    d=d;
125 	    tokval=t;
126 	    data.d=(const char *) NULL;
127 	    dtype=TEXT;
128 	    end=e;
129 	}
130 
tok(token t,const char * d,int e)131 	inline tok(token t, const char *d, int e)
132 	{
133 	    tokval=t;
134 	    if (d!=NULL)
135 		data.d=strdup(d);
136 	    else
137 		data.d=NULL;
138 	    dtype=TEXT;
139 	    end=e;
140 	}
tok(token t,int c,int r,int e)141 	inline tok(token t, int c, int r, int e)
142 	{
143 	    tokval=t;
144 	    data.table.rows=r;
145 	    data.table.cols=c;
146 	    dtype=TABLE;
147 	    end=e;
148 	}
~tok(void)149 	inline ~tok(void)
150 	{
151 	    if (dtype==TEXT && data.d!=NULL)
152 		free((void *) data.d);
153 	}
154     };
155 
156 
157 private:
158     /* Private class for table information */
159     class table_info
160     {
161     private:
162 	fifo<tok> toks;
163 
164     public:
165 	int rows;
166 	int cols;
167 	int col;
168 
table_info(void)169 	inline table_info(void)
170 	{
171 	    cols=0;
172 	    col=0;
173 	    rows=0;
174 	}
175 
tok_push(token t,tblock * s)176 	inline void tok_push(token t, tblock *s)
177 	{
178 	    tok *td;
179 	    td=new(tok)(t, (const char *) (*s), tok::TOK_START);
180 	    toks.enqueue(td);
181 	    td=new(tok)(t, (void *) NULL, tok::TOK_END);
182 	    toks.enqueue(td);
183 	}
184 
enqueue(const tok * t)185 	inline void enqueue(const tok *t)
186 	{
187 	    toks.enqueue(t);
188 	}
189 
finish(fifo<tok> * out)190 	inline void finish(fifo<tok> *out)
191 	{
192 	    tok *t;
193 
194 	    t=new(tok)(T_TABLE, cols, rows, tok::TOK_START);
195 	    out->enqueue(t);
196 	    out->transfer(&toks);
197 	    t=new(tok)(T_TABLE, cols, rows, tok::TOK_END);
198 	    out->enqueue(t);
199 	}
~table_info(void)200 	inline ~table_info(void) {} // Avoid compiler bug
201     };
202 
203 private:
204     fifo<tok> output;		/* Output with equation cleaned up */
205     const tok *saved_tok;
206     int done_end;
207     table_info *table;
208     int rd_token(void);
209     const tok *feed_token(void);
210     const tok *math_collect(void);
211 
212     /* Token pusher */
tok_push(token t,tblock * s)213     inline void tok_push(token t, tblock *s)
214     {
215 	tok *td;
216 	td=new(tok)(t, (const char *) (*s), tok::TOK_START);
217 	output.enqueue(td);
218 	td=new(tok)(t, (void *) NULL, tok::TOK_END);
219 	output.enqueue(td);
220     }
221 
222     const tok *eqn_rd_token(void);
223 
224     /* List handling */
225     typedef enum { LIST_BULLET, LIST_ENUMERATE, LIST_ENUM_ALPHA } l_type;
226     struct list_info
227     {
228 	struct list_info *next_list;
229 	l_type list_type;
230 	int obj_cnt;
231 	int text_cnt;
232 	int items;
233 	union
234 	{
235 	    int item_no;
236 	    int lbullet;
237 	} ldata;
238 	fifo<tok_seq::tok> *last_item;
239     };
240     struct list_info *lp;	/* List pointer */
241     fifo<tok> outqueue;		/* Final output (so far...) */
242     fifo<tok> *recycled;	/* elements to be processed again */
243     struct list_info *list_type(const char *);
244     const char *list_check(const char *, struct list_info **);
245     const char *l_type_name(const struct list_info *);
246 
247  public:
248 
249 
tok_seq(istream * in)250     tok_seq(istream *in):  chunk_reader(in)
251     {
252 	tok *t=new(tok)(T_DOC, "Converted by word2x", tok::TOK_START);
253 	table=NULL;		/* No table */
254 	saved_tok=NULL;		/* No saved token */
255 	lp=NULL;		/* No list */
256 	recycled=NULL;		/* Nothing recycled */
257 	done_end=0;
258 
259 	output.enqueue(t);
260     }
261 
return_toks(fifo<tok> * tp)262     inline void return_toks(fifo<tok> *tp)
263     {
264 	if (recycled==NULL)
265 	    recycled=new(fifo<tok>);
266 	recycled->ins_trans(tp);
267     }
268 
~tok_seq(void)269     inline ~tok_seq(void) {}	// Avoids compiler bug
270 
271     const tok *read_token(void);
272 
273 };
274 #endif /* __EXCLUDE_READER_CLASSES */
275 #endif /* __w6_reader_h__ */
276 
277 
278 
279 
280