PageRenderTime 51ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/sources.cc/pass2.cc

https://bitbucket.org/JaFojtik/wp2latex
C++ | 1857 lines | 1692 code | 116 blank | 49 comment | 227 complexity | 0fd4657272ee0b7f37a536e3e8c3e613 MD5 | raw file

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

  1. /******************************************************************************
  2. * program: wp2latex *
  3. * function: convert WordPerfect 5.x,6,7,8.x files into LaTeX *
  4. * modul: pass2.cc *
  5. * description: This modul contains functions for second pass. In the second *
  6. * pass the text file stripped from the WP binary file will be *
  7. * completed with the information of the binary table file which *
  8. * contains additional information about environments. *
  9. * licency: GPL *
  10. ******************************************************************************/
  11. //Ukoly: podivat se na: \\justified \\raggedright
  12. #include <string.h>
  13. #include <stdio.h>
  14. #include <math.h>
  15. #include <ctype.h>
  16. #include <strings.h>
  17. #include <lists.h>
  18. #include "wp2latex.h"
  19. extern list Counters, UserLists;
  20. //#define DEBUG_STOP_TEXT "xxxxx"
  21. #ifdef DEBUG_STOP_TEXT
  22. bool debug_stop = false;
  23. #define DEBUG_CHECK if(debug_stop) __asm int 3;
  24. #else
  25. #define DEBUG_CHECK /* void */
  26. #endif
  27. /// Attribute for each line of conferted text.
  28. typedef struct TLinePass2
  29. {
  30. string Lstring; ///< Text on the line.
  31. boolean new_tabset;
  32. int tabent_num_of_tabs;
  33. char envir, line_term;
  34. char Columns;
  35. signed char Empty;
  36. unsigned char LineFlag;
  37. attribute attr; ///< Attributes opened at the beginning of this line.
  38. boolean InhibitBsBslash;
  39. int ind_leftmargin;
  40. signed char Indent_Level;
  41. } TLinePass2;
  42. typedef long pchar;
  43. typedef struct TconvertedPass2
  44. {
  45. Percentor perc;
  46. long rownum;
  47. BYTE LangCount;
  48. TLinePass2 Lines[4];
  49. boolean underline, illegal_argument, just_envir_closed;
  50. int num_of_tabs;
  51. char Col2Break; ///< Amount of \columnbreak inside multicol environment
  52. unsigned short tabpos[40];
  53. unsigned int tabent_tabpos[4][40];
  54. short int pre, cur, next, next2;
  55. FILE *table;
  56. FILE *Strip, *LaTeX;
  57. FILE *log, *err;
  58. unsigned int LineSpacing;
  59. } TconvertedPass2;
  60. static void Read_TableEntry(TconvertedPass2 *cq2, short n)
  61. {
  62. #ifdef DEBUG
  63. fprintf(cq2->log,"\n#Read_TableEntry(%d) ",(int)n);fflush(cq2->log);
  64. #endif
  65. WORD w;
  66. BYTE b;
  67. int j;
  68. TLinePass2 *pCurLine;
  69. pCurLine=&cq2->Lines[n]; /* Begin met one schone lei die dan door this procedure verder wordt opgevuld. */
  70. pCurLine->envir = ' ';
  71. pCurLine->LineFlag = 0;
  72. pCurLine->new_tabset = false;
  73. InitAttr(pCurLine->attr);
  74. if (feof(cq2->table)) return;
  75. b = 0;
  76. while(b != 0xff)
  77. {
  78. if(fread(&b, 1, 1, cq2->table)==0) // We are probaly at the end of the file
  79. break;
  80. switch (b)
  81. {
  82. case 'B':pCurLine->envir = 'B'; break;
  83. case 'C':pCurLine->envir = 'C'; break;
  84. case 'L':pCurLine->envir = 'L'; break;
  85. case 'R':pCurLine->envir = 'R'; break;
  86. case 'T':pCurLine->envir = 'T'; break;
  87. case 'q':pCurLine->envir = 'q'; break;
  88. case 'Q':pCurLine->envir = 'Q'; break;
  89. case 'I':
  90. case 'i':pCurLine->envir=b;
  91. Rd_word(cq2->table, &w);
  92. pCurLine->ind_leftmargin=w;
  93. fread(&pCurLine->Indent_Level, 1, 1, cq2->table);
  94. break;
  95. case 'S':pCurLine->new_tabset = true;
  96. fread(&b, 1, 1, cq2->table);
  97. pCurLine->tabent_num_of_tabs = b;
  98. for (j = 0; j < b; j++)
  99. {
  100. Rd_word(cq2->table, &w);
  101. cq2->tabent_tabpos[n][j] = w;
  102. }
  103. break;
  104. case 'l': Rd_word(cq2->table, &w);
  105. if(w!=cq2->LineSpacing)
  106. {
  107. fprintf(cq2->LaTeX,"\\baselineskip=%2.2fex ",float(w)/128);
  108. cq2->LineSpacing=w;
  109. }
  110. break;
  111. case 'M':fread(&pCurLine->Columns, 1, 1, cq2->table); break;
  112. case 'h':
  113. case 's':
  114. case 'P':
  115. case 'p':pCurLine->line_term = b;
  116. break;
  117. case '%':pCurLine->LineFlag |= 1; break; /* Useless comment line */
  118. case '!':pCurLine->envir = '!'; break; /* Ignore enviroment before */
  119. case '^':pCurLine->envir = '^'; break; /* Ignore enviroment after */
  120. // Read all opened attributes into attr structure
  121. case 0xF0:fread(&b, 1, 1, cq2->table);
  122. pCurLine->attr.Opened_Depth=pCurLine->attr.Closed_Depth = b;
  123. for (j = 0; j < b; j++)
  124. fread(&(pCurLine->attr.stack[j]), 1, 1, cq2->table);
  125. b=0xF0;
  126. break;
  127. case 0xFF:
  128. case 10:
  129. case 13:break; //do nothing
  130. default:if(cq2->err!=NULL)
  131. fprintf(cq2->err,_("\nError: Bad command '%c' in table file!"),b);
  132. }
  133. }
  134. }
  135. static void UsePackage(TconvertedPass2 *cq2,const char *PkgName)
  136. {
  137. fprintf(cq2->LaTeX, "\\usepackage{%s}\n",PkgName);
  138. }
  139. /** -- Make the standard-heading for one latex-file -- */
  140. static void Latex_head(TconvertedPass2 *cq2)
  141. {
  142. #ifdef DEBUG
  143. fprintf(cq2->log,"\n#Latex_head() ");fflush(cq2->log);
  144. #endif
  145. int i;
  146. string TeX_RelativeFigDir;
  147. fprintf(cq2->LaTeX,_("%% This file was created by the WP2LaTeX program version: %s \n"), version );
  148. if(LaTeX_Version<0x300)
  149. {
  150. fprintf(cq2->LaTeX, "\\documentstyle[11pt,");
  151. if(Amssymb>=1) fprintf(cq2->LaTeX, "amssymb,");
  152. if(AmsMath>=1) fprintf(cq2->LaTeX, "amsmath,");
  153. if(MakeIdx>=1) fprintf(cq2->LaTeX, "makeidx,");
  154. if(Ulem>=1) fprintf(cq2->LaTeX, "ulem,");
  155. if(Rotate>=1) fprintf(cq2->LaTeX, "rotate,");
  156. if(LineNo>=1) fprintf(cq2->LaTeX, "lineno,");
  157. fprintf(cq2->LaTeX, "wp2latex");
  158. if(twoside) fprintf(cq2->LaTeX, ",twoside");
  159. if(Columns==2) fprintf(cq2->LaTeX, ",twocolumn");
  160. if(Columns>2) fprintf(cq2->LaTeX, ",multicol");
  161. if(EndNotes>=1) fprintf(cq2->LaTeX, ",endnotes");
  162. if(Cyrillic>=1) fprintf(cq2->LaTeX, ",cyrillic");
  163. if(cjHebrew>=1) fprintf(cq2->LaTeX, ",cjhebrew");
  164. if(InputPS==(IMG_InputPS|1)) fprintf(cq2->LaTeX, ",InputPS");
  165. if(InputPS==(IMG_graphicx|1)) fprintf(cq2->LaTeX, ",graphicx");
  166. if(InputPS==(IMG_epsfig|1)) fprintf(cq2->LaTeX, ",epsfig");
  167. if(InputPS==(IMG_graphics|1)) fprintf(cq2->LaTeX, ",graphics");
  168. if(Wasy>=1) fprintf(cq2->LaTeX, ",wasyfont");
  169. if(textcomp>=1) fprintf(cq2->LaTeX, ",textcomp");
  170. if(Bbm>=1) fprintf(cq2->LaTeX, ",bbm");
  171. if(Rsfs>=1) fprintf(cq2->LaTeX, ",mathrsfs");
  172. if(FancyHdr>=1) fprintf(cq2->LaTeX, ",fancyhdr");
  173. if(LongTable>=1)fprintf(cq2->LaTeX, ",longtable");
  174. if(pifont>=1) fprintf(cq2->LaTeX, ",pifont");
  175. for(int lng=0;lng<sizeof(LangTable)/sizeof(LangItem);lng++)
  176. {
  177. if(LangTable[lng].UseLang>=1)
  178. {
  179. fprintf(cq2->LaTeX, ",%s",LangTable[lng].LangDesc);
  180. cq2->LangCount++;
  181. }
  182. }
  183. fprintf(cq2->LaTeX, "]{article}\n\n");
  184. }
  185. else
  186. {
  187. fprintf(cq2->LaTeX, "\\documentclass[11pt");
  188. if(twoside) fprintf(cq2->LaTeX, ",twoside");
  189. if(Columns==2) fprintf(cq2->LaTeX, ",twocolumn");
  190. fprintf(cq2->LaTeX, "]{article}\n");
  191. if(Amssymb>=1) UsePackage(cq2, "amssymb");
  192. if(AmsMath>=1) UsePackage(cq2, "amsmath");
  193. if(LaTeXsym>=1) UsePackage(cq2, "latexsym");
  194. if(MakeIdx>=1) UsePackage(cq2, "makeidx");
  195. if(Ulem>=1) UsePackage(cq2, "ulem");
  196. if(Rotate>=1) UsePackage(cq2, "rotate");
  197. if(LineNo>=1) UsePackage(cq2, "lineno");
  198. UsePackage(cq2, "wp2latex");
  199. if(CPStyles) switch(CodePage)
  200. {
  201. case 0: break;
  202. case ISO8859_1:fprintf(cq2->LaTeX, "\\usepackage[latin1]{inputenc}\n");
  203. break;
  204. case ISO8859_2:fprintf(cq2->LaTeX, "\\usepackage[latin2]{inputenc}\n");
  205. break;
  206. case KOI8R: fprintf(cq2->LaTeX, "\\usepackage[koi8-r]{inputenc}\n");
  207. break;
  208. default:fprintf(cq2->LaTeX, "\\usepackage[cp%d]{inputenc}\n", CodePage);
  209. break;
  210. }
  211. if(colors>=1) UsePackage(cq2, "color");
  212. if(Cyrillic>=1) UsePackage(cq2, "cyrillic");
  213. if(cjHebrew>=1) UsePackage(cq2, "cjhebrew");
  214. if(EndNotes>=1) UsePackage(cq2, "endnotes");
  215. if(InputPS==(IMG_InputPS|1)) UsePackage(cq2, "InputPS");
  216. if(InputPS==(IMG_graphicx|1)) UsePackage(cq2, "graphicx");
  217. if(InputPS==(IMG_epsfig|1)) UsePackage(cq2, "epsfig");
  218. if(InputPS==(IMG_graphics|1)) UsePackage(cq2, "graphics");
  219. if(Columns>2) UsePackage(cq2, "multicol");
  220. if(Wasy>=1) UsePackage(cq2, "wasyfont");
  221. if(textcomp>=1) UsePackage(cq2, "textcomp");
  222. if(Bbm>=1) UsePackage(cq2, "bbm");
  223. if(TIPA>=1) fprintf(cq2->LaTeX, "\\usepackage[safe]{tipa}\n");
  224. if(Rsfs>=1) UsePackage(cq2, "mathrsfs");
  225. if(FancyHdr>=1) UsePackage(cq2, "fancyhdr");
  226. if(pifont>=1) UsePackage(cq2, "pifont");
  227. if(LongTable>=1)UsePackage(cq2, "longtable");
  228. for(int lng=0;lng<sizeof(LangTable)/sizeof(LangItem);lng++)
  229. {
  230. if(LangTable[lng].UseLang>=1)
  231. {
  232. if(cq2->LangCount==0)
  233. fprintf(cq2->LaTeX, "\\usepackage[%s",LangTable[lng].LangDesc);
  234. else
  235. fprintf(cq2->LaTeX, ",%s",LangTable[lng].LangDesc);
  236. cq2->LangCount++;
  237. }
  238. }
  239. if(cq2->LangCount>0)
  240. fprintf(cq2->LaTeX, "]{babel}\n");
  241. if(fontenc>=1) switch(CodePage)
  242. {
  243. case 866:
  244. case KOI8R:
  245. fprintf(cq2->LaTeX, "\\usepackage[T2A]{fontenc}\n");
  246. break;
  247. default: fprintf(cq2->LaTeX, "\\usepackage[T1]{fontenc}\n");
  248. }
  249. fputc('\n',cq2->LaTeX);
  250. }
  251. /*if (Cyrillic) fprintf(cq2->LaTeX, "\\font\\cyr=wncyr10\n");*/
  252. if(Columns==2)fprintf(cq2->LaTeX, "\\onecolumn\n");
  253. if (Index) fprintf(cq2->LaTeX, "\\makeindex\n");
  254. if(FancyHdr>=1) fprintf(cq2->LaTeX, "\\pagestyle{fancy}\\renewcommand{\\headrulewidth}{0pt}\n\\fancyfoot{}\\fancyhead{}\n");
  255. if((InputPS&1)==1) TeX_RelativeFigDir=replacesubstring(RelativeFigDir,"\\","/");
  256. if(InputPS==(IMG_InputPS|1) || InputPS==(IMG_epsfig|1))
  257. fprintf(cq2->LaTeX, "\\newcommand{\\FigDir}{%s}\n",TeX_RelativeFigDir());
  258. if(InputPS==(IMG_InputPS|1))
  259. fprintf(cq2->LaTeX, "\\ShowDisplacementBoxes\n");
  260. if(InputPS==(IMG_graphicx|1))
  261. fprintf(cq2->LaTeX, "\\graphicspath{{%s/}}\n",TeX_RelativeFigDir());
  262. fputc('\n',cq2->LaTeX);
  263. if(EndNotes<-1) fprintf(cq2->LaTeX, "\\def\\endnote{\\footnote}\n");
  264. if(length(Counters)>0)
  265. {
  266. for(i=0;i<length(Counters);i++)
  267. {
  268. fprintf(cq2->LaTeX, "\\newcounter{%s}\n",chk(Counters[i]));
  269. }
  270. fputc('\n',cq2->LaTeX);
  271. }
  272. for(i=0;i<length(UserLists);i++)
  273. {
  274. fprintf(cq2->LaTeX, "\\InitUserList{l%c} %%%s\n",i+'a',UserLists[i]);
  275. }
  276. if(length(UserLists)>0) fputc('\n',cq2->LaTeX);
  277. fprintf(cq2->LaTeX, "\\begin{document}\n");
  278. }
  279. /** -- Sluit the latex-file op the juiste wijze af -- */
  280. static void Latex_foot(TconvertedPass2 * cq2)
  281. {
  282. #ifdef DEBUG
  283. fprintf(cq2->log,"\n#Latex_foot() ");fflush(cq2->log);
  284. #endif
  285. if(EndNotes==1) fprintf(cq2->LaTeX,
  286. "\\begingroup\n"
  287. "\\parindent 0pt \\parskip 1ex\n"
  288. "\\def\\enotesize{\\normalsize}\n"
  289. "\\theendnotes\n"
  290. "\\endgroup\n\n");
  291. fprintf(cq2->LaTeX, "\\end{document}\n");
  292. }
  293. static void Latex_tabset(TconvertedPass2 *cq2)
  294. {
  295. #ifdef DEBUG
  296. fprintf(cq2->log,"\n#Latex_tabset() ");fflush(cq2->log);
  297. #endif
  298. long atpr = 0;
  299. long j;
  300. double l;
  301. double ol = 0.0;
  302. long FORLIM;
  303. /* Huiding aantal tabs per row */
  304. FORLIM = cq2->num_of_tabs;
  305. for (j = 0; j < FORLIM; j++)
  306. {
  307. l = cq2->tabpos[j] / 1200.0 * 2.54;
  308. fprintf(cq2->LaTeX, "\\hspace{%3.2fcm}\\=", l - ol);
  309. atpr++;
  310. if (atpr >= 4)
  311. {
  312. fprintf(cq2->LaTeX, "%%\n");
  313. atpr = 0;
  314. }
  315. ol = l;
  316. }
  317. fprintf(cq2->LaTeX, "\\kill\n");
  318. }
  319. static boolean Change_envir_BOL(TconvertedPass2 *cq2)
  320. {
  321. #ifdef DEBUG
  322. fprintf(cq2->log,"\n#Change_envir_BOL() ");fflush(cq2->log);
  323. #endif
  324. return (cq2->Lines[cq2->cur].envir != cq2->Lines[cq2->pre].envir &&
  325. (cq2->Lines[cq2->cur].envir == 'q' ||
  326. cq2->Lines[cq2->cur].envir == 'Q' ||
  327. cq2->Lines[cq2->cur].envir == 'T' ||
  328. cq2->Lines[cq2->cur].envir == 'C' ||
  329. cq2->Lines[cq2->cur].envir == 'R' ||
  330. cq2->Lines[cq2->cur].envir == 'L' ||
  331. cq2->Lines[cq2->cur].envir == 'B' ||
  332. toupper(cq2->Lines[cq2->cur].envir) == 'I' ) &&
  333. cq2->Lines[cq2->pre].envir != '^');
  334. // && cq2->Lines[cq2->cur].envir != '!'
  335. }
  336. static boolean Change_envir_EOL(TconvertedPass2 *cq2)
  337. {
  338. #ifdef DEBUG
  339. fprintf(cq2->log,"\n#Change_envir_EOL() ");fflush(cq2->log);
  340. #endif
  341. return (cq2->Lines[cq2->next].envir != cq2->Lines[cq2->cur].envir &&
  342. (cq2->Lines[cq2->cur].envir == 'Q' ||
  343. cq2->Lines[cq2->cur].envir == 'q' ||
  344. toupper(cq2->Lines[cq2->cur].envir) == 'I' ||
  345. cq2->Lines[cq2->cur].envir == 'T' ||
  346. cq2->Lines[cq2->cur].envir == 'C' ||
  347. cq2->Lines[cq2->cur].envir == 'R' ||
  348. cq2->Lines[cq2->cur].envir == 'L' ||
  349. cq2->Lines[cq2->cur].envir == 'B' ||
  350. cq2->Lines[cq2->next].envir == 'Q' ||
  351. cq2->Lines[cq2->next].envir == 'q' ||
  352. toupper(cq2->Lines[cq2->next].envir) == 'I' ||
  353. cq2->Lines[cq2->next].envir == 'T' ||
  354. cq2->Lines[cq2->next].envir == 'C' ||
  355. cq2->Lines[cq2->next].envir == 'R' ||
  356. cq2->Lines[cq2->next].envir == 'L' ||
  357. cq2->Lines[cq2->next].envir == 'B') &&
  358. cq2->Lines[cq2->next].envir != '!' &&
  359. cq2->Lines[cq2->cur].envir != '^');
  360. }
  361. static void Close_environment(TconvertedPass2 *cq2)
  362. {
  363. #ifdef DEBUG
  364. fprintf(cq2->log,"\n#Close_environment() ");fflush(cq2->log);
  365. #endif
  366. switch (cq2->Lines[cq2->cur].envir)
  367. {
  368. case 'B':if(LongTable>=1) fprintf(cq2->LaTeX, "\\end{longtable}\n");
  369. else fprintf(cq2->LaTeX, "\\end{tabular}\n");
  370. break;
  371. case 'C':fprintf(cq2->LaTeX, "\\end{center}\n");
  372. break;
  373. case 'L':fprintf(cq2->LaTeX, "\\end{flushleft}\n");
  374. break;
  375. case 'R':fprintf(cq2->LaTeX, "\\end{flushright}\n");
  376. break;
  377. case 'T':fprintf(cq2->LaTeX, "\\end{tabbing}\n");
  378. break;
  379. case 'I':
  380. case 'i':fprintf(cq2->LaTeX, "\\end{indenting}\n");
  381. break;
  382. case 'q':fprintf(cq2->LaTeX, "\\end{eqnarray}\n");
  383. break;
  384. case 'Q':fprintf(cq2->LaTeX, "\\end{displaymath}\n");
  385. break;
  386. }
  387. cq2->just_envir_closed = true;
  388. }
  389. static boolean Open_environment(TconvertedPass2 *cq2)
  390. {
  391. #ifdef DEBUG
  392. fprintf(cq2->log,"\n#Open_environment() ");fflush(cq2->log);
  393. #endif
  394. string s;
  395. if(cq2->Lines[cq2->cur].Columns!=cq2->Lines[cq2->pre].Columns)
  396. {
  397. if (cq2->Lines[cq2->cur].attr.Opened_Depth>0) /* Attributes are opened */
  398. {
  399. Close_All_Attr(cq2->Lines[cq2->cur].attr,s);
  400. cq2->Lines[cq2->cur].Lstring=s+cq2->Lines[cq2->cur].Lstring;
  401. }
  402. if(!cq2->just_envir_closed) Close_environment(cq2); //Close enviroment if still opened
  403. if(Columns>=3) //style Multicol used
  404. {
  405. if(cq2->Lines[cq2->pre].Columns>1) fprintf(cq2->LaTeX,"\\end{multicols}\n");
  406. if(cq2->Lines[cq2->cur].Columns>1)
  407. {
  408. fprintf(cq2->LaTeX,"\\begin{multicols}{%d}\n",(int)cq2->Lines[cq2->cur].Columns);
  409. cq2->Col2Break=1;
  410. }
  411. }
  412. else
  413. {
  414. switch(cq2->Lines[cq2->cur].Columns)
  415. {
  416. case 0:
  417. case 1:fprintf(cq2->LaTeX, "\\onecolumn\n"); break;
  418. case 2:fprintf(cq2->LaTeX, "\\twocolumn\n"); break;
  419. default:if(cq2->err!=NULL)
  420. fprintf(cq2->err,_("\nError: Bad number of columns:%d !"),(int)cq2->Lines[cq2->cur].Columns);
  421. }
  422. }
  423. }
  424. else if (!Change_envir_BOL(cq2)) /* Changed environment ? */
  425. {
  426. if (cq2->Lines[cq2->cur].new_tabset && cq2->Lines[cq2->cur].envir == 'T')
  427. Latex_tabset(cq2);
  428. if(cq2->Lines[cq2->cur].envir != ' ' && cq2->Lines[cq2->pre].envir == '^')
  429. cq2->just_envir_closed = false; //mark popped enviroment as open
  430. // if(!cq2->just_envir_closed)
  431. return(false);
  432. }
  433. if (cq2->Lines[cq2->cur].attr.Opened_Depth>0) /* Attributes are opened */
  434. {
  435. Close_All_Attr(cq2->Lines[cq2->cur].attr,s);
  436. cq2->Lines[cq2->cur].Lstring = s + cq2->Lines[cq2->cur].Lstring;
  437. }
  438. cq2->just_envir_closed = false;
  439. switch (cq2->Lines[cq2->cur].envir)
  440. {
  441. case 'B':if(LongTable>=1) fprintf(cq2->LaTeX, "\\begin{longtable}\n");
  442. else fprintf(cq2->LaTeX, "\\begin{tabular}\n");
  443. break;
  444. case 'C':fprintf(cq2->LaTeX, "\\begin{center}\n");
  445. break;
  446. case 'L':fprintf(cq2->LaTeX, "\\begin{flushleft}\n");
  447. break;
  448. case 'R':fprintf(cq2->LaTeX, "\\begin{flushright}\n");
  449. break;
  450. case 'T':fprintf(cq2->LaTeX, "\\begin{tabbing}\n");
  451. Latex_tabset(cq2);
  452. break;
  453. case 'I':
  454. case 'i':if(cq2->Lines[cq2->cur].Lstring=="") //indent nothing ??
  455. {
  456. return(true);
  457. }
  458. if((cq2->Lines[cq2->cur].Indent_Level<2)||(toupper(cq2->Lines[cq2->pre].envir)!='I'))
  459. {
  460. if(cq2->Lines[cq2->pre].Lstring!="")
  461. fprintf(cq2->LaTeX,"\\testlastline\n\n");
  462. else fprintf(cq2->LaTeX,"\\zerotestlastline\n");
  463. }
  464. fprintf(cq2->LaTeX, "\\begin{indenting}"
  465. "{%3.2fcm}\n",cq2->Lines[cq2->cur].ind_leftmargin / 1200.0 * 2.54);
  466. break;
  467. case 'q':fprintf(cq2->LaTeX, "\\begin{eqnarray}\n");
  468. break;
  469. case 'Q':fprintf(cq2->LaTeX, "\\begin{displaymath}\n");
  470. break;
  471. }
  472. return(false);
  473. }
  474. static void Update_global_information(TconvertedPass2 *cq2)
  475. {
  476. #ifdef DEBUG
  477. fprintf(cq2->log,"\n#Update_global_information() ");fflush(cq2->log);
  478. #endif
  479. int j, FORLIM;
  480. if (cq2->Lines[cq2->cur].new_tabset)
  481. {
  482. cq2->num_of_tabs = cq2->Lines[cq2->cur].tabent_num_of_tabs;
  483. FORLIM = cq2->num_of_tabs;
  484. for (j = 0; j < FORLIM; j++)
  485. cq2->tabpos[j] = cq2->tabent_tabpos[cq2->cur][j];
  486. }
  487. }
  488. static void Select_NextLine(TconvertedPass2 *cq2)
  489. {
  490. #ifdef DEBUG
  491. fprintf(cq2->log,"\n#Select_NextLine() ");fflush(cq2->log);
  492. #endif
  493. int help;
  494. help = cq2->pre;
  495. cq2->pre = cq2->cur;
  496. cq2->cur = cq2->next;
  497. cq2->next= cq2->next2;
  498. cq2->next2 = help;
  499. }
  500. static boolean FixTabs(TconvertedPass2 *cq2, char *Helps)
  501. {
  502. int i, j = 0, tabs = 0;
  503. string s;
  504. char CharStr[10];
  505. if(Helps == NULL) return false;
  506. if(*Helps == 0) return false;
  507. while(Helps[j++]=='\\')
  508. {
  509. if(Helps[j++] != 'T') break;
  510. if(Helps[j++] != 'A') break;
  511. if(Helps[j++] != 'B') break;
  512. if(Helps[j] != 0)
  513. {
  514. if(Helps[j++] != ' ') break;
  515. }
  516. tabs++;
  517. }
  518. if(tabs <= 0) return false;
  519. if((j>(int)strlen(Helps))&&(cq2->Lines[cq2->cur].line_term!='s')&&(cq2->Lines[cq2->cur].line_term!='p'))
  520. {
  521. if(cq2->err!=NULL && Verbosing>0)
  522. {
  523. cq2->perc.Hide();
  524. fprintf(cq2->err,_("\nWarning: Incorrect line with TABs at the end - fixed."));
  525. }
  526. *Helps=0;
  527. return false;
  528. }
  529. if(cq2->Lines[cq2->cur].envir == 'T')
  530. {
  531. j=0;
  532. for(i=0;i<tabs;i++)
  533. {
  534. Helps[j++]='\\';
  535. Helps[j++]='>';
  536. }
  537. i=5*tabs;
  538. while (Helps[i] != '\0')
  539. {
  540. Helps[j] = Helps[i];
  541. i++;
  542. j++;
  543. }
  544. Helps[j] = '\0';
  545. }
  546. else {
  547. i=Helps-cq2->Lines[cq2->cur].Lstring();
  548. s=copy(cq2->Lines[cq2->cur].Lstring,0,i);
  549. sprintf(CharStr,"%2.2f",float(cq2->tabpos[tabs-1])/ 470.0);
  550. s+="\\hspace*{";
  551. s+=CharStr;
  552. s+="cm}";
  553. s+=copy(cq2->Lines[cq2->cur].Lstring,i + 5*tabs,length(cq2->Lines[cq2->cur].Lstring)- i - 5*tabs);
  554. cq2->Lines[cq2->cur].Lstring=s;
  555. }
  556. return true;
  557. }
  558. static bool Fix1SectionStr(char *aline, const char *opt)
  559. {
  560. char *str, *str2;
  561. int optlen;
  562. int r;
  563. if((str=StrStr(aline, opt)) == NULL) return false;
  564. optlen = strlen(opt);
  565. str2 = str+1;
  566. for(r=0;r<optlen-1;r++)
  567. {
  568. *str2++=' ';
  569. }
  570. str2 = str + optlen;
  571. r = 0;
  572. while(*str2!=0)
  573. {
  574. if(*str2=='{') r++;
  575. if(*str2=='}')
  576. if(r==0)
  577. {
  578. *str2=' ';
  579. strcpy(str,str+optlen); // Overlapping regions
  580. //i = strlen(aline) - optlen;
  581. //memmove(str,str+7,strlen(str+7));str[i]=0; // Overlapping regions, but terminating 0 must be added for memmove.
  582. return true;
  583. }
  584. else r--;
  585. str2++;
  586. }
  587. return false;
  588. }
  589. static void OptimSectionStr(char *aline)
  590. {
  591. boolean optimized;
  592. int i;
  593. do {
  594. if(aline == NULL) return;
  595. i = strlen(aline);
  596. while(aline[i]==' ')
  597. {
  598. aline[i--] = 0;
  599. }
  600. if(*aline == 0) return;
  601. //i still contains strlen(aline)
  602. if(aline[i-1] == '\\' && aline[i-2] == '\\')
  603. {
  604. aline[i-2] = '\0';
  605. i -= 2;
  606. }
  607. optimized = Fix1SectionStr(aline, "{\\bfseries");
  608. optimized |= Fix1SectionStr(aline, "{\\bf");
  609. optimized |= Fix1SectionStr(aline, "{\\large");
  610. optimized |= Fix1SectionStr(aline, "{\\Large");
  611. optimized |= Fix1SectionStr(aline, "{\\LARGE");
  612. } while(optimized);
  613. }
  614. static int FixBracket(string & Line)
  615. {
  616. if (Line == "") return 0;
  617. Line="{}"+Line;
  618. return length(Line);
  619. }
  620. static char *TryToRemoveGeneric(char *Helps, const char *Generic)
  621. {
  622. int i = 0, j;
  623. if (Helps == NULL) return NULL;
  624. if (Generic == NULL) return NULL;
  625. if (*Helps == 0) return NULL;
  626. if (*Generic == 0) return NULL;
  627. Helps = StrStr(Helps, Generic);
  628. if(Helps == NULL) return NULL;
  629. j = strlen(Generic);
  630. while (Helps[j] == ' ')
  631. {
  632. j++;
  633. }
  634. if (Helps[j++] != '}') return Helps+1;
  635. while (Helps[j] != '\0')
  636. {
  637. Helps[i] = Helps[j];
  638. i++;
  639. j++;
  640. }
  641. Helps[i] = '\0';
  642. return Helps;
  643. }
  644. static char *TryToRemoveSelectLanguage(char * Helps)
  645. {
  646. int i = 0, j, k;
  647. if (Helps == NULL) return NULL;
  648. if (*Helps == 0) return NULL;
  649. Helps = StrStr(Helps, "\\selectlanguage{");
  650. if (Helps == NULL) return NULL;
  651. j = 16; // strlen("\\selectlanguage{");
  652. while (Helps[j] != '}')
  653. {
  654. if(Helps[j]==0) return Helps+1;
  655. j++;
  656. }
  657. if (Helps[j++] != '}') return Helps+1;
  658. k = j;
  659. while (Helps[j] == '~' || Helps[j] == ' ')
  660. {
  661. j++;
  662. }
  663. if (Helps[j++] != '\\') return Helps+1;
  664. if (Helps[j++] != 's') return Helps+1;
  665. if (Helps[j++] != 'e') return Helps+1;
  666. if (Helps[j++] != 'l') return Helps+1;
  667. if (Helps[j++] != 'e') return Helps+1;
  668. if (Helps[j++] != 'c') return Helps+1;
  669. if (Helps[j++] != 't') return Helps+1;
  670. if (Helps[j++] != 'l') return Helps+1;
  671. if (Helps[j++] != 'a') return Helps+1;
  672. if (Helps[j++] != 'n') return Helps+1;
  673. if (Helps[j++] != 'g') return Helps+1;
  674. if (Helps[j++] != 'u') return Helps+1;
  675. if (Helps[j++] != 'a') return Helps+1;
  676. if (Helps[j++] != 'g') return Helps+1;
  677. if (Helps[j++] != 'e') return Helps+1;
  678. if (Helps[j++] != '{') return Helps+1;
  679. while (Helps[k] != '\0')
  680. {
  681. Helps[i] = Helps[k];
  682. k++;
  683. i++;
  684. }
  685. Helps[i] = '\0';
  686. return Helps; //one command removed, try again next command
  687. }
  688. static char *TryToRemoveLineNumbering(char * Helps)
  689. {
  690. int i = 0, j, k;
  691. if (Helps == NULL) return NULL;
  692. if (*Helps == 0) return NULL;
  693. Helps = StrStr(Helps, "\\begin{linenumbers}");
  694. if (Helps == NULL) return NULL;
  695. j = 19; // strlen("\\begin{linenumbers}");
  696. k = j;
  697. while (Helps[j]==' ' || Helps[j]=='\t')
  698. {
  699. j++;
  700. }
  701. if (Helps[j++] != '\\') return Helps+1;
  702. if (Helps[j++] != 'e') return Helps+1;
  703. if (Helps[j++] != 'n') return Helps+1;
  704. if (Helps[j++] != 'd') return Helps+1;
  705. if (Helps[j++] != '{') return Helps+1;
  706. if (Helps[j++] != 'l') return Helps+1;
  707. if (Helps[j++] != 'i') return Helps+1;
  708. if (Helps[j++] != 'n') return Helps+1;
  709. if (Helps[j++] != 'e') return Helps+1;
  710. if (Helps[j++] != 'n') return Helps+1;
  711. if (Helps[j++] != 'u') return Helps+1;
  712. if (Helps[j++] != 'm') return Helps+1;
  713. if (Helps[j++] != 'b') return Helps+1;
  714. if (Helps[j++] != 'e') return Helps+1;
  715. if (Helps[j++] != 'r') return Helps+1;
  716. if (Helps[j++] != 's') return Helps+1;
  717. if (Helps[j++] != '}') return Helps+1;
  718. /* Copy spaces among linenum commands */
  719. while (Helps[k]!='\0' && Helps[k]!='\\')
  720. {
  721. Helps[i] = Helps[k];
  722. i++; k++;
  723. }
  724. /* Copy rest of a text */
  725. while (Helps[j] != '\0')
  726. {
  727. Helps[i] = Helps[j];
  728. i++;
  729. j++;
  730. }
  731. Helps[i] = '\0';
  732. return Helps; //one command removed, try again next command
  733. }
  734. /** Check whether line contains any user printable text, or control sequences only.
  735. * @return 1 when line contains sequences only; 0 printable text is present. */
  736. int EmptyLine(const string & s)
  737. {
  738. int i;
  739. char ch;
  740. i=0;
  741. while(i<length(s))
  742. {
  743. ch=s[i++];
  744. if(ch==' ') continue;
  745. if(ch=='\t') continue;
  746. if(ch=='}') continue;
  747. if(ch=='{') continue;
  748. if(ch=='\\')
  749. {
  750. if(s[i]=='/') //ignore \/
  751. {
  752. i++;
  753. continue;
  754. }
  755. if(s[i]=='>') //ignore \>
  756. {
  757. i++;
  758. continue;
  759. }
  760. if(s[i]=='b') //ignore \bf
  761. {
  762. i++;
  763. if(s[i++]!='f') return(0);
  764. continue;
  765. }
  766. if(s[i]=='c')
  767. {
  768. i++;
  769. if(s[i]=='l') //ignore \clubpenalty number
  770. {
  771. i++;
  772. if(s[i++]!='u') return(0);
  773. if(s[i++]!='b') return(0);
  774. if(s[i++]!='p') return(0);
  775. if(s[i++]!='e') return(0);
  776. if(s[i++]!='n') return(0);
  777. if(s[i++]!='a') return(0);
  778. if(s[i++]!='l') return(0);
  779. if(s[i++]!='t') return(0);
  780. if(s[i++]!='y') return(0);
  781. while(s[i]==' ') i++;
  782. while(isdigit(s[i])) i++;
  783. continue;
  784. }
  785. if(s[i++]!='o') return(0); //ignore \color{\anything}
  786. if(s[i++]!='l') return(0);
  787. if(s[i++]!='o') return(0);
  788. if(s[i++]!='r') return(0);
  789. if(s[i++]!='{') return(0);
  790. while(s[i++]!='}')
  791. {
  792. if(i>=length(s)) return(1);
  793. };
  794. continue;
  795. }
  796. if(s[i]=='f') //ignore \foottext{\anything}
  797. {
  798. i++;
  799. if(s[i++]!='o') return(0);
  800. if(s[i++]!='o') return(0);
  801. if(s[i++]!='t') return(0);
  802. if(s[i++]!='t') return(0);
  803. if(s[i++]!='e') return(0);
  804. if(s[i++]!='x') return(0);
  805. if(s[i++]!='t') return(0);
  806. if(s[i++]!='{') return(0);
  807. while(s[i++]!='}')
  808. {
  809. if(i>=length(s)) return(1);
  810. };
  811. continue;
  812. }
  813. if(s[i]=='h') //ignore \headtext{\anything}
  814. {
  815. i++;
  816. if(s[i++]!='e') return(0);
  817. if(s[i++]!='a') return(0);
  818. if(s[i++]!='d') return(0);
  819. if(s[i++]!='t') return(0);
  820. if(s[i++]!='e') return(0);
  821. if(s[i++]!='x') return(0);
  822. if(s[i++]!='t') return(0);
  823. if(s[i++]!='{') return(0);
  824. while(s[i++]!='}')
  825. {
  826. if(i>=length(s)) return(1);
  827. };
  828. continue;
  829. }
  830. if(s[i]=='i') //ignore \it
  831. {
  832. i++;
  833. if(s[i++]!='t') return(0);
  834. continue;
  835. }
  836. if(s[i]=='l') //ignore \label{anything}
  837. {
  838. i++;
  839. if(s[i++]!='a') return(0);
  840. if(s[i++]!='b') goto TryLanguage;
  841. if(s[i++]!='e') return(0);
  842. if(s[i++]!='l') return(0);
  843. if(s[i++]!='{') return(0);
  844. while(s[i++]!='}')
  845. {
  846. if(i>=length(s)) return(1);
  847. };
  848. continue;
  849. TryLanguage: //ignore \language anything
  850. i--;
  851. if(s[i++]!='n') return(0);
  852. if(s[i++]!='g') return(0);
  853. if(s[i++]!='u') return(0);
  854. if(s[i++]!='a') return(0);
  855. if(s[i++]!='g') return(0);
  856. if(s[i++]!='e') return(0);
  857. if(s[i++]!='=') return(0);
  858. if(s[i++]!='\\') return(0);
  859. while(isalpha(s[i]))
  860. {
  861. i++;
  862. }
  863. continue;
  864. };
  865. if(s[i]=='o') //ignore \onecolumn
  866. {
  867. i++;
  868. if(s[i++]!='n') return(0);
  869. if(s[i++]!='e') return(0);
  870. goto ColumnText;
  871. }
  872. if(s[i]=='p')
  873. {
  874. i++;
  875. if(s[i]=='a') //ignore \pagenumpos{...}
  876. {
  877. i++;
  878. if(s[i++]!='g') return(0);
  879. if(s[i++]!='e') return(0);
  880. if(s[i++]!='n') return(0);
  881. if(s[i++]!='u') return(0);
  882. if(s[i++]!='m') return(0);
  883. if(s[i++]!='p') return(0);
  884. if(s[i++]!='o') return(0);
  885. if(s[i++]!='s') return(0);
  886. if(s[i++]!='{') return(0);
  887. while(s[i]!='}' && s[i]!=0)
  888. {i++;}
  889. continue;
  890. }
  891. if(s[i++]!='e') return(0); //ignore \penalty NUM
  892. if(s[i++]!='n') return(0);
  893. if(s[i++]!='a') return(0);
  894. if(s[i++]!='l') return(0);
  895. if(s[i++]!='t') return(0);
  896. if(s[i++]!='y') return(0);
  897. while(s[i]==' ') i++;
  898. while(isdigit(s[i])) i++;
  899. continue;
  900. };
  901. if(s[i]=='s')
  902. {
  903. i++;
  904. if(s[i]=='c') continue; //ignore \sc
  905. if(s[i++]!='e') return(0);
  906. if(s[i]=='l')
  907. { //ignore \selectlanguage{lang}
  908. i++;
  909. if(s[i++]!='e') return(0);
  910. if(s[i++]!='c') return(0);
  911. if(s[i++]!='t') return(0);
  912. if(s[i++]!='l') return(0);
  913. if(s[i++]!='a') return(0);
  914. if(s[i++]!='n') return(0);
  915. if(s[i++]!='g') return(0);
  916. if(s[i++]!='u') return(0);
  917. if(s[i++]!='a') return(0);
  918. if(s[i++]!='g') return(0);
  919. if(s[i++]!='e') return(0);
  920. if(s[i++]!='{') return(0);
  921. while(s[i]!='}' && s[i]!=0) i++;
  922. continue;
  923. }
  924. if(s[i++]!='t') return(0); //ignore \setcounter{counter}{number}
  925. if(s[i++]!='c') return(0);
  926. if(s[i++]!='o') return(0);
  927. if(s[i++]!='u') return(0);
  928. if(s[i++]!='n') return(0);
  929. if(s[i++]!='t') return(0);
  930. if(s[i++]!='e') return(0);
  931. if(s[i++]!='r') return(0);
  932. if(s[i++]!='{') return(0);
  933. while(s[i]!='}' && s[i]!=0) i++;
  934. if(s[++i]!='{') return(0);
  935. while(s[i]!='}' && s[i]!=0) i++;
  936. i++;
  937. continue;
  938. };
  939. if(s[i]=='T') //ignore \TAB
  940. {
  941. i++;
  942. if(s[i++]!='A') return(0);
  943. if(s[i++]!='B') return(0);
  944. continue;
  945. }
  946. if(s[i]=='t') //ignore \twocolumn
  947. {
  948. i++;
  949. if(s[i]!='w') goto ThisPageStyle;
  950. i++;
  951. ColumnText: if(s[i++]!='o') return(0);
  952. if(s[i++]!='c') return(0);
  953. if(s[i++]!='o') return(0);
  954. if(s[i++]!='l') return(0);
  955. if(s[i++]!='u') return(0);
  956. if(s[i++]!='m') return(0);
  957. if(s[i++]!='n') return(0);
  958. if(s[i]==0) return(1);
  959. if(s[i++]!=' ') return(0);
  960. continue;
  961. ThisPageStyle: i++;
  962. if(s[i++]!='h') return(0);
  963. if(s[i++]!='i') return(0);
  964. if(s[i++]!='s') return(0);
  965. if(s[i++]!='p') return(0);
  966. if(s[i++]!='a') return(0);
  967. if(s[i++]!='g') return(0);
  968. if(s[i++]!='e') return(0);
  969. if(s[i++]!='s') return(0);
  970. if(s[i++]!='t') return(0);
  971. if(s[i++]!='y') return(0);
  972. if(s[i++]!='l') return(0);
  973. if(s[i++]!='e') return(0);
  974. if(s[i++]!='{') return(0);
  975. while(isalpha(s[i]))
  976. {
  977. i++;
  978. }
  979. if(s[i++]!='}') return(0);
  980. continue;
  981. }
  982. if(s[i]=='v')
  983. {
  984. i++;
  985. if(s[i++]!='s') return(0);
  986. switch(s[i++])
  987. {
  988. //ignore \vskip xxcm
  989. case 'k': if(s[i++]!='i') return(0);
  990. if(s[i++]!='p') return(0);
  991. if(s[i++]!=' ') return(0);
  992. while(s[i]==' ') i++;
  993. while(isdigit(s[i]) || (s[i]=='-') || (s[i]=='.')) i++;
  994. if(s[i]!='c') continue;
  995. i++;
  996. if(s[i]!='m') continue;
  997. i++;
  998. break;
  999. //ignore \vspace {xx cm}
  1000. case 'p': if(s[i++]!='a') return(0);
  1001. if(s[i++]!='c') return(0);
  1002. if(s[i++]!='e') return(0);
  1003. while(s[i]==' ') i++;
  1004. if(s[i++]!='{') return(0);
  1005. while(s[i]!='}')
  1006. {
  1007. if(s[i]==0) return(1);
  1008. i++;
  1009. }
  1010. break;
  1011. default: return(0);
  1012. }
  1013. continue;
  1014. };
  1015. if(s[i]=='w') //ignore \widowpenalty number
  1016. {
  1017. i++;
  1018. if(s[i++]!='i') return(0);
  1019. if(s[i++]!='d') return(0);
  1020. if(s[i++]!='o') return(0);
  1021. if(s[i++]!='w') return(0);
  1022. if(s[i++]!='p') return(0);
  1023. if(s[i++]!='e') return(0);
  1024. if(s[i++]!='n') return(0);
  1025. if(s[i++]!='a') return(0);
  1026. if(s[i++]!='l') return(0);
  1027. if(s[i++]!='t') return(0);
  1028. if(s[i++]!='y') return(0);
  1029. while(s[i]==' ') i++;
  1030. while(isdigit(s[i])) i++;
  1031. continue;
  1032. }
  1033. }
  1034. return(0); //Line is not Empty
  1035. }
  1036. return(1); //Line is Empty
  1037. }
  1038. /** This function groups multiple rows inside one table cell into a \shortstack*/
  1039. static int OptimizeMultiRows(string & aLine)
  1040. {
  1041. string NewLine,Cell;
  1042. int i;
  1043. char *HelpS,*aLinePtr,OldChar;
  1044. int shortstack;
  1045. HelpS=StrStr(aLine(), "\\penalty-10001");
  1046. shortstack=false;
  1047. aLinePtr=aLine();
  1048. OldChar=0;
  1049. while(*aLinePtr!=0)
  1050. {
  1051. if(aLinePtr==HelpS)
  1052. {
  1053. i=0;
  1054. HelpS=StrStr(++HelpS, "\\penalty-10001");
  1055. aLinePtr+=strlen("\\penalty-10001");
  1056. while(aLinePtr[i]==' ')
  1057. {
  1058. if(aLinePtr[i]==0) goto Reject;
  1059. if(aLinePtr[i]=='&') goto Reject;
  1060. if(aLinePtr[i]=='\\')
  1061. {
  1062. if(aLinePtr[++i]=='\\') goto Reject;
  1063. }
  1064. i++;
  1065. }
  1066. if(!shortstack) Cell="\\shortstack{"+Cell;
  1067. Cell+="\\\\";
  1068. if(aLinePtr[i]=='[') Cell+="{}";
  1069. else if(*aLinePtr!=' ') Cell+=' ';
  1070. shortstack=3;
  1071. }
  1072. Reject: if(OldChar!='\\')
  1073. if(*aLinePtr==0 || *aLinePtr=='&' || (*aLinePtr=='\\' && aLinePtr[1]=='\\'))
  1074. {
  1075. NewLine+=Cell;
  1076. if(shortstack)
  1077. {
  1078. if(shortstack>1) NewLine+="\\strut";
  1079. NewLine+='}';
  1080. }
  1081. NewLine+=OldChar=*aLinePtr++;
  1082. Cell="";
  1083. shortstack=0;
  1084. continue;
  1085. }
  1086. if(*aLinePtr!=' ') shortstack&=~2;
  1087. Cell+=OldChar=*aLinePtr++;
  1088. }
  1089. NewLine+=Cell;
  1090. if(shortstack)
  1091. {
  1092. if(shortstack>1) NewLine+="\\strut";
  1093. NewLine+='}';
  1094. }
  1095. aLine=NewLine;
  1096. return(shortstack);
  1097. }
  1098. /** fix occurence \/ in the vertical mode - remove it */
  1099. static void FixItallicAlignment(TconvertedPass2 & cq2, string *aLineStr)
  1100. {
  1101. if( (cq2.Lines[cq2.pre].Lstring=="")&&(length(*aLineStr)>=2) )
  1102. if ( (*aLineStr)[0]=='\\' && (*aLineStr)[1]=='/' )
  1103. *aLineStr=copy(*aLineStr,2,length(*aLineStr)-2);
  1104. if( (length(cq2.Lines[cq2.next].Lstring)>=2) &&
  1105. (*aLineStr=="" ||
  1106. cq2.Lines[cq2.cur].line_term=='h' || cq2.Lines[cq2.cur].line_term=='p') )
  1107. if( (cq2.Lines[cq2.next].Lstring)[0]=='\\' && (cq2.Lines[cq2.next].Lstring)[1]=='/' )
  1108. cq2.Lines[cq2.next].Lstring=copy(cq2.Lines[cq2.next].Lstring,2,length(cq2.Lines[cq2.next].Lstring)-2);
  1109. }
  1110. /** move } from the beginning of next line to the current line, only when some attribute is opened. */
  1111. static void MoveCurlyBrace(TconvertedPass2 & cq2)
  1112. {
  1113. const char *CHelpS;
  1114. TLinePass2 *NextLine = &cq2.Lines[cq2.next];
  1115. TLinePass2 *CurLine = &cq2.Lines[cq2.cur];
  1116. while(NextLine->attr.Opened_Depth>0)
  1117. {
  1118. CHelpS = NULL;
  1119. // check whether curly brace belongs to a style opened
  1120. if(NextLine->attr.Closed_Depth>0)
  1121. {
  1122. if(NextLine->attr.Opened_Depth >= NextLine->attr.Closed_Depth)
  1123. { // try to remove all string belonging to the attr
  1124. CHelpS = StyleOpCl[NextLine->attr.stack[NextLine->attr.Opened_Depth-1]].Close;
  1125. MatchAgain:
  1126. if(StrNCmp(NextLine->Lstring(), CHelpS, strlen(CHelpS)))
  1127. {
  1128. if(CHelpS[0]=='\\' && CHelpS[1]=='/') // give a last chance to match without \/
  1129. {
  1130. CHelpS += 2;
  1131. if(*CHelpS!=0) goto MatchAgain;
  1132. }
  1133. break; // close command differs, break the loop
  1134. }
  1135. NextLine->attr.Opened_Depth--;
  1136. }
  1137. NextLine->attr.Closed_Depth--;
  1138. }
  1139. if(CHelpS==NULL)
  1140. {
  1141. if(NextLine->Lstring[0]!='}') break;
  1142. CHelpS = "}";
  1143. }
  1144. // remove string from the next line
  1145. NextLine->Lstring = copy(NextLine->Lstring,strlen(CHelpS),length(NextLine->Lstring)-strlen(CHelpS));
  1146. // and append it to a current line
  1147. if(CurLine->Lstring=="" && cq2.Lines[cq2.pre].Lstring!="")
  1148. { // When a current line is empty, add \n
  1149. CurLine->Lstring += CHelpS;
  1150. CurLine->Lstring += "\n";
  1151. }
  1152. else
  1153. CurLine->Lstring += CHelpS;
  1154. }
  1155. }
  1156. static const char *GenericStr[] =
  1157. {"{\\bf", "{\\footnotesize", "{\\it",
  1158. "{\\large", "{\\Large", "{\\LARGE", "{\\rm",
  1159. "{\\sc", "{\\small","{\\tt"};
  1160. /*******************---PASS2---******************/
  1161. void Convert_second_pass(FILE *Strip, FILE *table, FILE *FileOut, FILE *log,FILE *ErrorFile)
  1162. {
  1163. #ifdef DEBUG
  1164. fprintf(log,"\n#Convert_second_pass() ");fflush(log);
  1165. #endif
  1166. int i, len_reg;
  1167. string *aLineStr, s;
  1168. char *HelpS;
  1169. TconvertedPass2 cq2;
  1170. if(FileOut==NULL) return;
  1171. cq2.table = table;
  1172. cq2.Strip = Strip;
  1173. cq2.LaTeX = FileOut;
  1174. cq2.log = log;
  1175. cq2.err = ErrorFile;
  1176. cq2.pre = 0;
  1177. cq2.cur = 1;
  1178. cq2.next = 2;
  1179. cq2.next2 = 3;
  1180. cq2.LangCount = 0;
  1181. cq2.Lines[cq2.pre].envir = ' ';
  1182. cq2.Lines[cq2.pre].new_tabset = false;
  1183. cq2.just_envir_closed = true;
  1184. cq2.LineSpacing=0;
  1185. cq2.Col2Break=1;
  1186. for(i=0; i<=3; i++)
  1187. {
  1188. cq2.Lines[i].Lstring = "";
  1189. cq2.Lines[i].Empty = true;
  1190. cq2.Lines[i].Columns = 1;
  1191. cq2.Lines[i].InhibitBsBslash = false;
  1192. InitAttr(cq2.Lines[i].attr);
  1193. }
  1194. cq2.rownum = 1;
  1195. cq2.perc.Init(0, num_of_lines_stripfile, _("Second pass:"));
  1196. Latex_head(&cq2);
  1197. /*read current row from strip file*/
  1198. Read_TableEntry(&cq2, cq2.cur);
  1199. fGets2(Strip, cq2.Lines[cq2.cur].Lstring );
  1200. cq2.Lines[cq2.cur].Empty = EmptyLine(cq2.Lines[cq2.cur].Lstring);
  1201. /*read next row from strip file*/
  1202. fGets2(Strip, cq2.Lines[cq2.next].Lstring);
  1203. Read_TableEntry(&cq2, cq2.next);
  1204. cq2.Lines[cq2.next].Empty = EmptyLine(cq2.Lines[cq2.next].Lstring);
  1205. /*read row after next row from strip file*/
  1206. fGets2(Strip, cq2.Lines[cq2.next2].Lstring);
  1207. Read_TableEntry(&cq2, cq2.next2);
  1208. cq2.Lines[cq2.next2].Empty = EmptyLine(cq2.Lines[cq2.next2].Lstring);
  1209. while((!feof(Strip) || cq2.Lines[cq2.cur].Lstring != "" || cq2.Lines[cq2.next].Lstring != "" || cq2.Lines[cq2.next2].Lstring != ""))
  1210. {
  1211. Update_global_information(&cq2);
  1212. if(Verbosing >= 1) //actualise a procentage counter
  1213. cq2.perc.Actualise(cq2.rownum);
  1214. aLineStr = &cq2.Lines[cq2.cur].Lstring;
  1215. if(TIPA>=2) // Unsafe Tipa
  1216. {
  1217. *aLineStr = replacesubstring(*aLineStr,"\\!","\\!{}");
  1218. }
  1219. len_reg = length(*aLineStr);
  1220. /* Remove all language mess if only one language is present in a document. */
  1221. if(cq2.LangCount<2)
  1222. {
  1223. HelpS = StrStr((*aLineStr)(), "\\selectlanguage{");
  1224. if(HelpS!=NULL)
  1225. {
  1226. i=*HelpS;
  1227. *HelpS = NULL;
  1228. s = (*aLineStr)();
  1229. *HelpS = i;
  1230. HelpS+=16;
  1231. for(i=0; i<strlen(HelpS); i++)
  1232. {
  1233. if(HelpS[i]==0) break;
  1234. if(HelpS[i]=='}') // remove everything till closing brace
  1235. {
  1236. s += HelpS+i+1;
  1237. *aLineStr = s;
  1238. break;
  1239. }
  1240. }
  1241. }
  1242. }
  1243. /* Try to find and remove useless trailing TAB */
  1244. if(cq2.Lines[cq2.next].line_term=='p' || cq2.Lines[cq2.next].line_term=='h')
  1245. {
  1246. int pos = -1;
  1247. for(i=length(cq2.Lines[cq2.next].Lstring)-1; i>=1; i--)
  1248. {
  1249. char ch = (cq2.Lines[cq2.next].Lstring)[i];
  1250. if(isspace(ch))
  1251. {
  1252. pos = i;
  1253. continue;
  1254. }
  1255. if(ch=='>' && (cq2.Lines[cq2.next].Lstring)[i-1]=='\\')
  1256. {
  1257. pos = i - 1;
  1258. i--;
  1259. continue;
  1260. }
  1261. break;
  1262. }
  1263. if(pos>=0)
  1264. {
  1265. cq2.Lines[cq2.next].Lstring = copy(cq2.Lines[cq2.next].Lstring, 0, pos);
  1266. }
  1267. }
  1268. /* Fix an empty environments C and L. */
  1269. if(((cq2.Lines[cq2.cur].envir==' ')||(cq2.Lines[cq2.cur].envir=='Q')||(cq2.Lines[cq2.cur].envir=='B')) &&
  1270. (cq2.Lines[cq2.next].Empty>0) && (cq2.Lines[cq2.next2].envir!='!') )
  1271. {
  1272. if(cq2.Lines[cq2.next].envir == 'C' || cq2.Lines[cq2.next].envir == 'L')
  1273. {
  1274. cq2.Lines[cq2.next].envir = ' ';
  1275. }
  1276. }
  1277. /* Fix tabs, which are not in the tabbing environment */
  1278. HelpS = StrStr((*aLineStr)(), "\\TAB");
  1279. if(HelpS!=NULL)
  1280. {
  1281. if(HelpS[4]==' ' || HelpS[4]==0)
  1282. {
  1283. FixTabs(&cq2,HelpS); /* Fix tabs must be called first because it can change environment */
  1284. check(*aLineStr);
  1285. }
  1286. }
  1287. if(cq2.Lines[cq2.cur].envir == 'T') /* fix wrongly accented chars in Tabbing enviroment */
  1288. {
  1289. if(StrStr((*aLineStr)(), "\\'{")!=NULL)
  1290. *aLineStr=replacesubstring(*aLineStr,"\\'{","\\a'{");
  1291. if(StrStr((*aLineStr)(), "\\`{")!=NULL)
  1292. *aLineStr=replacesubstring(*aLineStr,"\\`{","\\a`{");
  1293. }
  1294. if(FixSpaces) { /* More than two spaces must be fixed. */
  1295. if(toupper(cq2.Lines[cq2.cur].envir) != 'Q') {
  1296. for(i = 1; i < len_reg; i++)
  1297. {
  1298. if ((*aLineStr)[i] == ' ' && (*aLineStr)[i+1] == ' ')
  1299. {
  1300. (*aLineStr)[i+1] = '~';
  1301. }
  1302. }
  1303. }
  1304. }
  1305. /* Correct illegal argument which begins '['. */
  1306. if(len_reg >= 1 && (*aLineStr)[1] == '[' ||
  1307. len_reg >= 2 && (*aLineStr)[1] == ' ' && (*aLineStr)[2] == '[') {
  1308. len_reg = FixBracket(*aLineStr);
  1309. }
  1310. /* Try to repair \section{ */
  1311. if(OptimizeSection)
  1312. {
  1313. if (StrStr((*aLineStr)(), "\\part{") != NULL)
  1314. {
  1315. cq2.Lines[cq2.cur].InhibitBsBslash = true;
  1316. // cq2.Lines[cq2.next].InhibitBsBslash = true;
  1317. OptimSectionStr(strstr((*aLineStr)(), "\\part{") + 6L);
  1318. check(*aLineStr);
  1319. }
  1320. if (StrStr((*aLineStr)(), "\\chapter{") != NULL)
  1321. {
  1322. cq2.Lines[cq2.cur].InhibitBsBslash = true;
  1323. // cq2.Lines[cq2.next].InhibitBsBslash = true;
  1324. OptimSectionStr(strstr((*aLineStr)(), "\\chapter{") + 9L);
  1325. check(*aLineStr);
  1326. }
  1327. if (StrStr((*aLineStr)(), "\\section{") != NULL)
  1328. {
  1329. cq2.Lines[cq2.cur].InhibitBsBslash = true;
  1330. // cq2.Lines[cq2.next].InhibitBsBslash = true;
  1331. OptimSectionStr(strstr((*aLineStr)(), "\\section{") + 9L);
  1332. check(*aLineStr);
  1333. }
  1334. if (StrStr((*aLineStr)(), "\\subsection{") != NULL)
  1335. {
  1336. cq2.Lines[cq2.cur].InhibitBsBslash = true;
  1337. // cq2.Lines[cq2.next].InhibitBsBslash = true;
  1338. OptimSectionStr(strstr((*aLineStr)(), "\\subsection{") + 12L);
  1339. check(*aLineStr);
  1340. }
  1341. if (StrStr((*aLineStr)(), "\\subsubsection{") != NULL)
  1342. {
  1343. cq2.Lines[cq2.cur].InhibitBsBslash = true;
  1344. // cq2.Lines[cq2.next].InhibitBsBslash = true;
  1345. OptimSectionStr(strstr( (*aLineStr)(), "\\subsubsection{") + 15L);
  1346. check(*aLineStr);
  1347. }
  1348. if (StrStr((*aLineStr)(), "\\paragraph{") != NULL)
  1349. {
  1350. cq2.Lines[cq2.cur].InhibitBsBslash = true;
  1351. // cq2.Lines[cq2.next].InhibitBsBslash = true;
  1352. OptimSectionStr(strstr( (*aLineStr)(), "\\paragraph{") + 11L);
  1353. check(*aLineStr);
  1354. }
  1355. if (StrStr((*aLineStr)(), "\\subparagraph{") != NULL)
  1356. {
  1357. cq2.Lines[cq2.cur].InhibitBsBslash = true;
  1358. // cq2.Lines[cq2.next].InhibitBsBslash = true;
  1359. OptimSectionStr(strstr((*aLineStr)(), "\\subparagraph{") + 14L);
  1360. check(*aLineStr);
  1361. }
  1362. }
  1363. /* Some optimizations of text on current line */
  1364. //fix beginning paragraph with \raise command
  1365. if(cq2.Lines[cq2.pre].Lstring=="" && length(*aLineStr)>=6)
  1366. {
  1367. if(!strncmp((*aLineStr),"\\raise",6))
  1368. *aLineStr="\\strut"+*aLineStr;
  1369. }
  1370. // fix occurence \/ in the vertical mode - remove it
  1371. FixItallicAlignment(cq2,aLineStr);
  1372. // move } from the beginning of next line to the current line, only when some attribute is opened.
  1373. MoveCurlyBrace(cq2);
  1374. //fix \/ again - moving } could free \/
  1375. FixItallicAlignment(cq2,aLineStr);
  1376. if(Open_environment(&cq2)) //this procedure tests change of the environment
  1377. {
  1378. i=cq2.cur; //opening enviroment rejected for an empty line
  1379. cq2.cur=cq2.next;
  1380. cq2.next=cq2.next2;
  1381. cq2.next2=i;
  1382. fGets2(Strip, cq2.Lines[cq2.next2].Lstring);
  1383. cq2.Lines[cq2.next2].Columns = cq2.Lines[cq2.next].Columns;
  1384. Read_TableEntry(&cq2, cq2.next2);
  1385. if((cq2.Lines[cq2.cur].envir=='i')&&(cq2.Lines[cq2.pre].envir=='i'))
  1386. cq2.Lines[cq2.pre].envir='I';
  1387. if((cq2.Lines[cq2.cur].envir=='I')&&(cq2.Lines[cq2.pre].envir=='I'))
  1388. cq2.Lines[cq2.pre].envir='i';
  1389. goto SkipThisLine;
  1390. }
  1391. //fix closed attributes problem
  1392. if(ClosedAttr(cq2.Lines[cq2.cur].attr)) /* Are attributes closed? */
  1393. if(*aLineStr == "")
  1394. {
  1395. if(cq2.Lines[cq2.next].attr.Closed_Depth==cq2.Lines[cq2.cur].attr.Closed_Depth)
  1396. {
  1397. for(i=0;i<cq2.Lines[cq2.next].attr.Closed_Depth;i++)
  1398. {
  1399. if(cq2.Lines[cq2.next].attr.stack[i]!=cq2.Lines[cq2.cur].attr.stack[i])
  1400. { //attributes are not same for next line
  1401. goto FixOpen;
  1402. }
  1403. }
  1404. cq2.Lines[cq2.next].attr.Opened_Depth=cq2.Lines[cq2.cur].attr.Opened_Depth;
  1405. }
  1406. else {
  1407. FixOpen: Open_All_Attr(cq2.Lines[cq2.cur].attr,*aLineStr);
  1408. }
  1409. }
  1410. if (*aLineStr != "" || cq2.Lines[cq2.next].envir=='!')
  1411. { /* Attributes are closed */
  1412. if(cq2.Lines[cq2.cur].LineFlag & 1 && (*aLineStr == '%'||*aLineStr == ""))
  1413. {
  1414. if (Change_envir_EOL(&cq2))
  1415. if(!cq2.just_envir_closed) Close_environment(&cq2);
  1416. goto EmptyThisLine; /* Remove empty line added by wp2latex */
  1417. }
  1418. if(cq2.Lines[cq2.cur].attr.Closed_Depth > cq2.Lines[cq2.cur].attr.Opened_Depth)
  1419. {
  1420. Open_All_Attr(cq2.Lines[cq2.cur].attr,s);
  1421. *aLineStr=s+*aLineStr;
  1422. }
  1423. HelpS = StrStr((*aLineStr)(), "@{\\"); /*ignore tabular formater @{...}*/
  1424. if(HelpS==NULL)
  1425. {
  1426. for(i=0;i<sizeof(GenericStr)/sizeof(char*);i++)
  1427. {
  1428. HelpS = (*aLineStr)(); /**/
  1429. do {
  1430. HelpS = TryToRemoveGeneric(HelpS,GenericStr[i]);
  1431. } while(HelpS!=NULL);
  1432. }
  1433. }
  1434. /* remove duplicit items \selectlanguage */
  1435. HelpS = (*aLineStr)();
  1436. do {
  1437. HelpS = TryToRemoveSelectLanguage(HelpS);
  1438. } while(HelpS);
  1439. HelpS = (*aLineStr)();
  1440. do {
  1441. HelpS = TryToRemoveLineNumbering(HelpS);
  1442. } while(HelpS);
  1443. check(*aLineStr);
  1444. if(cq2.Lines[cq2.cur].envir=='B')
  1445. {
  1446. HelpS=StrStr((*aLineStr)(), "\\penalty-10001");
  1447. if(HelpS!=NULL)
  1448. {
  1449. if(OptimizeMultiRows(*aLineStr))
  1450. if(cq2.Lines[cq2.next].envir=='!' && cq2.Lines[cq2.next].Lstring=="%")
  1451. *aLineStr+="\\\\";
  1452. }
  1453. }
  1454. if(length(*aLineStr)>0)
  1455. if((i=fputs(*aLineStr,cq2.LaTeX))==EOF) /*here is written current line*/
  1456. {
  1457. RunError(0x20,"");
  1458. }
  1459. }
  1460. /*Is it possible to expand the tabbing enviroment? */
  1461. HelpS = StrStr(cq2.Lines[cq2.next].Lstring(), "\\TAB ");
  1462. if((HelpS!=NULL)&&(cq2.Lines[cq2.cur].envir=='T')&&(cq2.Lines[cq2.next].envir==' '))
  1463. {
  1464. cq2.Lines[cq2.next].envir='T'; /* Tabbing expanded for next line */
  1465. }
  1466. switch (cq2.Lines[cq2.cur].line_term)
  1467. {
  1468. case 's':
  1469. case 'p':if(Change_envir_EOL(&cq2))
  1470. {
  1471. if (cq2.Lines[cq2.next].attr.Opened_Depth>0) /* Attributes are opened */
  1472. {
  1473. Close_All_Attr(cq2.Lines[cq2.next].attr,s); /* close attributes on EOL */
  1474. if((cq2.Lines[cq2.pre].Lstring=="") && cq2.Lines[cq2.cur].Empty)
  1475. s=replacesubstring(s,"\\/",""); //remove \/ in vertical mode
  1476. fprintf(cq2.LaTeX,s());
  1477. }
  1478. putc('\n', cq2.LaTeX);
  1479. if(!cq2.just_envir_closed) Close_environment(&cq2);
  1480. }
  1481. else putc('\n', cq2.LaTeX);
  1482. break;
  1483. case 'h':if(toupper(cq2.Lines[cq2.cur].envir) == 'I')
  1484. {
  1485. if (cq2.Lines[cq2.next].attr.Opened_Depth>0) /* Attributes are opened */
  1486. {
  1487. Close_All_Attr(cq2.Lines[cq2.next].attr,cq2.LaTeX); /* close attributes on EOL */
  1488. }
  1489. putc('\n', cq2.LaTeX);
  1490. if(!cq2.just_envir_closed) Close_environment(&cq2);
  1491. cq2.Lines[cq2.cur].envir = ' ';
  1492. }
  1493. else {
  1494. cq2.underline = false;
  1495. for (i = 0; i < cq2.Lines[cq2.next].attr.Closed_Depth; i++)
  1496. cq2.underline = (cq2.underline ||
  1497. cq2.Lines[cq2.next].attr.stack[i] == 0xb || //DblUnd
  1498. cq2.Lines[cq2.next].attr.stack[i] == 0xd || //StrikeOut
  1499. cq2.Lines[cq2.next].attr.stack[i] == 0xe); //Underline
  1500. if (cq2.underline && (cq2.Lines[cq2.next].attr.Opened_Depth>0) &&
  1501. !ClosedAttr(cq2.Lines[cq2.cur].attr) )
  1502. {
  1503. Close_All_Attr(cq2.Lines[cq2.next].attr,cq2.LaTeX); /* close attributes on EOL */
  1504. }
  1505. /* Elke Indent-environment moet na one harde Return*/
  1506. /* Afgesloten worden.*/
  1507. if (Change_envir_EOL(&cq2))
  1508. {
  1509. if (cq2.just_envir_closed) fprintf(cq2.LaTeX, "\\nwln\n");
  1510. else putc('\n', cq2.LaTeX);
  1511. if (cq2.Lines[cq2.next].attr.Opened_Depth>0) /* Attributes are opened */
  1512. {
  1513. Close_All_Attr(cq2.Lines[cq2.next].attr,cq2.LaTeX); /* close attributes on EOL */
  1514. }
  1515. if(!cq2.just_envir_closed) Close_environment(&cq2);
  1516. }
  1517. else {
  1518. if(cq2.Lines[cq2.next].envir=='^'); // do not solve anything at the end of the minipage
  1519. else if (*aLineStr == "" &&
  1520. cq2.Lines[cq2.pre].Lstring == "")
  1521. {
  1522. fprintf(cq2.LaTeX, "\\bigskip");
  1523. }
  1524. else if (cq2.Lines[cq2.next].Empty>0)
  1525. {
  1526. cq2.Lines[cq2.next].InhibitBsBslash = true;
  1527. }
  1528. else if (!cq2.Lines[cq2.cur].InhibitBsBslash)
  1529. {
  1530. /* if (!cq2.just_envir_closed && (cq2.Lines[cq2.cur].envir=='L' || cq2.Lines[cq2.cur].envir=='R'))
  1531. fprintf(cq2.LaTeX, "\\nwln");
  1532. else*/ {
  1533. if(cq2.Lines[cq2.cur].Empty>0)
  1534. {
  1535. if(cq2.Lines[cq2.pre].Lstring!="")
  1536. fputc('\n',cq2.LaTeX);
  1537. fprintf(cq2.LaTeX, " \\bigskip");
  1538. }
  1539. else fprintf(cq2.LaTeX, "\\\\");
  1540. }
  1541. if (cq2.Lines[cq2.next].Lstring[0] == '[')
  1542. {

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