Details | Last modification | View Log | RSS feed
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: attr |
|||
25 | * Author name: Zach Smith |
|||
26 | * Create date: 01 Aug 01 |
|||
27 | * Purpose: Character attribute stack. |
|||
28 | *---------------------------------------------------------------------- |
|||
29 | * Changes: |
|||
30 | * 01 Aug 01, tuorfa@yahoo.com: moved code over from convert.c |
|||
31 | * 06 Aug 01, tuorfa@yahoo.com: added several font attributes. |
|||
32 | * 18 Sep 01, tuorfa@yahoo.com: added AttrStack (stack of stacks) paradigm |
|||
33 | * 22 Sep 01, tuorfa@yahoo.com: added comment blocks |
|||
34 | *--------------------------------------------------------------------*/ |
|||
35 | ||||
36 | ||||
37 | ||||
38 | #include |
|||
39 | #include |
|||
40 | ||||
41 | ||||
42 | #include "defs.h" |
|||
43 | #include "error.h" |
|||
44 | #include "attr.h" |
|||
45 | #include "main.h" |
|||
46 | ||||
47 | ||||
48 | ||||
49 | extern void starting_text(); |
|||
50 | ||||
51 | ||||
52 | extern int simulate_smallcaps; |
|||
53 | ||||
54 | ||||
55 | ||||
56 | ||||
57 | ||||
58 | ||||
59 | ||||
60 | * an AttrStack which is a stack of attributes and their optional |
|||
61 | * parameter. Since RTF text blocks are nested, these make up a |
|||
62 | * stack of stacks. And, since RTF text blocks inherit attributes |
|||
63 | * from parent blocks, all new AttrStacks do the same from |
|||
64 | * their parent AttrStack. |
|||
65 | */ |
|||
66 | typedef struct _stack { |
|||
67 | unsigned char attr_stack [MAX_ATTRS]; |
|||
68 | char *attr_stack_params [MAX_ATTRS]; |
|||
69 | int tos; |
|||
70 | struct _stack *next; |
|||
71 | } |
|||
72 | AttrStack; |
|||
73 | ||||
74 | ||||
75 | static AttrStack *stack_of_stacks_top = NULL; |
|||
76 | ||||
77 | ||||
78 | ||||
79 | ||||
80 | ||||
81 | * Name: attr_express_begin |
|||
82 | * Purpose: Print the HTML for beginning an attribute. |
|||
83 | * Args: Attribute number, optional string parameter. |
|||
84 | * Returns: None. |
|||
85 | *=======================================================================*/ |
|||
86 | ||||
87 | ||||
88 | attr_express_begin (int attr, char* param) { |
|||
89 | switch(attr) |
|||
90 | { |
|||
91 | case ATTR_BOLD: |
|||
92 | printf (op->bold_begin); |
|||
93 | break; |
|||
94 | case ATTR_ITALIC: |
|||
95 | printf (op->italic_begin); |
|||
96 | break; |
|||
97 | ||||
98 | ||||
99 | case ATTR_THICK_UL: |
|||
100 | case ATTR_WAVE_UL: |
|||
101 | case ATTR_DASH_UL: |
|||
102 | case ATTR_DOT_UL: |
|||
103 | case ATTR_DOT_DASH_UL: |
|||
104 | case ATTR_2DOT_DASH_UL: |
|||
105 | case ATTR_WORD_UL: |
|||
106 | case ATTR_UNDERLINE: |
|||
107 | printf (op->underline_begin); |
|||
108 | break; |
|||
109 | ||||
110 | ||||
111 | printf (op->dbl_underline_begin); |
|||
112 | break; |
|||
113 | ||||
114 | ||||
115 | op_begin_std_fontsize (op, atoi (param)); |
|||
116 | break; |
|||
117 | ||||
118 | ||||
119 | printf (op->font_begin,param); |
|||
120 | break; |
|||
121 | ||||
122 | ||||
123 | printf (op->foreground_begin, param); |
|||
124 | break; |
|||
125 | ||||
126 | ||||
127 | if (!simple_mode) |
|||
128 | printf (op->foreground_begin,param); |
|||
129 | break; |
|||
130 | ||||
131 | ||||
132 | printf (op->superscript_begin); |
|||
133 | break; |
|||
134 | case ATTR_SUB: |
|||
135 | printf (op->subscript_begin); |
|||
136 | break; |
|||
137 | ||||
138 | ||||
139 | printf (op->strikethru_begin); |
|||
140 | break; |
|||
141 | ||||
142 | ||||
143 | printf (op->dbl_strikethru_begin); |
|||
144 | break; |
|||
145 | ||||
146 | ||||
147 | printf (op->expand_begin, param); |
|||
148 | break; |
|||
149 | ||||
150 | ||||
151 | printf (op->outline_begin); |
|||
152 | break; |
|||
153 | case ATTR_SHADOW: |
|||
154 | printf (op->shadow_begin); |
|||
155 | break; |
|||
156 | case ATTR_EMBOSS: |
|||
157 | printf (op->emboss_begin); |
|||
158 | break; |
|||
159 | case ATTR_ENGRAVE: |
|||
160 | printf (op->engrave_begin); |
|||
161 | break; |
|||
162 | ||||
163 | ||||
164 | if (op->simulate_all_caps) |
|||
165 | simulate_allcaps = TRUE; |
|||
166 | break; |
|||
167 | ||||
168 | ||||
169 | if (op->simulate_small_caps) |
|||
170 | simulate_smallcaps = TRUE; |
|||
171 | else { |
|||
172 | if (op->small_caps_begin) |
|||
173 | printf (op->small_caps_begin); |
|||
174 | } |
|||
175 | break; |
|||
176 | } |
|||
177 | } |
|||
178 | ||||
179 | ||||
180 | ||||
181 | * Name: attr_express_end |
|||
182 | * Purpose: Print HTML to complete an attribute. |
|||
183 | * Args: Attribute number. |
|||
184 | * Returns: None. |
|||
185 | *=======================================================================*/ |
|||
186 | ||||
187 | ||||
188 | attr_express_end (int attr, char *param) |
|||
189 | { |
|||
190 | switch(attr) |
|||
191 | { |
|||
192 | case ATTR_BOLD: |
|||
193 | printf (op->bold_end); |
|||
194 | break; |
|||
195 | case ATTR_ITALIC: |
|||
196 | printf (op->italic_end); |
|||
197 | break; |
|||
198 | ||||
199 | ||||
200 | case ATTR_THICK_UL: |
|||
201 | case ATTR_WAVE_UL: |
|||
202 | case ATTR_DASH_UL: |
|||
203 | case ATTR_DOT_UL: |
|||
204 | case ATTR_DOT_DASH_UL: |
|||
205 | case ATTR_2DOT_DASH_UL: |
|||
206 | case ATTR_WORD_UL: |
|||
207 | case ATTR_UNDERLINE: |
|||
208 | printf (op->underline_end); |
|||
209 | break; |
|||
210 | ||||
211 | ||||
212 | printf (op->dbl_underline_end); |
|||
213 | break; |
|||
214 | ||||
215 | ||||
216 | op_end_std_fontsize (op, atoi (param)); |
|||
217 | break; |
|||
218 | ||||
219 | ||||
220 | printf (op->font_end); |
|||
221 | break; |
|||
222 | ||||
223 | ||||
224 | printf (op->foreground_end); |
|||
225 | break; |
|||
226 | case ATTR_BACKGROUND: |
|||
227 | if (!simple_mode) |
|||
228 | printf (op->background_end); |
|||
229 | break; |
|||
230 | ||||
231 | ||||
232 | printf (op->superscript_end); |
|||
233 | break; |
|||
234 | case ATTR_SUB: |
|||
235 | printf (op->subscript_end); |
|||
236 | break; |
|||
237 | ||||
238 | ||||
239 | printf (op->strikethru_end); |
|||
240 | break; |
|||
241 | ||||
242 | ||||
243 | printf (op->dbl_strikethru_end); |
|||
244 | break; |
|||
245 | ||||
246 | ||||
247 | printf (op->outline_end); |
|||
248 | break; |
|||
249 | case ATTR_SHADOW: |
|||
250 | printf (op->shadow_end); |
|||
251 | break; |
|||
252 | case ATTR_EMBOSS: |
|||
253 | printf (op->emboss_end); |
|||
254 | break; |
|||
255 | case ATTR_ENGRAVE: |
|||
256 | printf (op->engrave_end); |
|||
257 | break; |
|||
258 | ||||
259 | ||||
260 | printf (op->expand_end); |
|||
261 | break; |
|||
262 | ||||
263 | ||||
264 | if (op->simulate_all_caps) |
|||
265 | simulate_allcaps = FALSE; |
|||
266 | break; |
|||
267 | ||||
268 | ||||
269 | if (op->simulate_small_caps) |
|||
270 | simulate_smallcaps = FALSE; |
|||
271 | else { |
|||
272 | if (op->small_caps_end) |
|||
273 | printf (op->small_caps_end); |
|||
274 | } |
|||
275 | break; |
|||
276 | } |
|||
277 | } |
|||
278 | ||||
279 | ||||
280 | ||||
281 | ||||
282 | * Name: attr_push |
|||
283 | * Purpose: Pushes an attribute onto the current attribute stack. |
|||
284 | * Args: Attribute number, optional string parameter. |
|||
285 | * Returns: None. |
|||
286 | *=======================================================================*/ |
|||
287 | ||||
288 | ||||
289 | attr_push(int attr, char* param) |
|||
290 | { |
|||
291 | AttrStack *stack = stack_of_stacks_top; |
|||
292 | if (!stack) { |
|||
293 | warning_handler ("no stack to push attribute onto"); |
|||
294 | return; |
|||
295 | } |
|||
296 | ||||
297 | ||||
298 | ||||
299 | ||||
300 | /* KLUDGE */ |
|||
301 | starting_body(); |
|||
302 | starting_text(); |
|||
303 | ||||
304 | ||||
305 | stack->attr_stack [stack->tos]=attr; |
|||
306 | if (param) |
|||
307 | stack->attr_stack_params [stack->tos]=my_strdup(param); |
|||
308 | else |
|||
309 | stack->attr_stack_params [stack->tos]=NULL; |
|||
310 | ||||
311 | ||||
312 | } |
|||
313 | ||||
314 | ||||
315 | ||||
316 | * Name: attrstack_copy_all |
|||
317 | * Purpose: Routine to copy all attributes from one stack to another. |
|||
318 | * Args: Two stacks. |
|||
319 | * Returns: None. |
|||
320 | *=======================================================================*/ |
|||
321 | ||||
322 | ||||
323 | attrstack_copy_all (AttrStack *src, AttrStack *dest) |
|||
324 | { |
|||
325 | int i; |
|||
326 | int total; |
|||
327 | ||||
328 | ||||
329 | CHECK_PARAM_NOT_NULL(dest); |
|||
330 | ||||
331 | ||||
332 | ||||
333 | ||||
334 | { |
|||
335 | int attr=src->attr_stack [i]; |
|||
336 | char *param=src->attr_stack_params [i]; |
|||
337 | ||||
338 | ||||
339 | if (param) |
|||
340 | dest->attr_stack_params[i] = my_strdup (param); |
|||
341 | else |
|||
342 | dest->attr_stack_params[i] = NULL; |
|||
343 | } |
|||
344 | ||||
345 | ||||
346 | } |
|||
347 | ||||
348 | ||||
349 | * Name: attrstack_unexpress_all |
|||
350 | * Purpose: Routine to un-express all attributes heretofore applied, |
|||
351 | * without removing any from the stack. |
|||
352 | * Args: Stack whost contents should be unexpressed. |
|||
353 | * Returns: None. |
|||
354 | * Notes: This is needed by attrstack_push, but also for \cell, which |
|||
355 | * often occurs within a brace group, yet HTML uses |
|||
356 | * which clear attribute info within that block. |
|||
357 | *=======================================================================*/ |
|||
358 | ||||
359 | ||||
360 | attrstack_unexpress_all (AttrStack *stack) |
|||
361 | { |
|||
362 | int i; |
|||
363 | ||||
364 | ||||
365 | ||||
366 | ||||
367 | while (i>=0) |
|||
368 | { |
|||
369 | int attr=stack->attr_stack [i]; |
|||
370 | char *param=stack->attr_stack_params [i]; |
|||
371 | ||||
372 | ||||
373 | i--; |
|||
374 | } |
|||
375 | } |
|||
376 | ||||
377 | ||||
378 | ||||
379 | * Name: attrstack_push |
|||
380 | * Purpose: Creates a new attribute stack, pushes it onto the stack |
|||
381 | * of stacks, performs inheritance from previous stack. |
|||
382 | * Args: None. |
|||
383 | * Returns: None. |
|||
384 | *=======================================================================*/ |
|||
385 | void |
|||
386 | attrstack_push () |
|||
387 | { |
|||
388 | AttrStack *new_stack; |
|||
389 | AttrStack *prev_stack; |
|||
390 | ||||
391 | ||||
392 | bzero ((void*) new_stack, sizeof (AttrStack)); |
|||
393 | ||||
394 | ||||
395 | ||||
396 | ||||
397 | stack_of_stacks = new_stack; |
|||
398 | } else { |
|||
399 | stack_of_stacks_top->next = new_stack; |
|||
400 | } |
|||
401 | stack_of_stacks_top = new_stack; |
|||
402 | new_stack->tos = -1; |
|||
403 | ||||
404 | ||||
405 | attrstack_unexpress_all (prev_stack); |
|||
406 | attrstack_copy_all (prev_stack, new_stack); |
|||
407 | attrstack_express_all (); |
|||
408 | } |
|||
409 | } |
|||
410 | ||||
411 | ||||
412 | ||||
413 | ||||
414 | * Name: attr_pop |
|||
415 | * Purpose: Removes and undoes the effect of the top attribute of |
|||
416 | * the current AttrStack. |
|||
417 | * Args: The top attribute's number, for verification. |
|||
418 | * Returns: Success/fail flag. |
|||
419 | *=======================================================================*/ |
|||
420 | ||||
421 | ||||
422 | attr_pop (int attr) |
|||
423 | { |
|||
424 | AttrStack *stack = stack_of_stacks_top; |
|||
425 | ||||
426 | ||||
427 | warning_handler ("no stack to pop attribute from"); |
|||
428 | return FALSE; |
|||
429 | } |
|||
430 | ||||
431 | ||||
432 | { |
|||
433 | char *param = stack->attr_stack_params [stack->tos]; |
|||
434 | ||||
435 | ||||
436 | ||||
437 | ||||
438 | ||||
439 | ||||
440 | ||||
441 | ||||
442 | } |
|||
443 | else |
|||
444 | return FALSE; |
|||
445 | } |
|||
446 | ||||
447 | ||||
448 | ||||
449 | ||||
450 | * Name: attr_read |
|||
451 | * Purpose: Reads but leaves in place the top attribute of the top |
|||
452 | * attribute stack. |
|||
453 | * Args: None. |
|||
454 | * Returns: Attribute number. |
|||
455 | *=======================================================================*/ |
|||
456 | ||||
457 | ||||
458 | attr_read() { |
|||
459 | AttrStack *stack = stack_of_stacks_top; |
|||
460 | if (!stack) { |
|||
461 | warning_handler ("no stack to read attribute from"); |
|||
462 | return FALSE; |
|||
463 | } |
|||
464 | ||||
465 | ||||
466 | { |
|||
467 | int attr = stack->attr_stack [stack->tos]; |
|||
468 | return attr; |
|||
469 | } |
|||
470 | else |
|||
471 | return ATTR_NONE; |
|||
472 | } |
|||
473 | ||||
474 | ||||
475 | ||||
476 | * Name: attr_drop_all |
|||
477 | * Purpose: Undoes all attributes that an AttrStack contains. |
|||
478 | * Args: None. |
|||
479 | * Returns: None. |
|||
480 | *=======================================================================*/ |
|||
481 | ||||
482 | ||||
483 | attr_drop_all () |
|||
484 | { |
|||
485 | AttrStack *stack = stack_of_stacks_top; |
|||
486 | if (!stack) { |
|||
487 | warning_handler ("no stack to drop all attributes from"); |
|||
488 | return; |
|||
489 | } |
|||
490 | ||||
491 | ||||
492 | { |
|||
493 | char *param=stack->attr_stack_params [stack->tos]; |
|||
494 | if (param) my_free(param); |
|||
495 | stack->tos--; |
|||
496 | } |
|||
497 | } |
|||
498 | ||||
499 | ||||
500 | ||||
501 | * Name: attrstack_drop |
|||
502 | * Purpose: Removes the top AttrStack from the stack of stacks, undoing |
|||
503 | * all attributes that it had in it. |
|||
504 | * Args: None. |
|||
505 | * Returns: None. |
|||
506 | *=======================================================================*/ |
|||
507 | ||||
508 | ||||
509 | attrstack_drop () |
|||
510 | { |
|||
511 | AttrStack *stack = stack_of_stacks_top; |
|||
512 | AttrStack *prev_stack; |
|||
513 | if (!stack) { |
|||
514 | warning_handler ("no attr-stack to drop"); |
|||
515 | return; |
|||
516 | } |
|||
517 | ||||
518 | ||||
519 | ||||
520 | ||||
521 | while(prev_stack && prev_stack->next && prev_stack->next != stack) |
|||
522 | prev_stack = prev_stack->next; |
|||
523 | ||||
524 | ||||
525 | stack_of_stacks_top = prev_stack; |
|||
526 | prev_stack->next = NULL; |
|||
527 | } else { |
|||
528 | stack_of_stacks_top = NULL; |
|||
529 | stack_of_stacks = NULL; |
|||
530 | } |
|||
531 | my_free ((void*) stack); |
|||
532 | ||||
533 | ||||
534 | } |
|||
535 | ||||
536 | ||||
537 | * Name: attr_pop_all |
|||
538 | * Purpose: Routine to undo all attributes heretofore applied, |
|||
539 | * also reversing the order in which they were applied. |
|||
540 | * Args: None. |
|||
541 | * Returns: None. |
|||
542 | *=======================================================================*/ |
|||
543 | ||||
544 | ||||
545 | attr_pop_all() |
|||
546 | { |
|||
547 | AttrStack *stack = stack_of_stacks_top; |
|||
548 | if (!stack) { |
|||
549 | warning_handler ("no stack to pop from"); |
|||
550 | return; |
|||
551 | } |
|||
552 | ||||
553 | ||||
554 | int attr=stack->attr_stack [stack->tos]; |
|||
555 | char *param=stack->attr_stack_params [stack->tos]; |
|||
556 | attr_express_end (attr,param); |
|||
557 | if (param) my_free(param); |
|||
558 | stack->tos--; |
|||
559 | } |
|||
560 | } |
|||
561 | ||||
562 | ||||
563 | ||||
564 | * Name: attrstack_express_all |
|||
565 | * Purpose: Routine to re-express all attributes heretofore applied. |
|||
566 | * Args: None. |
|||
567 | * Returns: None. |
|||
568 | * Notes: This is needed by attrstack_push, but also for \cell, which |
|||
569 | * often occurs within a brace group, yet HTML uses |
|||
570 | * which clear attribute info within that block. |
|||
571 | *=======================================================================*/ |
|||
572 | ||||
573 | ||||
574 | attrstack_express_all() { |
|||
575 | AttrStack *stack = stack_of_stacks_top; |
|||
576 | int i; |
|||
577 | ||||
578 | ||||
579 | warning_handler ("no stack to pop from"); |
|||
580 | return; |
|||
581 | } |
|||
582 | ||||
583 | ||||
584 | while (i<=stack->tos) |
|||
585 | { |
|||
586 | int attr=stack->attr_stack [i]; |
|||
587 | char *param=stack->attr_stack_params [i]; |
|||
588 | attr_express_begin (attr, param); |
|||
589 | i++; |
|||
590 | } |
|||
591 | } |
|||
592 | ||||
593 | ||||
594 | ||||
595 | * Name: attr_pop_dump |
|||
596 | * Purpose: Routine to un-express all attributes heretofore applied. |
|||
597 | * Args: None. |
|||
598 | * Returns: None. |
|||
599 | * Notes: This is needed for \cell, which often occurs within a |
|||
600 | * brace group, yet HTML uses |
|||
601 | * info within that block. |
|||
602 | *=======================================================================*/ |
|||
603 | ||||
604 | ||||
605 | attr_pop_dump() { |
|||
606 | AttrStack *stack = stack_of_stacks_top; |
|||
607 | int i; |
|||
608 | ||||
609 | ||||
610 | ||||
611 | ||||
612 | while (i>=0) |
|||
613 | { |
|||
614 | int attr=stack->attr_stack [i]; |
|||
615 | attr_pop (attr); |
|||
616 | i--; |
|||
617 | } |
|||
618 | }=stack-> |