4 #include "multistring.h"
7 #define iswhite(_ch) (((_ch)==' ') || ((_ch)=='\t'))
10 #define iseol(_ch) (((_ch)=='\n') || ((_ch)=='\r'))
13 #define iswhiteeol(_ch) (iswhite(_ch) || iseol(_ch))
22 LPTSTR EscapeSpecialCharacters (LPTSTR pachIn, size_t cchIn)
24 static LPTSTR pszOut = NULL;
25 static size_t cchOut = 0;
27 size_t cchReq = cchIn * 2 + 1;
28 if (pszOut && (cchOut < cchReq))
30 GlobalFree ((HGLOBAL)pszOut);
37 pszOut = (LPTSTR)GlobalAlloc (GMEM_FIXED, cchReq);
43 LPTSTR pchOut = pszOut;
45 for ( ; cchIn; --cchIn)
49 *pchOut++ = TEXT('\\');
50 *pchOut++ = TEXT('\'');
51 *pchOut++ = TEXT('7');
52 *pchOut++ = TEXT('D');
57 if (strchr ("\\{", *pachIn))
58 *pchOut++ = TEXT('\\');
59 *pchOut++ = *pachIn++;
70 BOOL FormatFile (LPTSTR pszName, LPTSTR pszText)
72 // Find the appropriate output filename
74 TCHAR szName[ MAX_PATH ];
75 lstrcpy (szName, pszName);
77 LPTSTR pchSlash = NULL;
78 for (LPTSTR pch = szName; *pch; ++pch)
80 if (*pch == TEXT('\\'))
82 else if (*pch == TEXT('.'))
86 lstrcpy (pchSlash, TEXT(".rtf"));
88 lstrcat (szName, TEXT(".rtf"));
90 // Open an output file handle
93 if ((hFile = CreateFile (szName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE)
95 printf ("failed to create %s; error %lu\n", szName, GetLastError());
99 // Write the RTF prolog
101 char *pszPROLOG = "{\\rtf1\\ansi\\deff0\\deftab720\\ansicpg%lu\n"
102 "{\\colortbl\\red0\\green0\\blue0;}\\pard";
104 char szProlog[ 1024 ];
105 wsprintf (szProlog, pszPROLOG, g::CodePage);
108 WriteFile (hFile, szProlog, lstrlen(szProlog), &dwWrote, NULL);
110 // Translate the file itself
112 BOOL fAllowCRLF = FALSE;
113 BOOL fInFormatted = FALSE;
114 size_t cFormatted = FALSE;
115 LPTSTR pchNext = NULL;
116 for (LPTSTR pchRead = pszText; pchRead && *pchRead; pchRead = pchNext)
118 while (iswhiteeol(*pchRead))
125 pchNext = &pchRead[1];
126 while (*pchNext && (*pchNext != '>'))
131 // If this was a "<p>", write an EOL.
132 // If this was a "<d>", write paragraph-header formatting info.
133 // If this was a "<?>", write an EOL.
135 if (tolower(pchRead[1]) == '?')
138 WriteFile (hFile, "\r\n\\par ", lstrlen("\r\n\\par "), &dwWrote, NULL);
140 else if (tolower(pchRead[1]) == 'p')
143 WriteFile (hFile, "\r\n\\par \r\n\\par ", lstrlen("\r\n\\par \r\n\\par "), &dwWrote, NULL);
146 char *pszPLAIN = "\\plain\\fs20 ";
147 WriteFile (hFile, pszPLAIN, lstrlen(pszPLAIN), &dwWrote, NULL);
149 fInFormatted = FALSE;
151 else if (tolower(pchRead[1]) == 'd')
154 WriteFile (hFile, "\r\n\\par \r\n\\par ", lstrlen("\r\n\\par \r\n\\par "), &dwWrote, NULL);
157 if ((++cFormatted) <= 2)
158 pszWrite = "\\plain\\fs28\\b ";
159 else // (cFormatted > 2)
160 pszWrite = "\\plain\\fs24\\b ";
162 WriteFile (hFile, pszWrite, lstrlen(pszWrite), &dwWrote, NULL);
167 else // (*pchRead != '<')
169 pchNext = &pchRead[1];
170 while (*pchNext && (*pchNext != '<') && !iseol(*pchNext))
174 if ((pszEscaped = EscapeSpecialCharacters (pchRead, pchNext - pchRead)) == NULL)
177 WriteFile (hFile, pszEscaped, lstrlen(pszEscaped), &dwWrote, NULL);
182 // Write the RTF trailer
184 char *pszTRAILER = "\\par }";
186 WriteFile (hFile, pszTRAILER, lstrlen(pszTRAILER), &dwWrote, NULL);
188 SetEndOfFile (hFile);
194 BOOL TranslateFile (LPTSTR psz)
198 // First open the file and read it into memory.
201 if ((hFile = CreateFile (psz, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
203 printf ("failed to open %s; error %lu\n", psz, GetLastError());
208 if ((cbSource = GetFileSize (hFile, NULL)) != 0)
210 LPTSTR abSource = (LPTSTR)GlobalAlloc (GMEM_FIXED, cbSource + 5);
213 if (!ReadFile (hFile, abSource, cbSource, &dwRead, NULL))
215 printf ("failed to read %s; error %lu\n", psz, GetLastError());
220 abSource[ dwRead ] = 0;
221 size_t cbTarget = dwRead * 4;
222 LPSTR abTarget = (LPSTR)GlobalAlloc (GMEM_FIXED, cbTarget);
223 memset (abTarget, 0x00, cbTarget);
225 BOOL fDefault = FALSE;
226 WideCharToMultiByte (g::CodePage, 0, (LPCWSTR)abSource, dwRead, abTarget, cbTarget, TEXT(" "), &fDefault);
228 rc = FormatFile (psz, abTarget);
230 GlobalFree ((HGLOBAL)abTarget);
233 GlobalFree ((HGLOBAL)abSource);
241 LPTSTR FindFullPath (LPTSTR pszFormat, LPTSTR pszBaseName)
243 static TCHAR szOut[ MAX_PATH ];
244 lstrcpy (szOut, pszFormat);
246 LPTSTR pchSlash = NULL;
247 for (LPTSTR pch = szOut; *pch; ++pch)
248 if ((*pch == TEXT('\\')) || (*pch == TEXT('/')))
251 lstrcpy (pchSlash, TEXT("\\"));
253 szOut[0] = TEXT('\0');
254 lstrcat (szOut, pszBaseName);
259 void main (int argc, char **argv)
261 int cFilesRequested = 0;
263 g::CodePage = CP_ACP;
265 for (--argc,++argv; argc; --argc,++argv)
267 if ((argv[0][0] == '-') || (argv[0][0] == '/'))
269 g::CodePage = atol(&argv[0][1]);
271 else // ((argv[0][0] != '-') && (argv[0][0] != '/'))
273 WIN32_FIND_DATA Data;
276 if ((hFind = FindFirstFile (argv[0], &Data)) == INVALID_HANDLE_VALUE)
278 printf ("file %s not found\n", argv[0]);
282 LPTSTR pszNames = NULL;
285 if (!(Data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
286 mstrcat (&pszNames, TEXT('\0'), FindFullPath (argv[0], Data.cFileName));
287 } while (FindNextFile (hFind, &Data));
293 for (LPTSTR psz = pszNames; psz && *psz; psz += 1+lstrlen(psz))
295 printf ("translating %s into rtf...\n", psz);
306 if (!cFilesRequested)
308 printf ("format : sgml2rtf filename {...}\r\n\r\n");