PageRenderTime 45ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 1ms

/wxwindows/utils/tex2rtf/src/rtfutils.cpp

http://github.com/mhoffesommer/Very-Sleepy
C++ | 5342 lines | 4905 code | 172 blank | 265 comment | 773 complexity | d2fbe2b97888e587a358270a6f2a915a MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name: rtfutils.cpp
  3. // Purpose: Converts Latex to Word RTF/WinHelp RTF
  4. // Author: Julian Smart
  5. // Modified by: Wlodzimiez ABX Skiba 2003/2004 Unicode support
  6. // Ron Lee
  7. // Created: 7.9.93
  8. // RCS-ID: $Id: rtfutils.cpp 36101 2005-11-07 13:27:09Z ABX $
  9. // Copyright: (c) Julian Smart
  10. // Licence: wxWindows licence
  11. /////////////////////////////////////////////////////////////////////////////
  12. // For compilers that support precompilation, includes "wx.h".
  13. #include "wx/wxprec.h"
  14. #ifdef __BORLANDC__
  15. #pragma hdrstop
  16. #endif
  17. #ifndef WX_PRECOMP
  18. #endif
  19. #include "tex2any.h"
  20. #include "tex2rtf.h"
  21. #include <ctype.h>
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #ifdef __WIN32__
  25. #include <windows.h>
  26. #endif
  27. #include "bmputils.h"
  28. #include "table.h"
  29. #if !WXWIN_COMPATIBILITY_2_4
  30. static inline wxChar* copystring(const wxChar* s)
  31. { return wxStrcpy(new wxChar[wxStrlen(s) + 1], s); }
  32. #endif
  33. wxList itemizeStack;
  34. static int indentLevel = 0;
  35. static int forbidParindent = 0; // if > 0, no parindent (e.g. in center environment)
  36. int forbidResetPar = 0; // If > 0, don't reset memory of having output a new par
  37. static wxChar *contentsLineSection = NULL;
  38. static wxChar *contentsLineValue = NULL;
  39. static TexChunk *descriptionItemArg = NULL;
  40. static wxStringList environmentStack; // Stack of paragraph styles we need to remember
  41. static int footnoteCount = 0;
  42. static int citeCount = 1;
  43. extern bool winHelp;
  44. extern bool startedSections;
  45. extern FILE *Contents;
  46. extern FILE *Chapters;
  47. extern FILE *Popups;
  48. extern FILE *WinHelpContentsFile;
  49. extern wxChar *RTFCharset;
  50. // This is defined in the Tex2Any library and isn't in use after parsing
  51. extern wxChar *BigBuffer;
  52. extern wxHashTable TexReferences;
  53. // Are we in verbatim mode? If so, format differently.
  54. static bool inVerbatim = false;
  55. // We're in a series of PopRef topics, so don't output section headings
  56. bool inPopRefSection = false;
  57. // Green colour?
  58. static bool hotSpotColour = true;
  59. static bool hotSpotUnderline = true;
  60. // Transparency (WHITE = transparent)
  61. static bool bitmapTransparency = true;
  62. // Linear RTF requires us to set the style per section.
  63. static wxChar *currentNumberStyle = NULL;
  64. static int currentItemSep = 8;
  65. static int CurrentTextWidth = 8640; // Say, six inches
  66. static int CurrentLeftMarginOdd = 400;
  67. static int CurrentLeftMarginEven = 1440;
  68. static int CurrentRightMarginOdd = 1440;
  69. static int CurrentRightMarginEven = 400;
  70. static int CurrentMarginParWidth = 2000;
  71. static int CurrentMarginParSep = 400; // Gap between marginpar and text
  72. static int CurrentMarginParX = CurrentLeftMarginOdd + CurrentTextWidth + CurrentMarginParSep;
  73. static int GutterWidth = 2300;
  74. // Two-column table dimensions, in twips
  75. static int TwoColWidthA = 1500;
  76. static int TwoColWidthB = 3000;
  77. const int PageWidth = 12242; // 8.25 inches wide for A4
  78. // Remember the anchor in a helpref
  79. static TexChunk *helpRefText = NULL;
  80. /*
  81. * Flag to say we've just issued a \par\pard command, so don't
  82. * repeat this unnecessarily.
  83. *
  84. */
  85. int issuedNewParagraph = 0;
  86. // Need to know whether we're in a table or figure for benefit
  87. // of listoffigures/listoftables
  88. static bool inFigure = false;
  89. static bool inTable = false;
  90. /*
  91. * Current topics
  92. *
  93. */
  94. static wxChar *CurrentChapterName = NULL;
  95. static wxChar *CurrentSectionName = NULL;
  96. static wxChar *CurrentSubsectionName = NULL;
  97. static wxChar *CurrentTopic = NULL;
  98. static bool InPopups()
  99. {
  100. if (CurrentChapterName && (wxStrcmp(CurrentChapterName, _T("popups")) == 0))
  101. return true;
  102. if (CurrentSectionName && (wxStrcmp(CurrentSectionName, _T("popups")) == 0))
  103. return true;
  104. return false;
  105. }
  106. static void SetCurrentTopic(wxChar *s)
  107. {
  108. if (CurrentTopic) delete[] CurrentTopic;
  109. CurrentTopic = copystring(s);
  110. }
  111. void SetCurrentChapterName(wxChar *s)
  112. {
  113. if (CurrentChapterName) delete[] CurrentChapterName;
  114. CurrentChapterName = copystring(s);
  115. SetCurrentTopic(s);
  116. }
  117. void SetCurrentSectionName(wxChar *s)
  118. {
  119. if (CurrentSectionName) delete[] CurrentSectionName;
  120. CurrentSectionName = copystring(s);
  121. SetCurrentTopic(s);
  122. }
  123. void SetCurrentSubsectionName(wxChar *s)
  124. {
  125. if (CurrentSubsectionName) delete[] CurrentSubsectionName;
  126. CurrentSubsectionName = copystring(s);
  127. SetCurrentTopic(s);
  128. }
  129. // Indicate that a parent topic at level 'level' has children.
  130. // Level 1 is a chapter, 2 is a section, etc.
  131. void NotifyParentHasChildren(int parentLevel)
  132. {
  133. wxChar *parentTopic = NULL;
  134. switch (parentLevel)
  135. {
  136. case 1:
  137. {
  138. parentTopic = CurrentChapterName;
  139. break;
  140. }
  141. case 2:
  142. {
  143. parentTopic = CurrentSectionName;
  144. break;
  145. }
  146. case 3:
  147. {
  148. parentTopic = CurrentSubsectionName;
  149. break;
  150. }
  151. default:
  152. {
  153. break;
  154. }
  155. }
  156. if (parentTopic)
  157. {
  158. TexTopic *texTopic = (TexTopic *)TopicTable.Get(parentTopic);
  159. if (!texTopic)
  160. {
  161. texTopic = new TexTopic;
  162. TopicTable.Put(parentTopic, texTopic);
  163. }
  164. texTopic->hasChildren = true;
  165. }
  166. }
  167. // Have to keep a count of what levels are books, what are pages,
  168. // in order to correct for a Win95 bug which means that if you
  169. // have a book at level n, and then a page at level n, the page
  170. // ends up on level n + 1.
  171. bool ContentsLevels[5];
  172. // Reset below this level (starts from 1)
  173. void ResetContentsLevels(int l)
  174. {
  175. int i;
  176. for (i = l; i < 5; i++)
  177. ContentsLevels[i] = false;
  178. // There are always books on the top level
  179. ContentsLevels[0] = true;
  180. }
  181. // Output a WinHelp section as a keyword, substituting
  182. // : for space.
  183. void OutputSectionKeyword(FILE *fd)
  184. {
  185. OutputCurrentSectionToString(wxTex2RTFBuffer);
  186. unsigned int i;
  187. for (i = 0; i < wxStrlen(wxTex2RTFBuffer); i++)
  188. if (wxTex2RTFBuffer[i] == ':')
  189. wxTex2RTFBuffer[i] = ' ';
  190. // Don't write to index if there's some RTF in the string
  191. else if ( wxTex2RTFBuffer[i] == '{' )
  192. return;
  193. wxFprintf(fd, _T("K{\\footnote {K} "));
  194. wxFprintf(fd, _T("%s"), wxTex2RTFBuffer);
  195. wxFprintf(fd, _T("}\n"));
  196. }
  197. // Write a line for the .cnt file, if we're doing this.
  198. void WriteWinHelpContentsFileLine(wxChar *topicName, wxChar *xitle, int level)
  199. {
  200. // First, convert any RTF characters to ASCII
  201. wxChar title[255];
  202. int s=0;
  203. int d=0;
  204. // assuming iso-8859-1 here even in Unicode build (FIXME?)
  205. while ( (xitle[s]!=0)&&(d<255) )
  206. {
  207. wxChar ch=wxChar(xitle[s]&0xff);
  208. if (ch==0x5c) {
  209. wxChar ch1=wxChar(xitle[s+1]&0xff);
  210. wxChar ch2=wxChar(xitle[s+2]&0xff);
  211. wxChar ch3=wxChar(xitle[s+3]&0xff);
  212. s+=4; // next character
  213. if ((ch1==0x27)&&(ch2==0x66)&&(ch3==0x36)) { title[d++]=wxChar('ö'); }
  214. if ((ch1==0x27)&&(ch2==0x65)&&(ch3==0x34)) { title[d++]=wxChar('ä'); }
  215. if ((ch1==0x27)&&(ch2==0x66)&&(ch3==0x63)) { title[d++]=wxChar('ü'); }
  216. if ((ch1==0x27)&&(ch2==0x64)&&(ch3==0x36)) { title[d++]=wxChar('Ö'); }
  217. if ((ch1==0x27)&&(ch2==0x63)&&(ch3==0x34)) { title[d++]=wxChar('Ä'); }
  218. if ((ch1==0x27)&&(ch2==0x64)&&(ch3==0x63)) { title[d++]=wxChar('Ü'); }
  219. } else {
  220. title[d++]=ch;
  221. s++;
  222. }
  223. }
  224. title[d]=0;
  225. // Section (2) becomes level 1 if it's an article.
  226. if (DocumentStyle == LATEX_ARTICLE)
  227. level --;
  228. if (level == 0) // Means we had a Chapter in an article, oops.
  229. return;
  230. ResetContentsLevels(level);
  231. if (winHelp && winHelpContents && WinHelpContentsFile)
  232. {
  233. TexTopic *texTopic = (TexTopic *)TopicTable.Get(topicName);
  234. if (texTopic)
  235. {
  236. // If a previous section at this level was a book, we *have* to have a
  237. // book not a page, because of a bug in WHC (or WinHelp 4).
  238. if (texTopic->hasChildren || level == 1 || ContentsLevels[level-1])
  239. {
  240. // At this level, we have a pointer to a further hierarchy.
  241. // So we need a 'book' consisting of (say) Chapter 1.
  242. wxFprintf(WinHelpContentsFile, _T("%d %s\n"), level, title);
  243. // Then we have a 'page' consisting of the text for this chapter
  244. wxFprintf(WinHelpContentsFile, _T("%d %s=%s\n"), level+1, title, topicName);
  245. // Then we'll be writing out further pages or books at level + 1...
  246. // Remember that at this level, we had a book and *must* for the
  247. // remainder of sections at this level.
  248. ContentsLevels[level-1] = true;
  249. }
  250. else
  251. {
  252. wxFprintf(WinHelpContentsFile, _T("%d %s=%s\n"), level, title, topicName);
  253. }
  254. }
  255. else
  256. {
  257. if (level == 1 || ContentsLevels[level-1])
  258. {
  259. // Always have a book at level 1
  260. wxFprintf(WinHelpContentsFile, _T("%d %s\n"), level, title);
  261. wxFprintf(WinHelpContentsFile, _T("%d %s=%s\n"), level+1, title, topicName);
  262. ContentsLevels[level-1] = true;
  263. }
  264. else
  265. // Probably doesn't have children if it hasn't been added to the topic table
  266. wxFprintf(WinHelpContentsFile, _T("%d %s=%s\n"), level, title, topicName);
  267. }
  268. }
  269. }
  270. void SplitIndexEntry(wxChar *entry, wxChar *buf1, wxChar *buf2)
  271. {
  272. int len = wxStrlen(entry); int i = 0;
  273. while ((i < len) && entry[i] != '!')
  274. { buf1[i] = entry[i]; i ++; }
  275. buf1[i] = 0; buf2[0] = 0; int j = 0;
  276. if (entry[i] == '!')
  277. {
  278. i ++;
  279. while (i < len) { buf2[j] = entry[i]; i ++; j++; }
  280. buf2[j] = 0;
  281. }
  282. }
  283. /*
  284. * Output topic index entries in WinHelp RTF
  285. *
  286. */
  287. void GenerateKeywordsForTopic(wxChar *topic)
  288. {
  289. TexTopic *texTopic = (TexTopic *)TopicTable.Get(topic);
  290. if (!texTopic)
  291. return;
  292. wxStringList *list = texTopic->keywords;
  293. if (list)
  294. {
  295. wxStringListNode *node = list->GetFirst();
  296. while (node)
  297. {
  298. wxChar *s = (wxChar *)node->GetData();
  299. // Must separate out main entry form subentry (only 1 subentry allowed)
  300. wxChar buf1[100]; wxChar buf2[100];
  301. SplitIndexEntry(s, buf1, buf2);
  302. // Check for ':' which messes up index
  303. unsigned int i;
  304. for (i = 0; i < wxStrlen(buf1) ; i++)
  305. if (buf1[i] == ':')
  306. buf1[i] = ' ';
  307. for (i = 0; i < wxStrlen(buf2) ; i++)
  308. if (buf2[i] == ':')
  309. buf2[i] = ' ';
  310. // {K} is a strange fix to prevent words beginning with K not
  311. // being indexed properly
  312. TexOutput(_T("K{\\footnote {K} "));
  313. TexOutput(buf1);
  314. if (wxStrlen(buf2) > 0)
  315. {
  316. // Output subentry
  317. TexOutput(_T(", "));
  318. TexOutput(buf2);
  319. }
  320. TexOutput(_T("}\n"));
  321. node = node->GetNext();
  322. }
  323. }
  324. }
  325. /*
  326. * Output index entry in linear RTF
  327. *
  328. */
  329. void GenerateIndexEntry(wxChar *entry)
  330. {
  331. if (useWord)
  332. {
  333. wxChar buf1[100]; wxChar buf2[100];
  334. SplitIndexEntry(entry, buf1, buf2);
  335. TexOutput(_T("{\\xe\\v {"));
  336. TexOutput(buf1);
  337. if (wxStrlen(buf2) > 0)
  338. {
  339. TexOutput(_T("\\:"));
  340. TexOutput(buf2);
  341. }
  342. TexOutput(_T("}}"));
  343. }
  344. }
  345. /*
  346. * Write a suitable RTF header.
  347. *
  348. */
  349. void WriteColourTable(FILE *fd)
  350. {
  351. wxFprintf(fd, _T("{\\colortbl"));
  352. wxNode *node = ColourTable.GetFirst();
  353. while (node)
  354. {
  355. ColourTableEntry *entry = (ColourTableEntry *)node->GetData();
  356. wxFprintf(fd, _T("\\red%d\\green%d\\blue%d;\n"), entry->red, entry->green, entry->blue);
  357. node = node->GetNext();
  358. }
  359. wxFprintf(fd, _T("}"));
  360. }
  361. /*
  362. * Write heading style
  363. *
  364. */
  365. void WriteHeadingStyle(FILE *fd, int heading)
  366. {
  367. switch (heading)
  368. {
  369. case 1:
  370. {
  371. wxFprintf(fd, _T("\\sb300\\sa260\\f2\\b\\fs%d"), chapterFont*2);
  372. break;
  373. }
  374. case 2:
  375. {
  376. wxFprintf(fd, _T("\\sb200\\sa240\\f2\\b\\fs%d"), sectionFont*2);
  377. break;
  378. }
  379. case 3:
  380. {
  381. wxFprintf(fd, _T("\\sb120\\sa240\\f2\\b\\fs%d"), subsectionFont*2);
  382. break;
  383. }
  384. case 4:
  385. {
  386. wxFprintf(fd, _T("\\sb120\\sa240\\f2\\b\\fs%d"), subsectionFont*2);
  387. break;
  388. }
  389. default:
  390. break;
  391. }
  392. }
  393. void WriteRTFHeader(FILE *fd)
  394. {
  395. wxFprintf(fd, _T("{\\rtf1\\%s \\deff0\n"), RTFCharset);
  396. wxFprintf(fd, _T("{\\fonttbl{\\f0\\froman Times New Roman;}{\\f1\\ftech Symbol;}{\\f2\\fswiss Arial;}\n"));
  397. wxFprintf(fd, _T("{\\f3\\fmodern Courier New;}{\\f4\\ftech Wingdings;}{\\f5\\ftech Monotype Sorts;}\n}"));
  398. /*
  399. * Style sheet
  400. */
  401. wxFprintf(fd, _T("{\\stylesheet{\\f2\\fs22\\sa200 \\snext0 Normal;}\n"));
  402. // Headings
  403. wxFprintf(fd, _T("{\\s1 ")); WriteHeadingStyle(fd, 1); wxFprintf(fd, _T("\\sbasedon0\\snext0 heading 1;}\n"));
  404. wxFprintf(fd, _T("{\\s2 ")); WriteHeadingStyle(fd, 2); wxFprintf(fd, _T("\\sbasedon0\\snext0 heading 2;}\n"));
  405. wxFprintf(fd, _T("{\\s3 ")); WriteHeadingStyle(fd, 3); wxFprintf(fd, _T("\\sbasedon0\\snext0 heading 3;}\n"));
  406. wxFprintf(fd, _T("{\\s4 ")); WriteHeadingStyle(fd, 4); wxFprintf(fd, _T("\\sbasedon0\\snext0 heading 4;}\n"));
  407. // Code style
  408. wxFprintf(fd, _T("{\\s10\\ql \\li720\\ri0\\nowidctlpar\\faauto\\rin0\\lin720\\itap0 \\cbpat17\
  409. \\f2\\fs20 \\sbasedon0 \\snext24 Code;}\n"));
  410. // Table of contents styles
  411. wxFprintf(fd, _T("{\\s20\\sb300\\tqr\\tldot\\tx8640 \\b\\f2 \\sbasedon0\\snext0 toc 1;}\n"));
  412. wxFprintf(fd, _T("{\\s21\\sb90\\tqr\\tldot\\li400\\tqr\\tx8640 \\f2\\fs20\\sbasedon0\\snext0 toc 2;}\n"));
  413. wxFprintf(fd, _T("{\\s22\\sb90\\tqr\\tldot\\li800\\tx8640 \\f2\\fs20 \\sbasedon0\\snext0 toc 3;}\n"));
  414. wxFprintf(fd, _T("{\\s23\\sb90\\tqr\\tldot\\li1200\\tx8640 \\f2\\fs20 \\sbasedon0\\snext0 toc 4;}\n"));
  415. // Index styles
  416. wxFprintf(fd, _T("{\\s30\\fi-200\\li200\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 1;}\n"));
  417. wxFprintf(fd, _T("{\\s31\\fi-200\\li400\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 2;}\n"));
  418. wxFprintf(fd, _T("{\\s32\\fi-200\\li600\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 3;}\n"));
  419. wxFprintf(fd, _T("{\\s33\\fi-200\\li800\\tqr\\tx3960 \\f2\\fs18 \\sbasedon0\\snext0 index 4;}\n"));
  420. wxFprintf(fd, _T("{\\s35\\qc\\sb240\\sa120 \\b\\f2\\fs26 \\sbasedon0\\snext30 index heading;}\n"));
  421. wxFprintf(fd, _T("}\n"));
  422. WriteColourTable(fd);
  423. wxFprintf(fd, _T("\n\\ftnbj\\ftnrestart")); // Latex default is footnotes at bottom of page, not section.
  424. wxFprintf(fd, _T("\n"));
  425. }
  426. void OutputNumberStyle(wxChar *numberStyle)
  427. {
  428. if (numberStyle)
  429. {
  430. if (wxStrcmp(numberStyle, _T("arabic")) == 0)
  431. {
  432. TexOutput(_T("\\pgndec"));
  433. }
  434. else if (wxStrcmp(numberStyle, _T("roman")) == 0)
  435. {
  436. TexOutput(_T("\\pgnlcrm"));
  437. }
  438. else if (wxStrcmp(numberStyle, _T("Roman")) == 0)
  439. {
  440. TexOutput(_T("\\pgnucrm"));
  441. }
  442. else if (wxStrcmp(numberStyle, _T("alph")) == 0)
  443. {
  444. TexOutput(_T("\\pgnlcltr"));
  445. }
  446. else if (wxStrcmp(numberStyle, _T("Alph")) == 0)
  447. {
  448. TexOutput(_T("\\pgnucltr"));
  449. }
  450. }
  451. }
  452. /*
  453. * Write a Windows help project file
  454. */
  455. bool WriteHPJ(const wxString& filename)
  456. {
  457. wxChar hpjFilename[256];
  458. wxChar helpFile[50];
  459. wxChar rtfFile[50];
  460. wxStrcpy(hpjFilename, filename);
  461. StripExtension(hpjFilename);
  462. wxStrcat(hpjFilename, _T(".hpj"));
  463. wxStrcpy(helpFile, wxFileNameFromPath(filename));
  464. StripExtension(helpFile);
  465. wxStrcpy(rtfFile, helpFile);
  466. wxStrcat(helpFile, _T(".hlp"));
  467. wxStrcat(rtfFile, _T(".rtf"));
  468. FILE *fd = wxFopen(hpjFilename, _T("w"));
  469. if (!fd)
  470. return false;
  471. wxChar *helpTitle = winHelpTitle;
  472. if (!helpTitle)
  473. helpTitle = _T("Untitled");
  474. wxString thePath = wxPathOnly(InputFile);
  475. if (thePath.empty())
  476. thePath = _T(".");
  477. wxFprintf(fd, _T("[OPTIONS]\n"));
  478. wxFprintf(fd, _T("BMROOT=%s ; Assume that bitmaps are where the source is\n"), thePath.c_str());
  479. wxFprintf(fd, _T("TITLE=%s\n"), helpTitle);
  480. wxFprintf(fd, _T("CONTENTS=Contents\n"));
  481. if (winHelpVersion > 3)
  482. {
  483. wxFprintf(fd, _T("; COMPRESS=12 Hall Zeck ; Max compression, but needs lots of memory\n"));
  484. wxFprintf(fd, _T("COMPRESS=8 Zeck\n"));
  485. wxFprintf(fd, _T("LCID=0x809 0x0 0x0 ;English (British)\n"));
  486. wxFprintf(fd, _T("HLP=.\\%s.hlp\n"), wxFileNameFromPath(FileRoot));
  487. }
  488. else
  489. {
  490. wxFprintf(fd, _T("COMPRESS=HIGH\n"));
  491. }
  492. wxFprintf(fd, _T("\n"));
  493. if (winHelpVersion > 3)
  494. {
  495. wxFprintf(fd, _T("[WINDOWS]\n"));
  496. wxFprintf(fd, _T("Main=\"\",(553,102,400,600),20736,(r14876671),(r12632256),f3\n"));
  497. wxFprintf(fd, _T("\n"));
  498. }
  499. wxFprintf(fd, _T("[FILES]\n%s\n\n"), rtfFile);
  500. wxFprintf(fd, _T("[CONFIG]\n"));
  501. if (useUpButton)
  502. wxFprintf(fd, _T("CreateButton(\"Up\", \"&Up\", \"JumpId(`%s', `Contents')\")\n"), helpFile);
  503. wxFprintf(fd, _T("BrowseButtons()\n\n"));
  504. wxFprintf(fd, _T("[MAP]\n\n[BITMAPS]\n\n"));
  505. fclose(fd);
  506. return true;
  507. }
  508. /*
  509. * Given a TexChunk with a string value, scans through the string
  510. * converting Latex-isms into RTF-isms, such as 2 newlines -> \par,
  511. * and inserting spaces at the start of lines since in Latex, a newline
  512. * implies a space, but not in RTF.
  513. *
  514. */
  515. void ProcessText2RTF(TexChunk *chunk)
  516. {
  517. bool changed = false;
  518. int ptr = 0;
  519. int i = 0;
  520. wxChar ch = 1;
  521. int len = wxStrlen(chunk->value);
  522. while (ch != 0)
  523. {
  524. ch = chunk->value[i];
  525. if (ch == 10)
  526. {
  527. if (inVerbatim)
  528. {
  529. BigBuffer[ptr] = 0; wxStrcat(BigBuffer, _T("\\par\n")); ptr += 5;
  530. // BigBuffer[ptr] = 0; wxStrcat(BigBuffer, _T("\\par{\\v this was verbatim}\n")); ptr += 5;
  531. i ++;
  532. changed = true;
  533. }
  534. else
  535. {
  536. // If the first character of the next line is ASCII,
  537. // put a space in. Implicit in Latex, not in RTF.
  538. /*
  539. The reason this is difficult is that you don't really know
  540. where a space would be appropriate. If you always put in a space
  541. when you find a newline, unwanted spaces appear in the text.
  542. */
  543. if ((i > 0) && (len > i+1 && isascii(chunk->value[i+1]) &&
  544. !isspace(chunk->value[i+1])) ||
  545. ((len > i+1 && chunk->value[i+1] == 13) &&
  546. (len > i+2 && isascii(chunk->value[i+2]) &&
  547. !isspace(chunk->value[i+2]))))
  548. // if (true)
  549. {
  550. // DOS files have a 13 after the 10
  551. BigBuffer[ptr] = 10;
  552. ptr ++;
  553. i ++;
  554. if (chunk->value[i] == 13)
  555. {
  556. BigBuffer[ptr] = 13;
  557. ptr ++;
  558. i ++;
  559. }
  560. BigBuffer[ptr] = ' ';
  561. ptr ++;
  562. // Note that the actual ASCII character seen is dealt with in the next
  563. // iteration
  564. changed = true;
  565. }
  566. else
  567. {
  568. BigBuffer[ptr] = ch;
  569. i ++;
  570. }
  571. }
  572. }
  573. else if (!inVerbatim && ch == '`' && (len >= i+1 && chunk->value[i+1] == '`'))
  574. {
  575. BigBuffer[ptr] = '"'; ptr ++;
  576. i += 2;
  577. changed = true;
  578. }
  579. else if (!inVerbatim && ch == '`') // Change ` to '
  580. {
  581. BigBuffer[ptr] = 39; ptr ++;
  582. i += 1;
  583. changed = true;
  584. }
  585. else if (inVerbatim && ch == '\\') // Change backslash to two backslashes
  586. {
  587. BigBuffer[ptr] = '\\'; ptr ++;
  588. BigBuffer[ptr] = '\\'; ptr ++;
  589. i += 1;
  590. changed = true;
  591. }
  592. else if (inVerbatim && (ch == '{' || ch == '}')) // Escape the curly bracket
  593. {
  594. BigBuffer[ptr] = '\\'; ptr ++;
  595. BigBuffer[ptr] = ch; ptr ++;
  596. i += 1;
  597. changed = true;
  598. }
  599. else
  600. {
  601. BigBuffer[ptr] = ch;
  602. i ++;
  603. ptr ++;
  604. }
  605. }
  606. BigBuffer[ptr] = 0;
  607. if (changed)
  608. {
  609. delete[] chunk->value;
  610. chunk->value = copystring(BigBuffer);
  611. }
  612. }
  613. /*
  614. * Scan through all chunks starting from the given one,
  615. * calling ProcessText2RTF to convert Latex-isms to RTF-isms.
  616. * This should be called after Tex2Any has parsed the file,
  617. * and before TraverseDocument is called.
  618. *
  619. */
  620. void Text2RTF(TexChunk *chunk)
  621. {
  622. Tex2RTFYield();
  623. if (stopRunning) return;
  624. switch (chunk->type)
  625. {
  626. case CHUNK_TYPE_MACRO:
  627. {
  628. TexMacroDef *def = chunk->def;
  629. if (def && def->ignore)
  630. return;
  631. if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB))
  632. inVerbatim = true;
  633. wxNode *node = chunk->children.GetFirst();
  634. while (node)
  635. {
  636. TexChunk *child_chunk = (TexChunk *)node->GetData();
  637. Text2RTF(child_chunk);
  638. node = node->GetNext();
  639. }
  640. if (def && (def->macroId == ltVERBATIM || def->macroId == ltVERB))
  641. inVerbatim = false;
  642. break;
  643. }
  644. case CHUNK_TYPE_ARG:
  645. {
  646. wxNode *node = chunk->children.GetFirst();
  647. while (node)
  648. {
  649. TexChunk *child_chunk = (TexChunk *)node->GetData();
  650. Text2RTF(child_chunk);
  651. node = node->GetNext();
  652. }
  653. break;
  654. }
  655. case CHUNK_TYPE_STRING:
  656. {
  657. if (chunk->value)
  658. ProcessText2RTF(chunk);
  659. break;
  660. }
  661. }
  662. }
  663. /*
  664. * Not used yet
  665. *
  666. */
  667. wxChar browseBuf[10];
  668. static long browseId = 0;
  669. wxChar *GetBrowseString(void)
  670. {
  671. wxChar buf[10];
  672. browseId ++;
  673. wxSnprintf(buf, sizeof(buf), _T("%ld"), browseId);
  674. int noZeroes = 5-wxStrlen(buf);
  675. wxStrcpy(browseBuf, _T("browse"));
  676. for (int i = 0; i < noZeroes; i++)
  677. wxStrcat(browseBuf, _T("0"));
  678. wxStrcat(browseBuf, buf);
  679. return browseBuf;
  680. }
  681. /*
  682. * Keeping track of environments to restore the styles after \pard.
  683. * Push strings like "\qc" onto stack.
  684. *
  685. */
  686. void PushEnvironmentStyle(wxChar *style)
  687. {
  688. environmentStack.Add(style);
  689. }
  690. void PopEnvironmentStyle(void)
  691. {
  692. wxStringListNode *node = environmentStack.GetLast();
  693. if (node)
  694. {
  695. wxChar *val = (wxChar *)node->GetData();
  696. delete[] val;
  697. delete node;
  698. }
  699. }
  700. // Write out the styles, most recent first.
  701. void WriteEnvironmentStyles(void)
  702. {
  703. wxStringListNode *node = environmentStack.GetLast();
  704. while (node)
  705. {
  706. wxChar *val = (wxChar *)node->GetData();
  707. TexOutput(val);
  708. node = node->GetNext();
  709. }
  710. if (!inTabular && (ParIndent > 0) && (forbidParindent == 0))
  711. {
  712. wxChar buf[15];
  713. wxSnprintf(buf, sizeof(buf), _T("\\fi%d"), ParIndent*20); // Convert points to TWIPS
  714. TexOutput(buf);
  715. }
  716. if (environmentStack.GetCount() > 0 || (ParIndent > 0))
  717. TexOutput(_T("\n"));
  718. }
  719. /*
  720. * Output a header
  721. *
  722. */
  723. void OutputRTFHeaderCommands(void)
  724. {
  725. wxChar buf[300];
  726. if (PageStyle && wxStrcmp(PageStyle, _T("plain")) == 0)
  727. {
  728. TexOutput(_T("{\\headerl }{\\headerr }"));
  729. }
  730. else if (PageStyle && wxStrcmp(PageStyle, _T("empty")) == 0)
  731. {
  732. TexOutput(_T("{\\headerl }{\\headerr }"));
  733. }
  734. else if (PageStyle && wxStrcmp(PageStyle, _T("headings")) == 0)
  735. {
  736. // Left header
  737. TexOutput(_T("{\\headerl\\fi0 "));
  738. if (headerRule)
  739. TexOutput(_T("\\brdrb\\brdrs\\brdrw15\\brsp20 "));
  740. TexOutput(_T("{\\i \\qr "));
  741. if (DocumentStyle == LATEX_ARTICLE)
  742. {
  743. wxSnprintf(buf, sizeof(buf), _T("SECTION %d"), sectionNo);
  744. TexOutput(buf);
  745. }
  746. else
  747. {
  748. wxSnprintf(buf, sizeof(buf), _T("CHAPTER %d: "), chapterNo);
  749. TexOutput(buf);
  750. }
  751. TexOutput(_T("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}"));
  752. TexOutput(_T("}\\par\\pard}"));
  753. // Right header
  754. TexOutput(_T("{\\headerr\\fi0 "));
  755. if (headerRule)
  756. TexOutput(_T("\\brdrb\\brdrs\\brdrw15\\brsp20 "));
  757. TexOutput(_T("{\\i \\qc "));
  758. if (DocumentStyle == LATEX_ARTICLE)
  759. {
  760. wxSnprintf(buf, sizeof(buf), _T("SECTION %d"), sectionNo);
  761. TexOutput(buf);
  762. }
  763. else
  764. {
  765. wxSnprintf(buf, sizeof(buf), _T("CHAPTER %d"), chapterNo);
  766. TexOutput(buf);
  767. }
  768. TexOutput(_T("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}"));
  769. TexOutput(_T("}\\par\\pard}"));
  770. }
  771. else
  772. {
  773. int oldForbidResetPar = forbidResetPar;
  774. forbidResetPar = 0;
  775. if (LeftHeaderEven || CentreHeaderEven || RightHeaderEven)
  776. {
  777. TexOutput(_T("{\\headerl\\fi0 "));
  778. if (headerRule)
  779. TexOutput(_T("\\brdrb\\brdrs\\brdrw15\\brsp20 "));
  780. if (LeftHeaderEven)
  781. {
  782. if (!CentreHeaderEven && !RightHeaderEven)
  783. TexOutput(_T("\\ql "));
  784. TraverseChildrenFromChunk(LeftHeaderEven);
  785. }
  786. if (CentreHeaderEven)
  787. {
  788. if (!LeftHeaderEven && !RightHeaderEven)
  789. TexOutput(_T("\\qc "));
  790. else
  791. TexOutput(_T("\\tab\\tab\\tab "));
  792. TraverseChildrenFromChunk(CentreHeaderEven);
  793. }
  794. if (RightHeaderEven)
  795. {
  796. if (!LeftHeaderEven && !CentreHeaderEven)
  797. TexOutput(_T("\\qr "));
  798. else
  799. TexOutput(_T("\\tab\\tab\\tab\\tab\\tab\\tab "));
  800. TraverseChildrenFromChunk(RightHeaderEven);
  801. }
  802. TexOutput(_T("\\par\\pard}"));
  803. }
  804. if (LeftHeaderOdd || CentreHeaderOdd || RightHeaderOdd)
  805. {
  806. TexOutput(_T("{\\headerr\\fi0 "));
  807. if (headerRule)
  808. TexOutput(_T("\\brdrb\\brdrs\\brdrw15\\brsp20 "));
  809. if (LeftHeaderOdd)
  810. {
  811. if (!CentreHeaderOdd && !RightHeaderOdd)
  812. TexOutput(_T("\\ql "));
  813. TraverseChildrenFromChunk(LeftHeaderOdd);
  814. }
  815. if (CentreHeaderOdd)
  816. {
  817. if (!LeftHeaderOdd && !RightHeaderOdd)
  818. TexOutput(_T("\\qc "));
  819. else
  820. TexOutput(_T("\\tab\\tab\\tab "));
  821. TraverseChildrenFromChunk(CentreHeaderOdd);
  822. }
  823. if (RightHeaderOdd)
  824. {
  825. if (!LeftHeaderOdd && !CentreHeaderOdd)
  826. TexOutput(_T("\\qr "));
  827. else
  828. TexOutput(_T("\\tab\\tab\\tab\\tab\\tab\\tab "));
  829. TraverseChildrenFromChunk(RightHeaderOdd);
  830. }
  831. TexOutput(_T("\\par\\pard}"));
  832. }
  833. // As an approximation, don't put a header on the first page of a section.
  834. // This may not always be desired, but it's a reasonable guess.
  835. TexOutput(_T("{\\headerf }"));
  836. forbidResetPar = oldForbidResetPar;
  837. }
  838. }
  839. void OutputRTFFooterCommands(void)
  840. {
  841. if (PageStyle && wxStrcmp(PageStyle, _T("plain")) == 0)
  842. {
  843. TexOutput(_T("{\\footerl\\fi0 "));
  844. if (footerRule)
  845. TexOutput(_T("\\brdrt\\brdrs\\brdrw15\\brsp20 "));
  846. TexOutput(_T("{\\qc "));
  847. TexOutput(_T("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}"));
  848. TexOutput(_T("}\\par\\pard}"));
  849. TexOutput(_T("{\\footerr\\fi0 "));
  850. if (footerRule)
  851. TexOutput(_T("\\brdrt\\brdrs\\brdrw15\\brsp20 "));
  852. TexOutput(_T("{\\qc "));
  853. TexOutput(_T("{\\field{\\*\\fldinst PAGE \\\\* MERGEFORMAT }{\\fldrslt 1}}"));
  854. TexOutput(_T("}\\par\\pard}"));
  855. }
  856. else if (PageStyle && wxStrcmp(PageStyle, _T("empty")) == 0)
  857. {
  858. TexOutput(_T("{\\footerl }{\\footerr }"));
  859. }
  860. else if (PageStyle && wxStrcmp(PageStyle, _T("headings")) == 0)
  861. {
  862. TexOutput(_T("{\\footerl }{\\footerr }"));
  863. }
  864. else
  865. {
  866. if (LeftFooterEven || CentreFooterEven || RightFooterEven)
  867. {
  868. TexOutput(_T("{\\footerl\\fi0 "));
  869. if (footerRule)
  870. TexOutput(_T("\\brdrt\\brdrs\\brdrw15\\brsp20 "));
  871. if (LeftFooterEven)
  872. {
  873. if (!CentreFooterEven && !RightFooterEven)
  874. TexOutput(_T("\\ql "));
  875. TraverseChildrenFromChunk(LeftFooterEven);
  876. }
  877. if (CentreFooterEven)
  878. {
  879. if (!LeftFooterEven && !RightFooterEven)
  880. TexOutput(_T("\\qc "));
  881. else
  882. TexOutput(_T("\\tab\\tab\\tab "));
  883. TraverseChildrenFromChunk(CentreFooterEven);
  884. }
  885. if (RightFooterEven)
  886. {
  887. if (!LeftFooterEven && !CentreFooterEven)
  888. TexOutput(_T("\\qr "));
  889. else
  890. TexOutput(_T("\\tab\\tab\\tab\\tab\\tab\\tab "));
  891. TraverseChildrenFromChunk(RightFooterEven);
  892. }
  893. TexOutput(_T("\\par\\pard}"));
  894. }
  895. if (LeftFooterOdd || CentreFooterOdd || RightFooterOdd)
  896. {
  897. TexOutput(_T("{\\footerr\\fi0 "));
  898. if (footerRule)
  899. TexOutput(_T("\\brdrt\\brdrs\\brdrw15\\brsp20 "));
  900. if (LeftFooterOdd)
  901. {
  902. if (!CentreFooterOdd && !RightFooterOdd)
  903. TexOutput(_T("\\ql "));
  904. TraverseChildrenFromChunk(LeftFooterOdd);
  905. }
  906. if (CentreFooterOdd)
  907. {
  908. if (!LeftFooterOdd && !RightFooterOdd)
  909. TexOutput(_T("\\qc "));
  910. else
  911. TexOutput(_T("\\tab\\tab\\tab "));
  912. TraverseChildrenFromChunk(CentreFooterOdd);
  913. }
  914. if (RightFooterOdd)
  915. {
  916. if (!LeftFooterOdd && !CentreFooterOdd)
  917. TexOutput(_T("\\qr "));
  918. else
  919. TexOutput(_T("\\tab\\tab\\tab\\tab\\tab\\tab "));
  920. TraverseChildrenFromChunk(RightFooterOdd);
  921. }
  922. TexOutput(_T("\\par\\pard}"));
  923. }
  924. // As an approximation, put a footer on the first page of a section.
  925. // This may not always be desired, but it's a reasonable guess.
  926. if (LeftFooterOdd || CentreFooterOdd || RightFooterOdd)
  927. {
  928. TexOutput(_T("{\\footerf\\fi0 "));
  929. if (LeftFooterOdd)
  930. {
  931. if (!CentreFooterOdd && !RightFooterOdd)
  932. TexOutput(_T("\\ql "));
  933. TraverseChildrenFromChunk(LeftFooterOdd);
  934. }
  935. if (CentreFooterOdd)
  936. {
  937. if (!LeftFooterOdd && !RightFooterOdd)
  938. TexOutput(_T("\\qc "));
  939. else
  940. TexOutput(_T("\\tab\\tab\\tab "));
  941. TraverseChildrenFromChunk(CentreFooterOdd);
  942. }
  943. if (RightFooterOdd)
  944. {
  945. if (!LeftFooterOdd && !CentreFooterOdd)
  946. TexOutput(_T("\\qr "));
  947. else
  948. TexOutput(_T("\\tab\\tab\\tab\\tab\\tab\\tab "));
  949. TraverseChildrenFromChunk(RightFooterOdd);
  950. }
  951. TexOutput(_T("\\par\\pard}"));
  952. }
  953. }
  954. }
  955. // Called on start/end of macro examination
  956. void RTFOnMacro(int macroId, int no_args, bool start)
  957. {
  958. /*
  959. wxChar tmpBuf[40];
  960. wxSnprintf(tmpBuf, sizeof(tmpBuf), _T("%d (%d)"), macroId, (int)start);
  961. OutputDebugString("RTFOnMacro Start "); OutputDebugString(tmpBuf);
  962. OutputDebugString("\n"); wxYield();
  963. */
  964. // ltLABEL is included here because after a section but BEFORE
  965. // the label is seen, a new paragraph is issued. Don't upset this by
  966. // immediately forgetting we've done it.
  967. if (start && (macroId != ltPAR && macroId != ltITEMIZE &&
  968. macroId != ltENUMERATE && macroId != ltDESCRIPTION &&
  969. macroId != ltVERBATIM && macroId != ltLABEL &&
  970. macroId != ltSETHEADER && macroId != ltSETFOOTER &&
  971. macroId != ltPAGENUMBERING &&
  972. (forbidResetPar == 0)))
  973. {
  974. issuedNewParagraph = 0;
  975. }
  976. wxChar buf[300];
  977. switch (macroId)
  978. {
  979. case ltCHAPTER:
  980. case ltCHAPTERSTAR:
  981. case ltCHAPTERHEADING:
  982. case ltCHAPTERHEADINGSTAR:
  983. {
  984. if (!start)
  985. {
  986. sectionNo = 0;
  987. figureNo = 0;
  988. tableNo = 0;
  989. subsectionNo = 0;
  990. subsubsectionNo = 0;
  991. footnoteCount = 0;
  992. if (macroId != ltCHAPTERSTAR && macroId != ltCHAPTERHEADINGSTAR)
  993. chapterNo ++;
  994. wxChar *topicName = FindTopicName(GetNextChunk());
  995. SetCurrentChapterName(topicName);
  996. if (winHelpContents && winHelp && !InPopups())
  997. {
  998. OutputCurrentSectionToString(wxTex2RTFBuffer);
  999. WriteWinHelpContentsFileLine(topicName, wxTex2RTFBuffer, 1);
  1000. }
  1001. AddTexRef(topicName, NULL, ChapterNameString, chapterNo);
  1002. if (winHelp)
  1003. {
  1004. if (!InPopups())
  1005. wxFprintf(Contents, _T("\n{\\uldb "));
  1006. wxFprintf(Chapters, _T("\\page"));
  1007. wxFprintf(Chapters, _T("\n${\\footnote "));
  1008. if (!InPopups())
  1009. SetCurrentOutputs(Contents, Chapters);
  1010. else
  1011. SetCurrentOutput(Chapters);
  1012. }
  1013. else
  1014. {
  1015. wxFprintf(Chapters, _T("\\sect\\pgncont\\titlepg\n"));
  1016. // If a non-custom page style, we generate the header now.
  1017. if (PageStyle && (wxStrcmp(PageStyle, _T("plain")) == 0 ||
  1018. wxStrcmp(PageStyle, _T("empty")) == 0 ||
  1019. wxStrcmp(PageStyle, _T("headings")) == 0))
  1020. {
  1021. OutputRTFHeaderCommands();
  1022. OutputRTFFooterCommands();
  1023. }
  1024. // Need to reset the current numbering style, or RTF forgets it.
  1025. SetCurrentOutput(Chapters);
  1026. OutputNumberStyle(currentNumberStyle);
  1027. SetCurrentOutput(Contents);
  1028. if (!InPopups())
  1029. {
  1030. if (macroId == ltCHAPTER)
  1031. {
  1032. // Section
  1033. wxFprintf(Contents, _T("\\par\n\\pard{\\b %d\\tab "), chapterNo);
  1034. }
  1035. else if (macroId == ltCHAPTERHEADING)
  1036. {
  1037. wxFprintf(Contents, _T("\\par\n\\pard{\\b "));
  1038. }
  1039. else SetCurrentOutput(NULL); // No entry in table of contents
  1040. }
  1041. }
  1042. startedSections = true;
  1043. // Output heading to contents page
  1044. if (!InPopups())
  1045. {
  1046. OutputCurrentSection();
  1047. if (winHelp)
  1048. {
  1049. wxFprintf(Contents, _T("}{\\v %s}\\pard\\par\n"), topicName);
  1050. //WriteEnvironmentStyles();
  1051. }
  1052. else if ((macroId == ltCHAPTER) || (macroId == ltCHAPTERHEADING))
  1053. wxFprintf(Contents, _T("}\\par\\par\\pard\n"));
  1054. // From here, just output to chapter
  1055. SetCurrentOutput(Chapters);
  1056. }
  1057. if (winHelp)
  1058. {
  1059. wxFprintf(Chapters, _T("}\n#{\\footnote %s}\n"), topicName);
  1060. wxFprintf(Chapters, _T("+{\\footnote %s}\n"), GetBrowseString());
  1061. OutputSectionKeyword(Chapters);
  1062. GenerateKeywordsForTopic(topicName);
  1063. if (useUpButton)
  1064. {
  1065. // If we're generating a .cnt file, we don't want to be able
  1066. // jump up to the old-style contents page, so disable it.
  1067. if (winHelpContents)
  1068. wxFprintf(Chapters, _T("!{\\footnote DisableButton(\"Up\")}\n"));
  1069. else
  1070. wxFprintf(Chapters, _T("!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n"),
  1071. wxFileNameFromPath(FileRoot), _T("Contents"));
  1072. }
  1073. }
  1074. if (!InPopups())
  1075. {
  1076. wxChar *styleCommand = _T("");
  1077. if (!winHelp && useHeadingStyles && (macroId == ltCHAPTER || macroId == ltCHAPTERHEADING || macroId == ltCHAPTERHEADINGSTAR))
  1078. styleCommand = _T("\\s1");
  1079. wxFprintf(Chapters, _T("\\pard{%s"), ((winHelp && !InPopups()) ? _T("\\keepn\\sa140\\sb140") : styleCommand));
  1080. WriteHeadingStyle(Chapters, 1); wxFprintf(Chapters, _T(" "));
  1081. if (!winHelp)
  1082. {
  1083. if (macroId == ltCHAPTER)
  1084. {
  1085. if (useWord)
  1086. // wxFprintf(Chapters, "{\\bkmkstart %s}%d{\\bkmkend %s}. ", topicName, chapterNo,
  1087. wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName, topicName);
  1088. else
  1089. wxFprintf(Chapters, _T("%d. "), chapterNo);
  1090. }
  1091. else if ( useWord )
  1092. {
  1093. wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName, topicName);
  1094. }
  1095. }
  1096. OutputCurrentSection();
  1097. TexOutput(_T("\\par\\pard}\n"));
  1098. }
  1099. issuedNewParagraph = 1;
  1100. WriteEnvironmentStyles();
  1101. }
  1102. break;
  1103. }
  1104. case ltSECTION:
  1105. case ltSECTIONSTAR:
  1106. case ltSECTIONHEADING:
  1107. case ltSECTIONHEADINGSTAR:
  1108. case ltGLOSS:
  1109. {
  1110. FILE *jumpFrom;
  1111. if (DocumentStyle == LATEX_ARTICLE)
  1112. jumpFrom = Contents;
  1113. else
  1114. jumpFrom = Chapters;
  1115. if (!start)
  1116. {
  1117. subsectionNo = 0;
  1118. subsubsectionNo = 0;
  1119. if (DocumentStyle == LATEX_ARTICLE)
  1120. footnoteCount = 0;
  1121. if (macroId != ltSECTIONSTAR && macroId != ltSECTIONHEADINGSTAR)
  1122. sectionNo ++;
  1123. wxChar *topicName = FindTopicName(GetNextChunk());
  1124. SetCurrentSectionName(topicName);
  1125. NotifyParentHasChildren(1);
  1126. if (winHelpContents && winHelp && !InPopups())
  1127. {
  1128. OutputCurrentSectionToString(wxTex2RTFBuffer);
  1129. WriteWinHelpContentsFileLine(topicName, wxTex2RTFBuffer, 2);
  1130. }
  1131. AddTexRef(topicName, NULL, SectionNameString, chapterNo, sectionNo);
  1132. if (winHelp)
  1133. {
  1134. SetCurrentOutputs(jumpFrom, Sections);
  1135. // Newline for a new section if this is an article
  1136. if ((DocumentStyle == LATEX_ARTICLE) &&
  1137. ((macroId == ltSECTION) || (macroId == ltSECTIONSTAR) || (macroId == ltSECTIONHEADINGSTAR)))
  1138. wxFprintf(Sections, _T("\\page\n"));
  1139. if (!InPopups())
  1140. wxFprintf(jumpFrom, _T("\n{\\uldb "));
  1141. }
  1142. else
  1143. {
  1144. if (DocumentStyle == LATEX_ARTICLE)
  1145. {
  1146. TexOutput(_T("\\sect\\pgncont\n"));
  1147. // If a non-custom page style, we generate the header now.
  1148. if (PageStyle && (wxStrcmp(PageStyle, _T("plain")) == 0 ||
  1149. wxStrcmp(PageStyle, _T("empty")) == 0 ||
  1150. wxStrcmp(PageStyle, _T("headings")) == 0))
  1151. {
  1152. OutputRTFHeaderCommands();
  1153. OutputRTFFooterCommands();
  1154. }
  1155. }
  1156. SetCurrentOutput(Contents);
  1157. if (macroId == ltSECTION)
  1158. {
  1159. if (!InPopups())
  1160. {
  1161. if (DocumentStyle == LATEX_REPORT)
  1162. wxFprintf(Contents, _T("\n\\pard{\\tab %d.%d\\tab "), chapterNo, sectionNo);
  1163. else
  1164. wxFprintf(Contents, _T("\\par\n\\pard{\\b %d\\tab "), sectionNo);
  1165. }
  1166. }
  1167. else if (macroId == ltSECTIONHEADING)
  1168. {
  1169. if (!InPopups())
  1170. {
  1171. if (DocumentStyle == LATEX_REPORT)
  1172. wxFprintf(Contents, _T("\n\\pard{\\tab ")); //, chapterNo, sectionNo);
  1173. else
  1174. wxFprintf(Contents, _T("\\par\n\\pard{\\b ")); //, sectionNo);
  1175. }
  1176. }
  1177. else SetCurrentOutput(NULL);
  1178. }
  1179. if (startedSections)
  1180. {
  1181. if (winHelp)
  1182. wxFprintf(Sections, _T("\\page\n"));
  1183. }
  1184. startedSections = true;
  1185. if (winHelp)
  1186. wxFprintf(Sections, _T("\n${\\footnote "));
  1187. // Output heading to contents page
  1188. if (!InPopups())
  1189. OutputCurrentSection();
  1190. if (winHelp)
  1191. {
  1192. if (!InPopups())
  1193. {
  1194. wxFprintf(jumpFrom, _T("}{\\v %s}\\pard\\par\n"), topicName);
  1195. //WriteEnvironmentStyles();
  1196. }
  1197. }
  1198. else if ((macroId != ltSECTIONSTAR) && (macroId != ltGLOSS))
  1199. {
  1200. if (DocumentStyle == LATEX_REPORT)
  1201. wxFprintf(Contents, _T("}\\par\\pard\n"));
  1202. else
  1203. wxFprintf(Contents, _T("}\\par\\par\\pard\n"));
  1204. }
  1205. SetCurrentOutput(winHelp ? Sections : Chapters);
  1206. if (winHelp)
  1207. {
  1208. wxFprintf(Sections, _T("}\n#{\\footnote %s}\n"), topicName);
  1209. wxFprintf(Sections, _T("+{\\footnote %s}\n"), GetBrowseString());
  1210. OutputSectionKeyword(Sections);
  1211. GenerateKeywordsForTopic(topicName);
  1212. if (useUpButton)
  1213. {
  1214. if (DocumentStyle == LATEX_ARTICLE)
  1215. {
  1216. wxFprintf(Sections, _T("!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n"),
  1217. wxFileNameFromPath(FileRoot), _T("Contents"));
  1218. }
  1219. else if (CurrentChapterName)
  1220. {
  1221. wxFprintf(Sections, _T("!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n"),
  1222. wxFileNameFromPath(FileRoot), CurrentChapterName);
  1223. }
  1224. }
  1225. }
  1226. if (!InPopups())
  1227. {
  1228. wxChar *styleCommand = _T("");
  1229. if (!winHelp && useHeadingStyles && (macroId != ltSECTIONSTAR))
  1230. {
  1231. if (DocumentStyle == LATEX_ARTICLE)
  1232. styleCommand = _T("\\s1");
  1233. else
  1234. styleCommand = _T("\\s2");
  1235. }
  1236. wxChar *keep = _T("");
  1237. if (winHelp && (macroId != ltGLOSS) && !InPopups())
  1238. keep = _T("\\keepn\\sa140\\sb140");
  1239. wxFprintf(winHelp ? Sections : Chapters, _T("\\pard{%s%s"),
  1240. keep, styleCommand);
  1241. WriteHeadingStyle((winHelp ? Sections : Chapters),
  1242. (DocumentStyle == LATEX_ARTICLE ? 1 : 2));
  1243. wxFprintf(winHelp ? Sections : Chapters, _T(" "));
  1244. if (!winHelp)
  1245. {
  1246. if ((macroId != ltSECTIONSTAR) && (macroId != ltSECTIONHEADINGSTAR) && (macroId != ltGLOSS))
  1247. {
  1248. if (DocumentStyle == LATEX_REPORT)
  1249. {
  1250. if (useWord)
  1251. // wxFprintf(Chapters, _T("{\\bkmkstart %s}%d.%d{\\bkmkend %s}. "), topicName, chapterNo, sectionNo,
  1252. wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName,
  1253. topicName);
  1254. else
  1255. wxFprintf(Chapters, _T("%d.%d. "), chapterNo, sectionNo);
  1256. }
  1257. else
  1258. {
  1259. if (useWord)
  1260. // wxFprintf(Chapters, "{\\bkmkstart %s}%d{\\bkmkend %s}. ", topicName, sectionNo,
  1261. wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName,
  1262. topicName);
  1263. else
  1264. wxFprintf(Chapters, _T("%d. "), sectionNo);
  1265. }
  1266. }
  1267. else if ( useWord )
  1268. {
  1269. wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName, topicName);
  1270. }
  1271. }
  1272. OutputCurrentSection();
  1273. TexOutput(_T("\\par\\pard}\n"));
  1274. // TexOutput(_T("\\par\\pard}\\par\n"));
  1275. }
  1276. issuedNewParagraph = 1;
  1277. WriteEnvironmentStyles();
  1278. // issuedNewParagraph = 2;
  1279. }
  1280. break;
  1281. }
  1282. case ltSUBSECTION:
  1283. case ltSUBSECTIONSTAR:
  1284. case ltMEMBERSECTION:
  1285. case ltFUNCTIONSECTION:
  1286. {
  1287. if (!start)
  1288. {
  1289. if (winHelp && !Sections)
  1290. {
  1291. OnError(_T("You cannot have a subsection before a section!"));
  1292. }
  1293. else
  1294. {
  1295. subsubsectionNo = 0;
  1296. if (macroId != ltSUBSECTIONSTAR)
  1297. subsectionNo ++;
  1298. wxChar *topicName = FindTopicName(GetNextChunk());
  1299. SetCurrentSubsectionName(topicName);
  1300. NotifyParentHasChildren(2);
  1301. if (winHelpContents && winHelp && !InPopups())
  1302. {
  1303. OutputCurrentSectionToString(wxTex2RTFBuffer);
  1304. WriteWinHelpContentsFileLine(topicName, wxTex2RTFBuffer, 3);
  1305. }
  1306. AddTexRef(topicName, NULL, SectionNameString, chapterNo, sectionNo, subsectionNo);
  1307. if (winHelp)
  1308. {
  1309. SetCurrentOutputs(Sections, Subsections);
  1310. SetCurrentOutputs(Sections, Subsections);
  1311. if (!InPopups())
  1312. wxFprintf(Sections, _T("\n{\\uldb "));
  1313. }
  1314. else
  1315. {
  1316. if ((macroId != ltSUBSECTIONSTAR) && (macroId != ltMEMBERSECTION) &&
  1317. (macroId != ltFUNCTIONSECTION))
  1318. {
  1319. SetCurrentOutput(Contents);
  1320. if (DocumentStyle == LATEX_REPORT)
  1321. wxFprintf(Contents, _T("\n\\pard\\tab\\tab %d.%d.%d\\tab "), chapterNo, sectionNo, subsectionNo);
  1322. else
  1323. wxFprintf(Contents, _T("\n\\pard\\tab %d.%d\\tab "), sectionNo, subsectionNo);
  1324. } else SetCurrentOutput(NULL);
  1325. }
  1326. if (startedSections)
  1327. {
  1328. if (winHelp)
  1329. {
  1330. if (!InPopups())
  1331. wxFprintf(Subsections, _T("\\page\n"));
  1332. }
  1333. // Experimental JACS 2004-02-21
  1334. #if 0
  1335. else
  1336. wxFprintf(Chapters, _T("\\par\n"));
  1337. #endif
  1338. }
  1339. startedSections = true;
  1340. if (winHelp)
  1341. wxFprintf(Subsections, _T("\n${\\footnote "));
  1342. // Output to contents page
  1343. if (!InPopups())
  1344. OutputCurrentSection();
  1345. if (winHelp)
  1346. {
  1347. if (!InPopups())
  1348. {
  1349. wxFprintf(Sections, _T("}{\\v %s}\\pard\\par\n"), topicName);
  1350. //WriteEnvironmentStyles();
  1351. }
  1352. }
  1353. else if ((macroId != ltSUBSECTIONSTAR) && (macroId != ltMEMBERSECTION) &&
  1354. (macroId != ltFUNCTIONSECTION))
  1355. wxFprintf(Contents, _T("\\par\\pard\n"));
  1356. SetCurrentOutput(winHelp ? Subsections : Chapters);
  1357. if (winHelp)
  1358. {
  1359. wxFprintf(Subsections, _T("}\n#{\\footnote %s}\n"), topicName);
  1360. wxFprintf(Subsections, _T("+{\\footnote %s}\n"), GetBrowseString());
  1361. OutputSectionKeyword(Subsections);
  1362. GenerateKeywordsForTopic(topicName);
  1363. if (useUpButton && CurrentSectionName)
  1364. {
  1365. wxFprintf(Subsections, _T("!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n"),
  1366. wxFileNameFromPath(FileRoot), CurrentSectionName);
  1367. }
  1368. }
  1369. if (!winHelp && indexSubsections && useWord)
  1370. {
  1371. // Insert index entry for this subsection
  1372. TexOutput(_T("{\\xe\\v {"));
  1373. OutputCurrentSection();
  1374. TexOutput(_T("}}"));
  1375. }
  1376. if (!InPopups())
  1377. {
  1378. wxChar *styleCommand = _T("");
  1379. if (!winHelp && useHeadingStyles && (macroId != ltSUBSECTIONSTAR))
  1380. {
  1381. if (DocumentStyle == LATEX_ARTICLE)
  1382. styleCommand = _T("\\s2");
  1383. else
  1384. styleCommand = _T("\\s3");
  1385. }
  1386. wxChar *keep = _T("");
  1387. if (winHelp && !InPopups())
  1388. keep = _T("\\keepn\\sa140\\sb140");
  1389. wxFprintf(winHelp ? Subsections : Chapters, _T("\\pard{%s%s"),
  1390. keep, styleCommand);
  1391. WriteHeadingStyle((winHelp ? Subsections : Chapters),
  1392. (DocumentStyle == LATEX_ARTICLE ? 2 : 3));
  1393. wxFprintf(winHelp ? Subsections : Chapters, _T(" "));
  1394. if (!winHelp)
  1395. {
  1396. if ((macroId != ltSUBSECTIONSTAR) && (macroId != ltMEMBERSECTION) &&
  1397. (macroId != ltFUNCTIONSECTION))
  1398. {
  1399. if (DocumentStyle == LATEX_REPORT)
  1400. {
  1401. if (useWord)
  1402. // wxFprintf(Chapters, _T("{\\bkmkstart %s}%d.%d.%d{\\bkmkend %s}. "), topicName, chapterNo, sectionNo, subsectionNo,
  1403. wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName,
  1404. topicName);
  1405. else
  1406. wxFprintf(Chapters, _T("%d.%d.%d. "), chapterNo, sectionNo, subsectionNo);
  1407. }
  1408. else
  1409. {
  1410. if (useWord)
  1411. // wxFprintf(Chapters, _T("{\\bkmkstart %s}%d.%d{\\bkmkend %s}. "), topicName, sectionNo, subsectionNo,
  1412. wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName,
  1413. topicName);
  1414. else
  1415. wxFprintf(Chapters, _T("%d.%d. "), sectionNo, subsectionNo);
  1416. }
  1417. }
  1418. else if ( useWord )
  1419. {
  1420. wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName, topicName);
  1421. }
  1422. }
  1423. OutputCurrentSection(); // Repeat section header
  1424. // Experimental JACS
  1425. TexOutput(_T("\\par\\pard}\n"));
  1426. // TexOutput(_T("\\par\\pard}\\par\n"));
  1427. }
  1428. issuedNewParagraph = 1;
  1429. WriteEnvironmentStyles();
  1430. }
  1431. }
  1432. break;
  1433. }
  1434. case ltSUBSUBSECTION:
  1435. case ltSUBSUBSECTIONSTAR:
  1436. {
  1437. if (!start)
  1438. {
  1439. if (winHelp && !Subsections)
  1440. {
  1441. OnError(_T("You cannot have a subsubsection before a subsection!"));
  1442. }
  1443. else
  1444. {
  1445. if (macroId != ltSUBSUBSECTIONSTAR)
  1446. subsubsectionNo ++;
  1447. wxChar *topicName = FindTopicName(GetNextChunk());
  1448. SetCurrentTopic(topicName);
  1449. NotifyParentHasChildren(3);
  1450. if (winHelpContents && winHelp)
  1451. {
  1452. OutputCurrentSectionToString(wxTex2RTFBuffer);
  1453. WriteWinHelpContentsFileLine(topicName, wxTex2RTFBuffer, 4);
  1454. }
  1455. AddTexRef(topicName, NULL, SectionNameString, chapterNo, sectionNo, subsectionNo, subsubsectionNo);
  1456. if (winHelp)
  1457. {
  1458. SetCurrentOutputs(Subsections, Subsubsections);
  1459. wxFprintf(Subsections, _T("\n{\\uldb "));
  1460. }
  1461. else
  1462. {
  1463. if (macroId != ltSUBSUBSECTIONSTAR)
  1464. {
  1465. if (DocumentStyle == LATEX_ARTICLE)
  1466. {
  1467. SetCurrentOutput(Contents);
  1468. wxFprintf(Contents, _T("\n\\tab\\tab %d.%d.%d\\tab "),
  1469. sectionNo, subsectionNo, subsubsectionNo);
  1470. }
  1471. else
  1472. SetCurrentOutput(NULL); // Don't write it into the contents, or anywhere else
  1473. }
  1474. else
  1475. SetCurrentOutput(NULL); // Don't write it into the contents, or anywhere else
  1476. }
  1477. if (startedSections)
  1478. {
  1479. if (winHelp)
  1480. wxFprintf(Subsubsections, _T("\\page\n"));
  1481. // Experimental JACS 2004-02-21
  1482. #if 0
  1483. else
  1484. wxFprintf(Chapters, _T("\\par\n"));
  1485. #endif
  1486. }
  1487. startedSections = true;
  1488. if (winHelp)
  1489. wxFprintf(Subsubsections, _T("\n${\\footnote "));
  1490. // Output header to contents page
  1491. OutputCurrentSection();
  1492. if (winHelp)
  1493. {
  1494. wxFprintf(Subsections, _T("}{\\v %s}\\pard\\par\n"), topicName);
  1495. //WriteEnvironmentStyles();
  1496. }
  1497. else if ((DocumentStyle == LATEX_ARTICLE) && (macroId != ltSUBSUBSECTIONSTAR))
  1498. wxFprintf(Contents, _T("\\par\\pard\n"));
  1499. SetCurrentOutput(winHelp ? Subsubsections : Chapters);
  1500. if (winHelp)
  1501. {
  1502. wxFprintf(Subsubsections, _T("}\n#{\\footnote %s}\n"), topicName);
  1503. wxFprintf(Subsubsections, _T("+{\\footnote %s}\n"), GetBrowseString());
  1504. OutputSectionKeyword(Subsubsections);
  1505. GenerateKeywordsForTopic(topicName);
  1506. if (useUpButton && CurrentSubsectionName)
  1507. {
  1508. wxFprintf(Subsubsections, _T("!{\\footnote EnableButton(\"Up\");ChangeButtonBinding(\"Up\", \"JumpId(`%s.hlp', `%s')\")}\n"),
  1509. wxFileNameFromPath(FileRoot), CurrentSubsectionName);
  1510. }
  1511. }
  1512. if (!winHelp && indexSubsections && useWord)
  1513. {
  1514. // Insert index entry for this subsubsection
  1515. TexOutput(_T("{\\xe\\v {"));
  1516. OutputCurrentSection();
  1517. TexOutput(_T("}}"));
  1518. }
  1519. wxChar *styleCommand = _T("");
  1520. if (!winHelp && useHeadingStyles && (macroId != ltSUBSUBSECTIONSTAR))
  1521. {
  1522. if (DocumentStyle == LATEX_ARTICLE)
  1523. styleCommand = _T("\\s3");
  1524. else
  1525. styleCommand = _T("\\s4");
  1526. }
  1527. wxChar *keep = _T("");
  1528. if (winHelp)
  1529. keep = _T("\\keepn\\sa140\\sb140");
  1530. wxFprintf(winHelp ? Subsubsections : Chapters, _T("\\pard{%s%s"),
  1531. keep, styleCommand);
  1532. WriteHeadingStyle((winHelp ? Subsubsections : Chapters),
  1533. (DocumentStyle == LATEX_ARTICLE ? 3 : 4));
  1534. wxFprintf(winHelp ? Subsubsections : Chapters, _T(" "));
  1535. if (!winHelp)
  1536. {
  1537. if ((macroId != ltSUBSUBSECTIONSTAR))
  1538. {
  1539. if (DocumentStyle == LATEX_ARTICLE)
  1540. {
  1541. if (useWord)
  1542. // wxFprintf(Chapters, _T("{\\bkmkstart %s}%d.%d.%d{\\bkmkend %s}. "), topicName, sectionNo, subsectionNo, subsubsectionNo,
  1543. wxFprintf(Chapters, _T("{\\bkmkstart %s}{\\bkmkend %s}"), topicName,
  1544. topicName);
  1545. else
  1546. wxFprintf(Chapters, _T("%d.%d.%d. "), sectionNo, …

Large files files are truncated, but you can click here to view the full file