2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
13 #include "multistring.h"
16 #define iswhite(_ch) (((_ch)==' ') || ((_ch)=='\t'))
19 #define iseol(_ch) (((_ch)=='\n') || ((_ch)=='\r'))
22 #define iswhiteeol(_ch) (iswhite(_ch) || iseol(_ch))
31 LPTSTR
EscapeSpecialCharacters (LPTSTR pachIn
, size_t cchIn
)
33 static LPTSTR pszOut
= NULL
;
34 static size_t cchOut
= 0;
36 size_t cchReq
= cchIn
* 2 + 1;
37 if (pszOut
&& (cchOut
< cchReq
))
46 pszOut
= (LPTSTR
)malloc(cchReq
);
52 LPTSTR pchOut
= pszOut
;
54 for ( ; cchIn
; --cchIn
)
58 *pchOut
++ = TEXT('\\');
59 *pchOut
++ = TEXT('\'');
60 *pchOut
++ = TEXT('7');
61 *pchOut
++ = TEXT('D');
66 if (strchr ("\\{", *pachIn
))
67 *pchOut
++ = TEXT('\\');
68 *pchOut
++ = *pachIn
++;
79 BOOL
FormatFile (LPTSTR pszName
, LPTSTR pszText
)
81 // Find the appropriate output filename
83 TCHAR szName
[ MAX_PATH
];
84 lstrcpy (szName
, pszName
);
86 LPTSTR pchSlash
= NULL
;
87 for (LPTSTR pch
= szName
; *pch
; ++pch
)
89 if (*pch
== TEXT('\\'))
91 else if (*pch
== TEXT('.'))
95 lstrcpy (pchSlash
, TEXT(".rtf"));
97 lstrcat (szName
, TEXT(".rtf"));
99 // Open an output file handle
102 if ((hFile
= CreateFile (szName
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, NULL
)) == INVALID_HANDLE_VALUE
)
104 printf ("failed to create %s; error %lu\n", szName
, GetLastError());
108 // Write the RTF prolog
110 char *pszPROLOG
= "{\\rtf1\\ansi\\deff0\\deftab720\\ansicpg%lu\n"
111 "{\\colortbl\\red0\\green0\\blue0;}\\pard";
113 char szProlog
[ 1024 ];
114 wsprintf (szProlog
, pszPROLOG
, g::CodePage
);
117 WriteFile (hFile
, szProlog
, lstrlen(szProlog
), &dwWrote
, NULL
);
119 // Translate the file itself
121 BOOL fAllowCRLF
= FALSE
;
122 BOOL fInFormatted
= FALSE
;
123 size_t cFormatted
= FALSE
;
124 LPTSTR pchNext
= NULL
;
125 for (LPTSTR pchRead
= pszText
; pchRead
&& *pchRead
; pchRead
= pchNext
)
127 while (iswhiteeol(*pchRead
))
134 pchNext
= &pchRead
[1];
135 while (*pchNext
&& (*pchNext
!= '>'))
140 // If this was a "<p>", write an EOL.
141 // If this was a "<d>", write paragraph-header formatting info.
142 // If this was a "<?>", write an EOL.
144 if (tolower(pchRead
[1]) == '?')
147 WriteFile (hFile
, "\r\n\\par ", lstrlen("\r\n\\par "), &dwWrote
, NULL
);
149 else if (tolower(pchRead
[1]) == 'p')
152 WriteFile (hFile
, "\r\n\\par \r\n\\par ", lstrlen("\r\n\\par \r\n\\par "), &dwWrote
, NULL
);
155 char *pszPLAIN
= "\\plain\\fs20 ";
156 WriteFile (hFile
, pszPLAIN
, lstrlen(pszPLAIN
), &dwWrote
, NULL
);
158 fInFormatted
= FALSE
;
160 else if (tolower(pchRead
[1]) == 'd')
163 WriteFile (hFile
, "\r\n\\par \r\n\\par ", lstrlen("\r\n\\par \r\n\\par "), &dwWrote
, NULL
);
166 if ((++cFormatted
) <= 2)
167 pszWrite
= "\\plain\\fs28\\b ";
168 else // (cFormatted > 2)
169 pszWrite
= "\\plain\\fs24\\b ";
171 WriteFile (hFile
, pszWrite
, lstrlen(pszWrite
), &dwWrote
, NULL
);
176 else // (*pchRead != '<')
178 pchNext
= &pchRead
[1];
179 while (*pchNext
&& (*pchNext
!= '<') && !iseol(*pchNext
))
183 if ((pszEscaped
= EscapeSpecialCharacters (pchRead
, pchNext
- pchRead
)) == NULL
)
186 WriteFile (hFile
, pszEscaped
, lstrlen(pszEscaped
), &dwWrote
, NULL
);
191 // Write the RTF trailer
193 char *pszTRAILER
= "\\par }";
195 WriteFile (hFile
, pszTRAILER
, lstrlen(pszTRAILER
), &dwWrote
, NULL
);
197 SetEndOfFile (hFile
);
203 BOOL
TranslateFile (LPTSTR psz
)
207 // First open the file and read it into memory.
210 if ((hFile
= CreateFile (psz
, GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, NULL
)) == INVALID_HANDLE_VALUE
)
212 printf ("failed to open %s; error %lu\n", psz
, GetLastError());
217 if ((cbSource
= GetFileSize (hFile
, NULL
)) != 0)
219 LPTSTR abSource
= (LPTSTR
)malloc(cbSource
+ 4);
220 memset(abSource
, 0x00, cbSource
+ 4);
223 if (!ReadFile (hFile
, abSource
, cbSource
, &dwRead
, NULL
) || cbSource
!= dwRead
)
225 printf ("failed to read %s; error %lu\n", psz
, GetLastError());
230 DWORD cbTarget
= cbSource
* 4;
231 LPSTR abTarget
= (LPSTR
)malloc(cbTarget
);
232 memset (abTarget
, 0x00, cbTarget
);
234 BOOL fDefault
= FALSE
;
235 WideCharToMultiByte (g::CodePage
, 0, (LPCWSTR
)abSource
, -1, abTarget
, cbTarget
, TEXT(" "), &fDefault
);
237 rc
= FormatFile (psz
, abTarget
);
250 LPTSTR
FindFullPath (LPTSTR pszFormat
, LPTSTR pszBaseName
)
252 static TCHAR szOut
[ MAX_PATH
];
253 lstrcpy (szOut
, pszFormat
);
255 LPTSTR pchSlash
= NULL
;
256 for (LPTSTR pch
= szOut
; *pch
; ++pch
)
257 if ((*pch
== TEXT('\\')) || (*pch
== TEXT('/')))
260 lstrcpy (pchSlash
, TEXT("\\"));
262 szOut
[0] = TEXT('\0');
263 lstrcat (szOut
, pszBaseName
);
268 void main (int argc
, char **argv
)
270 int cFilesRequested
= 0;
272 g::CodePage
= CP_ACP
;
274 for (--argc
,++argv
; argc
; --argc
,++argv
)
276 if ((argv
[0][0] == '-') || (argv
[0][0] == '/'))
278 g::CodePage
= atol(&argv
[0][1]);
280 else // ((argv[0][0] != '-') && (argv[0][0] != '/'))
282 WIN32_FIND_DATA Data
;
285 if ((hFind
= FindFirstFile (argv
[0], &Data
)) == INVALID_HANDLE_VALUE
)
287 printf ("file %s not found\n", argv
[0]);
291 LPTSTR pszNames
= NULL
;
294 if (!(Data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
295 mstrcat (&pszNames
, TEXT('\0'), FindFullPath (argv
[0], Data
.cFileName
));
296 } while (FindNextFile (hFind
, &Data
));
302 for (LPTSTR psz
= pszNames
; psz
&& *psz
; psz
+= 1+lstrlen(psz
))
304 printf ("translating %s into rtf...\n", psz
);
315 if (!cFilesRequested
)
317 printf ("format : sgml2rtf filename {...}\r\n\r\n");