home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright 1990 by Norman Graham, Brandywine Softworks.
-
- Permission to use, copy, modify, and distribte this software for
- any purpose and without fee is hereby granted, provided that the
- above copyright notice appear in all copies and that both the
- copyright notice and this permission notice and warranty disclaimer
- appear in supporting documentation, and that the name of Brandywine
- Softworks or Norman Graham not be used in advertising or publicity
- pertaining to distribution of the software without specific, written
- prior permission.
-
- Brandywine Softworks and Norman Graham disclaim all warranties with
- regard to this software, including all implied warranties of
- merchantability and fitness. In no event shall Brandywine Softworks
- or Norman Graham be liable for any special, indirect, or consequential
- damages or any damages whatsoever resulting from loss of use, data,
- or profits, whether in an action of contract, negligence, or other
- tortious action, arising out of or in connection with the use or
- performance of this software.
- */
-
- /******************************************************************************
- File: Man2RTF.c
- Author: Norman Graham
- Date: 2 September 1990
-
- Usage: Man2RTF [-f|-h8|-h7] <Man.file >RTF.File
-
- Description:
-
- Man2RTF is a quick hack to convert a text file to Rich Text Format.
- It converts some of the control sequences common in Un*x files into
- the equivalent RTF character formatting. It converts the following
- sequences:
-
- "a\ba" => Bold 'a'
- "a\ba\ba" => Bold 'a'
- "a\ba\ba\ba" => Bold 'a'
- "_\ba" => Underlined 'a'
- "_\ba\ba" => Underlined Bold 'a'
- "`" => Typographer's Opening Single Quote
- "'" => Typographer's Closing Single Quote
-
- Any other string with a '\b' in it is written to stderr as an error.
- The idea is that Man2RTF will tell you when you need to extend it
- to handle control sequences not currently handled.
-
- Any non-control sequence is just copied to the RTF file.
-
-
- Options:
-
- -f Format the text with 10 point Courier and format the page
- to display 66 lines on a vertical 8.5 inch by 11 inch page.
- Margins are Top = 0.45 inch, Bottom = 0.45 inch, and
- Left = 1.25 inches.
-
- -h8 Format the text with 8 point Courier and format the page
- to display two columns of 66 lines on a horizontal 8.5 inch
- by 11 inch page. Margins are Top = 0.21 inch, Bottom = 0.21 inch,
- Left = 0.15 inch, and Right = 0.15 inch with 0.15 inch between
- columns. This format is not as useful as '-h7'.
-
- -h7 Format the text with 7 point Courier and format the page
- to display two columns of 66 lines on a horizontal 8.5 inch
- by 11 inch page. Margins are Top = 0.9 inch, Bottom = 0.45 inch,
- Left = 0.45 inch, and Right = 0.45 inch with 0.8 inch between
- columns. This is a nice format because it provides a top margin
- for binding and the space between columns is large enough that
- you need not worry about the columns running together.
-
- If no option is specified, Man2RTF will only generate font style
- information; it will not generate font name, font size, or
- page formating information.
-
-
- Caveats:
-
- If you use this tool on a Un*x box with the intention of
- downloading the resulting file to your Mac, you need to
- be aware that the resulting file probably contains typographer's
- opening and closing quotes. These characters have values > 127
- (i.e. their high bits are set), thus you'll need to make special
- arangements to download the file. I'd suggest using mcvert
- (available on sumex-aim) to convert the file to a macbinary
- text file and then do a macbinary file transfer. As an alternative,
- you could just nullify the typographer quote code by changing
- kOpenSingleQuote to '`' and kCloseSingleQuote to '\''.
-
-
- MPW build commands:
-
- In MPW, you can build Man2RTF by executing the following commands
- directly from this file. You'll need to edit the Link command
- to put the tool where you want it and to repair the line continuation
- characters that undoubtly will be munged by transport over the
- internet.
-
- C "{Active}"
-
- Link -w -c 'MPS ' -t MPST 6
- "{Active}".o 6
- "{CLibraries}"StdClib.o 6
- "{CLibraries}"CInterface.o 6
- "{Libraries}"Stubs.o 6
- "{CLibraries}"CRuntime.o 6
- "{Libraries}"Interface.o 6
- -o {MPW}Tools:LocalTools:Man2RTF
-
- Delete "{Active}".o
-
-
- Porting:
-
- This program is written in ANSI C. If your compiler does not
- support the ANSI C standard, you will need to modify this code.
- Pay attention to the function prototypes, the new style function
- definitions, and the string concatenation [used in calls to fprintf()
- and puts()]. I believe most C compilers now support enum types,
- but if yours doesn't you'll need to do some modifications here
- as well.
-
- For MPW users. Watch out for munged characters in the Link
- command (from above) and in the definitions of kOpenSingleQuote
- and kCloseSingleQuote. These definitions contain characters
- that are > 127 (i.e. their high bit is set).
-
-
- Bugs:
-
- As with most quick hacks, the internals of this program are almost
- completely undocumented. But it is a very simple program and
- experienced C programmers should have no trouble following its
- logic.
-
-
- The following are some simple test strings:
-
- Clear text _U_n_d_e_r_l_i_n_e_ _t_e_x_t Clear text
-
- Clear text BBoolldd tteexxtt Clear text
-
- Clear text _BB_oo_ll_dd_--_UU_nn_dd_ee_rr_ll_ii_nn_ee_ _tt_ee_xx_tt Clear text
-
- Clear text BBBaaaddd ttteeexxxttt Clear text
-
- Clear text B_Ba_ad_d _ t_te_ex_xt_t Clear text
-
- ******************************************************************************/
-
- #include <stdio.h>
-
-
- /* Type Definitions... */
-
- enum TypeStyle {
- kUndefinedStyle,
- kPlain,
- kBold,
- kExtraBold,
- kUltraBold,
- kUnderline,
- kBoldUnderline
- };
- typedef enum TypeStyle TypeStyle;
-
- enum PageFormat {
- kUndefinedPage,
- kDefaultPage,
- kFullPage10Point,
- kHalfPage8Point,
- kHalfPage7Point
- };
- typedef enum PageFormat PageFormat;
-
- typedef unsigned char Char;
-
-
- /* Function Prototypes... */
-
- PageFormat ParseArguments (int, Char *[]);
-
- void PrintHeader (PageFormat);
-
- TypeStyle WhatStyle (Char *);
-
- int CollectPlain (Char *, Char *);
- int CollectBold (Char *, Char *);
- int CollectExtraBold (Char *, Char *);
- int CollectUltraBold (Char *, Char *);
- int CollectUnderline (Char *, Char *);
- int CollectBoldUnderline (Char *, Char *);
-
-
- /* Global Constants... */
-
- #ifdef applec
- const Char kOpenSingleQuote = 'T'; /* Replace T with Option-] */
- const Char kCloseSingleQuote = 'U'; /* Replace U with Shift-Option-] */
- #else
- const Char kOpenSingleQuote = 0xD4;
- const Char kCloseSingleQuote = 0xD5;
- #endif
-
-
- /* Entry Point... */
-
- main (int argc, Char *argv[])
- {
- int indexInLine;
- int lengthInLine;
- int (*collectChars)(Char *, Char *);
-
- Char *styleCommand;
- Char inLine [1024]; /* Actually, I believe these buffers need be */
- Char outLine [1024]; /* only inLine [561], outLine [103], and */
- Char pureChars [1024]; /* putChars [81]. But hey, memory is cheap. */
- Char *fontCommand;
-
- PageFormat fmt;
-
-
- /* Parse the command line arguments */
- fmt = ParseArguments (argc, argv);
- if ( fmt == kUndefinedPage )
- {
- fprintf (stderr, "Invalid Argument\n");
- fprintf (stderr,
- "Usage: %s [-f | -h8 | -h7] <Man.file >RTF.File\n",
- argv[0]);
- return 0;
- }
-
- /* Print the appropriate header. */
- PrintHeader (fmt);
-
- /* Set up the font command string */
- switch ( fmt )
- {
- case kFullPage10Point :
- fontCommand = "\\f1\\fs20";
- break;
-
- case kHalfPage8Point :
- fontCommand = "\\f1\\fs16";
- break;
-
- case kHalfPage7Point :
- fontCommand = "\\f1\\fs14";
- break;
-
- case kDefaultPage :
- case kUndefinedPage :
- default :
- fontCommand = "";
- break;
- }
-
- /* Convert the file */
- while ( gets(inLine) != NULL )
- {
- indexInLine = 0;
- lengthInLine = strlen(inLine) + 1; /* Process the '\0' also. */
-
- while ( indexInLine < lengthInLine )
- {
- switch ( WhatStyle (&inLine[indexInLine]) )
- {
- case kPlain :
- collectChars = CollectPlain;
- styleCommand = "";
- break;
-
- case kBold :
- collectChars = CollectBold;
- styleCommand = "\\b";
- break;
-
- case kExtraBold :
- collectChars = CollectExtraBold;
- styleCommand = "\\b";
- break;
-
- case kUltraBold :
- collectChars = CollectUltraBold;
- styleCommand = "\\b";
- break;
-
- case kUnderline :
- collectChars = CollectUnderline;
- styleCommand = "\\ul";
- break;
-
- case kBoldUnderline :
- collectChars = CollectBoldUnderline;
- styleCommand = "\\b\\ul";
- break;
-
- case kUndefinedStyle :
- default :
- fprintf (stderr,
- "\nUnknown style returned from 'WhatStyle()'"
- "\nIndex is %d"
- "\nLine is \"%s\"\n",
- indexInLine + 1, inLine);
- inLine [indexInLine + 1] = '\0';
- fprintf (stderr,"Error is %s^--Here\n",inLine);
- return -1;
- }
-
- indexInLine += collectChars (&inLine[indexInLine], pureChars);
-
- strcpy (outLine, "{\\plain");
- strcat (outLine, fontCommand);
- strcat (outLine, styleCommand);
- strcat (outLine, " ");
- strcat (outLine, pureChars);
- strcat (outLine, "}");
-
- puts (outLine);
- }
- }
-
- /* Print trailer */
- puts ("}");
-
- return 0;
- }
-
-
- PageFormat ParseArguments (int argc, Char *argv[])
- {
- switch ( argc )
- {
- case 1 :
- return kDefaultPage;
-
- case 2 :
- if ( strcmp (argv[1], "-f") == 0 )
- return kFullPage10Point;
- else if ( strcmp (argv[1], "-h8") == 0 )
- return kHalfPage8Point;
- else if ( strcmp (argv[1], "-h7") == 0 )
- return kHalfPage7Point;
- else
- return kUndefinedPage;
-
- default :
- return kUndefinedPage;
- }
- }
-
- void PrintHeader (PageFormat fmt)
- {
- puts ("{\\rtf0\\mac\\deff1");
- puts ("{\\fonttbl{\\f0 \\fswiss Helvetica;}{\\f1 \\fmodern Courier;}}");
-
- switch ( fmt )
- {
- case kFullPage10Point :
- puts ("\\paperw12240\\paperh15840\\margt648\\margb648"
- "\\margl1800\\margr0\\widowctrl\\ftnbj\\ftnrestart"
- "\\ftnstart1\\pgnstart1\\deftab720\\fracwidth\\sectd"
- "\\linemod0\\linex0\\cols1\\colsx863");
- break;
-
- case kHalfPage8Point :
- puts ("\\paperw15840\\paperh12240\\landscape\\margt144"
- "\\margb432\\margl144\\margr144\\widowctrl\\ftnbj"
- "\\ftnrestart\\ftnstart1\\pgnstart1\\deftab720"
- "\\fracwidth\\sectd\\linemod0\\linex0\\cols2\\colsx144");
- break;
-
- case kHalfPage7Point :
- puts ("\\paperw15840\\paperh12240\\landscape\\margt1440"
- "\\margb576\\margl720\\margr720\\widowctrl\\ftnbj"
- "\\ftnrestart\\ftnstart1\\pgnstart1\\deftab720"
- "\\fracwidth\\sectd\\linemod0\\linex0\\cols2\\colsx1080");
- break;
-
- case kUndefinedPage :
- default :
- break;
- }
-
- puts ("\\pard\\plain");
- }
-
- TypeStyle WhatStyle ( Char *line )
- {
- Char c1, c2, c3, c4, c5, c6, c7;
-
- c1 = line [0];
- c2 = line [1];
- c3 = line [2];
- c4 = line [3];
- c5 = line [4];
- c6 = line [5];
- c7 = line [6];
-
- if ( c1 == c3 && c3 == c5 && c5 ==c7
- && c2 == '\b' && c4 == '\b' && c6 == '\b'
- && c1 != '\0' )
- return kUltraBold;
-
- else if ( c1 == c3 && c3 == c5
- && c2 == '\b' && c4 == '\b'
- && c1 != '\0' )
- return kExtraBold;
-
- else if ( c1 == '_' && c3 == c5
- && c2 == '\b' && c4 == '\b'
- && c3 != '\0' )
- return kBoldUnderline;
-
- else if ( c1 == '_' && c2 == '\b' )
- return kUnderline;
-
- else if ( c1 == c3 && c2 == '\b' && c1 != '\0' )
- return kBold;
-
- else if ( c1 == '\b' || (c1 != '\0' && c2 == '\b') )
- return kUndefinedStyle;
-
- else
- return kPlain;
- }
-
- int CollectPlain (Char *in, Char *out)
- {
- Char c;
- Char *startPos;
-
- startPos = in;
-
- while ( 1 )
- {
- switch ( c = *in++ )
- {
- case '\b' :
- *--out = '\0';
- return (in - startPos) - 2;
-
- case '\f' :
- *out++ = '\\';
- *out++ = 'p';
- *out++ = 'a';
- *out++ = 'g';
- *out++ = 'e';
- *out++ = ' ';
- break;
-
- case '`' :
- *out++ = kOpenSingleQuote;
- break;
-
- case '\'' :
- *out++ = kCloseSingleQuote;
- break;
-
- case '\0' :
- *out++ = '\\';
- *out++ = 'p';
- *out++ = 'a';
- *out++ = 'r';
- *out++ = ' ';
- *out = '\0';
- return in - startPos;
-
- case '{' :
- *out++ = '\\';
- *out++ = '{';
- break;
-
- case '}' :
- *out++ = '\\';
- *out++ = '}';
- break;
-
- case '\\' :
- *out++ = '\\';
- *out++ = '\\';
- break;
-
- default :
- *out++ = c;
- break;
- }
- }
- }
-
- int CollectBold (Char *in, Char *out)
- {
- Char c1, c2, c3;
- Char *startPos;
-
- startPos = in;
-
- while ( 1 )
- {
- c1 = in [0];
- c2 = in [1];
- c3 = in [2];
-
- if ( c1 != c3 || c2 != '\b' || c1 == '\0' )
- {
- *out = '\0';
- return in - startPos;
- }
- else
- {
- in += 3;
- switch ( c1 )
- {
- case '`' :
- *out++ = kOpenSingleQuote;
- break;
-
- case '\'' :
- *out++ = kCloseSingleQuote;
- break;
-
- case '{' :
- *out++ = '\\';
- *out++ = '{';
- break;
-
- case '}' :
- *out++ = '\\';
- *out++ = '}';
- break;
-
- case '\\' :
- *out++ = '\\';
- *out++ = '\\';
- break;
-
- default :
- *out++ = c1;
- break;
- }
- }
- }
- }
-
- int CollectExtraBold (Char *in, Char *out)
- {
- Char c1, c2, c3, c4, c5;
- Char *startPos;
-
- startPos = in;
-
- while ( 1 )
- {
- c1 = in [0];
- c2 = in [1];
- c3 = in [2];
- c4 = in [3];
- c5 = in [4];
-
- if ( c1 != c3 || c3 != c5
- || c2 != '\b' || c4 != '\b'
- || c1 == '\0' )
- {
- *out = '\0';
- return in - startPos;
- }
- else
- {
- in += 5;
- switch ( c1 )
- {
- case '`' :
- *out++ = kOpenSingleQuote;
- break;
-
- case '\'' :
- *out++ = kCloseSingleQuote;
- break;
-
- case '{' :
- *out++ = '\\';
- *out++ = '{';
- break;
-
- case '}' :
- *out++ = '\\';
- *out++ = '}';
- break;
-
- case '\\' :
- *out++ = '\\';
- *out++ = '\\';
- break;
-
- default :
- *out++ = c1;
- break;
- }
- }
- }
- }
-
- int CollectUltraBold (Char *in, Char *out)
- {
- Char c1, c2, c3, c4, c5, c6, c7;
- Char *startPos;
-
- startPos = in;
-
- while ( 1 )
- {
- c1 = in [0];
- c2 = in [1];
- c3 = in [2];
- c4 = in [3];
- c5 = in [4];
- c6 = in [5];
- c7 = in [6];
-
- if ( c1 != c3 || c3 != c5 || c5 != c7
- || c2 != '\b' || c4 != '\b' || c6 != '\b'
- || c1 == '\0' )
- {
- *out = '\0';
- return in - startPos;
- }
- else
- {
- in += 7;
- switch ( c1 )
- {
- case '`' :
- *out++ = kOpenSingleQuote;
- break;
-
- case '\'' :
- *out++ = kCloseSingleQuote;
- break;
-
- case '{' :
- *out++ = '\\';
- *out++ = '{';
- break;
-
- case '}' :
- *out++ = '\\';
- *out++ = '}';
- break;
-
- case '\\' :
- *out++ = '\\';
- *out++ = '\\';
- break;
-
- default :
- *out++ = c1;
- break;
- }
- }
- }
- }
-
- int CollectUnderline (Char *in, Char *out)
- {
- Char c1, c2, c3;
- Char *startPos;
-
- startPos = in;
-
- while ( 1 )
- {
- c1 = in [0];
- c2 = in [1];
- c3 = in [2];
-
- if ( c1 != '_' || c2 != '\b' || c3 == '\0' )
- {
- *out = '\0';
- return in - startPos;
- }
- else
- {
- in += 3;
- switch ( c3 )
- {
- case '`' :
- *out++ = kOpenSingleQuote;
- break;
-
- case '\'' :
- *out++ = kCloseSingleQuote;
- break;
-
- case '{' :
- *out++ = '\\';
- *out++ = '{';
- break;
-
- case '}' :
- *out++ = '\\';
- *out++ = '}';
- break;
-
- case '\\' :
- *out++ = '\\';
- *out++ = '\\';
- break;
-
- default :
- *out++ = c3;
- break;
- }
- }
- }
- }
-
- int CollectBoldUnderline (Char *in, Char *out)
- {
- Char c1, c2, c3, c4, c5;
- Char *startPos;
-
- startPos = in;
-
- while ( 1 )
- {
- c1 = in [0];
- c2 = in [1];
- c3 = in [2];
- c4 = in [3];
- c5 = in [4];
-
- if ( c1 != '_' || c2 != '\b' || c4 != '\b' || c3 != c5 || c3 == '\0' )
- {
- *out = '\0';
- return in - startPos;
- }
- else
- {
- in += 5;
- switch ( c3 )
- {
- case '`' :
- *out++ = kOpenSingleQuote;
- break;
-
- case '\'' :
- *out++ = kCloseSingleQuote;
- break;
-
- case '{' :
- *out++ = '\\';
- *out++ = '{';
- break;
-
- case '}' :
- *out++ = '\\';
- *out++ = '}';
- break;
-
- case '\\' :
- *out++ = '\\';
- *out++ = '\\';
- break;
-
- default :
- *out++ = c3;
- break;
- }
- }
- }
- }
-