Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

and .
Rev Author Line No. Line
8335 maxcodehac 1
 
2
   GNU UnRTF, a command-line program to convert RTF documents to other formats.
3
   Copyright (C) 2000,2001 Zachary Thayer Smith
4
5
 
6
   it under the terms of the GNU General Public License as published by
7
   the Free Software Foundation; either version 2 of the License, or
8
   (at your option) any later version.
9
10
 
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
   GNU General Public License for more details.
14
15
 
16
   along with this program; if not, write to the Free Software
17
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19
 
20
===========================================================================*/
21
22
 
23
 
24
 * Module name:    convert
25
 * Author name:    Zach Smith
26
 * Create date:    24 Jul 01
27
 * Purpose:        Performs conversion from RTF to other formats.
28
 *----------------------------------------------------------------------
29
 * Changes:
30
 * 24 Jul 01, tuorfa@yahoo.com: moved code over from word.c
31
 * 24 Jul 01, tuorfa@yahoo.com: fixed color table reference numbering.
32
 * 30 Jul 01, tuorfa@yahoo.com: moved hex convert to util.c
33
 * 30 Jul 01, tuorfa@yahoo.com: moved special expr tables to special.c
34
 * 30 Jul 01, tuorfa@yahoo.com: moved attribute stack to attr.c
35
 * 31 Jul 01, tuorfa@yahoo.com: began addition of hash of rtf commands
36
 * 01 Aug 01, tuorfa@yahoo.com: finished bulk of rtf command hash
37
 * 03 Aug 01, tuorfa@yahoo.com: removed no-op hash entries to save space
38
 * 03 Aug 01, tuorfa@yahoo.com: code to ignore rest of groups for \*, etc
39
 * 03 Aug 01, tuorfa@yahoo.com: fixed para-alignnot being cleared by \pard
40
 * 03 Aug 01, tuorfa@yahoo.com: added support for \keywords group
41
 * 03 Aug 01, tuorfa@yahoo.com: added dummy funcs for header/footer
42
 * 03 Aug 01, tuorfa@yahoo.com: began addition of hyperlink support
43
 * 04 Aug 01, tuorfa@yahoo.com: fixed debug string printing
44
 * 05 Aug 01, tuorfa@yahoo.com: added support for hyperlink data with \field
45
 * 06 Aug 01, tuorfa@yahoo.com: added support for several font attributes
46
 * 08 Aug 01, gommer@gmx.net: bugfix for picture storing mechanism
47
 * 08 Sep 01, tuorfa@yahoo.com: added use of PROGRAM_NAME
48
 * 11 Sep 01, tuorfa@yahoo.com: added support for JPEG and PNG pictures
49
 * 19 Sep 01, tuorfa@yahoo.com: added output personality support
50
 * 22 Sep 01, tuorfa@yahoo.com: added function-level comment blocks
51
 * 23 Sep 01, tuorfa@yahoo.com: fixed translation of \'XX expressions
52
 *--------------------------------------------------------------------*/
53
54
 
55
#include 
56
#include 
57
#include 
58
59
 
60
#include "parse.h"
61
#include "util.h"
62
#include "malloc.h"
63
#include "main.h"
64
#include "error.h"
65
#include "word.h"
66
#include "hash.h"
67
#include "convert.h"
68
#include "attr.h"
69
70
 
71
 
72
#define BINARY_ATTRS
73
*/
74
75
 
76
 
77
78
 
79
 
80
 */
81
static int coming_pars_that_are_tabular = 0;
82
static int within_table = FALSE;
83
static int have_printed_row_begin=FALSE;
84
static int have_printed_cell_begin=FALSE;
85
static int have_printed_row_end=FALSE;
86
static int have_printed_cell_end=FALSE;
87
88
 
89
 
90
 */
91
static int total_chars_this_line=0; /* for simulating \tab */
92
93
 
94
 
95
 */
96
enum {
97
	ALIGN_LEFT=0,
98
	ALIGN_RIGHT,
99
	ALIGN_CENTER,
100
	ALIGN_JUSTIFY
101
};
102
103
 
104
 
105
 
106
 */
107
int simulate_smallcaps;
108
int simulate_allcaps;
109
110
 
111
 
112
enum {
113
	PICT_UNKNOWN=0,
114
	PICT_WM,
115
	PICT_MAC,
116
	PICT_PM,
117
	PICT_DI,
118
	PICT_WB,
119
	PICT_JPEG,
120
	PICT_PNG,
121
};
122
static int within_picture=FALSE;
123
static int picture_file_number=1;
124
static char picture_path[255];
125
static int picture_width;
126
static int picture_height;
127
static int picture_bits_per_pixel=1;
128
static int picture_type=PICT_UNKNOWN;
129
static int picture_wmetafile_type;
130
static char *picture_wmetafile_type_str;
131
132
 
133
 
134
static int within_header=TRUE;
135
136
 
137
 
138
 
139
140
 
141
 
142
 
143
void starting_text();
144
145
 
146
 
147
148
 
149
 
150
 
151
 * Name:	print_banner
152
 * Purpose:	Writes program-identifying text to the output stream.
153
 * Args:	None.
154
 * Returns:	None.
155
 *=======================================================================*/
156
157
 
158
print_banner () {
159
	if (!banner_printed) {
160
		printf (op->comment_begin);
161
	  	printf ("Translation from RTF performed by ");
162
		printf ("%s, version ", PROGRAM_NAME);
163
		printf ("%s", PROGRAM_VERSION);
164
		printf (op->comment_end);
165
166
 
167
	  	printf ("For information about this marvellous program,");
168
		printf (op->comment_end);
169
170
 
171
	  	printf ("please go to %s", PROGRAM_WEBSITE);
172
		printf (op->comment_end);
173
	}
174
	banner_printed=TRUE;
175
}
176
177
 
178
 
179
 * Name:	starting_body
180
 * Purpose:	Switches output stream for writing document contents.
181
 * Args:	None.
182
 * Returns:	None.
183
 *=======================================================================*/
184
185
 
186
starting_body ()
187
{
188
	if (!have_printed_body) {
189
		if (!inline_mode) {
190
			printf (op->header_end);
191
			printf (op->body_begin);
192
		}
193
		within_header=FALSE;
194
		have_printed_body=TRUE;
195
	}
196
}
197
198
 
199
 
200
/*-------------------------------------------------------------------*/
201
/*-------------------------------------------------------------------*/
202
203
 
204
 
205
#ifdef ENGLISH
206
  "January","February","March","April","May","June","July","August",
207
  "September","October","November","December"
208
#endif
209
#ifdef FRANCAIS
210
  "Janvier","Fevrier","Mars","Avril","Mai","Juin","Juillet","Aout","Septembre",
211
  "Octobre","Novembre","Decembre"
212
#endif
213
#ifdef ITALIANO
214
  "Ianuario","Febbraio","Marzo","Aprile","Maggio","Iuno",
215
  "Luglio","Agusto","Settembre","Ottobre","Novembre","Dicembre"
216
#endif
217
#ifdef ESPANOL
218
  "?","Febraio","Marzo","Abril","Mayo","?","?","Agosto",
219
  "Septiembre","Octubre","Noviembre","Diciembre"
220
#endif
221
#ifdef DEUTCH
222
  "?","?","?","?","?","?","?","?",
223
  "?","?","?","?"
224
#endif
225
};
226
227
 
228
 
229
 * Name:	word_dump_date
230
 * Purpose:	Extracts date from an RTF input stream, writes it to
231
 *              output stream.
232
 * Args:	Word*, buffered RTF stream
233
 * Returns:	None.
234
 *=======================================================================*/
235
236
 
237
word_dump_date (Word *w)
238
{
239
	int year=0, month=0, day=0, hour=0, minute=0;
240
	CHECK_PARAM_NOT_NULL(w);
241
	while (w) {
242
	 	char *s = word_string (w);
243
		if (*s == '\\') {
244
			++s;
245
			if (!strncmp (s, "yr", 2) && isdigit(s[2])) {
246
				year = atoi (&s[2]);
247
			}
248
			else if (!strncmp (s, "mo", 2) && isdigit(s[2])) {
249
				month= atoi (&s[2]);
250
			}
251
			else if (!strncmp (s, "dy", 2) && isdigit(s[2])) {
252
				day= atoi (&s[2]);
253
			}
254
			else if (!strncmp (s, "min", 3) && isdigit(s[3])) {
255
				minute= atoi (&s[3]);
256
			}
257
			else if (!strncmp (s, "hr", 2) && isdigit(s[2])) {
258
				hour= atoi (&s[2]);
259
			}
260
		}
261
		w=w->next;
262
	}
263
	if (year && month && day) {
264
		printf ("%d %s %d ", day, month_strings[month-1], year);
265
	}
266
	if (hour && minute) {
267
		printf ("%02d:%02d ", hour, minute);
268
	}
269
}
270
271
 
272
 
273
 
274
275
 
276
	int num;
277
	char *name;
278
} FontEntry;
279
280
 
281
static FontEntry font_table[MAX_FONTS];
282
static int total_fonts=0;
283
284
 
285
 
286
 
287
 * Name:	lookup_fontname
288
 * Purpose:	Fetches the name of a font from the already-read font table.
289
 * Args:	Font#.
290
 * Returns:	Font name.
291
 *=======================================================================*/
292
293
 
294
lookup_fontname (int num) {
295
	int i;
296
	if (total_fonts)
297
	for(i=0;i
298
		if (font_table[i].num==num)
299
			return font_table[i].name;
300
	}
301
	return NULL;
302
}
303
304
 
305
 
306
 * Name:	process_font_table
307
 * Purpose:	Processes the font table of an RTF file.
308
 * Args:	Tree of words.
309
 * Returns:	None.
310
 *=======================================================================*/
311
312
 
313
process_font_table (Word *w)
314
{
315
	Word *w2;
316
317
 
318
319
 
320
		int num;
321
		char name[255];
322
		char *tmp;
323
324
 
325
			tmp = word_string (w2);
326
			if (!strncmp("\\f",tmp,2)) {
327
				num = atoi (&tmp[2]);
328
				name[0]=0;
329
330
 
331
				while(w2) {
332
					tmp = word_string (w2);
333
					if (tmp && tmp[0] != '\\')
334
						strcat(name,tmp);
335
336
 
337
				}
338
339
 
340
				if ((tmp=strchr(name,';')))
341
					*tmp=0;
342
343
 
344
				font_table[total_fonts].name=my_strdup(name);
345
				total_fonts++;
346
			}
347
		}
348
		w=w->next;
349
	}
350
351
 
352
	printf ("font table contains %d fonts total",total_fonts);
353
	printf (op->comment_end);
354
355
 
356
		int i;
357
358
 
359
		printf ("font table dump: \n");
360
		for (i=0; i
361
			printf (" font %d = %s\n", font_table[i].num,
362
				font_table[i].name);
363
		}
364
		printf (op->comment_end);
365
	}
366
}
367
368
 
369
 
370
 * Name:	process_index_entry
371
 * Purpose:	Processes an index entry of an RTF file.
372
 * Args:	Tree of words.
373
 * Returns:	None.
374
 *=======================================================================*/
375
376
 
377
process_index_entry (Word *w)
378
{
379
	Word *w2;
380
381
 
382
383
 
384
		if ((w2=w->child)) {
385
			char *str = word_string (w2);
386
387
 
388
				printf (op->comment_begin);
389
				printf ("index entry word: %s ", str);
390
				printf (op->comment_end);
391
			}
392
		}
393
		w=w->next;
394
	}
395
}
396
397
 
398
 
399
 * Name:	process_toc_entry
400
 * Purpose:	Processes an index entry of an RTF file.
401
 * Args:	Tree of words, flag to say whether to include a page#.
402
 * Returns:	None.
403
 *=======================================================================*/
404
405
 
406
process_toc_entry (Word *w, int include_page_num)
407
{
408
	Word *w2;
409
410
 
411
412
 
413
		if ((w2=w->child)) {
414
			char *str = word_string (w2);
415
416
 
417
				printf (op->comment_begin);
418
				printf ("toc %s entry word: %s ",
419
					include_page_num ? "page#":"no page#",
420
					str);
421
				printf (op->comment_end);
422
			}
423
		}
424
		w=w->next;
425
	}
426
}
427
428
 
429
 
430
 * Name:	process_info_group
431
 * Purpose:	Processes the \info group of an RTF file.
432
 * Args:	Tree of words.
433
 * Returns:	None.
434
 *=======================================================================*/
435
436
 
437
process_info_group (Word *w)
438
{
439
	Word *child;
440
441
 
442
443
 
444
		child = w->child;
445
		if (child) {
446
			Word *w2;
447
			char *s;
448
449
 
450
451
 
452
				if (!strcmp("\\title", s)) {
453
					printf (op->document_title_begin);
454
					w2=child->next;
455
					while (w2) {
456
						char *s2 = word_string(w2);
457
						if (s2[0] != '\\')
458
							printf ("%s", s2);
459
						w2=w2->next;
460
					}
461
					printf (op->document_title_end);
462
				}
463
				else if (!strcmp("\\keywords", s)) {
464
					printf (op->document_keywords_begin);
465
					w2=child->next;
466
					while (w2) {
467
						char *s2 = word_string(w2);
468
						if (s2[0] != '\\')
469
							printf ("%s,", s2);
470
						w2=w2->next;
471
					}
472
					printf (op->document_keywords_end);
473
				}
474
				else if (!strcmp("\\author", s)) {
475
					printf (op->document_author_begin);
476
					w2=child->next;
477
					while (w2) {
478
						char *s2 = word_string(w2);
479
						if (s2[0] != '\\')
480
							printf ("%s", s2);
481
						w2=w2->next;
482
					}
483
					printf (op->document_author_end);
484
				}
485
				else if (!strcmp("\\comment", s)) {
486
					printf (op->comment_begin);
487
					printf ("comments: ");
488
					w2=child->next;
489
					while (w2) {
490
						char *s2 = word_string(w2);
491
						if (s2[0] != '\\')
492
							printf ("%s", s2);
493
						w2=w2->next;
494
					}
495
					printf (op->comment_end);
496
				}
497
				else if (!strncmp("\\nofpages", s, 9)) {
498
					printf (op->comment_begin);
499
					printf ("total pages: %s",&s[9]);
500
					printf (op->comment_end);
501
				}
502
				else if (!strncmp("\\nofwords", s, 9)) {
503
					printf (op->comment_begin);
504
					printf ("total words: %s",&s[9]);
505
					printf (op->comment_end);
506
				}
507
				else if (!strncmp("\\nofchars", s, 9) && isdigit(s[9])) {
508
					printf (op->comment_begin);
509
					printf ("total chars: %s",&s[9]);
510
					printf (op->comment_end);
511
				}
512
				else if (!strcmp("\\creatim", s)) {
513
					printf (op->comment_begin);
514
					printf ("creaton date: ");
515
					if (child->next) word_dump_date (child->next);
516
					printf (op->comment_end);
517
				}
518
				else if (!strcmp("\\printim", s)) {
519
					printf (op->comment_begin);
520
					printf ("last printed: ");
521
					if (child->next) word_dump_date (child->next);
522
					printf (op->comment_end);
523
				}
524
				else if (!strcmp("\\buptim", s)) {
525
					printf (op->comment_begin);
526
					printf ("last backup: ");
527
					if (child->next) word_dump_date (child->next);
528
					printf (op->comment_end);
529
				}
530
				else if (!strcmp("\\revtim", s)) {
531
					printf (op->comment_begin);
532
					printf ("revision date: ");
533
					if (child->next) word_dump_date (child->next);
534
					printf (op->comment_end);
535
				}
536
			}
537
538
 
539
			 * we want to process the following.
540
			 */
541
			if (!strcmp("\\hlinkbase", s)) {
542
				char *linkstr = NULL;
543
544
 
545
				printf ("hyperlink base: ");
546
				if (child->next) {
547
					Word *nextword = child->next;
548
549
 
550
						linkstr=word_string (nextword);
551
				}
552
553
 
554
					printf ("%s", linkstr);
555
				else
556
					printf ("(none)");
557
				printf (op->comment_end);
558
559
 
560
				hyperlink_base = linkstr;
561
			}
562
		}
563
		w = w->next;
564
	}
565
}
566
567
 
568
569
 
570
571
 
572
	unsigned char r,g,b;
573
} Color;
574
575
 
576
static Color color_table[MAX_COLORS];
577
static int total_colors=0;
578
579
 
580
 
581
 * Name:	process_color_table
582
 * Purpose:	Processes the color table of an RTF file.
583
 * Args:	Tree of words.
584
 * Returns:	None.
585
 *=======================================================================*/
586
587
 
588
process_color_table (Word *w)
589
{
590
	int r,g,b;
591
592
 
593
594
 
595
	 * i.e. an empty color entry. This seems to indicate that color 0
596
	 * will not be used, so here I set it to black.
597
	 */
598
	r=g=b=0;
599
600
 
601
		char *s = word_string (w);
602
603
 
604
		printf (op->comment_begin);
605
		printf ("found this color table word: %s", word_string(w));
606
		printf (op->comment_end);
607
#endif
608
609
 
610
			r = atoi(&s[4]);
611
			while(r>255) r>>=8;
612
		}
613
		else if(!strncmp("\\green",s,6)) {
614
			g = atoi(&s[6]);
615
			while(g>255) g>>=8;
616
		}
617
		else if(!strncmp("\\blue",s,5)) {
618
			b = atoi(&s[5]);
619
			while(b>255) b>>=8;
620
		}
621
		else
622
		/* If we find the semicolon which denotes the end of
623
		 * a color entry then store the color, even if we don't
624
		 * have all of it.
625
		 */
626
		if (!strcmp (";", s)) {
627
			color_table[total_colors].r = r;
628
			color_table[total_colors].g = g;
629
			color_table[total_colors++].b = b;
630
			if (debug_mode) {
631
				printf (op->comment_begin);
632
				printf ("storing color entry %d: %02x%02x%02x",
633
					total_colors-1, r,g,b);
634
				printf (op->comment_end);
635
			}
636
			r=g=b=0;
637
		}
638
639
 
640
	}
641
642
 
643
		printf (op->comment_begin);
644
	  	printf ("color table had %d entries -->\n", total_colors);
645
		printf (op->comment_end);
646
	}
647
}
648
649
 
650
 * Name:	cmd_cf
651
 * Purpose:	Executes the \cf command.
652
 * Args:	Word, paragraph align info, and numeric param if any.
653
 * Returns:	Flag, true only if rest of Words on line should be ignored.
654
 *=======================================================================*/
655
656
 
657
cmd_cf (Word *w, int align, char has_param, short num) {
658
	char str[40];
659
660
 
661
		warning_handler ("font color change attempted is invalid");
662
	}
663
	else
664
	{
665
		sprintf (str,"#%02x%02x%02x",
666
			color_table[num].r,
667
			color_table[num].g,
668
			color_table[num].b);
669
		attr_push(ATTR_FOREGROUND,str);
670
	}
671
	return FALSE;
672
}
673
674
 
675
 
676
 
677
 * Name:	cmd_cb
678
 * Purpose:	Executes the \cb command.
679
 * Args:	Word, paragraph align info, and numeric param if any.
680
 * Returns:	Flag, true only if rest of Words on line should be ignored.
681
 *=======================================================================*/
682
683
 
684
cmd_cb (Word *w, int align, char has_param, short num) {
685
	char str[40];
686
687
 
688
		warning_handler ("font color change attempted is invalid");
689
	}
690
	else
691
	{
692
		sprintf (str,"#%02x%02x%02x",
693
			color_table[num].r,
694
			color_table[num].g,
695
			color_table[num].b);
696
		attr_push(ATTR_BACKGROUND,str);
697
	}
698
	return FALSE;
699
}
700
701
 
702
 
703
 * Name:	cmd_fs
704
 * Purpose:	Executes the \fs command.
705
 * Args:	Word, paragraph align info, and numeric param if any.
706
 * Returns:	Flag, true only if rest of Words on line should be ignored.
707
 *=======================================================================*/
708
static int
709
cmd_fs (Word *w, int align, char has_param, short points) {
710
	char str[20];
711
712
 
713
714
 
715
	points /= 2;
716
717
 
718
	attr_push(ATTR_FONTSIZE,str);
719
720
 
721
}
722
723
 
724
 
725
 * Name:	cmd_field
726
 * Purpose:	Interprets fields looking for hyperlinks.
727
 * Comment:	Because hyperlinks are put in \field groups,
728
 *		we must interpret all \field groups, which is
729
 *		slow and laborious.
730
 * Returns:	Flag, true only if rest of Words on line should be ignored.
731
 *=======================================================================*/
732
733
 
734
cmd_field (Word *w, int align, char has_param, short num) {
735
	Word *child;
736
737
 
738
739
 
740
		child = w->child;
741
		if (child) {
742
			Word *w2;
743
			char *s;
744
745
 
746
747
 
748
				w2=child->next;
749
				while (w2) {
750
					char *s2 = word_string(w2);
751
					if (s2 && !strcmp("\\fldinst", s2)) {
752
						Word *w3;
753
						w3=w2->next;
754
						while (w3 && !w3->child) {
755
							w3=w3->next;
756
						}
757
						if (w3) w3=w3->child;
758
						while (w3) {
759
							char *s3=word_string(w3);
760
							if (s3 && !strcmp("HYPERLINK",s3)) {
761
								Word *w4;
762
								char *s4;
763
								w4=w3->next;
764
								while (w4 && !strcmp(" ", word_string(w4)))
765
									w4=w4->next;
766
								if (w4) {
767
									s4=word_string(w4);
768
									printf (op->hyperlink_begin);
769
									printf ("%s", s4);
770
									printf (op->hyperlink_end);
771
									return TRUE;
772
								}
773
774
 
775
							w3=w3->next;
776
						}
777
					}
778
					w2=w2->next;
779
				}
780
781
 
782
		}
783
		w=w->next;
784
	}
785
	return TRUE;
786
}
787
788
 
789
 
790
 
791
 * Name:	cmd_f
792
 * Purpose:	Executes the \f command.
793
 * Args:	Word, paragraph align info, and numeric param if any.
794
 * Returns:	Flag, true only if rest of Words on line should be ignored.
795
 *=======================================================================*/
796
static int
797
cmd_f (Word *w, int align, char has_param, short num) {
798
	char *name;
799
800
 
801
	if (!has_param)
802
		return FALSE;
803
804
 
805
	if(!name) {
806
		printf (op->comment_begin);
807
		printf ("invalid font number %d",num);
808
		printf (op->comment_end);
809
	} else {
810
		attr_push(ATTR_FONTFACE,name);
811
	}
812
813
 
814
}
815
816
 
817
 
818
 * Name:	cmd_highlight
819
 * Purpose:	Executes the \cf command.
820
 * Args:	Word, paragraph align info, and numeric param if any.
821
 * Returns:	Flag, true only if rest of Words on line should be ignored.
822
 *=======================================================================*/
823
824
 
825
cmd_highlight (Word *w, int align, char has_param, short num)
826
{
827
	char str[40];
828
829
 
830
		warning_handler ("font background color change attempted is invalid");
831
	}
832
	else
833
	{
834
		sprintf (str,"#%02x%02x%02x",
835
			color_table[num].r,
836
			color_table[num].g,
837
			color_table[num].b);
838
		attr_push(ATTR_BACKGROUND,str);
839
	}
840
	return FALSE;
841
}
842
843
 
844
 
845
 
846
 * Name:	cmd_tab
847
 * Purpose:	Executes the \tab command.
848
 * Args:	Word, paragraph align info, and numeric param if any.
849
 * Returns:	Flag, true only if rest of Words on line should be ignored.
850
 *=======================================================================*/
851
852
 
853
cmd_tab (Word *w, int align, char has_param, short param)
854
{
855
	/* Tab presents a genuine problem
856
	 * since some output formats don't have
857
	 * an equivalent. As a kludge fix, I shall
858
	 * assume the font is fixed width and that
859
	 * the tabstops are 8 characters apart.
860
	 */
861
	int need= 8-(total_chars_this_line%8);
862
	total_chars_this_line += need;
863
	while(need>0) {
864
		printf (op->forced_space);
865
		need--;
866
	}
867
	printf ("\n");
868
	return FALSE;
869
}
870
871
 
872
 
873
 * Name:	cmd_plain
874
 * Purpose:	Executes the \plain command.
875
 * Args:	Word, paragraph align info, and numeric param if any.
876
 * Returns:	Flag, true only if rest of Words on line should be ignored.
877
 *=======================================================================*/
878
879
 
880
cmd_plain (Word *w, int align, char has_param, short param) {
881
	attr_pop_all();
882
	return FALSE;
883
}
884
885
 
886
 
887
 * Name:	cmd_fnil
888
 * Purpose:	Executes the \fnil command.
889
 * Args:	Word, paragraph align info, and numeric param if any.
890
 * Returns:	Flag, true only if rest of Words on line should be ignored.
891
 *=======================================================================*/
892
static int
893
cmd_fnil (Word *w, int align, char has_param, short param) {
894
	attr_push(ATTR_FONTFACE,FONTNIL_STR);
895
	return FALSE;
896
}
897
898
 
899
 
900
 
901
 * Name:	cmd_froman
902
 * Purpose:	Executes the \froman command.
903
 * Args:	Word, paragraph align info, and numeric param if any.
904
 * Returns:	Flag, true only if rest of Words on line should be ignored.
905
 *=======================================================================*/
906
static int
907
cmd_froman (Word *w, int align, char has_param, short param) {
908
	attr_push(ATTR_FONTFACE,FONTROMAN_STR);
909
	return FALSE;
910
}
911
912
 
913
 
914
 * Name:	cmd_fswiss
915
 * Purpose:	Executes the \fswiss command.
916
 * Args:	Word, paragraph align info, and numeric param if any.
917
 * Returns:	Flag, true only if rest of Words on line should be ignored.
918
 *=======================================================================*/
919
920
 
921
cmd_fswiss (Word *w, int align, char has_param, short param) {
922
	attr_push(ATTR_FONTFACE,FONTSWISS_STR);
923
	return FALSE;
924
}
925
926
 
927
 
928
 * Name:	cmd_fmodern
929
 * Purpose:	Executes the \fmodern command.
930
 * Args:	Word, paragraph align info, and numeric param if any.
931
 * Returns:	Flag, true only if rest of Words on line should be ignored.
932
 *=======================================================================*/
933
934
 
935
cmd_fmodern (Word *w, int align, char has_param, short param) {
936
	attr_push(ATTR_FONTFACE,FONTMODERN_STR);
937
	return FALSE;
938
}
939
940
 
941
 
942
 * Name:	cmd_fscript
943
 * Purpose:	Executes the \fscript command.
944
 * Args:	Word, paragraph align info, and numeric param if any.
945
 * Returns:	Flag, true only if rest of Words on line should be ignored.
946
 *=======================================================================*/
947
948
 
949
cmd_fscript (Word *w, int align, char has_param, short param) {
950
	attr_push(ATTR_FONTFACE,FONTSCRIPT_STR);
951
	return FALSE;
952
}
953
954
 
955
 * Name:	cmd_fdecor
956
 * Purpose:	Executes the \fdecor command.
957
 * Args:	Word, paragraph align info, and numeric param if any.
958
 * Returns:	Flag, true only if rest of Words on line should be ignored.
959
 *=======================================================================*/
960
961
 
962
cmd_fdecor (Word *w, int align, char has_param, short param) {
963
	attr_push(ATTR_FONTFACE,FONTDECOR_STR);
964
	return FALSE;
965
}
966
967
 
968
 * Name:	cmd_ftech
969
 * Purpose:	Executes the \ftech command.
970
 * Args:	Word, paragraph align info, and numeric param if any.
971
 * Returns:	Flag, true only if rest of Words on line should be ignored.
972
 *=======================================================================*/
973
974
 
975
cmd_ftech (Word *w, int align, char has_param, short param) {
976
	attr_push(ATTR_FONTFACE,FONTTECH_STR);
977
	return FALSE;
978
}
979
980
 
981
 * Name:	cmd_expand
982
 * Purpose:	Executes the \expand command.
983
 * Args:	Word, paragraph align info, and numeric param if any.
984
 * Returns:	Flag, true only if rest of Words on line should be ignored.
985
 *=======================================================================*/
986
987
 
988
cmd_expand (Word *w, int align, char has_param, short param) {
989
	char str[10];
990
	if (has_param) {
991
		sprintf (str, "%d", param/4);
992
		if (!param)
993
			attr_pop(ATTR_EXPAND);
994
		else
995
			attr_push(ATTR_EXPAND, str);
996
	}
997
	return FALSE;
998
}
999
1000
 
1001
 
1002
 * Name:	cmd_emboss
1003
 * Purpose:	Executes the \embo command.
1004
 * Args:	Word, paragraph align info, and numeric param if any.
1005
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1006
 *=======================================================================*/
1007
1008
 
1009
cmd_emboss (Word *w, int align, char has_param, short param) {
1010
	char str[10];
1011
	if (has_param && !param)
1012
		attr_pop(ATTR_EMBOSS);
1013
	else
1014
	{
1015
		sprintf (str, "%d", param);
1016
		attr_push(ATTR_EMBOSS, str);
1017
	}
1018
	return FALSE;
1019
}
1020
1021
 
1022
 
1023
 * Name:	cmd_engrave
1024
 * Purpose:	Executes the \impr command.
1025
 * Args:	Word, paragraph align info, and numeric param if any.
1026
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1027
 *=======================================================================*/
1028
1029
 
1030
cmd_engrave (Word *w, int align, char has_param, short param) {
1031
	char str[10];
1032
	if (has_param && !param)
1033
		attr_pop(ATTR_ENGRAVE);
1034
	else
1035
	{
1036
		sprintf (str, "%d", param);
1037
		attr_push(ATTR_ENGRAVE, str);
1038
	}
1039
	return FALSE;
1040
}
1041
1042
 
1043
 * Name:	cmd_caps
1044
 * Purpose:	Executes the \caps command.
1045
 * Args:	Word, paragraph align info, and numeric param if any.
1046
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1047
 *=======================================================================*/
1048
1049
 
1050
cmd_caps (Word *w, int align, char has_param, short param) {
1051
	if (has_param && !param)
1052
		attr_pop(ATTR_CAPS);
1053
	else
1054
		attr_push(ATTR_CAPS,NULL);
1055
	return FALSE;
1056
}
1057
1058
 
1059
 
1060
 * Name:	cmd_scaps
1061
 * Purpose:	Executes the \scaps command.
1062
 * Args:	Word, paragraph align info, and numeric param if any.
1063
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1064
 *=======================================================================*/
1065
static int
1066
cmd_scaps (Word *w, int align, char has_param, short param) {
1067
	if (has_param && !param)
1068
		attr_pop(ATTR_SMALLCAPS);
1069
	else
1070
		attr_push(ATTR_SMALLCAPS,NULL);
1071
	return FALSE;
1072
}
1073
1074
 
1075
 
1076
 * Name:	cmd_bullet
1077
 * Purpose:	Executes the \bullet command.
1078
 * Args:	Word, paragraph align info, and numeric param if any.
1079
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1080
 *=======================================================================*/
1081
static int
1082
cmd_bullet (Word *w, int align, char has_param, short param) {
1083
	printf (op->chars.bullet);
1084
	++total_chars_this_line; /* \tab */
1085
	return FALSE;
1086
}
1087
1088
 
1089
 * Name:	cmd_ldblquote
1090
 * Purpose:	Executes the \ldblquote command.
1091
 * Args:	Word, paragraph align info, and numeric param if any.
1092
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1093
 *=======================================================================*/
1094
static int
1095
cmd_ldblquote (Word *w, int align, char has_param, short param) {
1096
	printf (op->chars.left_dbl_quote);
1097
	++total_chars_this_line; /* \tab */
1098
	return FALSE;
1099
}
1100
1101
 
1102
 
1103
 * Name:	cmd_rdblquote
1104
 * Purpose:	Executes the \rdblquote command.
1105
 * Args:	Word, paragraph align info, and numeric param if any.
1106
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1107
 *=======================================================================*/
1108
1109
 
1110
cmd_rdblquote (Word *w, int align, char has_param, short param) {
1111
	printf (op->chars.right_dbl_quote);
1112
	++total_chars_this_line; /* \tab */
1113
	return FALSE;
1114
}
1115
1116
 
1117
 
1118
 * Name:	cmd_lquote
1119
 * Purpose:	Executes the \lquote command.
1120
 * Args:	Word, paragraph align info, and numeric param if any.
1121
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1122
 *=======================================================================*/
1123
static int
1124
cmd_lquote (Word *w, int align, char has_param, short param) {
1125
	printf (op->chars.left_quote);
1126
	++total_chars_this_line; /* \tab */
1127
	return FALSE;
1128
}
1129
1130
 
1131
 
1132
 * Name:	cmd_nonbreaking_space
1133
 * Purpose:	Executes the nonbreaking space command.
1134
 * Args:	Word, paragraph align info, and numeric param if any.
1135
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1136
 *=======================================================================*/
1137
1138
 
1139
cmd_nonbreaking_space (Word *w, int align, char has_param, short param) {
1140
	printf (op->chars.nonbreaking_space);
1141
	++total_chars_this_line; /* \tab */
1142
	return FALSE;
1143
}
1144
1145
 
1146
 
1147
 * Name:	cmd_nonbreaking_hyphen
1148
 * Purpose:	Executes the nonbreaking hyphen command.
1149
 * Args:	Word, paragraph align info, and numeric param if any.
1150
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1151
 *=======================================================================*/
1152
1153
 
1154
cmd_nonbreaking_hyphen (Word *w, int align, char has_param, short param) {
1155
	printf (op->chars.nonbreaking_hyphen);
1156
	++total_chars_this_line; /* \tab */
1157
	return FALSE;
1158
}
1159
1160
 
1161
 
1162
 * Name:	cmd_optional_hyphen
1163
 * Purpose:	Executes the optional hyphen command.
1164
 * Args:	Word, paragraph align info, and numeric param if any.
1165
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1166
 *=======================================================================*/
1167
1168
 
1169
cmd_optional_hyphen (Word *w, int align, char has_param, short param) {
1170
	printf (op->chars.optional_hyphen);
1171
	++total_chars_this_line; /* \tab */
1172
	return FALSE;
1173
}
1174
1175
 
1176
 
1177
 * Name:	cmd_emdash
1178
 * Purpose:	Executes the \emdash command.
1179
 * Args:	Word, paragraph align info, and numeric param if any.
1180
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1181
 *=======================================================================*/
1182
static int
1183
cmd_emdash (Word *w, int align, char has_param, short param) {
1184
	printf (op->chars.emdash);
1185
	++total_chars_this_line; /* \tab */
1186
	return FALSE;
1187
}
1188
1189
 
1190
 
1191
 * Name:	cmd_endash
1192
 * Purpose:	Executes the \endash command.
1193
 * Args:	Word, paragraph align info, and numeric param if any.
1194
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1195
 *=======================================================================*/
1196
1197
 
1198
cmd_endash (Word *w, int align, char has_param, short param) {
1199
	printf (op->chars.endash);
1200
	++total_chars_this_line; /* \tab */
1201
	return FALSE;
1202
}
1203
1204
 
1205
 
1206
 * Name:	cmd_rquote
1207
 * Purpose:	Executes the \rquote command.
1208
 * Args:	Word, paragraph align info, and numeric param if any.
1209
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1210
 *=======================================================================*/
1211
1212
 
1213
cmd_rquote (Word *w, int align, char has_param, short param) {
1214
	printf (op->chars.right_quote);
1215
	++total_chars_this_line; /* \tab */
1216
	return FALSE;
1217
}
1218
1219
 
1220
 
1221
 * Name:	cmd_par
1222
 * Purpose:	Executes the \par command.
1223
 * Args:	Word, paragraph align info, and numeric param if any.
1224
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1225
 *=======================================================================*/
1226
static int
1227
cmd_par (Word *w, int align, char has_param, short param) {
1228
	printf (op->line_break);
1229
	total_chars_this_line = 0; /* \tab */
1230
	return FALSE;
1231
}
1232
1233
 
1234
 
1235
 * Name:	cmd_line
1236
 * Purpose:	Executes the \line command.
1237
 * Args:	Word, paragraph align info, and numeric param if any.
1238
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1239
 *=======================================================================*/
1240
1241
 
1242
cmd_line (Word *w, int align, char has_param, short param) {
1243
	printf (op->line_break);
1244
	total_chars_this_line = 0; /* \tab */
1245
	return FALSE;
1246
}
1247
1248
 
1249
 
1250
 * Name:	cmd_page
1251
 * Purpose:	Executes the \page command.
1252
 * Args:	Word, paragraph align info, and numeric param if any.
1253
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1254
 *=======================================================================*/
1255
1256
 
1257
	printf (op->page_break);
1258
	total_chars_this_line = 0; /* \tab */
1259
	return FALSE;
1260
}
1261
1262
 
1263
 
1264
 * Name:	cmd_intbl
1265
 * Purpose:	Executes the \intbl command.
1266
 * Args:	Word, paragraph align info, and numeric param if any.
1267
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1268
 *=======================================================================*/
1269
1270
 
1271
	++coming_pars_that_are_tabular;
1272
	return FALSE;
1273
}
1274
1275
 
1276
 
1277
 * Name:	cmd_ulnone
1278
 * Purpose:	Executes the \ulnone command.
1279
 * Args:	Word, paragraph align info, and numeric param if any.
1280
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1281
 *=======================================================================*/
1282
1283
 
1284
	int attr, more=TRUE;
1285
#ifdef BINARY_ATTRS
1286
	attr_remove_underlining();
1287
#else
1288
	do {
1289
		attr = attr_read();
1290
		if (attr==ATTR_UNDERLINE ||
1291
		    attr==ATTR_DOT_UL ||
1292
		    attr==ATTR_DASH_UL ||
1293
		    attr==ATTR_DOT_DASH_UL ||
1294
		    attr==ATTR_2DOT_DASH_UL ||
1295
		    attr==ATTR_WORD_UL ||
1296
		    attr==ATTR_WAVE_UL ||
1297
		    attr==ATTR_THICK_UL ||
1298
		    attr==ATTR_DOUBLE_UL)
1299
		{
1300
		  if (!attr_pop(ATTR_UNDERLINE))
1301
		    ;
1302
		} else
1303
		  more=FALSE;
1304
	} while(more);
1305
#endif
1306
	return FALSE;
1307
}
1308
1309
 
1310
 * Name:	cmd_ul
1311
 * Purpose:	Executes the \ul command.
1312
 * Args:	Word, paragraph align info, and numeric param if any.
1313
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1314
 *=======================================================================*/
1315
1316
 
1317
	if (has_param && param == 0) {
1318
		cmd_ulnone (w, align, has_param, param);
1319
	} else {
1320
		attr_push (ATTR_UNDERLINE,NULL);
1321
	}
1322
	return FALSE;
1323
}
1324
1325
 
1326
 * Name:	cmd_uld
1327
 * Purpose:	Executes the \uld command.
1328
 * Args:	Word, paragraph align info, and numeric param if any.
1329
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1330
 *=======================================================================*/
1331
1332
 
1333
	attr_push(ATTR_DOUBLE_UL,NULL);
1334
	return FALSE;
1335
}
1336
1337
 
1338
 * Name:	cmd_uldb
1339
 * Purpose:	Executes the \uldb command.
1340
 * Args:	Word, paragraph align info, and numeric param if any.
1341
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1342
 *=======================================================================*/
1343
1344
 
1345
	attr_push(ATTR_DOT_UL,NULL);
1346
	return FALSE;
1347
}
1348
1349
 
1350
 
1351
 * Name:	cmd_uldash
1352
 * Purpose:	Executes the \uldash command.
1353
 * Args:	Word, paragraph align info, and numeric param if any.
1354
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1355
 *=======================================================================*/
1356
1357
 
1358
	attr_push(ATTR_DASH_UL,NULL);
1359
	return FALSE;
1360
}
1361
1362
 
1363
 
1364
 * Name:	cmd_uldashd
1365
 * Purpose:	Executes the \cmd_uldashd command.
1366
 * Args:	Word, paragraph align info, and numeric param if any.
1367
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1368
 *=======================================================================*/
1369
1370
 
1371
	attr_push(ATTR_DOT_DASH_UL,NULL);
1372
	return FALSE;
1373
}
1374
1375
 
1376
 
1377
 * Name:	cmd_uldashdd
1378
 * Purpose:	Executes the \uldashdd command.
1379
 * Args:	Word, paragraph align info, and numeric param if any.
1380
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1381
 *=======================================================================*/
1382
1383
 
1384
	attr_push(ATTR_2DOT_DASH_UL,NULL);
1385
	return FALSE;
1386
}
1387
1388
 
1389
 
1390
 * Name:	cmd_ulw
1391
 * Purpose:	Executes the \ulw command.
1392
 * Args:	Word, paragraph align info, and numeric param if any.
1393
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1394
 *=======================================================================*/
1395
1396
 
1397
	attr_push(ATTR_WORD_UL,NULL);
1398
	return FALSE;
1399
}
1400
1401
 
1402
 
1403
 * Name:	cmd_ulth
1404
 * Purpose:	Executes the \ulth command.
1405
 * Args:	Word, paragraph align info, and numeric param if any.
1406
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1407
 *=======================================================================*/
1408
1409
 
1410
	attr_push(ATTR_THICK_UL,NULL);
1411
	return FALSE;
1412
}
1413
1414
 
1415
 
1416
 * Name:	cmd_ulwave
1417
 * Purpose:	Executes the \ulwave command.
1418
 * Args:	Word, paragraph align info, and numeric param if any.
1419
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1420
 *=======================================================================*/
1421
1422
 
1423
	attr_push(ATTR_WAVE_UL,NULL);
1424
	return FALSE;
1425
}
1426
1427
 
1428
 
1429
 * Name:	cmd_strike
1430
 * Purpose:	Executes the \strike command.
1431
 * Args:	Word, paragraph align info, and numeric param if any.
1432
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1433
 *=======================================================================*/
1434
1435
 
1436
	if (has_param && param==0)
1437
		attr_pop(ATTR_STRIKE);
1438
	else
1439
		attr_push(ATTR_STRIKE,NULL);
1440
	return FALSE;
1441
}
1442
1443
 
1444
 * Name:	cmd_strikedl
1445
 * Purpose:	Executes the \strikedl command.
1446
 * Args:	Word, paragraph align info, and numeric param if any.
1447
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1448
 *=======================================================================*/
1449
1450
 
1451
	if (has_param && param==0)
1452
		attr_pop(ATTR_DBL_STRIKE);
1453
	else
1454
		attr_push(ATTR_DBL_STRIKE,NULL);
1455
	return FALSE;
1456
}
1457
1458
 
1459
 
1460
 * Name:	cmd_striked
1461
 * Purpose:	Executes the \striked command.
1462
 * Args:	Word, paragraph align info, and numeric param if any.
1463
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1464
 *=======================================================================*/
1465
1466
 
1467
	if (has_param && param==0)
1468
		attr_pop(ATTR_DBL_STRIKE);
1469
	else
1470
		attr_push(ATTR_DBL_STRIKE,NULL);
1471
	return FALSE;
1472
}
1473
1474
 
1475
 
1476
 * Name:	cmd_rtf
1477
 * Purpose:	Executes the \rtf command.
1478
 * Args:	Word, paragraph align info, and numeric param if any.
1479
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1480
 *=======================================================================*/
1481
1482
 
1483
	return FALSE;
1484
}
1485
1486
 
1487
 
1488
 * Name:	cmd_up
1489
 * Purpose:	Executes the \up command.
1490
 * Args:	Word, paragraph align info, and numeric param if any.
1491
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1492
 *=======================================================================*/
1493
1494
 
1495
	if (has_param && param==0)
1496
		attr_pop(ATTR_SUPER);
1497
	else
1498
		attr_push(ATTR_SUPER,NULL);
1499
	return FALSE;
1500
}
1501
1502
 
1503
 
1504
 * Name:	cmd_dn
1505
 * Purpose:	Executes the \dn command.
1506
 * Args:	Word, paragraph align info, and numeric param if any.
1507
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1508
 *=======================================================================*/
1509
1510
 
1511
	if (has_param && param==0)
1512
		attr_pop(ATTR_SUB);
1513
	else
1514
		attr_push(ATTR_SUB,NULL);
1515
	return FALSE;
1516
}
1517
1518
 
1519
 * Name:	cmd_nosupersub
1520
 * Purpose:	Executes the \nosupersub command.
1521
 * Args:	Word, paragraph align info, and numeric param if any.
1522
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1523
 *=======================================================================*/
1524
1525
 
1526
	attr_pop(ATTR_SUPER);
1527
	attr_pop(ATTR_SUB);
1528
	return FALSE;
1529
}
1530
1531
 
1532
 * Name:	cmd_super
1533
 * Purpose:	Executes the \super command.
1534
 * Args:	Word, paragraph align info, and numeric param if any.
1535
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1536
 *=======================================================================*/
1537
1538
 
1539
	if (has_param && param==0)
1540
		attr_pop(ATTR_SUPER);
1541
	else
1542
		attr_push(ATTR_SUPER,NULL);
1543
	return FALSE;
1544
}
1545
1546
 
1547
 * Name:	cmd_sub
1548
 * Purpose:	Executes the \sub command.
1549
 * Args:	Word, paragraph align info, and numeric param if any.
1550
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1551
 *=======================================================================*/
1552
1553
 
1554
	if (has_param && param==0)
1555
		attr_pop(ATTR_SUB);
1556
	else
1557
		attr_push(ATTR_SUB,NULL);
1558
	return FALSE;
1559
}
1560
1561
 
1562
 * Name:	cmd_shad
1563
 * Purpose:	Executes the \shad command.
1564
 * Args:	Word, paragraph align info, and numeric param if any.
1565
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1566
 *=======================================================================*/
1567
1568
 
1569
	if (has_param && param==0)
1570
		attr_pop(ATTR_SHADOW);
1571
	else
1572
		attr_push(ATTR_SHADOW,NULL);
1573
	return FALSE;
1574
}
1575
1576
 
1577
 * Name:	cmd_b
1578
 * Purpose:	Executes the \b command.
1579
 * Args:	Word, paragraph align info, and numeric param if any.
1580
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1581
 *=======================================================================*/
1582
1583
 
1584
cmd_b (Word *w, int align, char has_param, short param) {
1585
	if (has_param && param==0) {
1586
		attr_pop(ATTR_BOLD);
1587
	}
1588
	else
1589
		attr_push(ATTR_BOLD,NULL);
1590
	return FALSE;
1591
}
1592
1593
 
1594
 * Name:	cmd_i
1595
 * Purpose:	Executes the \i command.
1596
 * Args:	Word, paragraph align info, and numeric param if any.
1597
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1598
 *=======================================================================*/
1599
1600
 
1601
	if (has_param && param==0)
1602
		attr_pop(ATTR_ITALIC);
1603
	else
1604
		attr_push(ATTR_ITALIC,NULL);
1605
	return FALSE;
1606
}
1607
1608
 
1609
 * Name:	cmd_s
1610
 * Purpose:	Executes the \s command.
1611
 * Args:	Word, paragraph align info, and numeric param if any.
1612
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1613
 *=======================================================================*/
1614
static int cmd_s (Word *w, int align, char has_param, short param) {
1615
	return FALSE;
1616
}
1617
1618
 
1619
 * Name:	cmd_sect
1620
 * Purpose:	Executes the \sect command.
1621
 * Args:	Word, paragraph align info, and numeric param if any.
1622
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1623
 *=======================================================================*/
1624
1625
 
1626
	/* XX kludge */
1627
	printf (op->paragraph_begin);
1628
	return FALSE;
1629
}
1630
1631
 
1632
 * Name:	cmd_shp
1633
 * Purpose:	Executes the \shp command.
1634
 * Args:	Word, paragraph align info, and numeric param if any.
1635
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1636
 *=======================================================================*/
1637
1638
 
1639
	printf (op->comment_begin);
1640
	printf ("Drawn Shape (ignored--not implemented yet)");
1641
	printf (op->comment_begin);
1642
	return FALSE;
1643
}
1644
1645
 
1646
 * Name:	cmd_outl
1647
 * Purpose:	Executes the \outl command.
1648
 * Args:	Word, paragraph align info, and numeric param if any.
1649
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1650
 *=======================================================================*/
1651
1652
 
1653
	if (has_param && param==0)
1654
		attr_pop(ATTR_OUTLINE);
1655
	else
1656
		attr_push(ATTR_OUTLINE,NULL);
1657
	return FALSE;
1658
}
1659
1660
 
1661
 * Name:	cmd_ansi
1662
 * Purpose:	Executes the \ansi command.
1663
 * Args:	Word, paragraph align info, and numeric param if any.
1664
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1665
 *=======================================================================*/
1666
1667
 
1668
	charset_type = CHARSET_ANSI;
1669
	printf (op->comment_begin);
1670
	printf ("document uses ANSI character set");
1671
	printf (op->comment_end);
1672
	return FALSE;
1673
}
1674
1675
 
1676
 * Name:	cmd_pc
1677
 * Purpose:	Executes the \pc command.
1678
 * Args:	Word, paragraph align info, and numeric param if any.
1679
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1680
 *=======================================================================*/
1681
1682
 
1683
	charset_type = CHARSET_CP437 ;
1684
	printf (op->comment_begin);
1685
	printf ("document uses PC codepage 437 character set");
1686
	printf (op->comment_end);
1687
	return FALSE;
1688
}
1689
1690
 
1691
 * Name:	cmd_pca
1692
 * Purpose:	Executes the \pca command.
1693
 * Args:	Word, paragraph align info, and numeric param if any.
1694
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1695
 *=======================================================================*/
1696
1697
 
1698
	charset_type = CHARSET_CP850;
1699
	printf (op->comment_begin);
1700
	printf ("document uses PC codepage 850 character set");
1701
	printf (op->comment_end);
1702
	return FALSE;
1703
}
1704
1705
 
1706
 * Name:	cmd_mac
1707
 * Purpose:	Executes the \mac command.
1708
 * Args:	Word, paragraph align info, and numeric param if any.
1709
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1710
 *=======================================================================*/
1711
1712
 
1713
	charset_type = CHARSET_MAC;
1714
	printf (op->comment_begin);
1715
	printf ("document uses Macintosh character set");
1716
	printf (op->comment_end);
1717
	return FALSE;
1718
}
1719
1720
 
1721
 * Name:	cmd_colortbl
1722
 * Purpose:	Executes the \colortbl command.
1723
 * Args:	Word, paragraph align info, and numeric param if any.
1724
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1725
 *=======================================================================*/
1726
1727
 
1728
	if (w->next) {
1729
		process_color_table(w->next);
1730
	}
1731
	return TRUE;
1732
}
1733
1734
 
1735
 * Name:	cmd_fonttbl
1736
 * Purpose:	Executes the \fonttbl command.
1737
 * Args:	Word, paragraph align info, and numeric param if any.
1738
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1739
 *=======================================================================*/
1740
1741
 
1742
	if (w->next) {
1743
		process_font_table(w->next);
1744
	}
1745
	return TRUE;
1746
}
1747
1748
 
1749
 * Name:	cmd_header
1750
 * Purpose:	Executes the \header command.
1751
 * Args:	Word, paragraph align info, and numeric param if any.
1752
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1753
 *=======================================================================*/
1754
1755
 
1756
	return TRUE;
1757
}
1758
1759
 
1760
 * Name:	cmd_headerl
1761
 * Purpose:	Executes the \headerl command.
1762
 * Args:	Word, paragraph align info, and numeric param if any.
1763
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1764
 *=======================================================================*/
1765
1766
 
1767
	return TRUE;
1768
}
1769
1770
 
1771
 * Name:	cmd_headerr
1772
 * Purpose:	Executes the \headerr command.
1773
 * Args:	Word, paragraph align info, and numeric param if any.
1774
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1775
 *=======================================================================*/
1776
1777
 
1778
	return TRUE;
1779
}
1780
1781
 
1782
 * Name:	cmd_headerf
1783
 * Purpose:	Executes the \headerf command.
1784
 * Args:	Word, paragraph align info, and numeric param if any.
1785
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1786
 *=======================================================================*/
1787
1788
 
1789
	return TRUE;
1790
}
1791
1792
 
1793
 * Name:	cmd_footer
1794
 * Purpose:	Executes the \footer command.
1795
 * Args:	Word, paragraph align info, and numeric param if any.
1796
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1797
 *=======================================================================*/
1798
1799
 
1800
	return TRUE;
1801
}
1802
1803
 
1804
 * Name:	cmd_footerl
1805
 * Purpose:	Executes the \footerl command.
1806
 * Args:	Word, paragraph align info, and numeric param if any.
1807
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1808
 *=======================================================================*/
1809
1810
 
1811
	return TRUE;
1812
}
1813
1814
 
1815
 * Name:	cmd_footerr
1816
 * Purpose:	Executes the \footerr command.
1817
 * Args:	Word, paragraph align info, and numeric param if any.
1818
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1819
 *=======================================================================*/
1820
1821
 
1822
	return TRUE;
1823
}
1824
1825
 
1826
 * Name:	cmd_footerf
1827
 * Purpose:	Executes the \footerf command.
1828
 * Args:	Word, paragraph align info, and numeric param if any.
1829
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1830
 *=======================================================================*/
1831
1832
 
1833
	return TRUE;
1834
}
1835
1836
 
1837
 * Name:	cmd_ignore
1838
 * Purpose:	Dummy function to get rid of subgroups
1839
 * Args:	Word, paragraph align info, and numeric param if any.
1840
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1841
 *=======================================================================*/
1842
1843
 
1844
	return TRUE;
1845
}
1846
1847
 
1848
 * Name:	cmd_info
1849
 * Purpose:	Executes the \info command.
1850
 * Args:	Word, paragraph align info, and numeric param if any.
1851
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1852
 *=======================================================================*/
1853
1854
 
1855
	process_info_group (w->next);
1856
	return TRUE;
1857
}
1858
1859
 
1860
 * Name:	cmd_pict
1861
 * Purpose:	Executes the \pict command.
1862
 * Args:	Word, paragraph align info, and numeric param if any.
1863
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1864
 *=======================================================================*/
1865
1866
 
1867
	within_picture=TRUE;
1868
	picture_width = picture_height = 0;
1869
	picture_type = PICT_WB;
1870
	return FALSE;
1871
}
1872
1873
 
1874
 * Name:	cmd_bin
1875
 * Purpose:	Executes the \bin command.
1876
 * Args:	Word, paragraph align info, and numeric param if any.
1877
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1878
 *=======================================================================*/
1879
1880
 
1881
	return FALSE;
1882
}
1883
1884
 
1885
 
1886
 * Name:	cmd_macpict
1887
 * Purpose:	Executes the \macpict command.
1888
 * Args:	Word, paragraph align info, and numeric param if any.
1889
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1890
 *=======================================================================*/
1891
1892
 
1893
	picture_type = PICT_MAC;
1894
	return FALSE;
1895
}
1896
1897
 
1898
 * Name:	cmd_jpegblip
1899
 * Purpose:	Executes the \jpegblip command.
1900
 * Args:	Word, paragraph align info, and numeric param if any.
1901
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1902
 *=======================================================================*/
1903
1904
 
1905
	picture_type = PICT_JPEG;
1906
	return FALSE;
1907
}
1908
1909
 
1910
 * Name:	cmd_pngblip
1911
 * Purpose:	Executes the \pngblip command.
1912
 * Args:	Word, paragraph align info, and numeric param if any.
1913
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1914
 *=======================================================================*/
1915
1916
 
1917
	picture_type = PICT_PNG;
1918
	return FALSE;
1919
}
1920
1921
 
1922
 * Name:	cmd_pnmetafile
1923
 * Purpose:	Executes the \pnmetafile command.
1924
 * Args:	Word, paragraph align info, and numeric param if any.
1925
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1926
 *=======================================================================*/
1927
1928
 
1929
	picture_type = PICT_PM;
1930
	return FALSE;
1931
}
1932
1933
 
1934
 * Name:	cmd_wmetafile
1935
 * Purpose:	Executes the \wmetafile command.
1936
 * Args:	Word, paragraph align info, and numeric param if any.
1937
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1938
 *=======================================================================*/
1939
1940
 
1941
	picture_type = PICT_WM;
1942
	if (within_picture && has_param) {
1943
		picture_wmetafile_type=param;
1944
		switch(param) {
1945
		case 1: picture_wmetafile_type_str="MM_TEXT"; break;
1946
		case 2: picture_wmetafile_type_str="MM_LOMETRIC"; break;
1947
		case 3: picture_wmetafile_type_str="MM_HIMETRIC"; break;
1948
		case 4: picture_wmetafile_type_str="MM_LOENGLISH"; break;
1949
		case 5: picture_wmetafile_type_str="MM_HIENGLISH"; break;
1950
		case 6: picture_wmetafile_type_str="MM_TWIPS"; break;
1951
		case 7: picture_wmetafile_type_str="MM_ISOTROPIC"; break;
1952
		case 8: picture_wmetafile_type_str="MM_ANISOTROPIC"; break;
1953
		default: picture_wmetafile_type_str="default:MM_TEXT"; break;
1954
		}
1955
	}
1956
	return FALSE;
1957
}
1958
1959
 
1960
 * Name:	cmd_wbmbitspixel
1961
 * Purpose:	Executes the \wbmbitspixel command.
1962
 * Args:	Word, paragraph align info, and numeric param if any.
1963
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1964
 *=======================================================================*/
1965
1966
 
1967
	if (within_picture && has_param)
1968
		picture_bits_per_pixel = param;
1969
	return FALSE;
1970
}
1971
1972
 
1973
 * Name:	cmd_picw
1974
 * Purpose:	Executes the \picw command.
1975
 * Args:	Word, paragraph align info, and numeric param if any.
1976
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1977
 *=======================================================================*/
1978
1979
 
1980
	if (within_picture && has_param)
1981
		picture_width = param;
1982
	return FALSE;
1983
}
1984
1985
 
1986
 * Name:	cmd_pich
1987
 * Purpose:	Executes the \pich command.
1988
 * Args:	Word, paragraph align info, and numeric param if any.
1989
 * Returns:	Flag, true only if rest of Words on line should be ignored.
1990
 *=======================================================================*/
1991
1992
 
1993
	if (within_picture && has_param)
1994
		picture_height = param;
1995
	return FALSE;
1996
}
1997
1998
 
1999
 
2000
 * Name:	cmd_xe
2001
 * Purpose:	Executes the \xe (index entry) command.
2002
 * Args:	Word, paragraph align info, and numeric param if any.
2003
 * Returns:	Flag, true only if rest of Words on line should be ignored.
2004
 *=======================================================================*/
2005
2006
 
2007
	process_index_entry (w);
2008
	return TRUE;
2009
}
2010
2011
 
2012
 * Name:	cmd_tc
2013
 * Purpose:	Executes the \tc (TOC entry) command.
2014
 * Args:	Word, paragraph align info, and numeric param if any.
2015
 * Returns:	Flag, true only if rest of Words on line should be ignored.
2016
 *=======================================================================*/
2017
2018
 
2019
	process_toc_entry (w, TRUE);
2020
	return TRUE;
2021
}
2022
2023
 
2024
 * Name:	cmd_tcn
2025
 * Purpose:	Executes the \tcn (TOC entry, no page #) command.
2026
 * Args:	Word, paragraph align info, and numeric param if any.
2027
 * Returns:	Flag, true only if rest of Words on line should be ignored.
2028
 *=======================================================================*/
2029
2030
 
2031
	process_toc_entry (w, FALSE);
2032
	return TRUE;
2033
}
2034
2035
 
2036
 
2037
	char *name;
2038
	int (*func)(Word*,int,char,short);
2039
	char *debug_print;
2040
}
2041
HashItem;
2042
2043
 
2044
 
2045
 
2046
	{ "*", cmd_ignore, NULL },
2047
	{ "-", cmd_optional_hyphen, "optional hyphen" },
2048
	{ "_", cmd_nonbreaking_hyphen, "nonbreaking hyphen" },
2049
	{ "~", cmd_nonbreaking_space, NULL },
2050
	{ NULL, NULL, NULL}
2051
};
2052
static HashItem hashArray_a [] = {
2053
	{ "ansi", &cmd_ansi , NULL },
2054
	{ NULL, NULL, NULL}
2055
};
2056
static HashItem hashArray_b [] = {
2057
	{ "b", &cmd_b, NULL },
2058
	{ "bullet", &cmd_bullet, NULL },
2059
	{ "bin", &cmd_bin, "picture is binary" },
2060
#if 0
2061
	{ "bgbdiag", NULL, NULL },
2062
	{ "bgcross", NULL, NULL },
2063
	{ "bgdcross", NULL, NULL },
2064
	{ "bgfdiag", NULL, NULL },
2065
	{ "bghoriz", NULL, NULL },
2066
	{ "bgkbdiag", NULL, NULL },
2067
	{ "bgkcross", NULL, NULL },
2068
	{ "bgkdcross", NULL, NULL },
2069
	{ "bgkfdiag", NULL, NULL },
2070
	{ "bgkhoriz", NULL, NULL },
2071
	{ "bgkvert", NULL, NULL },
2072
	{ "bgvert", NULL, NULL },
2073
	{ "brdrcf", NULL, NULL },
2074
	{ "brdrdb", NULL, NULL },
2075
	{ "brdrdot", NULL, NULL },
2076
	{ "brdrhair", NULL, NULL },
2077
	{ "brdrs", NULL, NULL },
2078
	{ "brdrsh", NULL, NULL },
2079
	{ "brdrth", NULL, NULL },
2080
	{ "brdrw", NULL, NULL },
2081
#endif
2082
	{ NULL, NULL, NULL}
2083
};
2084
static HashItem hashArray_c [] = {
2085
	{ "caps", &cmd_caps, NULL },
2086
	{ "cb", cmd_cb, NULL },
2087
	{ "cf", cmd_cf, NULL },
2088
	{ "colortbl", &cmd_colortbl, "color table" },
2089
	{ "cols", NULL, "columns (not implemented)" },
2090
	{ "column", NULL, "column break (not implemented)" },
2091
#if 0
2092
	{ "cbpat", NULL, NULL },
2093
	{ "cellx", NULL, NULL },
2094
	{ "cfpat", NULL, NULL },
2095
	{ "cgrid", NULL, NULL },
2096
	{ "clbgbcross", NULL, NULL },
2097
	{ "clbgbdiag", NULL, NULL },
2098
	{ "clbgbkbdiag", NULL, NULL },
2099
	{ "clbgbkcross", NULL, NULL },
2100
	{ "clbgbkdcross", NULL, NULL },
2101
	{ "clbgbkfdiag", NULL, NULL },
2102
	{ "clbgbkhor", NULL, NULL },
2103
	{ "clbgbkvert", NULL, NULL },
2104
	{ "clbgdcross", NULL, NULL },
2105
	{ "clbgfdiag", NULL, NULL },
2106
	{ "clbghoriz", NULL, NULL },
2107
	{ "clbgvert", NULL, NULL },
2108
	{ "clbrdrb", NULL, NULL },
2109
	{ "clbrdrl", NULL, NULL },
2110
	{ "clbrdrr", NULL, NULL },
2111
	{ "clbrdrt", NULL, NULL },
2112
	{ "clcbpat", NULL, NULL },
2113
	{ "clcfpat", NULL, NULL },
2114
	{ "clmgf", NULL, NULL },
2115
	{ "clmrg", NULL, NULL },
2116
	{ "clshdng", NULL, NULL },
2117
#endif
2118
	{ NULL, NULL, NULL}
2119
};
2120
static HashItem hashArray_d [] = {
2121
	{ "dn", &cmd_dn, NULL },
2122
#if 0
2123
	{ "dibitmap", NULL, NULL },
2124
#endif
2125
	{ NULL, NULL, NULL}
2126
};
2127
static HashItem hashArray_e [] = {
2128
	{ "emdash", cmd_emdash, NULL },
2129
	{ "endash", cmd_endash, NULL },
2130
	{ "embo", &cmd_emboss, NULL },
2131
	{ "expand", &cmd_expand, NULL },
2132
	{ "expnd", &cmd_expand, NULL },
2133
	{ NULL, NULL, NULL}
2134
};
2135
static HashItem hashArray_f [] = {
2136
	{ "f", cmd_f, NULL },
2137
	{ "fdecor", cmd_fdecor, NULL },
2138
	{ "fmodern", cmd_fmodern, NULL },
2139
	{ "fnil", cmd_fnil, NULL },
2140
	{ "fonttbl", cmd_fonttbl, "font table" },
2141
	{ "froman", cmd_froman, NULL },
2142
	{ "fs", cmd_fs, NULL },
2143
	{ "fscript", cmd_fscript, NULL },
2144
	{ "fswiss", cmd_fswiss, NULL },
2145
	{ "ftech", cmd_ftech, NULL },
2146
	{ "field", cmd_field, NULL },
2147
	{ "footer", cmd_footer, NULL },
2148
	{ "footerf", cmd_footerf, NULL },
2149
	{ "footerl", cmd_footerl, NULL },
2150
	{ "footerr", cmd_footerr, NULL },
2151
	{ NULL, NULL, NULL}
2152
};
2153
static HashItem hashArray_h [] = {
2154
	{ "highlight", &cmd_highlight, NULL },
2155
	{ "header", cmd_header, NULL },
2156
	{ "headerf", cmd_headerf, NULL },
2157
	{ "headerl", cmd_headerl, NULL },
2158
	{ "headerr", cmd_headerr, NULL },
2159
	{ "hl", cmd_ignore, "hyperlink within object" },
2160
	{ NULL, NULL, NULL}
2161
};
2162
static HashItem hashArray_i [] = {
2163
	{ "i", &cmd_i, NULL },
2164
	{ "info", &cmd_info, NULL },
2165
	{ "intbl", &cmd_intbl, NULL },
2166
	{ "impr", &cmd_engrave, NULL },
2167
	{ NULL, NULL, NULL}
2168
};
2169
static HashItem hashArray_j [] = {
2170
	{ "jpegblip", &cmd_jpegblip, NULL },
2171
	{ NULL, NULL, NULL}
2172
};
2173
static HashItem hashArray_l [] = {
2174
	{ "ldblquote", &cmd_ldblquote, NULL },
2175
	{ "line", &cmd_line, NULL },
2176
	{ "lquote", &cmd_lquote, NULL },
2177
	{ NULL, NULL, NULL}
2178
};
2179
static HashItem hashArray_m [] = {
2180
	{ "mac", &cmd_mac , NULL },
2181
	{ "macpict", &cmd_macpict, NULL },
2182
	{ NULL, NULL, NULL}
2183
};
2184
static HashItem hashArray_n [] = {
2185
	{ "nosupersub", &cmd_nosupersub, NULL },
2186
	{ NULL, NULL, NULL}
2187
};
2188
static HashItem hashArray_o [] = {
2189
	{ "outl", &cmd_outl, NULL },
2190
	{ NULL, NULL, NULL}
2191
};
2192
static HashItem hashArray_p [] = {
2193
	{ "page", &cmd_page, NULL },
2194
	{ "par", &cmd_par, NULL },
2195
	{ "pc", &cmd_pc , NULL },
2196
	{ "pca", &cmd_pca , NULL },
2197
	{ "pich", &cmd_pich, NULL },
2198
	{ "pict", &cmd_pict, "picture" },
2199
	{ "picw", &cmd_picw, NULL },
2200
	{ "plain", &cmd_plain, NULL },
2201
	{ "pngblip", &cmd_pngblip, NULL },
2202
	{ "pnmetafile", &cmd_pnmetafile, NULL },
2203
#if 0
2204
	{ "piccropb", NULL, NULL },
2205
	{ "piccropl", NULL, NULL },
2206
	{ "piccropr", NULL, NULL },
2207
	{ "piccropt", NULL, NULL },
2208
	{ "pichgoal", NULL, NULL },
2209
	{ "pichgoal", NULL, NULL },
2210
	{ "picscaled", NULL, NULL },
2211
	{ "picscalex", NULL, NULL },
2212
	{ "picwgoal", NULL, NULL },
2213
#endif
2214
	{ NULL, NULL, NULL}
2215
};
2216
static HashItem hashArray_r [] = {
2217
	{ "rdblquote", &cmd_rdblquote, NULL },
2218
	{ "rquote", &cmd_rquote, NULL },
2219
	{ "rtf", &cmd_rtf, NULL },
2220
	{ NULL, NULL, NULL}
2221
};
2222
static HashItem hashArray_s [] = {
2223
	{ "s", cmd_s, "style" },
2224
	{ "sect", &cmd_sect, "section break"},
2225
	{ "scaps", &cmd_scaps, NULL },
2226
	{ "super", &cmd_super, NULL },
2227
	{ "sub", &cmd_sub, NULL },
2228
	{ "shad", &cmd_shad, NULL },
2229
	{ "strike", &cmd_strike, NULL },
2230
	{ "striked", &cmd_striked, NULL },
2231
	{ "strikedl", &cmd_strikedl, NULL },
2232
	{ "stylesheet", &cmd_ignore, "style sheet" },
2233
	{ "shp", cmd_shp, "drawn shape" },
2234
#if 0
2235
	{ "shading", NULL, NULL },
2236
#endif
2237
	{ NULL, NULL, NULL}
2238
};
2239
static HashItem hashArray_t [] = {
2240
	{ "tab", &cmd_tab, NULL },
2241
	{ "tc", cmd_tc, "TOC entry" },
2242
	{ "tcn", cmd_tcn, "TOC entry" },
2243
#if 0
2244
	{ "tcf", NULL , NULL },
2245
	{ "tcl", NULL , NULL },
2246
	{ "trgaph", NULL , NULL },
2247
	{ "trleft", NULL , NULL },
2248
	{ "trowd", NULL , NULL },
2249
	{ "trqc", NULL , NULL },
2250
	{ "trql", NULL , NULL },
2251
	{ "trqr", NULL , NULL },
2252
	{ "trrh", NULL , NULL },
2253
#endif
2254
	{ NULL, NULL, NULL}
2255
};
2256
static HashItem hashArray_u [] = {
2257
	{ "ul", &cmd_ul, NULL },
2258
	{ "up", &cmd_up, NULL },
2259
	{ "uld", &cmd_uld, NULL },
2260
	{ "uldash", &cmd_uldash, NULL },
2261
	{ "uldashd", &cmd_uldashd, NULL },
2262
	{ "uldashdd", &cmd_uldashdd, NULL },
2263
	{ "uldb", &cmd_uldb, NULL },
2264
	{ "ulnone", &cmd_ulnone, NULL },
2265
	{ "ulth", &cmd_ulth, NULL },
2266
	{ "ulw", &cmd_ulw, NULL },
2267
	{ "ulwave", &cmd_ulwave, NULL },
2268
	{ NULL, NULL, NULL}
2269
};
2270
2271
 
2272
	{ "wbmbitspixel", &cmd_wbmbitspixel, NULL },
2273
	{ "wmetafile", &cmd_wmetafile, NULL },
2274
#if 0
2275
	{ "wbitmap", NULL, NULL },
2276
	{ "wbmplanes", NULL, NULL },
2277
	{ "wbmwidthbytes", NULL, NULL },
2278
#endif
2279
	{ NULL, NULL, NULL}
2280
};
2281
2282
 
2283
	{ "xe", cmd_xe, "index entry" },
2284
	{ NULL, NULL, NULL}
2285
};
2286
2287
 
2288
	hashArray_a,
2289
	hashArray_b,
2290
	hashArray_c,
2291
	hashArray_d,
2292
	hashArray_e,
2293
	hashArray_f,
2294
	NULL,
2295
	hashArray_h,
2296
	hashArray_i,
2297
	hashArray_j,
2298
	NULL,
2299
	hashArray_l,
2300
	hashArray_m,
2301
	hashArray_n,
2302
	hashArray_o,
2303
	hashArray_p,
2304
	NULL,
2305
	hashArray_r,
2306
	hashArray_s,
2307
	hashArray_t,
2308
	hashArray_u,
2309
	NULL,
2310
	hashArray_w,
2311
	hashArray_x,
2312
	NULL, NULL
2313
};
2314
2315
 
2316
 
2317
/*-------------------------------------------------------------------*/
2318
2319
 
2320
 
2321
 
2322
/*-------------------------------------------------------------------*/
2323
2324
 
2325
 
2326
 * Name:
2327
 * Purpose:
2328
 * Args:	None.
2329
 * Returns:	None.
2330
 *=======================================================================*/
2331
2332
 
2333
print_with_special_exprs (char *s) {
2334
	int ch;
2335
	int state;
2336
2337
 
2338
2339
 
2340
2341
 
2342
		if (*s >= 'a' && *s <= 'z') {
2343
			state=SMALL;
2344
			printf (op->smaller_begin);
2345
		}
2346
		else
2347
			state=BIG;
2348
	}
2349
2350
 
2351
		char *post_trans = NULL;
2352
2353
 
2354
			ch = toupper (ch);
2355
2356
 
2357
			post_trans = op_translate_char (op, charset_type, ch);
2358
			printf ("%s",post_trans);
2359
		}
2360
2361
 
2362
2363
 
2364
			ch = *s;
2365
			if (ch >= 'a' && ch <= 'z') {
2366
				if (state==BIG)
2367
					printf (op->smaller_begin);
2368
				state=SMALL;
2369
			}
2370
			else
2371
			{
2372
				if (state==SMALL)
2373
					printf (op->smaller_end);
2374
				state=BIG;
2375
			}
2376
		}
2377
	}
2378
}
2379
2380
 
2381
 
2382
 
2383
 * Name:
2384
 * Purpose:
2385
 * Args:	None.
2386
 * Returns:	None.
2387
 *=======================================================================*/
2388
2389
 
2390
begin_table()
2391
{
2392
	within_table=TRUE;
2393
	have_printed_row_begin = FALSE;
2394
	have_printed_cell_begin = FALSE;
2395
	have_printed_row_end = FALSE;
2396
	have_printed_cell_end = FALSE;
2397
	attrstack_push();
2398
	starting_body();
2399
	printf (op->table_begin);
2400
}
2401
2402
 
2403
 
2404
 
2405
 * Name:
2406
 * Purpose:
2407
 * Args:	None.
2408
 * Returns:	None.
2409
 *=======================================================================*/
2410
2411
 
2412
end_table ()
2413
{
2414
	if (within_table) {
2415
		if (!have_printed_cell_end) {
2416
			attr_pop_dump();
2417
			printf (op->table_cell_end);
2418
		}
2419
		if (!have_printed_row_end) {
2420
			printf (op->table_row_end);
2421
		}
2422
		printf (op->table_end);
2423
		within_table=FALSE;
2424
		have_printed_row_begin = FALSE;
2425
		have_printed_cell_begin = FALSE;
2426
		have_printed_row_end = FALSE;
2427
		have_printed_cell_end = FALSE;
2428
	}
2429
}
2430
2431
 
2432
 
2433
 
2434
 * Name:
2435
 * Purpose:
2436
 * Args:	None.
2437
 * Returns:	None.
2438
 *=======================================================================*/
2439
2440
 
2441
starting_text() {
2442
	if (within_table) {
2443
		if (!have_printed_row_begin) {
2444
			printf (op->table_row_begin);
2445
			have_printed_row_begin=TRUE;
2446
			have_printed_row_end=FALSE;
2447
			have_printed_cell_begin=FALSE;
2448
		}
2449
		if (!have_printed_cell_begin) {
2450
			printf (op->table_cell_begin);
2451
			attrstack_express_all();
2452
			have_printed_cell_begin=TRUE;
2453
			have_printed_cell_end=FALSE;
2454
		}
2455
	}
2456
}
2457
2458
 
2459
 
2460
 
2461
 
2462
 * Name:
2463
 * Purpose:
2464
 * Args:	None.
2465
 * Returns:	None.
2466
 *=======================================================================*/
2467
2468
 
2469
starting_paragraph_align (int align)
2470
{
2471
	if (within_header && align != ALIGN_LEFT)
2472
		starting_body();
2473
2474
 
2475
	{
2476
	case ALIGN_CENTER:
2477
		printf (op->center_begin);
2478
		break;
2479
	case ALIGN_LEFT:
2480
		break;
2481
	case ALIGN_RIGHT:
2482
		printf (op->align_right_begin);
2483
		break;
2484
	case ALIGN_JUSTIFY:
2485
		printf (op->align_right_begin);
2486
		break;
2487
	}
2488
}
2489
2490
 
2491
 
2492
 
2493
 * Name:
2494
 * Purpose:
2495
 * Args:	None.
2496
 * Returns:	None.
2497
 *=======================================================================*/
2498
2499
 
2500
ending_paragraph_align (int align)
2501
{
2502
	switch (align) {
2503
	case ALIGN_CENTER:
2504
		printf (op->center_end);
2505
		break;
2506
	case ALIGN_LEFT:
2507
		// printf (op->align_left_end);
2508
		break;
2509
	case ALIGN_RIGHT:
2510
		printf (op->align_right_end);
2511
		break;
2512
	case ALIGN_JUSTIFY:
2513
		printf (op->justify_end);
2514
		break;
2515
	}
2516
}
2517
2518
 
2519
 
2520
 * Name:
2521
 * Purpose:	Recursive routine to produce the output in the target
2522
 *		format given on a tree of words.
2523
 * Args:	Word* (the tree).
2524
 * Returns:	None.
2525
 *=======================================================================*/
2526
2527
 
2528
word_print_core (Word *w)
2529
{
2530
	char *s;
2531
	FILE *f=NULL;
2532
	int is_cell_group=FALSE;
2533
	int paragraph_begined=FALSE;
2534
	int paragraph_align=ALIGN_LEFT;
2535
2536
 
2537
2538
 
2539
		end_table();
2540
	}
2541
	else if (coming_pars_that_are_tabular && !within_table) {
2542
		begin_table();
2543
	}
2544
2545
 
2546
	attrstack_push();
2547
2548
 
2549
		s = word_string (w);
2550
2551
 
2552
			/*--Ignore whitespace in header--------------------*/
2553
			if (*s==' ' && within_header) {
2554
				/* no op */
2555
			}
2556
			else
2557
			/*--Handle word -----------------------------------*/
2558
			if (s[0] != '\\')
2559
			{
2560
				starting_body();
2561
				starting_text();
2562
2563
 
2564
					starting_paragraph_align (paragraph_align);
2565
					paragraph_begined=TRUE;
2566
				}
2567
2568
 
2569
				if (within_picture) {
2570
					starting_body();
2571
					if (!f) {
2572
						char *ext=NULL;
2573
						switch (picture_type) {
2574
						case PICT_WB: ext="bmp"; break;
2575
						case PICT_WM: ext="wmf"; break;
2576
						case PICT_MAC: ext="pict"; break;
2577
						case PICT_JPEG: ext="jpg"; break;
2578
						case PICT_PNG: ext="png"; break;
2579
						case PICT_DI: ext="dib"; break; /* Device independent bitmap=??? */
2580
						case PICT_PM: ext="pmm"; break; /* OS/2 metafile=??? */
2581
						}
2582
						sprintf (picture_path, "pict%03d.%s",
2583
							picture_file_number++,ext);
2584
						f=fopen(picture_path,"w");
2585
					}
2586
2587
 
2588
						char *s2;
2589
						printf (op->comment_begin);
2590
						printf ("picture data found, ");
2591
						if (picture_wmetafile_type_str) {
2592
							printf ("WMF type is %s, ",
2593
								picture_wmetafile_type_str);
2594
						}
2595
						printf ("picture dimensions are %d by %d, depth %d",
2596
							picture_width, picture_height, picture_bits_per_pixel);
2597
						printf (op->comment_end);
2598
						if (picture_width && picture_height && picture_bits_per_pixel) {
2599
							s2=s;
2600
							while (*s2) {
2601
								unsigned int tmp,value;
2602
								tmp=tolower(*s2++);
2603
								if (tmp>'9') tmp-=('a'-10);
2604
								else tmp-='0';
2605
								value=16*tmp;
2606
								tmp=tolower(*s2++);
2607
								if (tmp>'9') tmp-=('a'-10);
2608
								else tmp-='0';
2609
								value+=tmp;
2610
								fprintf (f,"%c", value);
2611
							}
2612
						}
2613
					}
2614
				}
2615
				/*----------------------------------------*/
2616
				else {
2617
					total_chars_this_line += strlen(s);
2618
2619
 
2620
						printf (op->word_begin);
2621
2622
 
2623
2624
 
2625
						printf (op->word_end);
2626
				}
2627
2628
 
2629
2630
 
2631
				int done=FALSE;
2632
2633
 
2634
2635
 
2636
				if (!strcmp ("ql", s))
2637
					paragraph_align = ALIGN_LEFT;
2638
				else if (!strcmp ("qr", s))
2639
					paragraph_align = ALIGN_RIGHT;
2640
				else if (!strcmp ("qj", s))
2641
					paragraph_align = ALIGN_JUSTIFY;
2642
				else if (!strcmp ("qc", s))
2643
					paragraph_align = ALIGN_CENTER;
2644
				else if (!strcmp ("pard", s))
2645
				{
2646
					/* Clear out all font attributes.
2647
					 */
2648
					attr_pop_all();
2649
					if(coming_pars_that_are_tabular) {
2650
						--coming_pars_that_are_tabular;
2651
					}
2652
2653
 
2654
					 */
2655
					ending_paragraph_align(paragraph_align);
2656
					paragraph_align = ALIGN_LEFT;
2657
					paragraph_begined = FALSE;
2658
				}
2659
/*----Table keywords---------------------------------------------------------*/
2660
				else
2661
				if (!strcmp (s, "cell")) {
2662
					is_cell_group=TRUE;
2663
					if (!have_printed_cell_begin) {
2664
						/* Need this with empty cells */
2665
						printf (op->table_cell_begin);
2666
						attrstack_express_all();
2667
					}
2668
					attr_pop_dump();
2669
					printf (op->table_cell_end);
2670
					have_printed_cell_begin = FALSE;
2671
					have_printed_cell_end=TRUE;
2672
				}
2673
				else if (!strcmp (s, "row")) {
2674
					if (within_table) {
2675
						printf (op->table_row_end);
2676
						have_printed_row_begin = FALSE;
2677
						have_printed_row_end=TRUE;
2678
					} else {
2679
						if (debug_mode) {
2680
							printf (op->comment_begin);
2681
							printf ("end of table row");
2682
							printf (op->comment_end);
2683
						}
2684
					}
2685
				}
2686
2687
 
2688
				else if (*s == '\'') {
2689
					/* \'XX is a hex char code expression */
2690
					int ch = h2toi (&s[1]);
2691
					char *s2;
2692
2693
 
2694
2695
 
2696
						printf (op->comment_begin);
2697
						printf("char 0x%02x",ch);
2698
						printf (op->comment_end);
2699
					} else {
2700
						if (op->word_begin)
2701
							printf (op->word_begin);
2702
						printf ("%s", s2);
2703
						if (op->word_end)
2704
							printf (op->word_end);
2705
					}
2706
				}
2707
				else
2708
/*----Search the RTF command hash-------------------------------------------*/
2709
				{
2710
					int ch;
2711
					int index=0;
2712
					int have_param=FALSE, param=0;
2713
					HashItem *hip;
2714
					char *p;
2715
					int match;
2716
2717
 
2718
					p=s;
2719
					while(*p && (!isdigit(*p) && *p!='-')) p++;
2720
					if (*p && (isdigit(*p) || *p=='-')) {
2721
						have_param=TRUE;
2722
						param=atoi (p);
2723
					}
2724
2725
 
2726
					 */
2727
					ch = tolower (*s);
2728
					if (ch>='a' && ch<='z')
2729
						hip = hash [ch-'a'];
2730
					else
2731
						hip = hashArray_other;
2732
2733
 
2734
						if (debug_mode) {
2735
							printf (op->comment_begin);
2736
							printf ("unfamiliar rtf command: %s", s);
2737
							printf (op->comment_begin);
2738
						}
2739
					}
2740
					else
2741
					{
2742
						while (!done) {
2743
							match=FALSE;
2744
2745
 
2746
								int len=p-s;
2747
								if (!hip[index].name[len] && !strncmp (s, hip[index].name, len))
2748
									match=TRUE;
2749
							}
2750
							else
2751
								match = !strcmp(s, hip[index].name);
2752
2753
 
2754
#if 0
2755
								char *always;
2756
#endif
2757
								char *debug;
2758
								int terminate_group;
2759
2760
 
2761
									terminate_group = hip[index].func (w,paragraph_align, have_param, param);
2762
2763
 
2764
										while(w) w=w->next;
2765
								}
2766
2767
 
2768
2769
 
2770
								always=hip[index].always_print;
2771
								if (always)
2772
									printf ("%s", always);
2773
#endif
2774
								if (debug && debug_mode) {
2775
									printf (op->comment_begin);
2776
									printf ("%s", debug);
2777
									printf (op->comment_end);
2778
								}
2779
2780
 
2781
							}
2782
							else
2783
							{
2784
								index++;
2785
								if (!hip[index].name)
2786
									done=TRUE;
2787
							}
2788
						}
2789
					}
2790
					if (!match) {
2791
						if (debug_mode) {
2792
							printf (op->comment_begin);
2793
							printf ("unfamiliar rtf command: %s", s);
2794
							printf (op->comment_end);
2795
						}
2796
					}
2797
				}
2798
			}
2799
/*-------------------------------------------------------------------------*/
2800
		} else {
2801
			Word *child;
2802
2803
 
2804
2805
 
2806
				starting_paragraph_align (paragraph_align);
2807
				paragraph_begined=TRUE;
2808
			}
2809
2810
 
2811
			  word_print_core (child);
2812
		}
2813
2814
 
2815
			w = w->next;
2816
	}
2817
2818
 
2819
		if(f) {
2820
			fclose(f);
2821
			printf (op->imagelink_begin);
2822
			printf ("%s", picture_path);
2823
			printf (op->imagelink_end);
2824
			within_picture=FALSE;
2825
		}
2826
	}
2827
2828
 
2829
	 * since they would appear between 
2830
	 */
2831
	if (!is_cell_group)
2832
		attr_pop_all();
2833
	else
2834
		attr_drop_all();
2835
2836
 
2837
	 */
2838
	if (paragraph_begined)
2839
		ending_paragraph_align (paragraph_align);
2840
2841
 
2842
}
2843
2844
 
2845
 
2846
 
2847
 
2848
 * Name:
2849
 * Purpose:
2850
 * Args:	None.
2851
 * Returns:	None.
2852
 *=======================================================================*/
2853
2854
 
2855
word_print (Word *w)
2856
{
2857
	CHECK_PARAM_NOT_NULL (w);
2858
2859
 
2860
		printf (op->document_begin);
2861
		printf (op->header_begin);
2862
	}
2863
2864
 
2865
2866
 
2867
	have_printed_body=FALSE;
2868
	within_table=FALSE;
2869
	simulate_allcaps=FALSE;
2870
	word_print_core (w);
2871
	end_table();
2872
2873
 
2874
		printf (op->body_end);
2875
		printf (op->document_end);
2876
	}
2877
}
2878