Codebase list unrtf / 0c292bb
Imported Upstream version 0.19.3 Willi Mann 10 years ago
66 changed file(s) with 11342 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
Binary diff not shown
0
1 Overall Program Change Log for GNU UnRTF
2 ----------------------------------------
3 0.1: original version, known as "rtf2htm"
4 0.2: first civilized (Un*x) version
5 0.3: addition of hash storage for all strings
6 0.4: support for a few HTML special exprs
7 0.5: tables finally work
8 0.6: addition of usage()
9 0.7: added special chars, \tab, info group, <body>
10 0.8: font table support
11
12 0.9.0: images are stored to files
13 0.9.1: pict files extensions a bit more accurate
14 0.9.2: font size changes (\fs) more accurate.
15 0.9.3: fixed bug regarding where <body> goes
16 0.9.4: added -nopict option
17 0.9.5: fixed table data printing.
18 0.9.6: if >1 \cell in a group, font attrs affect all.
19 0.9.7: Chunk class renamed Word
20
21 0.10.0: input file type is checked, -echo renamed -dump
22 0.11.0: addition of ANSI->HTML conversion, plus limited Mac->HTML
23 0.11.1: unknown chars are printed as <!--0x##-->
24
25 0.12.0: separated parser from word module
26 0.12.1: added -version option
27 0.12.2: backslash-newline is now \par
28 0.12.3: added default font families (\fswiss etc)
29 0.12.4: added blurb about program in the output HTML
30 0.12.5: added recognition of files with ".RTF" ending, not just ".rtf"
31 0.12.6: added charset tables for CP437 and CP850
32 0.12.7: fixed bug preventing \'## sequences from being translated
33 0.12.8: removed size limit for words, verified DJGPP compilation works.
34 0.12.9: compilation bugfix, fixed author/date information
35 0.12.10: added --simple switch for generating HTML without SPAN/DIV tags
36
37 0.13.0: paragraph alignment added
38 0.13.1: fix for words getting lost after \par
39 0.13.2: fix for color table not being recognized
40
41 0.14.0: separation of word and convert modules
42 0.14.1: fixed color table indexing, added support for font background color.
43 0.14.2: updated parsing mechanism
44 0.14.3: fix for DIV nesting; fix for NS's hiding any table within a span.
45 0.14.4: fix for color table parsing; added better underline/strikethru support.
46
47 0.15.0: hashing of RTF keywords in convert.c; moved much code out of convert.c
48 0.15.1: removed null entries from special.c to reduce program size
49 0.15.2: removed no-op entries from hash in convert.c to reduce program size
50 0.15.3: first 16-bit MSDOS executable
51 0.15.4: fixed paragraph alignment not getting cleared by \pard
52 0.15.5: updated code to produce as few paragraph alignment tags as possible
53
54 0.16.0: added input buffering to improve speed
55 0.16.1: bugfix for printing of debugging strings stored in command hash
56
57 0.17.0: hyperlink support added
58 0.17.1: added support for several font attributes e.g. smallcaps, caps, \expand
59 0.17.2: added Amiga(TM) compilation support
60 0.17.3: fixed problem in interpretation of RTF command words
61 0.17.4: changed attr.c to use AttrStack (stack of stacks) paradigm
62 ----program renamed UnRTF----
63 0.17.5: began implementation of output personalities; wrote HTML personality.
64 0.17.6: added text and vt personalities
65 0.17.7: began addition of PostScript(TM) and LaTeX and WPML output
66 0.17.8: first fully commented version, removed "last change" lines
67 0.17.9: fixed translation between character sets
68 0.17.10: PS now supports underline, strikethrough, shadowed text
69 0.17.11: PS now uses ISOLatin1Encoding
70 0.17.12: PS now supports these fonts: Times,Courier,Symbol,Helvetica
71
72 ----program is now GNU UnRTF----
73 0.18.0: updates to comments, documentation to reflect inclusion in GNU suite.
74 0.18.1: updated manual
75
76 0.19.1: new maintainers: minor fixes to prevent segmentation violations;
77 further special character code; minor cleanups
78 0.19.2: updated some files;
79 0.19.3: fix bug #225592: null pointer param in convert.c
80
81 Note:
82 LaTeX is a system of macros for TeX by Leslie Lamport.
83 WPML is a tentative document format by Z.T. Smith
84
85
86
0 GNU GENERAL PUBLIC LICENSE
1 Version 2, June 1991
2
3 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
4 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
5 Everyone is permitted to copy and distribute verbatim copies
6 of this license document, but changing it is not allowed.
7
8 Preamble
9
10 The licenses for most software are designed to take away your
11 freedom to share and change it. By contrast, the GNU General Public
12 License is intended to guarantee your freedom to share and change free
13 software--to make sure the software is free for all its users. This
14 General Public License applies to most of the Free Software
15 Foundation's software and to any other program whose authors commit to
16 using it. (Some other Free Software Foundation software is covered by
17 the GNU Library General Public License instead.) You can apply it to
18 your programs, too.
19
20 When we speak of free software, we are referring to freedom, not
21 price. Our General Public Licenses are designed to make sure that you
22 have the freedom to distribute copies of free software (and charge for
23 this service if you wish), that you receive source code or can get it
24 if you want it, that you can change the software or use pieces of it
25 in new free programs; and that you know you can do these things.
26
27 To protect your rights, we need to make restrictions that forbid
28 anyone to deny you these rights or to ask you to surrender the rights.
29 These restrictions translate to certain responsibilities for you if you
30 distribute copies of the software, or if you modify it.
31
32 For example, if you distribute copies of such a program, whether
33 gratis or for a fee, you must give the recipients all the rights that
34 you have. You must make sure that they, too, receive or can get the
35 source code. And you must show them these terms so they know their
36 rights.
37
38 We protect your rights with two steps: (1) copyright the software, and
39 (2) offer you this license which gives you legal permission to copy,
40 distribute and/or modify the software.
41
42 Also, for each author's protection and ours, we want to make certain
43 that everyone understands that there is no warranty for this free
44 software. If the software is modified by someone else and passed on, we
45 want its recipients to know that what they have is not the original, so
46 that any problems introduced by others will not reflect on the original
47 authors' reputations.
48
49 Finally, any free program is threatened constantly by software
50 patents. We wish to avoid the danger that redistributors of a free
51 program will individually obtain patent licenses, in effect making the
52 program proprietary. To prevent this, we have made it clear that any
53 patent must be licensed for everyone's free use or not licensed at all.
54
55 The precise terms and conditions for copying, distribution and
56 modification follow.
57
58 GNU GENERAL PUBLIC LICENSE
59 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
60
61 0. This License applies to any program or other work which contains
62 a notice placed by the copyright holder saying it may be distributed
63 under the terms of this General Public License. The "Program", below,
64 refers to any such program or work, and a "work based on the Program"
65 means either the Program or any derivative work under copyright law:
66 that is to say, a work containing the Program or a portion of it,
67 either verbatim or with modifications and/or translated into another
68 language. (Hereinafter, translation is included without limitation in
69 the term "modification".) Each licensee is addressed as "you".
70
71 Activities other than copying, distribution and modification are not
72 covered by this License; they are outside its scope. The act of
73 running the Program is not restricted, and the output from the Program
74 is covered only if its contents constitute a work based on the
75 Program (independent of having been made by running the Program).
76 Whether that is true depends on what the Program does.
77
78 1. You may copy and distribute verbatim copies of the Program's
79 source code as you receive it, in any medium, provided that you
80 conspicuously and appropriately publish on each copy an appropriate
81 copyright notice and disclaimer of warranty; keep intact all the
82 notices that refer to this License and to the absence of any warranty;
83 and give any other recipients of the Program a copy of this License
84 along with the Program.
85
86 You may charge a fee for the physical act of transferring a copy, and
87 you may at your option offer warranty protection in exchange for a fee.
88
89 2. You may modify your copy or copies of the Program or any portion
90 of it, thus forming a work based on the Program, and copy and
91 distribute such modifications or work under the terms of Section 1
92 above, provided that you also meet all of these conditions:
93
94 a) You must cause the modified files to carry prominent notices
95 stating that you changed the files and the date of any change.
96
97 b) You must cause any work that you distribute or publish, that in
98 whole or in part contains or is derived from the Program or any
99 part thereof, to be licensed as a whole at no charge to all third
100 parties under the terms of this License.
101
102 c) If the modified program normally reads commands interactively
103 when run, you must cause it, when started running for such
104 interactive use in the most ordinary way, to print or display an
105 announcement including an appropriate copyright notice and a
106 notice that there is no warranty (or else, saying that you provide
107 a warranty) and that users may redistribute the program under
108 these conditions, and telling the user how to view a copy of this
109 License. (Exception: if the Program itself is interactive but
110 does not normally print such an announcement, your work based on
111 the Program is not required to print an announcement.)
112
113 These requirements apply to the modified work as a whole. If
114 identifiable sections of that work are not derived from the Program,
115 and can be reasonably considered independent and separate works in
116 themselves, then this License, and its terms, do not apply to those
117 sections when you distribute them as separate works. But when you
118 distribute the same sections as part of a whole which is a work based
119 on the Program, the distribution of the whole must be on the terms of
120 this License, whose permissions for other licensees extend to the
121 entire whole, and thus to each and every part regardless of who wrote it.
122
123 Thus, it is not the intent of this section to claim rights or contest
124 your rights to work written entirely by you; rather, the intent is to
125 exercise the right to control the distribution of derivative or
126 collective works based on the Program.
127
128 In addition, mere aggregation of another work not based on the Program
129 with the Program (or with a work based on the Program) on a volume of
130 a storage or distribution medium does not bring the other work under
131 the scope of this License.
132
133 3. You may copy and distribute the Program (or a work based on it,
134 under Section 2) in object code or executable form under the terms of
135 Sections 1 and 2 above provided that you also do one of the following:
136
137 a) Accompany it with the complete corresponding machine-readable
138 source code, which must be distributed under the terms of Sections
139 1 and 2 above on a medium customarily used for software interchange; or,
140
141 b) Accompany it with a written offer, valid for at least three
142 years, to give any third party, for a charge no more than your
143 cost of physically performing source distribution, a complete
144 machine-readable copy of the corresponding source code, to be
145 distributed under the terms of Sections 1 and 2 above on a medium
146 customarily used for software interchange; or,
147
148 c) Accompany it with the information you received as to the offer
149 to distribute corresponding source code. (This alternative is
150 allowed only for noncommercial distribution and only if you
151 received the program in object code or executable form with such
152 an offer, in accord with Subsection b above.)
153
154 The source code for a work means the preferred form of the work for
155 making modifications to it. For an executable work, complete source
156 code means all the source code for all modules it contains, plus any
157 associated interface definition files, plus the scripts used to
158 control compilation and installation of the executable. However, as a
159 special exception, the source code distributed need not include
160 anything that is normally distributed (in either source or binary
161 form) with the major components (compiler, kernel, and so on) of the
162 operating system on which the executable runs, unless that component
163 itself accompanies the executable.
164
165 If distribution of executable or object code is made by offering
166 access to copy from a designated place, then offering equivalent
167 access to copy the source code from the same place counts as
168 distribution of the source code, even though third parties are not
169 compelled to copy the source along with the object code.
170
171 4. You may not copy, modify, sublicense, or distribute the Program
172 except as expressly provided under this License. Any attempt
173 otherwise to copy, modify, sublicense or distribute the Program is
174 void, and will automatically terminate your rights under this License.
175 However, parties who have received copies, or rights, from you under
176 this License will not have their licenses terminated so long as such
177 parties remain in full compliance.
178
179 5. You are not required to accept this License, since you have not
180 signed it. However, nothing else grants you permission to modify or
181 distribute the Program or its derivative works. These actions are
182 prohibited by law if you do not accept this License. Therefore, by
183 modifying or distributing the Program (or any work based on the
184 Program), you indicate your acceptance of this License to do so, and
185 all its terms and conditions for copying, distributing or modifying
186 the Program or works based on it.
187
188 6. Each time you redistribute the Program (or any work based on the
189 Program), the recipient automatically receives a license from the
190 original licensor to copy, distribute or modify the Program subject to
191 these terms and conditions. You may not impose any further
192 restrictions on the recipients' exercise of the rights granted herein.
193 You are not responsible for enforcing compliance by third parties to
194 this License.
195
196 7. If, as a consequence of a court judgment or allegation of patent
197 infringement or for any other reason (not limited to patent issues),
198 conditions are imposed on you (whether by court order, agreement or
199 otherwise) that contradict the conditions of this License, they do not
200 excuse you from the conditions of this License. If you cannot
201 distribute so as to satisfy simultaneously your obligations under this
202 License and any other pertinent obligations, then as a consequence you
203 may not distribute the Program at all. For example, if a patent
204 license would not permit royalty-free redistribution of the Program by
205 all those who receive copies directly or indirectly through you, then
206 the only way you could satisfy both it and this License would be to
207 refrain entirely from distribution of the Program.
208
209 If any portion of this section is held invalid or unenforceable under
210 any particular circumstance, the balance of the section is intended to
211 apply and the section as a whole is intended to apply in other
212 circumstances.
213
214 It is not the purpose of this section to induce you to infringe any
215 patents or other property right claims or to contest validity of any
216 such claims; this section has the sole purpose of protecting the
217 integrity of the free software distribution system, which is
218 implemented by public license practices. Many people have made
219 generous contributions to the wide range of software distributed
220 through that system in reliance on consistent application of that
221 system; it is up to the author/donor to decide if he or she is willing
222 to distribute software through any other system and a licensee cannot
223 impose that choice.
224
225 This section is intended to make thoroughly clear what is believed to
226 be a consequence of the rest of this License.
227
228 8. If the distribution and/or use of the Program is restricted in
229 certain countries either by patents or by copyrighted interfaces, the
230 original copyright holder who places the Program under this License
231 may add an explicit geographical distribution limitation excluding
232 those countries, so that distribution is permitted only in or among
233 countries not thus excluded. In such case, this License incorporates
234 the limitation as if written in the body of this License.
235
236 9. The Free Software Foundation may publish revised and/or new versions
237 of the General Public License from time to time. Such new versions will
238 be similar in spirit to the present version, but may differ in detail to
239 address new problems or concerns.
240
241 Each version is given a distinguishing version number. If the Program
242 specifies a version number of this License which applies to it and "any
243 later version", you have the option of following the terms and conditions
244 either of that version or of any later version published by the Free
245 Software Foundation. If the Program does not specify a version number of
246 this License, you may choose any version ever published by the Free Software
247 Foundation.
248
249 10. If you wish to incorporate parts of the Program into other free
250 programs whose distribution conditions are different, write to the author
251 to ask for permission. For software which is copyrighted by the Free
252 Software Foundation, write to the Free Software Foundation; we sometimes
253 make exceptions for this. Our decision will be guided by the two goals
254 of preserving the free status of all derivatives of our free software and
255 of promoting the sharing and reuse of software generally.
256
257 NO WARRANTY
258
259 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
260 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
261 OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
262 PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
263 OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
264 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
265 TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
266 PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
267 REPAIR OR CORRECTION.
268
269 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
270 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
271 REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
272 INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
273 OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
274 TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
275 YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
276 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
277 POSSIBILITY OF SUCH DAMAGES.
278
279 END OF TERMS AND CONDITIONS
280
281 How to Apply These Terms to Your New Programs
282
283 If you develop a new program, and you want it to be of the greatest
284 possible use to the public, the best way to achieve this is to make it
285 free software which everyone can redistribute and change under these terms.
286
287 To do so, attach the following notices to the program. It is safest
288 to attach them to the start of each source file to most effectively
289 convey the exclusion of warranty; and each file should have at least
290 the "copyright" line and a pointer to where the full notice is found.
291
292 <one line to give the program's name and a brief idea of what it does.>
293 Copyright (C) 19yy <name of author>
294
295 This program is free software; you can redistribute it and/or modify
296 it under the terms of the GNU General Public License as published by
297 the Free Software Foundation; either version 2 of the License, or
298 (at your option) any later version.
299
300 This program is distributed in the hope that it will be useful,
301 but WITHOUT ANY WARRANTY; without even the implied warranty of
302 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
303 GNU General Public License for more details.
304
305 You should have received a copy of the GNU General Public License
306 along with this program; if not, write to the Free Software
307 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
308
309
310 Also add information on how to contact you by electronic and paper mail.
311
312 If the program is interactive, make it output a short notice like this
313 when it starts in an interactive mode:
314
315 Gnomovision version 69, Copyright (C) 19yy name of author
316 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 This is free software, and you are welcome to redistribute it
318 under certain conditions; type `show c' for details.
319
320 The hypothetical commands `show w' and `show c' should show the appropriate
321 parts of the General Public License. Of course, the commands you use may
322 be called something other than `show w' and `show c'; they could even be
323 mouse-clicks or menu items--whatever suits your program.
324
325 You should also get your employer (if you work as a programmer) or your
326 school, if any, to sign a "copyright disclaimer" for the program, if
327 necessary. Here is a sample; alter the names:
328
329 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 `Gnomovision' (which makes passes at compilers) written by James Hacker.
331
332 <signature of Ty Coon>, 1 April 1989
333 Ty Coon, President of Vice
334
335 This General Public License does not permit incorporating your program into
336 proprietary programs. If your program is a subroutine library, you may
337 consider it more useful to permit linking proprietary applications with the
338 library. If this is what you want to do, use the GNU Library General
339 Public License instead of this License.
0
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 # This program is free software; you can redistribute it and/or modify
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 # This program is distributed in the hope that it will be useful,
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 # You should have received a copy of the GNU General Public License
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 # The author is reachable by electronic mail at tuorfa@yahoo.com.
20 ##############################################################################
21
22 #
23 # Makefile for UnRTF
24 #
25
26
27 CFLAGS=-g -Wall
28 CC=gcc
29
30 OBJS=convert.o word.o error.o main.o hash.o \
31 parse.o malloc.o attr.o util.o \
32 output.o html.o text.o vt.o ps.o latex.o wpml.o entity.o
33
34 TARGET=unrtf
35
36 ${TARGET}: ${OBJS}
37 gcc ${OBJS} -o ${TARGET}
38
39 clean:
40 rm -f ${OBJS} ${TARGET} bcount bcount.o
41
42 tidy:
43 rm -f ${OBJS} bcount.o
44 strip ${TARGET}
45
46 tests:
47 ${TARGET} test/table.rtf > test/table.html
48 ${TARGET} test/slashnewline.rtf > test/slashnewline.html
49 ${TARGET} test/fontface.rtf > test/fontface.html
50 ${TARGET} test/fontsize.rtf > test/fontsize.html
51
52 bcount: bcount.c
53 gcc bcount.c -o bcount
54
55 all: ${TARGET} bcount
56 rm -f ${OBJS}
57
58 install: ${TARGET}
59 cp ${TARGET} /usr/local/bin
60
61 attr.o: attr.c defs.h error.h attr.h main.h malloc.h
62 convert.o: convert.c attr.h convert.h defs.h error.h hash.h main.h malloc.h \
63 parse.h util.h word.h
64 entity.o: entity.c
65 error.o: error.c defs.h main.h
66 hash.o: hash.c error.h hash.h main.h malloc.h
67 html.o: html.c defs.h error.h main.h malloc.h output.h
68 latex.o: latex.c defs.h error.h main.h malloc.h output.h
69 main.o: main.c convert.h defs.h error.h hash.h html.h latex.h output.h \
70 parse.h ps.h text.h vt.h wpml.h word.h
71 malloc.o: malloc.c error.h
72 output.o: output.c convert.h defs.h error.h main.h malloc.h output.h
73 parse.o: parse.c defs.h error.h main.h malloc.h parse.h word.h
74 ps.o: ps.c defs.h error.h main.h malloc.h output.h
75 text.o: text.c defs.h error.h main.h malloc.h output.h
76 util.o: util.c
77 vt.o: vt.c defs.h error.h main.h malloc.h output.h
78 word.o: word.c defs.h error.h hash.h main.h malloc.h parse.h word.h
79 wpml.o: wpml.c defs.h error.h main.h malloc.h output.h
0 Greetings,
1
2 UnRTF is a moderately complicated converter from RTF to other
3 formats, including HTML, LaTeX, text, and PostScript. Converting
4 to HTML, it supports tables, fonts, colors, embedded images,
5 hyperlinks, paragraph alignment among other things. All other
6 conversions are "alpha"--just begun.
7
8 Compiling with GCC: type "make all", and assuming you have GCC
9 and GNU make, it should compile without any warnings or errors
10 under Linux, BSD, and DOS (using DJGPP). Amiga/GCC users
11 should utilize the build.amiga file. Please let me know of
12 any compilation problems.
13
14 This program includes no warranty whatsoever. It is provided
15 "AS IS". For more information please read the COPYING
16 document, which should be included with the source code.
17 It describes the GNU Public License, which covers UnRTF.
18
19 Enjoy.
20
21 Zachary Thayer Smith
22 tuorfa@yahoo.com
23
24 22 Sept 01
25
0
1 UnRTF by Zach Smith
2
3 A few tasks that need doing as of 18 Sept 01
4 --------------------------------------------
5
6 * Make sure --inline still works; limit it to HTML.
7
8 * Add a module for an intermediate character set for charset
9 conversions.
10
11 * Finish output personalities for LaTeX, PostScript, text, vt, WPML.
12 - Postscript word-level metrics and printing.
13 - Postscript paragraph alignment.
14 - Postscript tables.
15 - Postscript more font faces.
16 - Does LaTeX support emboss, engrave, outline, shadow?
17
18 * Point-lists -- rather important.
19
20 * Index entries.
21
22 * TOC entries.
23
24 * Headers.
25
26 * Footers.
27
28 * Add support for line-based images (the RTF "shape" concept),
29 converting to Beest format or another?
30
31 * Centering not working within tables?
32
33 * HTML: javascript-based shadow/outline/emboss/engrave ?
34
35 * Style sheet support?
36
37 * HTML: Multiple columns kludge using tables or layers?
38
39 * Need to support more Mac RTF special expressions.
40
0
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 This program is free software; you can redistribute it and/or modify
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 This program is distributed in the hope that it will be useful,
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 You should have received a copy of the GNU General Public License
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 The author is reachable by electronic mail at tuorfa@yahoo.com.
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 #include <stdio.h>
38 #include <string.h>
39 #include <stdlib.h>
40
41 #include "malloc.h"
42 #include "defs.h"
43 #include "error.h"
44 #include "attr.h"
45 #include "main.h"
46
47
48 extern void starting_body();
49 extern void starting_text();
50
51 extern int simulate_allcaps;
52 extern int simulate_smallcaps;
53
54
55 #define MAX_ATTRS (1000)
56
57
58
59 /* For each RTF text block (the text within braces) we must keep
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 static AttrStack *stack_of_stacks = NULL;
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 void
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 /* Various underlines, they all resolve to HTML's <u> */
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 case ATTR_DOUBLE_UL:
111 printf (op->dbl_underline_begin);
112 break;
113
114 case ATTR_FONTSIZE:
115 op_begin_std_fontsize (op, atoi (param));
116 break;
117
118 case ATTR_FONTFACE:
119 printf (op->font_begin,param);
120 break;
121
122 case ATTR_FOREGROUND:
123 printf (op->foreground_begin, param);
124 break;
125
126 case ATTR_BACKGROUND:
127 if (!simple_mode)
128 printf (op->foreground_begin,param);
129 break;
130
131 case ATTR_SUPER:
132 printf (op->superscript_begin);
133 break;
134 case ATTR_SUB:
135 printf (op->subscript_begin);
136 break;
137
138 case ATTR_STRIKE:
139 printf (op->strikethru_begin);
140 break;
141
142 case ATTR_DBL_STRIKE:
143 printf (op->dbl_strikethru_begin);
144 break;
145
146 case ATTR_EXPAND:
147 printf (op->expand_begin, param);
148 break;
149
150 case ATTR_OUTLINE:
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 case ATTR_CAPS:
164 if (op->simulate_all_caps)
165 simulate_allcaps = TRUE;
166 break;
167
168 case ATTR_SMALLCAPS:
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 void
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 /* Various underlines, they all resolve to HTML's </u> */
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 case ATTR_DOUBLE_UL:
212 printf (op->dbl_underline_end);
213 break;
214
215 case ATTR_FONTSIZE:
216 op_end_std_fontsize (op, atoi (param));
217 break;
218
219 case ATTR_FONTFACE:
220 printf (op->font_end);
221 break;
222
223 case ATTR_FOREGROUND:
224 printf (op->foreground_end);
225 break;
226 case ATTR_BACKGROUND:
227 if (!simple_mode)
228 printf (op->background_end);
229 break;
230
231 case ATTR_SUPER:
232 printf (op->superscript_end);
233 break;
234 case ATTR_SUB:
235 printf (op->subscript_end);
236 break;
237
238 case ATTR_STRIKE:
239 printf (op->strikethru_end);
240 break;
241
242 case ATTR_DBL_STRIKE:
243 printf (op->dbl_strikethru_end);
244 break;
245
246 case ATTR_OUTLINE:
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 case ATTR_EXPAND:
260 printf (op->expand_end);
261 break;
262
263 case ATTR_CAPS:
264 if (op->simulate_all_caps)
265 simulate_allcaps = FALSE;
266 break;
267
268 case ATTR_SMALLCAPS:
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 void
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 if (stack->tos>=MAX_ATTRS) { fprintf (stderr,"Too many attributes!\n"); return; }
298
299 /* Make sure it's understood we're in the <body> section. */
300 /* KLUDGE */
301 starting_body();
302 starting_text();
303
304 ++stack->tos;
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 attr_express_begin (attr, param);
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 void
323 attrstack_copy_all (AttrStack *src, AttrStack *dest)
324 {
325 int i;
326 int total;
327
328 CHECK_PARAM_NOT_NULL(src);
329 CHECK_PARAM_NOT_NULL(dest);
330
331 total = src->tos + 1;
332
333 for (i=0; i<total; i++)
334 {
335 int attr=src->attr_stack [i];
336 char *param=src->attr_stack_params [i];
337
338 dest->attr_stack[i] = attr;
339 if (param)
340 dest->attr_stack_params[i] = my_strdup (param);
341 else
342 dest->attr_stack_params[i] = NULL;
343 }
344
345 dest->tos = src->tos;
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 <td></td>
356 * which clear attribute info within that block.
357 *=======================================================================*/
358
359 void
360 attrstack_unexpress_all (AttrStack *stack)
361 {
362 int i;
363
364 CHECK_PARAM_NOT_NULL(stack);
365
366 i=stack->tos;
367 while (i>=0)
368 {
369 int attr=stack->attr_stack [i];
370 char *param=stack->attr_stack_params [i];
371
372 attr_express_end (attr, param);
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 new_stack = (AttrStack*) my_malloc (sizeof (AttrStack));
392 bzero ((void*) new_stack, sizeof (AttrStack));
393
394 prev_stack = stack_of_stacks_top;
395
396 if (!stack_of_stacks) {
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 if (prev_stack) {
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 int
422 attr_pop (int attr)
423 {
424 AttrStack *stack = stack_of_stacks_top;
425
426 if (!stack) {
427 warning_handler ("no stack to pop attribute from");
428 return FALSE;
429 }
430
431 if(stack->tos>=0 && stack->attr_stack[stack->tos]==attr)
432 {
433 char *param = stack->attr_stack_params [stack->tos];
434
435 attr_express_end (attr, param);
436
437 if (param) my_free(param);
438
439 stack->tos--;
440
441 return TRUE;
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 int
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 if(stack->tos>=0)
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 void
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 while (stack->tos>=0)
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 void
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 attr_pop_all ();
519
520 prev_stack = stack_of_stacks;
521 while(prev_stack && prev_stack->next && prev_stack->next != stack)
522 prev_stack = prev_stack->next;
523
524 if (prev_stack) {
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 attrstack_express_all ();
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 void
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 while (stack->tos>=0) {
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 <td></td>
570 * which clear attribute info within that block.
571 *=======================================================================*/
572
573 void
574 attrstack_express_all() {
575 AttrStack *stack = stack_of_stacks_top;
576 int i;
577
578 if (!stack) {
579 warning_handler ("no stack to pop from");
580 return;
581 }
582
583 i=0;
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 <td></td> which clear attribute
601 * info within that block.
602 *=======================================================================*/
603
604 void
605 attr_pop_dump() {
606 AttrStack *stack = stack_of_stacks_top;
607 int i;
608
609 if (!stack) return;
610
611 i=stack->tos;
612 while (i>=0)
613 {
614 int attr=stack->attr_stack [i];
615 attr_pop (attr);
616 i--;
617 }
618 }
619
0
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 This program is free software; you can redistribute it and/or modify
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 This program is distributed in the hope that it will be useful,
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 You should have received a copy of the GNU General Public License
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 The author is reachable by electronic mail at tuorfa@yahoo.com.
20 =============================================================================*/
21
22
23 /*----------------------------------------------------------------------
24 * Module name: attr
25 * Author name: Zach Smith
26 * Create date: 1 Aug 2001
27 * Purpose: Definitions for attribute stack module.
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 attributes
32 * 18 Sep 01, tuorfa@yahoo.com: updates for AttrStack paradigm
33 *--------------------------------------------------------------------*/
34
35 enum {
36 ATTR_NONE=0,
37 ATTR_BOLD, ATTR_ITALIC,
38
39 ATTR_UNDERLINE, ATTR_DOUBLE_UL, ATTR_WORD_UL,
40
41 ATTR_THICK_UL, ATTR_WAVE_UL,
42
43 ATTR_DOT_UL, ATTR_DASH_UL, ATTR_DOT_DASH_UL, ATTR_2DOT_DASH_UL,
44
45 ATTR_FONTSIZE, ATTR_STD_FONTSIZE,
46 ATTR_FONTFACE,
47 ATTR_FOREGROUND, ATTR_BACKGROUND,
48 ATTR_CAPS,
49 ATTR_SMALLCAPS,
50
51 ATTR_SHADOW,
52 ATTR_OUTLINE,
53 ATTR_EMBOSS,
54 ATTR_ENGRAVE,
55
56 ATTR_SUPER, ATTR_SUB,
57 ATTR_STRIKE,
58 ATTR_DBL_STRIKE,
59
60 ATTR_EXPAND,
61 /* ATTR_CONDENSE */
62 };
63
64
65
66 extern void attr_push_core (int attr, char* param);
67
68 extern void attr_pop_core (int attr);
69
70 extern void attr_push(int attr, char* param);
71
72 extern void attrstack_push();
73 extern void attrstack_drop();
74 extern void attrstack_express_all();
75
76 extern int attr_pop(int attr);
77
78 extern int attr_read();
79
80 extern void attr_drop_all ();
81
82 extern void attr_pop_all();
83
84 extern void attr_pop_dump();
85
86
87
0
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 This program is free software; you can redistribute it and/or modify
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 This program is distributed in the hope that it will be useful,
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 You should have received a copy of the GNU General Public License
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 The author is reachable by electronic mail at tuorfa@yahoo.com.
20 =============================================================================*/
21
22 /*----------------------------------------------------------------------
23 * Program name: bcount
24 * Author name: Zach Smith
25 * Create date: 15 Oct 00
26 * Purpose: Counts the number of opening and closing braces while
27 * reading from stdin.
28 *--------------------------------------------------------------------*/
29
30
31
32 #include <stdio.h>
33 main (){
34 int n1,n2;
35 int ch;
36 n1=n2=0;
37 while (EOF!=(ch=getchar())) {
38 if (ch=='}') ++n1;
39 if (ch=='{') ++n2;
40 }
41 printf ("{=%d, }=%d\n", n2,n1);
42 }
43
44
0 .KEY CLEAR/S,INSTALL/S,MAKE/S,UNINSTALL/S
1 .BRA {
2 .KET }
3 ;------------------------------------------------------------------------------
4 ; UnRTF, a command-line program to convert RTF documents to other formats.
5 ; Copyright (C) 2000,2001 Zachary Thayer Smith
6 ;
7 ; This program is free software; you can redistribute it and/or modify
8 ; it under the terms of the GNU General Public License as published by
9 ; the Free Software Foundation; either version 2 of the License, or
10 ; (at your option) any later version.
11 ;
12 ; This program is distributed in the hope that it will be useful,
13 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ; GNU General Public License for more details.
16 ;
17 ; You should have received a copy of the GNU General Public License
18 ; along with this program; if not, write to the Free Software
19 ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 ;
21 ; The author is reachable by electronic mail at tuorfa@yahoo.com.
22 ;------------------------------------------------------------------------------
23 ; Author name: Lars Unger <l.unger@tu-bs.de>
24 ; Create date: 15 Aug 01
25 ; Last change: 16 Aug 01
26 ; Purpose: AmigaDOS batch file to build GNU UnRTF using GNU GCC
27 ;
28 ;Version
29 ;$VER: build.amiga 0.4
30 ;------------------------------------------------------------------------------
31 ;
32 ;
33 ; definitions (feel free to modify)
34 ;
35 set GCC "gnu:bin/gccv"
36 set CFLAGS "-g -Wall"
37 set OBJS "convert.o word.o entity.o error.o main.o hash.o parse.o special.o malloc.o attr.o util.o"
38 set CSRC "convert.c word.c entity.c error.c main.c hash.c parse.c special.c malloc.c attr.c util.c"
39 set TARGET "unrtf"
40 set BINARY "C:unrtf"
41 set HELP "HELP:english/unrtf"
42 ;
43 ; end of definitions
44 ;
45 ; gcc installed ?
46 if not exists $GCC
47 echo ERROR: $GCC not found !
48 quit 20
49 endif
50 ; action control switch
51 set BUILDAMIGA NO
52 ; delete old gcc run
53 if "{CLEAR}" EQ "CLEAR"
54 set BUILDAMIGA YES
55 delete #?.o >NIL:
56 delete $TRAGET >NIL:
57 endif
58 ; uninstall unrtfl
59 if "{UNINSTALL}" EQ "UNINSTALL"
60 set BUILDAMIGA YES
61 delete $BINARY >NIL:
62 delete $HELP all >NIL:
63 endif
64 ; install unrtf
65 if "{INSTALL}" EQ "INSTALL"
66 set BUILDAMIGA YES
67 ask "Install unrtf in $BINARY ?"
68 if warn
69 if exists $TARGET
70 copy $TARGET $BINARY
71 echo "Installed $TARGET in $BINARY"
72 else
73 echo "ERROR: No unrtf executable found !"
74 endif
75 endif
76 ask "Install unrtf docs in $HELP ?"
77 if warn
78 if not exists $HELP
79 makedir $HELP
80 endif
81 copy unrtf.guide changes todo readme $HELP >NIL:
82 endif
83 endif
84 ; use gccv to create unrtf executable (compile)
85 if "{MAKE}" EQ "MAKE"
86 set BUILDAMIGA YES
87 ; set stack for gcc
88 if exists env:GCCSTACK
89 stack $GCCSTACK
90 else
91 stack 250000
92 endif
93 ; compile source file(s)
94 $GCC $CFLAGS -c $CSRC
95 ; link objects
96 $GCC -o $TARGET $OBJS
97 ; check output
98 if exists $TARGET
99 protect $TARGET +e
100 echo "$TARGET was created and is executable. Maybe you"
101 echo "have to increase the stack size of your shell. "
102 echo "Have fun !"
103 else
104 echo "ERROR: unrtf executable not found !"
105 echo "Please check output from GCC."
106 endif
107 endif
108 ; any action performed otherwise give help
109 if $BUILDAMIGA EQ NO
110 echo "This is an AmigaDOS batch file to build unrtf using GCC"
111 echo "Using: build.amiga CLEAR/S,INSTALL/S,MAKE/S,UNINSTALL/S"
112 endif
113
114
0
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 This program is free software; you can redistribute it and/or modify
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 This program is distributed in the hope that it will be useful,
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 You should have received a copy of the GNU General Public License
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 The author is reachable by electronic mail at tuorfa@yahoo.com.
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 * 08 Oct 03, daved@physiol.usyd.edu.au: more special character code
53 *--------------------------------------------------------------------*/
54
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <ctype.h>
58 #include <string.h>
59
60 #include "defs.h"
61 #include "parse.h"
62 #include "util.h"
63 #include "malloc.h"
64 #include "main.h"
65 #include "error.h"
66 #include "word.h"
67 #include "hash.h"
68 #include "convert.h"
69 #include "attr.h"
70
71
72 /*
73 #define BINARY_ATTRS
74 */
75
76
77 static int charset_type=CHARSET_ANSI;
78
79
80 /* Nested tables aren't supported.
81 */
82 static int coming_pars_that_are_tabular = 0;
83 static int within_table = FALSE;
84 static int have_printed_row_begin=FALSE;
85 static int have_printed_cell_begin=FALSE;
86 static int have_printed_row_end=FALSE;
87 static int have_printed_cell_end=FALSE;
88
89
90 /* Previously in word_print_core function
91 */
92 static int total_chars_this_line=0; /* for simulating \tab */
93
94
95 /* Paragraph alignment (kludge)
96 */
97 enum {
98 ALIGN_LEFT=0,
99 ALIGN_RIGHT,
100 ALIGN_CENTER,
101 ALIGN_JUSTIFY
102 };
103
104
105
106 /* This value is set by attr_push and attr_pop
107 */
108 int simulate_smallcaps;
109 int simulate_allcaps;
110
111
112 /* Most pictures must be written to files. */
113 enum {
114 PICT_UNKNOWN=0,
115 PICT_WM,
116 PICT_MAC,
117 PICT_PM,
118 PICT_DI,
119 PICT_WB,
120 PICT_JPEG,
121 PICT_PNG,
122 };
123 static int within_picture=FALSE;
124 static int picture_file_number=1;
125 static char picture_path[255];
126 static int picture_width;
127 static int picture_height;
128 static int picture_bits_per_pixel=1;
129 static int picture_type=PICT_UNKNOWN;
130 static int picture_wmetafile_type;
131 static char *picture_wmetafile_type_str;
132
133
134 static int have_printed_body=FALSE;
135 static int within_header=TRUE;
136
137
138
139 static char *hyperlink_base = NULL;
140
141
142
143 void starting_body();
144 void starting_text();
145
146
147 static int banner_printed=FALSE;
148
149 #if 1 /* daved - 0.19.0 */
150 char *entity(int symbol);
151 #endif
152
153
154
155 /*========================================================================
156 * Name: print_banner
157 * Purpose: Writes program-identifying text to the output stream.
158 * Args: None.
159 * Returns: None.
160 *=======================================================================*/
161
162 void
163 print_banner () {
164 if (!banner_printed) {
165 printf (op->comment_begin);
166 printf ("Translation from RTF performed by ");
167 printf ("%s, version ", PROGRAM_NAME);
168 printf ("%s", PROGRAM_VERSION);
169 printf (op->comment_end);
170
171 printf (op->comment_begin);
172 printf ("For information about this marvellous program,");
173 printf (op->comment_end);
174
175 printf (op->comment_begin);
176 printf ("please go to %s", PROGRAM_WEBSITE);
177 printf (op->comment_end);
178 }
179 banner_printed=TRUE;
180 }
181
182
183 /*========================================================================
184 * Name: starting_body
185 * Purpose: Switches output stream for writing document contents.
186 * Args: None.
187 * Returns: None.
188 *=======================================================================*/
189
190 void
191 starting_body ()
192 {
193 if (!have_printed_body) {
194 if (!inline_mode) {
195 printf (op->header_end);
196 printf (op->body_begin);
197 }
198 within_header=FALSE;
199 have_printed_body=TRUE;
200 }
201 }
202
203
204 /*-------------------------------------------------------------------*/
205 /*-------------------------------------------------------------------*/
206 /*-------------------------------------------------------------------*/
207
208
209 static char *month_strings[12]= {
210 #ifdef ENGLISH
211 "January","February","March","April","May","June","July","August",
212 "September","October","November","December"
213 #endif
214 #ifdef FRANCAIS
215 "Janvier","Fevrier","Mars","Avril","Mai","Juin","Juillet","Aout","Septembre",
216 "Octobre","Novembre","Decembre"
217 #endif
218 #ifdef ITALIANO
219 "Ianuario","Febbraio","Marzo","Aprile","Maggio","Iuno",
220 "Luglio","Agusto","Settembre","Ottobre","Novembre","Dicembre"
221 #endif
222 #ifdef ESPANOL /* amaral - 0.19.2 */
223 "Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto",
224 "Septiembre","Octubre","Noviembre","Diciembre"
225 #endif
226 #ifdef DEUTCH
227 "?","?","?","?","?","?","?","?",
228 "?","?","?","?"
229 #endif
230 #ifdef PORTUGUES /* amaral - 0.19.2 */
231 "Janeiro","Fevereiro","Marco","Abril","Maio","Junho","Julho","Agosto",
232 "Setembro","Outubro","Novembro","Dezembro"
233 #endif
234 };
235
236
237 /*========================================================================
238 * Name: word_dump_date
239 * Purpose: Extracts date from an RTF input stream, writes it to
240 * output stream.
241 * Args: Word*, buffered RTF stream
242 * Returns: None.
243 *=======================================================================*/
244
245 void
246 word_dump_date (Word *w)
247 {
248 int year=0, month=0, day=0, hour=0, minute=0;
249 CHECK_PARAM_NOT_NULL(w);
250 while (w) {
251 char *s = word_string (w);
252 if (*s == '\\') {
253 ++s;
254 if (!strncmp (s, "yr", 2) && isdigit(s[2])) {
255 year = atoi (&s[2]);
256 }
257 else if (!strncmp (s, "mo", 2) && isdigit(s[2])) {
258 month= atoi (&s[2]);
259 }
260 else if (!strncmp (s, "dy", 2) && isdigit(s[2])) {
261 day= atoi (&s[2]);
262 }
263 else if (!strncmp (s, "min", 3) && isdigit(s[3])) {
264 minute= atoi (&s[3]);
265 }
266 else if (!strncmp (s, "hr", 2) && isdigit(s[2])) {
267 hour= atoi (&s[2]);
268 }
269 }
270 w=w->next;
271 }
272 if (year && month && day) {
273 printf ("%d %s %d ", day, month_strings[month-1], year);
274 }
275 if (hour && minute) {
276 printf ("%02d:%02d ", hour, minute);
277 }
278 }
279
280
281
282 /*-------------------------------------------------------------------*/
283
284 typedef struct {
285 int num;
286 char *name;
287 } FontEntry;
288
289 #define MAX_FONTS (256)
290 static FontEntry font_table[MAX_FONTS];
291 static int total_fonts=0;
292
293
294
295 /*========================================================================
296 * Name: lookup_fontname
297 * Purpose: Fetches the name of a font from the already-read font table.
298 * Args: Font#.
299 * Returns: Font name.
300 *=======================================================================*/
301
302 char*
303 lookup_fontname (int num) {
304 int i;
305 if (total_fonts)
306 for(i=0;i<total_fonts;i++) {
307 if (font_table[i].num==num)
308 return font_table[i].name;
309 }
310 return NULL;
311 }
312
313
314 /*========================================================================
315 * Name: process_font_table
316 * Purpose: Processes the font table of an RTF file.
317 * Args: Tree of words.
318 * Returns: None.
319 *=======================================================================*/
320
321 void
322 process_font_table (Word *w)
323 {
324 Word *w2;
325
326 CHECK_PARAM_NOT_NULL(w);
327
328 while(w) {
329 int num;
330 char name[255];
331 char *tmp;
332
333 if ((w2=w->child)) {
334 tmp = word_string (w2);
335 if (!strncmp("\\f",tmp,2)) {
336 num = atoi (&tmp[2]);
337 name[0]=0;
338
339 w2=w2->next;
340 while(w2) {
341 tmp = word_string (w2);
342 if (tmp && tmp[0] != '\\')
343 strcat(name,tmp);
344
345 w2=w2->next;
346 }
347
348 /* Chop the gall-derned semicolon. */
349 if ((tmp=strchr(name,';')))
350 *tmp=0;
351
352 font_table[total_fonts].num=num;
353 font_table[total_fonts].name=my_strdup(name);
354 total_fonts++;
355 }
356 }
357 w=w->next;
358 }
359
360 printf (op->comment_begin);
361 printf ("font table contains %d fonts total",total_fonts);
362 printf (op->comment_end);
363
364 if (debug_mode) {
365 int i;
366
367 printf (op->comment_begin);
368 printf ("font table dump: \n");
369 for (i=0; i<total_fonts; i++) {
370 printf (" font %d = %s\n", font_table[i].num,
371 font_table[i].name);
372 }
373 printf (op->comment_end);
374 }
375 }
376
377
378 /*========================================================================
379 * Name: process_index_entry
380 * Purpose: Processes an index entry of an RTF file.
381 * Args: Tree of words.
382 * Returns: None.
383 *=======================================================================*/
384
385 void
386 process_index_entry (Word *w)
387 {
388 Word *w2;
389
390 CHECK_PARAM_NOT_NULL(w);
391
392 while(w) {
393 if ((w2=w->child)) {
394 char *str = word_string (w2);
395
396 if (debug_mode && str) {
397 printf (op->comment_begin);
398 printf ("index entry word: %s ", str);
399 printf (op->comment_end);
400 }
401 }
402 w=w->next;
403 }
404 }
405
406
407 /*========================================================================
408 * Name: process_toc_entry
409 * Purpose: Processes an index entry of an RTF file.
410 * Args: Tree of words, flag to say whether to include a page#.
411 * Returns: None.
412 *=======================================================================*/
413
414 void
415 process_toc_entry (Word *w, int include_page_num)
416 {
417 Word *w2;
418
419 CHECK_PARAM_NOT_NULL(w);
420
421 while(w) {
422 if ((w2=w->child)) {
423 char *str = word_string (w2);
424
425 if (debug_mode && str) {
426 printf (op->comment_begin);
427 printf ("toc %s entry word: %s ",
428 include_page_num ? "page#":"no page#",
429 str);
430 printf (op->comment_end);
431 }
432 }
433 w=w->next;
434 }
435 }
436
437
438 /*========================================================================
439 * Name: process_info_group
440 * Purpose: Processes the \info group of an RTF file.
441 * Args: Tree of words.
442 * Returns: None.
443 *=======================================================================*/
444
445 void
446 process_info_group (Word *w)
447 {
448 Word *child;
449
450 #if 1 /* amaral - 0.19.2 */
451 /* CHECK_PARAM_NOT_NULL(w); */
452 if (!w) printf ("AUTHOR'S COMMENT: \\info command is null!\n");
453 #endif
454
455
456 while(w) {
457 child = w->child;
458 if (child) {
459 Word *w2;
460 char *s;
461
462 s = word_string(child);
463
464 if (!inline_mode) {
465 if (!strcmp("\\title", s)) {
466 printf (op->document_title_begin);
467 w2=child->next;
468 while (w2) {
469 char *s2 = word_string(w2);
470 if (s2[0] != '\\')
471 printf ("%s", s2);
472 w2=w2->next;
473 }
474 printf (op->document_title_end);
475 }
476 else if (!strcmp("\\keywords", s)) {
477 printf (op->document_keywords_begin);
478 w2=child->next;
479 while (w2) {
480 char *s2 = word_string(w2);
481 if (s2[0] != '\\')
482 printf ("%s,", s2);
483 w2=w2->next;
484 }
485 printf (op->document_keywords_end);
486 }
487 else if (!strcmp("\\author", s)) {
488 printf (op->document_author_begin);
489 w2=child->next;
490 while (w2) {
491 char *s2 = word_string(w2);
492 if (s2[0] != '\\')
493 printf ("%s", s2);
494 w2=w2->next;
495 }
496 printf (op->document_author_end);
497 }
498 else if (!strcmp("\\comment", s)) {
499 printf (op->comment_begin);
500 printf ("comments: ");
501 w2=child->next;
502 while (w2) {
503 char *s2 = word_string(w2);
504 if (s2[0] != '\\')
505 printf ("%s", s2);
506 w2=w2->next;
507 }
508 printf (op->comment_end);
509 }
510 else if (!strncmp("\\nofpages", s, 9)) {
511 printf (op->comment_begin);
512 printf ("total pages: %s",&s[9]);
513 printf (op->comment_end);
514 }
515 else if (!strncmp("\\nofwords", s, 9)) {
516 printf (op->comment_begin);
517 printf ("total words: %s",&s[9]);
518 printf (op->comment_end);
519 }
520 else if (!strncmp("\\nofchars", s, 9) && isdigit(s[9])) {
521 printf (op->comment_begin);
522 printf ("total chars: %s",&s[9]);
523 printf (op->comment_end);
524 }
525 else if (!strcmp("\\creatim", s)) {
526 printf (op->comment_begin);
527 printf ("creaton date: ");
528 if (child->next) word_dump_date (child->next);
529 printf (op->comment_end);
530 }
531 else if (!strcmp("\\printim", s)) {
532 printf (op->comment_begin);
533 printf ("last printed: ");
534 if (child->next) word_dump_date (child->next);
535 printf (op->comment_end);
536 }
537 else if (!strcmp("\\buptim", s)) {
538 printf (op->comment_begin);
539 printf ("last backup: ");
540 if (child->next) word_dump_date (child->next);
541 printf (op->comment_end);
542 }
543 else if (!strcmp("\\revtim", s)) {
544 printf (op->comment_begin);
545 printf ("revision date: ");
546 if (child->next) word_dump_date (child->next);
547 printf (op->comment_end);
548 }
549 }
550
551 /* Irregardless of whether we're in inline mode,
552 * we want to process the following.
553 */
554 if (!strcmp("\\hlinkbase", s)) {
555 char *linkstr = NULL;
556
557 printf (op->comment_begin);
558 printf ("hyperlink base: ");
559 if (child->next) {
560 Word *nextword = child->next;
561
562 if (nextword)
563 linkstr=word_string (nextword);
564 }
565
566 if (linkstr)
567 printf ("%s", linkstr);
568 else
569 printf ("(none)");
570 printf (op->comment_end);
571
572 /* Store the pointer, it will remain good. */
573 hyperlink_base = linkstr;
574 }
575 }
576 w = w->next;
577 }
578 }
579
580 /*-------------------------------------------------------------------*/
581
582 /* RTF color table colors are RGB */
583
584 typedef struct {
585 unsigned char r,g,b;
586 } Color;
587
588 #define MAX_COLORS (256)
589 static Color color_table[MAX_COLORS];
590 static int total_colors=0;
591
592
593 /*========================================================================
594 * Name: process_color_table
595 * Purpose: Processes the color table of an RTF file.
596 * Args: Tree of words.
597 * Returns: None.
598 *=======================================================================*/
599
600 void
601 process_color_table (Word *w)
602 {
603 int r,g,b;
604
605 CHECK_PARAM_NOT_NULL(w);
606
607 /* Sometimes, RTF color tables begin with a semicolon,
608 * i.e. an empty color entry. This seems to indicate that color 0
609 * will not be used, so here I set it to black.
610 */
611 r=g=b=0;
612
613 while(w) {
614 char *s = word_string (w);
615
616 #if 0
617 printf (op->comment_begin);
618 printf ("found this color table word: %s", word_string(w));
619 printf (op->comment_end);
620 #endif
621
622 if(!strncmp("\\red",s,4)) {
623 r = atoi(&s[4]);
624 while(r>255) r>>=8;
625 }
626 else if(!strncmp("\\green",s,6)) {
627 g = atoi(&s[6]);
628 while(g>255) g>>=8;
629 }
630 else if(!strncmp("\\blue",s,5)) {
631 b = atoi(&s[5]);
632 while(b>255) b>>=8;
633 }
634 else
635 /* If we find the semicolon which denotes the end of
636 * a color entry then store the color, even if we don't
637 * have all of it.
638 */
639 if (!strcmp (";", s)) {
640 color_table[total_colors].r = r;
641 color_table[total_colors].g = g;
642 color_table[total_colors++].b = b;
643 if (debug_mode) {
644 printf (op->comment_begin);
645 printf ("storing color entry %d: %02x%02x%02x",
646 total_colors-1, r,g,b);
647 printf (op->comment_end);
648 }
649 r=g=b=0;
650 }
651
652 w=w->next;
653 }
654
655 if (debug_mode) {
656 printf (op->comment_begin);
657 printf ("color table had %d entries -->\n", total_colors);
658 printf (op->comment_end);
659 }
660 }
661
662 /*========================================================================
663 * Name: cmd_cf
664 * Purpose: Executes the \cf command.
665 * Args: Word, paragraph align info, and numeric param if any.
666 * Returns: Flag, true only if rest of Words on line should be ignored.
667 *=======================================================================*/
668
669 static int
670 cmd_cf (Word *w, int align, char has_param, short num) {
671 char str[40];
672
673 if (!has_param || num>=total_colors) {
674 warning_handler ("font color change attempted is invalid");
675 }
676 else
677 {
678 sprintf (str,"#%02x%02x%02x",
679 color_table[num].r,
680 color_table[num].g,
681 color_table[num].b);
682 attr_push(ATTR_FOREGROUND,str);
683 }
684 return FALSE;
685 }
686
687
688
689 /*========================================================================
690 * Name: cmd_cb
691 * Purpose: Executes the \cb command.
692 * Args: Word, paragraph align info, and numeric param if any.
693 * Returns: Flag, true only if rest of Words on line should be ignored.
694 *=======================================================================*/
695
696 static int
697 cmd_cb (Word *w, int align, char has_param, short num) {
698 char str[40];
699
700 if (!has_param || num>=total_colors) {
701 warning_handler ("font color change attempted is invalid");
702 }
703 else
704 {
705 sprintf (str,"#%02x%02x%02x",
706 color_table[num].r,
707 color_table[num].g,
708 color_table[num].b);
709 attr_push(ATTR_BACKGROUND,str);
710 }
711 return FALSE;
712 }
713
714
715 /*========================================================================
716 * Name: cmd_fs
717 * Purpose: Executes the \fs command.
718 * Args: Word, paragraph align info, and numeric param if any.
719 * Returns: Flag, true only if rest of Words on line should be ignored.
720 *=======================================================================*/
721 static int
722 cmd_fs (Word *w, int align, char has_param, short points) {
723 char str[20];
724
725 if (!has_param) return FALSE;
726
727 /* Note, fs20 means 10pt */
728 points /= 2;
729
730 sprintf (str,"%d",points);
731 attr_push(ATTR_FONTSIZE,str);
732
733 return FALSE;
734 }
735
736
737 /*========================================================================
738 * Name: cmd_field
739 * Purpose: Interprets fields looking for hyperlinks.
740 * Comment: Because hyperlinks are put in \field groups,
741 * we must interpret all \field groups, which is
742 * slow and laborious.
743 * Returns: Flag, true only if rest of Words on line should be ignored.
744 *=======================================================================*/
745
746 static int
747 cmd_field (Word *w, int align, char has_param, short num) {
748 Word *child;
749
750 CHECK_PARAM_NOT_NULL(w);
751
752 while(w) {
753 child = w->child;
754 if (child) {
755 Word *w2;
756 char *s;
757
758 s = word_string(child);
759
760 if (!strcmp("\\*", s)) {
761 w2=child->next;
762 while (w2) {
763 char *s2 = word_string(w2);
764 if (s2 && !strcmp("\\fldinst", s2)) {
765 Word *w3;
766 w3=w2->next;
767 #if 1 /* daved - 0.19.0 */
768 {
769 char *s;
770 char *s4;
771 Word *w4;
772 s = word_string(w3);
773 if(s && !strcmp(s, "SYMBOL") )
774 {
775 w4=w3->next;
776 while(w4 && !strcmp(word_string(w4), " "))
777 w4 = w4->next;
778 s4 = word_string(w4);
779 if(s4)
780 printf("%s", entity(atoi(s4)));
781 }
782 }
783 #endif
784 while (w3 && !w3->child) {
785 w3=w3->next;
786 }
787 if (w3) w3=w3->child;
788 while (w3) {
789 char *s3=word_string(w3);
790 if (s3 && !strcmp("HYPERLINK",s3)) {
791 Word *w4;
792 char *s4;
793 w4=w3->next;
794 while (w4 && !strcmp(" ", word_string(w4)))
795 w4=w4->next;
796 if (w4) {
797 s4=word_string(w4);
798 printf (op->hyperlink_begin);
799 printf ("%s", s4);
800 printf (op->hyperlink_end);
801 return TRUE;
802 }
803
804 }
805 w3=w3->next;
806 }
807 }
808 w2=w2->next;
809 }
810
811 }
812 }
813 w=w->next;
814 }
815 return TRUE;
816 }
817
818
819
820 /*========================================================================
821 * Name: cmd_f
822 * Purpose: Executes the \f command.
823 * Args: Word, paragraph align info, and numeric param if any.
824 * Returns: Flag, true only if rest of Words on line should be ignored.
825 *=======================================================================*/
826 static int
827 cmd_f (Word *w, int align, char has_param, short num) {
828 char *name;
829
830 /* no param exit early XX */
831 if (!has_param)
832 return FALSE;
833
834 name = lookup_fontname(num);
835 if(!name) {
836 printf (op->comment_begin);
837 printf ("invalid font number %d",num);
838 printf (op->comment_end);
839 } else {
840 attr_push(ATTR_FONTFACE,name);
841 }
842
843 return FALSE;
844 }
845
846
847 /*========================================================================
848 * Name: cmd_highlight
849 * Purpose: Executes the \cf command.
850 * Args: Word, paragraph align info, and numeric param if any.
851 * Returns: Flag, true only if rest of Words on line should be ignored.
852 *=======================================================================*/
853
854 static int
855 cmd_highlight (Word *w, int align, char has_param, short num)
856 {
857 char str[40];
858
859 if (!has_param || num>=total_colors) {
860 warning_handler ("font background color change attempted is invalid");
861 }
862 else
863 {
864 sprintf (str,"#%02x%02x%02x",
865 color_table[num].r,
866 color_table[num].g,
867 color_table[num].b);
868 attr_push(ATTR_BACKGROUND,str);
869 }
870 return FALSE;
871 }
872
873
874
875 /*========================================================================
876 * Name: cmd_tab
877 * Purpose: Executes the \tab command.
878 * Args: Word, paragraph align info, and numeric param if any.
879 * Returns: Flag, true only if rest of Words on line should be ignored.
880 *=======================================================================*/
881
882 static int
883 cmd_tab (Word *w, int align, char has_param, short param)
884 {
885 /* Tab presents a genuine problem
886 * since some output formats don't have
887 * an equivalent. As a kludge fix, I shall
888 * assume the font is fixed width and that
889 * the tabstops are 8 characters apart.
890 */
891 int need= 8-(total_chars_this_line%8);
892 total_chars_this_line += need;
893 while(need>0) {
894 printf (op->forced_space);
895 need--;
896 }
897 printf ("\n");
898 return FALSE;
899 }
900
901
902 /*========================================================================
903 * Name: cmd_plain
904 * Purpose: Executes the \plain command.
905 * Args: Word, paragraph align info, and numeric param if any.
906 * Returns: Flag, true only if rest of Words on line should be ignored.
907 *=======================================================================*/
908
909 static int
910 cmd_plain (Word *w, int align, char has_param, short param) {
911 attr_pop_all();
912 return FALSE;
913 }
914
915
916 /*========================================================================
917 * Name: cmd_fnil
918 * Purpose: Executes the \fnil command.
919 * Args: Word, paragraph align info, and numeric param if any.
920 * Returns: Flag, true only if rest of Words on line should be ignored.
921 *=======================================================================*/
922 static int
923 cmd_fnil (Word *w, int align, char has_param, short param) {
924 attr_push(ATTR_FONTFACE,FONTNIL_STR);
925 return FALSE;
926 }
927
928
929
930 /*========================================================================
931 * Name: cmd_froman
932 * Purpose: Executes the \froman command.
933 * Args: Word, paragraph align info, and numeric param if any.
934 * Returns: Flag, true only if rest of Words on line should be ignored.
935 *=======================================================================*/
936 static int
937 cmd_froman (Word *w, int align, char has_param, short param) {
938 attr_push(ATTR_FONTFACE,FONTROMAN_STR);
939 return FALSE;
940 }
941
942
943 /*========================================================================
944 * Name: cmd_fswiss
945 * Purpose: Executes the \fswiss command.
946 * Args: Word, paragraph align info, and numeric param if any.
947 * Returns: Flag, true only if rest of Words on line should be ignored.
948 *=======================================================================*/
949
950 static int
951 cmd_fswiss (Word *w, int align, char has_param, short param) {
952 attr_push(ATTR_FONTFACE,FONTSWISS_STR);
953 return FALSE;
954 }
955
956
957 /*========================================================================
958 * Name: cmd_fmodern
959 * Purpose: Executes the \fmodern command.
960 * Args: Word, paragraph align info, and numeric param if any.
961 * Returns: Flag, true only if rest of Words on line should be ignored.
962 *=======================================================================*/
963
964 static int
965 cmd_fmodern (Word *w, int align, char has_param, short param) {
966 attr_push(ATTR_FONTFACE,FONTMODERN_STR);
967 return FALSE;
968 }
969
970
971 /*========================================================================
972 * Name: cmd_fscript
973 * Purpose: Executes the \fscript command.
974 * Args: Word, paragraph align info, and numeric param if any.
975 * Returns: Flag, true only if rest of Words on line should be ignored.
976 *=======================================================================*/
977
978 static int
979 cmd_fscript (Word *w, int align, char has_param, short param) {
980 attr_push(ATTR_FONTFACE,FONTSCRIPT_STR);
981 return FALSE;
982 }
983
984 /*========================================================================
985 * Name: cmd_fdecor
986 * Purpose: Executes the \fdecor command.
987 * Args: Word, paragraph align info, and numeric param if any.
988 * Returns: Flag, true only if rest of Words on line should be ignored.
989 *=======================================================================*/
990
991 static int
992 cmd_fdecor (Word *w, int align, char has_param, short param) {
993 attr_push(ATTR_FONTFACE,FONTDECOR_STR);
994 return FALSE;
995 }
996
997 /*========================================================================
998 * Name: cmd_ftech
999 * Purpose: Executes the \ftech command.
1000 * Args: Word, paragraph align info, and numeric param if any.
1001 * Returns: Flag, true only if rest of Words on line should be ignored.
1002 *=======================================================================*/
1003
1004 static int
1005 cmd_ftech (Word *w, int align, char has_param, short param) {
1006 attr_push(ATTR_FONTFACE,FONTTECH_STR);
1007 return FALSE;
1008 }
1009
1010 /*========================================================================
1011 * Name: cmd_expand
1012 * Purpose: Executes the \expand command.
1013 * Args: Word, paragraph align info, and numeric param if any.
1014 * Returns: Flag, true only if rest of Words on line should be ignored.
1015 *=======================================================================*/
1016
1017 static int
1018 cmd_expand (Word *w, int align, char has_param, short param) {
1019 char str[10];
1020 if (has_param) {
1021 sprintf (str, "%d", param/4);
1022 if (!param)
1023 attr_pop(ATTR_EXPAND);
1024 else
1025 attr_push(ATTR_EXPAND, str);
1026 }
1027 return FALSE;
1028 }
1029
1030
1031 /*========================================================================
1032 * Name: cmd_emboss
1033 * Purpose: Executes the \embo command.
1034 * Args: Word, paragraph align info, and numeric param if any.
1035 * Returns: Flag, true only if rest of Words on line should be ignored.
1036 *=======================================================================*/
1037
1038 static int
1039 cmd_emboss (Word *w, int align, char has_param, short param) {
1040 char str[10];
1041 if (has_param && !param)
1042 attr_pop(ATTR_EMBOSS);
1043 else
1044 {
1045 sprintf (str, "%d", param);
1046 attr_push(ATTR_EMBOSS, str);
1047 }
1048 return FALSE;
1049 }
1050
1051
1052 /*========================================================================
1053 * Name: cmd_engrave
1054 * Purpose: Executes the \impr command.
1055 * Args: Word, paragraph align info, and numeric param if any.
1056 * Returns: Flag, true only if rest of Words on line should be ignored.
1057 *=======================================================================*/
1058
1059 static int
1060 cmd_engrave (Word *w, int align, char has_param, short param) {
1061 char str[10];
1062 if (has_param && !param)
1063 attr_pop(ATTR_ENGRAVE);
1064 else
1065 {
1066 sprintf (str, "%d", param);
1067 attr_push(ATTR_ENGRAVE, str);
1068 }
1069 return FALSE;
1070 }
1071
1072 /*========================================================================
1073 * Name: cmd_caps
1074 * Purpose: Executes the \caps command.
1075 * Args: Word, paragraph align info, and numeric param if any.
1076 * Returns: Flag, true only if rest of Words on line should be ignored.
1077 *=======================================================================*/
1078
1079 static int
1080 cmd_caps (Word *w, int align, char has_param, short param) {
1081 if (has_param && !param)
1082 attr_pop(ATTR_CAPS);
1083 else
1084 attr_push(ATTR_CAPS,NULL);
1085 return FALSE;
1086 }
1087
1088
1089 /*========================================================================
1090 * Name: cmd_scaps
1091 * Purpose: Executes the \scaps command.
1092 * Args: Word, paragraph align info, and numeric param if any.
1093 * Returns: Flag, true only if rest of Words on line should be ignored.
1094 *=======================================================================*/
1095 static int
1096 cmd_scaps (Word *w, int align, char has_param, short param) {
1097 if (has_param && !param)
1098 attr_pop(ATTR_SMALLCAPS);
1099 else
1100 attr_push(ATTR_SMALLCAPS,NULL);
1101 return FALSE;
1102 }
1103
1104
1105 /*========================================================================
1106 * Name: cmd_bullet
1107 * Purpose: Executes the \bullet command.
1108 * Args: Word, paragraph align info, and numeric param if any.
1109 * Returns: Flag, true only if rest of Words on line should be ignored.
1110 *=======================================================================*/
1111 static int
1112 cmd_bullet (Word *w, int align, char has_param, short param) {
1113 printf (op->chars.bullet);
1114 ++total_chars_this_line; /* \tab */
1115 return FALSE;
1116 }
1117
1118 /*========================================================================
1119 * Name: cmd_ldblquote
1120 * Purpose: Executes the \ldblquote command.
1121 * Args: Word, paragraph align info, and numeric param if any.
1122 * Returns: Flag, true only if rest of Words on line should be ignored.
1123 *=======================================================================*/
1124 static int
1125 cmd_ldblquote (Word *w, int align, char has_param, short param) {
1126 printf (op->chars.left_dbl_quote);
1127 ++total_chars_this_line; /* \tab */
1128 return FALSE;
1129 }
1130
1131
1132 /*========================================================================
1133 * Name: cmd_rdblquote
1134 * Purpose: Executes the \rdblquote command.
1135 * Args: Word, paragraph align info, and numeric param if any.
1136 * Returns: Flag, true only if rest of Words on line should be ignored.
1137 *=======================================================================*/
1138
1139 static int
1140 cmd_rdblquote (Word *w, int align, char has_param, short param) {
1141 printf (op->chars.right_dbl_quote);
1142 ++total_chars_this_line; /* \tab */
1143 return FALSE;
1144 }
1145
1146
1147 /*========================================================================
1148 * Name: cmd_lquote
1149 * Purpose: Executes the \lquote command.
1150 * Args: Word, paragraph align info, and numeric param if any.
1151 * Returns: Flag, true only if rest of Words on line should be ignored.
1152 *=======================================================================*/
1153 static int
1154 cmd_lquote (Word *w, int align, char has_param, short param) {
1155 printf (op->chars.left_quote);
1156 ++total_chars_this_line; /* \tab */
1157 return FALSE;
1158 }
1159
1160
1161 /*========================================================================
1162 * Name: cmd_nonbreaking_space
1163 * Purpose: Executes the nonbreaking space 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 static int
1169 cmd_nonbreaking_space (Word *w, int align, char has_param, short param) {
1170 printf (op->chars.nonbreaking_space);
1171 ++total_chars_this_line; /* \tab */
1172 return FALSE;
1173 }
1174
1175
1176 /*========================================================================
1177 * Name: cmd_nonbreaking_hyphen
1178 * Purpose: Executes the nonbreaking hyphen 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
1183 static int
1184 cmd_nonbreaking_hyphen (Word *w, int align, char has_param, short param) {
1185 printf (op->chars.nonbreaking_hyphen);
1186 ++total_chars_this_line; /* \tab */
1187 return FALSE;
1188 }
1189
1190
1191 /*========================================================================
1192 * Name: cmd_optional_hyphen
1193 * Purpose: Executes the optional hyphen command.
1194 * Args: Word, paragraph align info, and numeric param if any.
1195 * Returns: Flag, true only if rest of Words on line should be ignored.
1196 *=======================================================================*/
1197
1198 static int
1199 cmd_optional_hyphen (Word *w, int align, char has_param, short param) {
1200 printf (op->chars.optional_hyphen);
1201 ++total_chars_this_line; /* \tab */
1202 return FALSE;
1203 }
1204
1205
1206 /*========================================================================
1207 * Name: cmd_emdash
1208 * Purpose: Executes the \emdash command.
1209 * Args: Word, paragraph align info, and numeric param if any.
1210 * Returns: Flag, true only if rest of Words on line should be ignored.
1211 *=======================================================================*/
1212 static int
1213 cmd_emdash (Word *w, int align, char has_param, short param) {
1214 printf (op->chars.emdash);
1215 ++total_chars_this_line; /* \tab */
1216 return FALSE;
1217 }
1218
1219
1220 /*========================================================================
1221 * Name: cmd_endash
1222 * Purpose: Executes the \endash 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
1227 static int
1228 cmd_endash (Word *w, int align, char has_param, short param) {
1229 printf (op->chars.endash);
1230 ++total_chars_this_line; /* \tab */
1231 return FALSE;
1232 }
1233
1234
1235 /*========================================================================
1236 * Name: cmd_rquote
1237 * Purpose: Executes the \rquote command.
1238 * Args: Word, paragraph align info, and numeric param if any.
1239 * Returns: Flag, true only if rest of Words on line should be ignored.
1240 *=======================================================================*/
1241
1242 static int
1243 cmd_rquote (Word *w, int align, char has_param, short param) {
1244 printf (op->chars.right_quote);
1245 ++total_chars_this_line; /* \tab */
1246 return FALSE;
1247 }
1248
1249
1250 /*========================================================================
1251 * Name: cmd_par
1252 * Purpose: Executes the \par command.
1253 * Args: Word, paragraph align info, and numeric param if any.
1254 * Returns: Flag, true only if rest of Words on line should be ignored.
1255 *=======================================================================*/
1256 static int
1257 cmd_par (Word *w, int align, char has_param, short param) {
1258 printf (op->line_break);
1259 total_chars_this_line = 0; /* \tab */
1260 return FALSE;
1261 }
1262
1263
1264 /*========================================================================
1265 * Name: cmd_line
1266 * Purpose: Executes the \line command.
1267 * Args: Word, paragraph align info, and numeric param if any.
1268 * Returns: Flag, true only if rest of Words on line should be ignored.
1269 *=======================================================================*/
1270
1271 static int
1272 cmd_line (Word *w, int align, char has_param, short param) {
1273 printf (op->line_break);
1274 total_chars_this_line = 0; /* \tab */
1275 return FALSE;
1276 }
1277
1278
1279 /*========================================================================
1280 * Name: cmd_page
1281 * Purpose: Executes the \page command.
1282 * Args: Word, paragraph align info, and numeric param if any.
1283 * Returns: Flag, true only if rest of Words on line should be ignored.
1284 *=======================================================================*/
1285
1286 static int cmd_page (Word *w, int align, char has_param, short param) {
1287 printf (op->page_break);
1288 total_chars_this_line = 0; /* \tab */
1289 return FALSE;
1290 }
1291
1292
1293 /*========================================================================
1294 * Name: cmd_intbl
1295 * Purpose: Executes the \intbl command.
1296 * Args: Word, paragraph align info, and numeric param if any.
1297 * Returns: Flag, true only if rest of Words on line should be ignored.
1298 *=======================================================================*/
1299
1300 static int cmd_intbl (Word *w, int align, char has_param, short param) {
1301 ++coming_pars_that_are_tabular;
1302 return FALSE;
1303 }
1304
1305
1306 /*========================================================================
1307 * Name: cmd_ulnone
1308 * Purpose: Executes the \ulnone command.
1309 * Args: Word, paragraph align info, and numeric param if any.
1310 * Returns: Flag, true only if rest of Words on line should be ignored.
1311 *=======================================================================*/
1312
1313 static int cmd_ulnone (Word *w, int align, char has_param, short param) {
1314 int attr, more=TRUE;
1315 #ifdef BINARY_ATTRS
1316 attr_remove_underlining();
1317 #else
1318 do {
1319 attr = attr_read();
1320 if (attr==ATTR_UNDERLINE ||
1321 attr==ATTR_DOT_UL ||
1322 attr==ATTR_DASH_UL ||
1323 attr==ATTR_DOT_DASH_UL ||
1324 attr==ATTR_2DOT_DASH_UL ||
1325 attr==ATTR_WORD_UL ||
1326 attr==ATTR_WAVE_UL ||
1327 attr==ATTR_THICK_UL ||
1328 attr==ATTR_DOUBLE_UL)
1329 {
1330 if (!attr_pop(ATTR_UNDERLINE))
1331 ;
1332 } else
1333 more=FALSE;
1334 } while(more);
1335 #endif
1336 return FALSE;
1337 }
1338
1339 /*========================================================================
1340 * Name: cmd_ul
1341 * Purpose: Executes the \ul command.
1342 * Args: Word, paragraph align info, and numeric param if any.
1343 * Returns: Flag, true only if rest of Words on line should be ignored.
1344 *=======================================================================*/
1345
1346 static int cmd_ul (Word *w, int align, char has_param, short param) {
1347 if (has_param && param == 0) {
1348 cmd_ulnone (w, align, has_param, param);
1349 } else {
1350 attr_push (ATTR_UNDERLINE,NULL);
1351 }
1352 return FALSE;
1353 }
1354
1355 /*========================================================================
1356 * Name: cmd_uld
1357 * Purpose: Executes the \uld command.
1358 * Args: Word, paragraph align info, and numeric param if any.
1359 * Returns: Flag, true only if rest of Words on line should be ignored.
1360 *=======================================================================*/
1361
1362 static int cmd_uld (Word *w, int align, char has_param, short param) {
1363 attr_push(ATTR_DOUBLE_UL,NULL);
1364 return FALSE;
1365 }
1366
1367 /*========================================================================
1368 * Name: cmd_uldb
1369 * Purpose: Executes the \uldb command.
1370 * Args: Word, paragraph align info, and numeric param if any.
1371 * Returns: Flag, true only if rest of Words on line should be ignored.
1372 *=======================================================================*/
1373
1374 static int cmd_uldb (Word *w, int align, char has_param, short param) {
1375 attr_push(ATTR_DOT_UL,NULL);
1376 return FALSE;
1377 }
1378
1379
1380 /*========================================================================
1381 * Name: cmd_uldash
1382 * Purpose: Executes the \uldash command.
1383 * Args: Word, paragraph align info, and numeric param if any.
1384 * Returns: Flag, true only if rest of Words on line should be ignored.
1385 *=======================================================================*/
1386
1387 static int cmd_uldash (Word *w, int align, char has_param, short param) {
1388 attr_push(ATTR_DASH_UL,NULL);
1389 return FALSE;
1390 }
1391
1392
1393 /*========================================================================
1394 * Name: cmd_uldashd
1395 * Purpose: Executes the \cmd_uldashd command.
1396 * Args: Word, paragraph align info, and numeric param if any.
1397 * Returns: Flag, true only if rest of Words on line should be ignored.
1398 *=======================================================================*/
1399
1400 static int cmd_uldashd (Word *w, int align, char has_param, short param) {
1401 attr_push(ATTR_DOT_DASH_UL,NULL);
1402 return FALSE;
1403 }
1404
1405
1406 /*========================================================================
1407 * Name: cmd_uldashdd
1408 * Purpose: Executes the \uldashdd command.
1409 * Args: Word, paragraph align info, and numeric param if any.
1410 * Returns: Flag, true only if rest of Words on line should be ignored.
1411 *=======================================================================*/
1412
1413 static int cmd_uldashdd (Word *w, int align, char has_param, short param) {
1414 attr_push(ATTR_2DOT_DASH_UL,NULL);
1415 return FALSE;
1416 }
1417
1418
1419 /*========================================================================
1420 * Name: cmd_ulw
1421 * Purpose: Executes the \ulw command.
1422 * Args: Word, paragraph align info, and numeric param if any.
1423 * Returns: Flag, true only if rest of Words on line should be ignored.
1424 *=======================================================================*/
1425
1426 static int cmd_ulw (Word *w, int align, char has_param, short param) {
1427 attr_push(ATTR_WORD_UL,NULL);
1428 return FALSE;
1429 }
1430
1431
1432 /*========================================================================
1433 * Name: cmd_ulth
1434 * Purpose: Executes the \ulth command.
1435 * Args: Word, paragraph align info, and numeric param if any.
1436 * Returns: Flag, true only if rest of Words on line should be ignored.
1437 *=======================================================================*/
1438
1439 static int cmd_ulth (Word *w, int align, char has_param, short param) {
1440 attr_push(ATTR_THICK_UL,NULL);
1441 return FALSE;
1442 }
1443
1444
1445 /*========================================================================
1446 * Name: cmd_ulwave
1447 * Purpose: Executes the \ulwave command.
1448 * Args: Word, paragraph align info, and numeric param if any.
1449 * Returns: Flag, true only if rest of Words on line should be ignored.
1450 *=======================================================================*/
1451
1452 static int cmd_ulwave (Word *w, int align, char has_param, short param) {
1453 attr_push(ATTR_WAVE_UL,NULL);
1454 return FALSE;
1455 }
1456
1457
1458 /*========================================================================
1459 * Name: cmd_strike
1460 * Purpose: Executes the \strike command.
1461 * Args: Word, paragraph align info, and numeric param if any.
1462 * Returns: Flag, true only if rest of Words on line should be ignored.
1463 *=======================================================================*/
1464
1465 static int cmd_strike (Word *w, int align, char has_param, short param) {
1466 if (has_param && param==0)
1467 attr_pop(ATTR_STRIKE);
1468 else
1469 attr_push(ATTR_STRIKE,NULL);
1470 return FALSE;
1471 }
1472
1473 /*========================================================================
1474 * Name: cmd_strikedl
1475 * Purpose: Executes the \strikedl command.
1476 * Args: Word, paragraph align info, and numeric param if any.
1477 * Returns: Flag, true only if rest of Words on line should be ignored.
1478 *=======================================================================*/
1479
1480 static int cmd_strikedl (Word *w, int align, char has_param, short param) {
1481 if (has_param && param==0)
1482 attr_pop(ATTR_DBL_STRIKE);
1483 else
1484 attr_push(ATTR_DBL_STRIKE,NULL);
1485 return FALSE;
1486 }
1487
1488
1489 /*========================================================================
1490 * Name: cmd_striked
1491 * Purpose: Executes the \striked command.
1492 * Args: Word, paragraph align info, and numeric param if any.
1493 * Returns: Flag, true only if rest of Words on line should be ignored.
1494 *=======================================================================*/
1495
1496 static int cmd_striked (Word *w, int align, char has_param, short param) {
1497 if (has_param && param==0)
1498 attr_pop(ATTR_DBL_STRIKE);
1499 else
1500 attr_push(ATTR_DBL_STRIKE,NULL);
1501 return FALSE;
1502 }
1503
1504
1505 /*========================================================================
1506 * Name: cmd_rtf
1507 * Purpose: Executes the \rtf command.
1508 * Args: Word, paragraph align info, and numeric param if any.
1509 * Returns: Flag, true only if rest of Words on line should be ignored.
1510 *=======================================================================*/
1511
1512 static int cmd_rtf (Word *w, int align, char has_param, short param) {
1513 return FALSE;
1514 }
1515
1516
1517 /*========================================================================
1518 * Name: cmd_up
1519 * Purpose: Executes the \up command.
1520 * Args: Word, paragraph align info, and numeric param if any.
1521 * Returns: Flag, true only if rest of Words on line should be ignored.
1522 *=======================================================================*/
1523
1524 static int cmd_up (Word *w, int align, char has_param, short param) {
1525 if (has_param && param==0)
1526 attr_pop(ATTR_SUPER);
1527 else
1528 attr_push(ATTR_SUPER,NULL);
1529 return FALSE;
1530 }
1531
1532
1533 /*========================================================================
1534 * Name: cmd_dn
1535 * Purpose: Executes the \dn command.
1536 * Args: Word, paragraph align info, and numeric param if any.
1537 * Returns: Flag, true only if rest of Words on line should be ignored.
1538 *=======================================================================*/
1539
1540 static int cmd_dn (Word *w, int align, char has_param, short param) {
1541 if (has_param && param==0)
1542 attr_pop(ATTR_SUB);
1543 else
1544 attr_push(ATTR_SUB,NULL);
1545 return FALSE;
1546 }
1547
1548 /*========================================================================
1549 * Name: cmd_nosupersub
1550 * Purpose: Executes the \nosupersub command.
1551 * Args: Word, paragraph align info, and numeric param if any.
1552 * Returns: Flag, true only if rest of Words on line should be ignored.
1553 *=======================================================================*/
1554
1555 static int cmd_nosupersub (Word *w, int align, char has_param, short param) {
1556 attr_pop(ATTR_SUPER);
1557 attr_pop(ATTR_SUB);
1558 return FALSE;
1559 }
1560
1561 /*========================================================================
1562 * Name: cmd_super
1563 * Purpose: Executes the \super 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 static int cmd_super (Word *w, int align, char has_param, short param) {
1569 if (has_param && param==0)
1570 attr_pop(ATTR_SUPER);
1571 else
1572 attr_push(ATTR_SUPER,NULL);
1573 return FALSE;
1574 }
1575
1576 /*========================================================================
1577 * Name: cmd_sub
1578 * Purpose: Executes the \sub 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 static int cmd_sub (Word *w, int align, char has_param, short param) {
1584 if (has_param && param==0)
1585 attr_pop(ATTR_SUB);
1586 else
1587 attr_push(ATTR_SUB,NULL);
1588 return FALSE;
1589 }
1590
1591 /*========================================================================
1592 * Name: cmd_shad
1593 * Purpose: Executes the \shad command.
1594 * Args: Word, paragraph align info, and numeric param if any.
1595 * Returns: Flag, true only if rest of Words on line should be ignored.
1596 *=======================================================================*/
1597
1598 static int cmd_shad (Word *w, int align, char has_param, short param) {
1599 if (has_param && param==0)
1600 attr_pop(ATTR_SHADOW);
1601 else
1602 attr_push(ATTR_SHADOW,NULL);
1603 return FALSE;
1604 }
1605
1606 /*========================================================================
1607 * Name: cmd_b
1608 * Purpose: Executes the \b command.
1609 * Args: Word, paragraph align info, and numeric param if any.
1610 * Returns: Flag, true only if rest of Words on line should be ignored.
1611 *=======================================================================*/
1612
1613 static int
1614 cmd_b (Word *w, int align, char has_param, short param) {
1615 if (has_param && param==0) {
1616 attr_pop(ATTR_BOLD);
1617 }
1618 else
1619 attr_push(ATTR_BOLD,NULL);
1620 return FALSE;
1621 }
1622
1623 /*========================================================================
1624 * Name: cmd_i
1625 * Purpose: Executes the \i command.
1626 * Args: Word, paragraph align info, and numeric param if any.
1627 * Returns: Flag, true only if rest of Words on line should be ignored.
1628 *=======================================================================*/
1629
1630 static int cmd_i (Word *w, int align, char has_param, short param) {
1631 if (has_param && param==0)
1632 attr_pop(ATTR_ITALIC);
1633 else
1634 attr_push(ATTR_ITALIC,NULL);
1635 return FALSE;
1636 }
1637
1638 /*========================================================================
1639 * Name: cmd_s
1640 * Purpose: Executes the \s command.
1641 * Args: Word, paragraph align info, and numeric param if any.
1642 * Returns: Flag, true only if rest of Words on line should be ignored.
1643 *=======================================================================*/
1644 static int cmd_s (Word *w, int align, char has_param, short param) {
1645 return FALSE;
1646 }
1647
1648 /*========================================================================
1649 * Name: cmd_sect
1650 * Purpose: Executes the \sect command.
1651 * Args: Word, paragraph align info, and numeric param if any.
1652 * Returns: Flag, true only if rest of Words on line should be ignored.
1653 *=======================================================================*/
1654
1655 static int cmd_sect (Word *w, int align, char has_param, short param) {
1656 /* XX kludge */
1657 printf (op->paragraph_begin);
1658 return FALSE;
1659 }
1660
1661 /*========================================================================
1662 * Name: cmd_shp
1663 * Purpose: Executes the \shp command.
1664 * Args: Word, paragraph align info, and numeric param if any.
1665 * Returns: Flag, true only if rest of Words on line should be ignored.
1666 *=======================================================================*/