w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

equation.c
Go to the documentation of this file.
1 /* equation.c - Translate TeX equations
2 
3 Copyright (C) 1995-2002 The Free Software Foundation
4 
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19 This file is available from http://sourceforge.net/projects/latex2rtf/
20 
21 Authors:
22  1995-1997 Ralf Schlatterbeck
23  1998-2000 Georg Lehner
24  2001-2002 Scott Prahl
25 */
26 
27 #include <stdlib.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include "main.h"
31 #include "convert.h"
32 #include "commands.h"
33 #include "stack.h"
34 #include "l2r_fonts.h"
35 #include "cfg.h"
36 #include "ignore.h"
37 #include "parser.h"
38 #include "equation.h"
39 #include "counters.h"
40 #include "funct1.h"
41 #include "lengths.h"
42 #include "util.h"
43 #include "graphics.h"
44 #include "xref.h"
45 
47 
48 int script_shift(void)
49 {
50  return CurrentFontSize() / 3.0;
51 }
52 
53 int script_size(void)
54 {
55  return CurrentFontSize() / 1.2;
56 }
57 
58 void
60 /******************************************************************************
61  purpose : Handles \nonumber to suppress numbering in equations
62  ******************************************************************************/
63 {
66 }
67 
68 static char *
70 /******************************************************************************
71  purpose : reads an equation delimited by $...$
72  this routine is needed to handle $ x \mbox{if $x$} $
73  ******************************************************************************/
74 {
75 int brace=0;
76 int slash=0;
77 int i;
78 char *s, *t, *u;
79 
80  s = malloc(1024*sizeof(char));
81  t = s;
82 
83  for (i=0; i<1024; i++) {
84  *t = getTexChar();
85  if (*t == '\\')
86  slash++;
87  else if (*t == '{' && even(slash) &&
88  !(i>5 && strncmp(t-5,"\\left{", 6)==0) &&
89  !(i>6 && strncmp(t-6,"\\right{", 7)==0))
90  brace++;
91  else if (*t == '}' && even(slash) &&
92  !(i>5 && !strncmp(t-5,"\\left}", 6)) &&
93  !(i>6 && !strncmp(t-6,"\\right}", 7)))
94  brace--;
95  else if (*t == '$' && even(slash) && brace == 0) {
96  break;
97  } else
98  slash = 0;
99  t++;
100  }
101  *t = '\0';
102 
103  u = strdup(s); /* return much smaller string */
104  free(s); /* release the big string */
105  return u;
106 }
107 
108 static void
109 SlurpEquation(int code, char **pre, char **eq, char **post)
110 {
111  int true_code = code & ~~ON;
112 
113  switch (true_code) {
114 
115  case EQN_MATH:
116  diagnostics(4, "SlurpEquation() ... \\begin{math}");
117  *pre = strdup("\\begin{math}");
118  *post = strdup("\\end{math}");
119  *eq = getTexUntil(*post,0);
120  break;
121 
122  case EQN_DOLLAR:
123  diagnostics(4, "SlurpEquation() ... $");
124  *pre = strdup("$");
125  *post = strdup("$");
126  *eq = SlurpDollarEquation();
127  break;
128 
129  case EQN_RND_OPEN:
130  diagnostics(4, "SlurpEquation() ... \\(");
131  *pre = strdup("\\(");
132  *post = strdup("\\)");
133  *eq = getTexUntil(*post,0);
134  break;
135 
136  case EQN_DISPLAYMATH:
137  diagnostics(4,"SlurpEquation -- displaymath");
138  *pre = strdup("\\begin{displaymath}");
139  *post = strdup("\\end{displaymath}");
140  *eq = getTexUntil(*post,0);
141  break;
142 
143  case EQN_EQUATION_STAR:
144  diagnostics(4,"SlurpEquation() -- equation*");
145  *pre = strdup("\\begin{equation*}");
146  *post = strdup("\\end{equation*}");
147  *eq = getTexUntil(*post,0);
148  break;
149 
150  case EQN_DOLLAR_DOLLAR:
151  diagnostics(4,"SlurpEquation() -- $$");
152  *pre = strdup("$$");
153  *post = strdup("$$");
154  *eq = getTexUntil(*post,0);
155  break;
156 
157  case EQN_BRACKET_OPEN:
158  diagnostics(4,"SlurpEquation()-- \\[");
159  *pre = strdup("\\[");
160  *post = strdup("\\]");
161  *eq = getTexUntil(*post,0);
162  break;
163 
164  case EQN_EQUATION:
165  diagnostics(4,"SlurpEquation() -- equation");
166  *pre = strdup("\\begin{equation}");
167  *post = strdup("\\end{equation}");
168  *eq = getTexUntil(*post,0);
169  break;
170 
171  case EQN_ARRAY_STAR:
172  diagnostics(4,"Entering CmdDisplayMath -- eqnarray* ");
173  *pre = strdup("\\begin{eqnarray*}");
174  *post = strdup("\\end{eqnarray*}");
175  *eq = getTexUntil(*post,0);
176  break;
177 
178  case EQN_ARRAY:
179  diagnostics(4,"SlurpEquation() --- eqnarray");
180  *pre = strdup("\\begin{eqnarray}");
181  *post = strdup("\\end{eqnarray}");
182  *eq = getTexUntil(*post,0);
183  break;
184  }
185 }
186 
187 static int
189 /******************************************************************************
190  purpose : Determine if equation needs EQ field for RTF conversion
191  ******************************************************************************/
192 {
193  if (strstr(eq,"\\frac")) return 1;
194  if (strstr(eq,"\\sum")) return 1;
195  if (strstr(eq,"\\int")) return 1;
196  if (strstr(eq,"\\iint")) return 1;
197  if (strstr(eq,"\\iiint")) return 1;
198  if (strstr(eq,"\\prod")) return 1;
199  if (strstr(eq,"\\begin{array}")) return 1;
200  if (strstr(eq,"\\left")) return 1;
201  if (strstr(eq,"\\right")) return 1;
202  if (strstr(eq,"\\root")) return 1;
203  if (strstr(eq,"\\sqrt")) return 1;
204  if (strstr(eq,"\\over")) return 1;
205  if (strstr(eq,"\\stackrel")) return 1;
206  if (strstr(eq,"_") || strstr(eq,"^")) return 1;
207  if (strstr(eq,"\\dfrac")) return 1;
208  if (strstr(eq,"\\lim")) return 1;
209  if (strstr(eq,"\\liminf")) return 1;
210  if (strstr(eq,"\\limsup")) return 1;
211  return 0;
212 }
213 
214 static void
215 WriteEquationAsComment(char *pre, char *eq, char *post)
216 /******************************************************************************
217  purpose : Writes equation to RTF file as text of COMMENT field
218  ******************************************************************************/
219 {
220  fprintRTF("{\\field{\\*\\fldinst{ COMMENTS \" ");
221  while (*pre) putRtfChar(*pre++);
222  while (*eq) putRtfChar(*eq++);
223  while (*post) putRtfChar(*post++);
224  fprintRTF("\" }{ }}{\\fldrslt }}");
225 }
226 
227 static char *
228 SaveEquationAsFile(char *pre, char *eq_with_spaces, char *post)
229 {
230  FILE * f;
231  char name[15];
232  char *tmp_dir, *fullname, *texname, *eq;
233  static int file_number = 0;
234 
235  if (!pre || !eq_with_spaces || !post) return NULL;
236 
237  eq = strdup_noendblanks(eq_with_spaces);
238 
239 /* create needed file names */
240  file_number++;
241  tmp_dir = getTmpPath();
242  snprintf(name, 15, "l2r_%04d", file_number);
243  fullname = strdup_together(tmp_dir, name);
244  texname = strdup_together(fullname,".tex");
245 
246  diagnostics(4, "SaveEquationAsFile =%s", texname);
247 
248  f = fopen(texname,"wb");
249  while (eq && (*eq == '\n' || *eq == ' ')) eq++; /* skip whitespace */
250  if (f) {
251  fprintf(f, "%s", g_preamble);
252  fprintf(f, "\\thispagestyle{empty}\n");
253  fprintf(f, "\\begin{document}\n");
254  fprintf(f, "\\setcounter{equation}{%d}\n",getCounter("equation"));
255  if ((strcmp(pre,"$")==0) || (strcmp(pre,"\\begin{math}")==0) || (strcmp(pre,"\\(")==0)) {
256  fprintf(f, "%%INLINE_DOT_ON_BASELINE\n");
257  fprintf(f, "%s\n.\\quad %s\n%s", pre, eq, post);
258  } else if (strstr(pre, "equation"))
259  fprintf(f, "$$%s$$", eq);
260  else
261  fprintf(f, "%s\n%s\n%s", pre, eq, post);
262  fprintf(f, "\n\\end{document}");
263  fclose(f);
264  } else {
265  free(fullname);
266  fullname = NULL;
267  }
268 
269  free(eq);
270  free(tmp_dir);
271  free(texname);
272  return(fullname);
273 }
274 
275 
276 void
277 WriteLatexAsBitmap(char *pre, char *eq, char *post)
278 /******************************************************************************
279  purpose : Convert LaTeX to Bitmap and write to RTF file
280  ******************************************************************************/
281 {
282  char *p, *name;
283  double scale;
284 
285  diagnostics(4, "Entering WriteEquationAsBitmap");
286 
287  if (eq == NULL) return;
288 
290  if (strstr(pre,"music") || strstr(pre,"figure") || strstr(pre,"picture"))
292 
293 /* suppress bitmap equation numbers in eqnarrays with zero or one \label{}'s*/
294  if (strcmp(pre,"\\begin{eqnarray}")==0){
295  p = strstr(eq, "\\label");
296  if (p != NULL && strlen(p)>6) /* found one ... is there a second? */
297  p = strstr(p+6, "\\label");
298  if (p==NULL)
299  name = SaveEquationAsFile("\\begin{eqnarray*}",eq,"\\end{eqnarray*}");
300  else
302  } else
304 
306 }
307 
308 static void
309 PrepareRtfEquation(int code, int EQ_Needed)
310 {
311  int width,a,b,c;
312 
313  width = getLength("textwidth");
314  a = (int) (0.45 * width);
315  b = (int) (0.50 * width);
316  c = (int) (0.55 * width);
317 
318  switch (code) {
319 
320  case EQN_MATH:
321  diagnostics(4, "PrepareRtfEquation ... \\begin{math}");
323  break;
324 
325  case EQN_DOLLAR:
326  diagnostics(4, "PrepareRtfEquation ... $");
327  fprintRTF("{");
329  break;
330 
331  case EQN_RND_OPEN:
332  diagnostics(4, "PrepareRtfEquation ... \\(");
333  fprintRTF("{");
335  break;
336 
337  case EQN_DOLLAR_DOLLAR:
338  diagnostics(4,"PrepareRtfEquation -- $$");
339  CmdEndParagraph(0);
342  fprintRTF("{\\pard\\tqc\\tx%d\\tab ", b);
343  break;
344 
345  case EQN_BRACKET_OPEN:
346  diagnostics(4,"PrepareRtfEquation -- \\[");
349  fprintRTF("\\par\\par\n{\\pard\\tqc\\tx%d\\tqr\\tx%d\n\\tab ", b, width);
350  break;
351 
352  case EQN_DISPLAYMATH:
353  diagnostics(4,"PrepareRtfEquation -- displaymath");
355  fprintRTF("\\par\\par\n\\pard");
356  fprintRTF("\\tqc\\tx%d", b);
357  fprintRTF("\\tab ");
359  break;
360 
361  case EQN_EQUATION_STAR:
362  diagnostics(4,"PrepareRtfEquation -- equation*");
364  fprintRTF("\\par\\par\n\\pard");
365  fprintRTF("\\tqc\\tx%d", b);
366  fprintRTF("\\tab ");
368  break;
369 
370  case EQN_EQUATION:
371  diagnostics(4,"PrepareRtfEquation -- equation");
372  g_equation_column = 5; /* avoid adding \tabs when finishing */
374  fprintRTF("\\par\\par\n\\pard");
375  fprintRTF("\\tqc\\tx%d\\tqr\\tx%d", b, width);
376  fprintRTF("\\tab ");
378  break;
379 
380  case EQN_ARRAY_STAR:
381  diagnostics(4,"PrepareRtfEquation -- eqnarray* ");
385  g_equation_column = 1;
386  fprintRTF("\\par\\par\n\\pard");
387  fprintRTF("\\tqr\\tx%d\\tqc\\tx%d\\tql\\tx%d", a, b, c);
388  fprintRTF("\\tab ");
390  break;
391 
392  case EQN_ARRAY:
393  diagnostics(4,"PrepareRtfEquation --- eqnarray");
397  g_equation_column = 1;
398  fprintRTF("\\par\\par\n\\pard");
399  fprintRTF("\\tqr\\tx%d\\tqc\\tx%d\\tql\\tx%d\\tqr\\tx%d", a, b, c, width);
400  fprintRTF("\\tab ");
402  break;
403 
404  default:
405  diagnostics(ERROR, "calling PrepareRtfEquation with OFF code");
406  break;
407  }
408 
409  if (g_fields_use_EQ && EQ_Needed && g_processing_fields==0) {
410  fprintRTF("{\\field{\\*\\fldinst{ EQ ");
412  }
413 
414 }
415 
416 static void
417 FinishRtfEquation(int code, int EQ_Needed)
418 {
419  if (g_fields_use_EQ && EQ_Needed && g_processing_fields==1) {
420  fprintRTF("}}{\\fldrslt }}");
422  }
423 
424  switch (code) {
425 
426  case EQN_MATH:
427  diagnostics(4,"FinishRtfEquation -- \\end{math}");
430  break;
431 
432  case EQN_DOLLAR:
433  diagnostics(4,"FinishRtfEquation -- $");
434  fprintRTF("}");
436  break;
437 
438  case EQN_RND_OPEN:
439  diagnostics(4,"FinishRtfEquation -- \\)");
440  fprintRTF("}");
442  break;
443 
444  case EQN_DOLLAR_DOLLAR:
445  diagnostics(4,"FinishRtfEquation -- $$");
446  CmdEndParagraph(0);
448  fprintRTF("}");
449  break;
450 
451  case EQN_BRACKET_OPEN:
452  diagnostics(4,"FinishRtfEquation -- \\[");
454  fprintRTF("\\par\\par\n}");
455  break;
456 
457  case EQN_DISPLAYMATH:
458  diagnostics(4,"FinishRtfEquation -- displaymath");
459  CmdEndParagraph(0);
461  break;
462 
463  case EQN_EQUATION_STAR:
464  diagnostics(4,"FinishRtfEquation -- equation*");
465  CmdEndParagraph(0);
467  break;
468 
469  case EQN_ARRAY_STAR:
470  diagnostics(4,"FinishRtfEquation -- eqnarray* ");
471  CmdEndParagraph(0);
475  break;
476 
477  case EQN_EQUATION:
478  case EQN_ARRAY:
479  diagnostics(4,"FinishRtfEquation --- equation or eqnarray");
481  char number[20];
482  incrementCounter("equation");
483  for (; g_equation_column < 3; g_equation_column++)
484  fprintRTF("\\tab ");
485  fprintRTF("\\tab{\\b0 (");
486  snprintf(number,20,"%d",getCounter("equation"));
488  if (g_equation_label) {
491  }
492  fprintRTF(")}");
493  }
496  CmdEndParagraph(0);
498  break;
499 
500  default:
501  diagnostics(ERROR, "calling FinishRtfEquation with OFF code");
502  break;
503  }
504 }
505 
506 static char *
507 scanback(char *s, char *t)
508 /******************************************************************************
509  purpose : Find '{' that starts a fraction designated by \over
510  Consider \int_0 { \{a_{x+y} + b \} \over a_{x+y} }
511  ^ ^ ^
512  s result t
513  ******************************************************************************/
514 {
515  int braces = 1;
516  if (!s || !t || t < s) return NULL;
517 
518  while (braces && s < t) {
519  if (*t=='{' &&
520  !(*(t-1) == '\\') && /* avoid \{ */
521  !(s+5 <= t && !strncmp(t-5,"\\left",5)) && /* avoid \left{ */
522  !(s+6 <= t && !strncmp(t-6,"\\right",6)) /* avoid \right{ */
523  ) braces--;
524 
525  if (*t=='}' &&
526  !(*(t-1) == '\\') && /* avoid \} */
527  !(s+5 <= t && !strncmp(t-5,"\\left",5)) && /* avoid \left} */
528  !(s+6 <= t && !strncmp(t-6,"\\right",6)) /* avoid \right} */
529  ) braces++;
530 
531  if (braces) t--;
532  }
533  return t;
534 }
535 
536 static char *
537 scanahead(char *s)
538 /******************************************************************************
539  purpose : Find '}' that ends a fraction designated by \over
540  Consider \int_0 { \{a_{x+y} + b \} \over a_{x+y} }
541  ^ ^
542  s t
543  ******************************************************************************/
544 {
545  char *t;
546  int braces = 1;
547  int slashes = 0;
548  if (!s) return NULL;
549  t = s;
550 
551  while (braces && t && *t != '\0') {
552 
553  if (even(slashes)) {
554  if (*t=='}' &&
555  !(s+5 <= t && !strncmp(t-5,"\\left",5)) && /* avoid \left} */
556  !(s+6 <= t && !strncmp(t-6,"\\right",6)) /* avoid \right} */
557  ) braces--;
558 
559  if (*t=='{' &&
560  !(s+5 <= t && !strncmp(t-5,"\\left",5)) && /* avoid \left{ */
561  !(s+6 <= t && !strncmp(t-6,"\\right",6)) /* avoid \right{ */
562  ) braces++;
563  }
564 
565  if (*t=='\\') slashes++; else slashes = 0;
566  if (braces) t++;
567  }
568 
569  return t;
570 }
571 
572 static void
573 ConvertOverToFrac(char ** equation)
574 /******************************************************************************
575  purpose : Convert {A \over B} to \frac{A}{B}
576  ******************************************************************************/
577 {
578  char cNext, *eq, *mid, *first, *last, *s, *p, *t;
579  eq = *equation;
580  p = eq;
581  diagnostics(4,"ConvertOverToFrac before <%s>",p);
582 
583  while ((mid = strstr(p,"\\over")) != NULL) {
584  diagnostics(5,"Matched at <%s>",mid);
585  cNext = *(mid+5);
586  diagnostics(5,"Next char is <%c>",cNext);
587  if (!isalpha((int)cNext)) {
588 
589  first = scanback(eq, mid);
590  diagnostics(6, "first = <%s>", first);
591  last = scanahead(mid);
592  diagnostics(6, "last = <%s>", last);
593 
594  strncpy(mid," }{ ",5);
595  diagnostics(6, "mid = <%s>", mid);
596  s = (char *) malloc(strlen(eq)+sizeof("\\frac{}")+1);
597  t = s;
598 
599  strncpy(t, eq, (size_t) (first-eq)); /* everything up to {A\over B} */
600  t += first-eq;
601 
602  strncpy(t, "\\frac", 5); /* insert new \frac */
603  t += 5;
604  if (*first!='{') {*t='{'; t++;} /* add { if missing */
605 
606  strncpy(t, first, (size_t) (last-first)); /* copy A}{B */
607  t += last-first;
608 
609  if (*last!='}') {*t='}'; t++;} /* add } if missing */
610 
611  strcpy(t, last); /* everything after {A\over B} */
612  free(eq);
613  eq = s;
614  p = eq;
615  } else
616  p = mid+5;
617  diagnostics(6,"ConvertOverToFrac current <%s>",eq);
618  }
619  *equation = eq;
620  diagnostics(4,"ConvertOverToFrac after <%s>",eq);
621 }
622 
623 static void
624 WriteEquationAsRTF(int code, char **eq)
625 /******************************************************************************
626  purpose : Translate equation to RTF
627  ******************************************************************************/
628 {
629  int EQ_Needed;
630 
631  EQ_Needed = EquationNeedsFields(*eq);
632 
633  PrepareRtfEquation(code,EQ_Needed);
634  ConvertOverToFrac(eq);
635  ConvertString(*eq);
636  FinishRtfEquation(code,EQ_Needed);
637 }
638 
639 void
641 /******************************************************************************
642  purpose : Handle everything associated with equations
643  ******************************************************************************/
644 {
645  char *pre, *eq, *post;
646  int inline_equation, number, true_code;
647 
648  true_code = code & ~~ON;
649 
650  if (!(code & ON)) return ;
651 
652  SlurpEquation(code,&pre,&eq,&post);
653 
654  diagnostics(4, "Entering CmdEquation --------%x\n<%s>\n<%s>\n<%s>",code,pre,eq,post);
655 
656  inline_equation = (true_code == EQN_MATH) || (true_code == EQN_DOLLAR) || (true_code == EQN_RND_OPEN);
657 
658  number=getCounter("equation");
659 
660  if (g_equation_comment)
662 
663  diagnostics(4,"inline=%d inline_bitmap=%d",inline_equation,g_equation_inline_bitmap);
664  diagnostics(4,"inline=%d display_bitmap=%d",inline_equation,g_equation_display_bitmap);
665  diagnostics(4,"inline=%d inline_rtf =%d",inline_equation,g_equation_inline_rtf);
666  diagnostics(4,"inline=%d display_rtf =%d",inline_equation,g_equation_display_rtf);
667 
668  if ((inline_equation && g_equation_inline_bitmap) ||
669  (!inline_equation && g_equation_display_bitmap) ) {
670  if (true_code != EQN_ARRAY) {
671  PrepareRtfEquation(true_code,FALSE);
673  FinishRtfEquation(true_code,FALSE);
674  } else {
675  char *s, *t;
676  s=eq;
677  diagnostics(4,"eqnarray whole = <%s>",s);
678  do {
679  t=strstr(s,"\\\\");
680  if (t) *t = '\0';
681  diagnostics(4,"eqnarray piece = <%s>",s);
682  if (strstr(s,"\\nonumber"))
684  else
686 
687  PrepareRtfEquation(true_code,FALSE);
688  WriteLatexAsBitmap("\\begin{eqnarray*}",s,"\\end{eqnarray*}");
689  FinishRtfEquation(true_code,FALSE);
690  if (t) s = t+2;
691  } while (t);
692  }
693  }
694 
695  if ((inline_equation && g_equation_inline_rtf) ||
696  (!inline_equation && g_equation_display_rtf) ) {
697  setCounter("equation",number);
698  WriteEquationAsRTF(true_code,&eq);
699  }
700 
701 /* balance \begin{xxx} with \end{xxx} call */
702  if (true_code == EQN_MATH || true_code == EQN_DISPLAYMATH ||
703  true_code == EQN_EQUATION || true_code == EQN_EQUATION_STAR ||
704  true_code == EQN_ARRAY || true_code == EQN_ARRAY_STAR )
706 
707  free(pre);
708  free(eq);
709  free(post);
710 
711 }
712 
713 void
715 /******************************************************************************
716  purpose: converts \sqrt{x} or \root[\alpha]{x+y}
717 ******************************************************************************/
718 {
719  char *root=NULL;
720  char *power=NULL;
721  int symfont;
722 
724  root = getBraceParam();
725 
726  if (g_fields_use_EQ){
727  fprintRTF(" \\\\R(");
728  if (power && strlen(power)>0)
732  fprintRTF(")");
733  } else {
734  if (power && strlen(power)>0) {
735  fprintRTF("{\\up%d\\fs%d ",script_shift(),script_size());
737  fprintRTF("}");
738  }
739  symfont = RtfFontNumber("Symbol");
740  fprintRTF("{\\f%d\\'d6}(",symfont);
742  fprintRTF(")");
743  }
744 
745  if (power) free(power);
746  if (root) free(root);
747 }
748 
749 void
751 /******************************************************************************
752  purpose: converts \frac{x}{y}
753 ******************************************************************************/
754 {
755  char *denominator, *numerator, *nptr, *dptr;
756 
759  skipSpaces();
762 
763  free(numerator);
764  free(denominator);
765  diagnostics(4,"CmdFraction -- numerator = <%s>", nptr);
766  diagnostics(4,"CmdFraction -- denominator = <%s>", dptr);
767 
768  if (g_fields_use_EQ){
769  fprintRTF(" \\\\F(");
772  ConvertString(dptr);
773  fprintRTF(")");
774  } else {
775  fprintRTF(" ");
777  fprintRTF("/");
778  ConvertString(dptr);
779  fprintRTF(" ");
780  }
781 
782  free(nptr);
783  free(dptr);
784 }
785 
786 void
788 /******************************************************************************
789  converts: amssymb \leftrightarrows and \rightleftarrows
790  ******************************************************************************/
791 {
792  int size = (int) (CurrentFontSize()/4.5);
793 
794  fprintRTF(" \\\\o ({\\up%d ",size);
795 
796  switch (code) {
797  case LEFT_RIGHT:
798  ConvertString("\\leftarrow");
799  fprintRTF("}%c{\\dn%d ", g_field_separator, size);
800  ConvertString("\\rightarrow");
801  break;
802 
803  case RIGHT_LEFT:
804  ConvertString("\\rightarrow");
805  fprintRTF("}%c{\\dn%d ", g_field_separator, size);
806  ConvertString("\\leftarrow");
807  break;
808 
809  case RIGHT_RIGHT:
810  ConvertString("\\rightarrow");
811  fprintRTF("}%c{\\dn%d ", g_field_separator, size);
812  ConvertString("\\rightarrow");
813  break;
814 
815  case LEFT_LEFT:
816  ConvertString("\\leftarrow");
817  fprintRTF("}%c{\\dn%d ", g_field_separator, size);
818  ConvertString("\\leftarrow");
819  break;
820 
821  case LONG_LEFTRIGHT:
822  ConvertString("\\longleftarrow");
823  fprintRTF("}%c{\\dn%d ", g_field_separator, size);
824  ConvertString("\\longrightarrow");
825  break;
826 
827  case LONG_RIGHTLEFT:
828  ConvertString("\\longrightarrow");
829  fprintRTF("}%c{\\dn%d ", g_field_separator, size);
830  ConvertString("\\longleftarrow");
831  break;
832  }
833  fprintRTF("}) ");
834 }
835 
836 void
838 /******************************************************************************
839  purpose: handles \lim
840 parameter: 0=\lim, 1=\limsup, 2=\liminf
841  ******************************************************************************/
842 {
843  char cThis, *s, *lower_limit=NULL;
844 
845  cThis = getNonBlank();
846  if (cThis == '_')
847  lower_limit = getBraceParam();
848  else
849  ungetTexChar(cThis);
850 
851  if (code == 0)
852  s=strdup("lim");
853  else if (code == 1)
854  s=strdup("lim sup");
855  else
856  s=strdup("lim inf");
857 
858  if (g_fields_use_EQ){
859  if (lower_limit)
860  fprintRTF("\\\\a\\\\ac(");
861 
862  fprintRTF("%s",s);
863 
864  if (lower_limit) {
866  ConvertString(lower_limit);
867  fprintRTF(")");
868  }
869 
870  } else {
871  fprintRTF("%s ",s);
872  if (lower_limit) {
873  fprintRTF("{\\dn%d\\fs%d ",script_shift(),script_size());
874  ConvertString(lower_limit);
875  fprintRTF("}");
876  }
877 
878  }
879 
880  free(s);
881 }
882 
883 void
885 /******************************************************************************
886  purpose: converts integral symbol and the "exponent" and "subscript" fields
887 parameter: type of operand
888  ******************************************************************************/
889 {
890  char *upper_limit = NULL;
891  char *lower_limit = NULL;
892  char cThis;
893  int no_limits = FALSE;
894  int limits = FALSE;
895 
896  /* is there an exponent/subscript ? */
897  cThis = getNonBlank();
898 
899  if (cThis=='\\') { /* accept \nolimits and \limits */
900  char *command;
901  ungetTexChar(cThis);
903  if (strcmp(command,"\\nolimits")==0) {
904  no_limits = TRUE;
905  diagnostics(WARNING__,"no limits found");
906  free(command);
907  } else if (strcmp(command,"\\limits")==0) {
908  limits = TRUE;
909  diagnostics(WARNING__,"limits found");
910  free(command);
911  } else
913  cThis = getNonBlank();
914  }
915 
916  if (cThis == '_')
917  lower_limit = getBraceParam();
918  else if (cThis == '^')
919  upper_limit = getBraceParam();
920  else
921  ungetTexChar(cThis);
922 
923  if (upper_limit || lower_limit) {
924  cThis = getNonBlank();
925  if (cThis == '_')
926  lower_limit = getBraceParam();
927  else if (cThis == '^')
928  upper_limit = getBraceParam();
929  else
930  ungetTexChar(cThis);
931  }
932 
933  if (g_fields_use_EQ){
934 
935  fprintRTF(" \\\\I");
936  switch(code) {
937  case 4 : if (limits)
938  fprintRTF("( %c %c )\\\\I", g_field_separator, g_field_separator);
939  else
940  fprintRTF("\\\\in( %c %c )\\\\I", g_field_separator, g_field_separator);
941  /*\iiint --- fall through*/
942  case 3 : if (limits)
943  fprintRTF("( %c %c )\\\\I", g_field_separator, g_field_separator);
944  else
945  fprintRTF("\\\\in( %c %c )\\\\I", g_field_separator, g_field_separator);
946  /*\iint --- fall through*/
947  case 0 : if (limits)
949  else
951  break;
952  case 1 : fprintRTF("\\\\su("); break;
953  case 2 : fprintRTF("\\\\pr("); break;
954  default: diagnostics(ERROR, "Illegal code to CmdIntegral");
955  }
956 
957  if (lower_limit)
958  ConvertString(lower_limit);
960  if (upper_limit)
961  ConvertString(upper_limit);
962  fprintRTF("%c )", g_field_separator);
963 
964  } else {
965 
966  int symfont = RtfFontNumber("Symbol");
967  switch(code) {
968  case 4 : fprintRTF("{\\f%d\\'f2}",symfont); /*\iiint --- fall through*/
969  case 3 : fprintRTF("{\\f%d\\'f2}",symfont); /* \iint --- fall through*/
970  case 0 : fprintRTF("{\\f%d\\'f2}",symfont); break;
971  case 1 : fprintRTF("{\\f%d\\'e5}",symfont); break;
972  case 2 : fprintRTF("{\\f%d\\'d5}",symfont); break;
973  default: diagnostics(ERROR, "Illegal code to CmdIntegral");
974  }
975 
976  if (lower_limit) {
977  fprintRTF("{\\dn%d\\fs%d ",script_shift(),script_size());
978  ConvertString(lower_limit);
979  fprintRTF("}");
980  }
981  if (upper_limit){
982  fprintRTF("{\\up%d\\fs%d ",script_shift(),script_size());
983  ConvertString(upper_limit);
984  fprintRTF("}");
985  }
986  }
987 
988  if (lower_limit) free(lower_limit);
989  if (upper_limit) free(upper_limit);
990 }
991 
992 void
993 SubSupWorker (bool big)
994 /******************************************************************************
995  purpose : Stack a superscript and a subscript together
996  ******************************************************************************/
997 {
998  int vertical_shift;
999  char cThis;
1000  char *upper_limit = NULL;
1001  char *lower_limit = NULL;
1002 
1003  for (;;) {
1004  cThis = getNonBlank ();
1005  if (cThis == '_') {
1006  if (lower_limit) diagnostics (WARNING__, "Double subscript");
1007  lower_limit = getBraceParam ();
1008  }
1009  else if (cThis == '^') {
1010  if (upper_limit) diagnostics (WARNING__, "Double superscript");
1011  upper_limit = getBraceParam ();
1012  } else {
1013  ungetTexChar (cThis);
1014  break;
1015  }
1016  }
1017 
1018  if (big)
1019  vertical_shift = CurrentFontSize () / 1.4;
1020  else
1021  vertical_shift = CurrentFontSize () / 4;
1022 
1023  if (upper_limit && lower_limit) {
1024  fprintRTF ("\\\\s\\\\up({\\fs%d ", script_size());
1025  ConvertString (upper_limit);
1026  if (big)
1028  else
1029  fprintRTF ("%c", g_field_separator);
1030  ConvertString (lower_limit);
1031  fprintRTF ("})");
1032 
1033  } else if (lower_limit) {
1034  fprintRTF ("\\\\s\\\\do%d({\\fs%d ", vertical_shift, script_size());
1035  ConvertString (lower_limit);
1036  fprintRTF ("})");
1037 
1038  } else if (upper_limit) {
1039  fprintRTF ("\\\\s\\\\up%d({\\fs%d ", vertical_shift, script_size());
1040  ConvertString (upper_limit);
1041  fprintRTF ("})");
1042  }
1043 
1044  if (lower_limit) free(lower_limit);
1045  if (upper_limit) free(upper_limit);
1046 }
1047 
1048 void
1050 /******************************************************************************
1051  purpose : Handles superscripts ^\alpha, ^a, ^{a} code=0
1052  \textsuperscript{a} code=1
1053  ******************************************************************************/
1054 {
1055  char *s = NULL;
1056 
1057  if (code==0 && g_fields_use_EQ){
1058  ungetTexChar('^');
1060  return;
1061  }
1062 
1063  if ((s = getBraceParam())) {
1064  fprintRTF("{\\up%d\\fs%d ",script_shift(),script_size());
1065  ConvertString(s);
1066  fprintRTF("}");
1067  free(s);
1068  }
1069 }
1070 
1071 void
1073 /******************************************************************************
1074  purpose : Handles subscripts _\alpha, _a, _{a}, code=0
1075  \textsubscript{script} code=1
1076  ******************************************************************************/
1077 {
1078  char *s = NULL;
1079 
1080  if (code==0 && g_fields_use_EQ){
1081  ungetTexChar('_');
1082  SubSupWorker (FALSE);
1083  return;
1084  }
1085 
1086  if ((s = getBraceParam())) {
1087  fprintRTF("{\\dn%d\\fs%d ",script_shift(),script_size());
1088  ConvertString(s);
1089  fprintRTF("}");
1090  free(s);
1091  }
1092 }
1093 
1094 void
1096 /******************************************************************************
1097  purpose : Handles \left \right
1098  to properly handle \left. or \right. would require prescanning the
1099  entire equation.
1100  ******************************************************************************/
1101 {
1102  char ldelim,rdelim;
1103  char *contents;
1104 
1105  ldelim = getNonSpace();
1106  if (ldelim == '\\') /* might be \{ or \} */
1107  ldelim = getTexChar();
1108 
1109  contents= getLeftRightParam();
1110  rdelim= getNonSpace();
1111 
1112  if (rdelim == '\\') /* might be \{ or \} */
1113  rdelim = getTexChar();
1114 
1115  if (code == 1) diagnostics(ERROR, "\\right without opening \\left");
1116 
1117  diagnostics(4, "CmdLeftRight() ... \\left <%c> \\right <%c>", ldelim, rdelim);
1118 
1119  if (g_fields_use_EQ) {
1120 
1121  fprintRTF(" \\\\b ");
1122  if (ldelim == '(' && rdelim == ')'){
1123  fprintRTF("(");
1124  goto finish;
1125  }
1126 
1127  if (ldelim == '{' && rdelim == '}'){
1128  fprintRTF("\\\\bc\\\\\\{ (");
1129  goto finish;
1130  }
1131 
1132  if (ldelim == '[' && rdelim == ']'){
1133  fprintRTF("\\\\bc\\\\[ (");
1134  goto finish;
1135  }
1136 
1137  if (ldelim == '{' || ldelim == '}'){
1138  fprintRTF("\\\\lc\\\\\\%c",ldelim);
1139  } else {
1140  if (ldelim != '.') fprintRTF("\\\\lc\\\\%c", ldelim);
1141  }
1142 
1143  if (rdelim == '{' || rdelim == '}'){
1144  fprintRTF("\\\\rc\\\\\\%c (",ldelim);
1145 
1146  }else{
1147  if (rdelim != '.')
1148  fprintRTF("\\\\rc\\\\%c (", ldelim);
1149  else
1150  fprintRTF("(");
1151  }
1152 
1153  finish:
1154  ConvertString(contents);
1155  fprintRTF(")");
1156  SubSupWorker(TRUE); /* move super or subscripts a lot */
1157 
1158  } else { /*g_fields_use_EQ */
1159 
1160  putRtfChar(ldelim);
1161  ConvertString(contents);
1162  putRtfChar(rdelim);
1163  }
1164 
1165 
1166 }
1167 
1168 void
1170 /******************************************************************************
1171  purpose : Handles \begin{array}[c]{ccc} ... \end{array}
1172  ******************************************************************************/
1173 {
1174 char * v_align, * col_align, *s;
1175 int n=0;
1176 
1177  if (code & ON) {
1178  v_align = getBracketParam();
1179  col_align = getBraceParam();
1180  diagnostics(4, "CmdArray() ... \\begin{array}[%s]{%s}", v_align?v_align:"", col_align);
1181  if (v_align) free(v_align);
1182 
1183  s = col_align;
1184  while (*s) {
1185  if (*s == 'c' || *s == 'l' || *s == 'r' ) n++;
1186  s++;
1187  }
1188  free(col_align);
1189 
1190  fprintRTF(" \\\\a \\\\ac \\\\co%d (", n);
1192 
1193  } else {
1194  fprintRTF(")");
1195  diagnostics(4, "CmdArray() ... \\end{array}");
1197  }
1198 }
1199 
1200 void
1202 /******************************************************************************
1203  purpose : Does not handle plain tex \matrix command, but does not
1204  produce improper RTF either.
1205  ******************************************************************************/
1206 {
1207  char *contents;
1208 
1209  fprintRTF(" matrix not implemented ");
1210  contents = getBraceParam();
1211  free(contents);
1212 }
1213 
1214 void
1216 /******************************************************************************
1217  purpose : Handles \stackrel{a}{=}
1218  ******************************************************************************/
1219 {
1220 char * numer, *denom;
1221 int size;
1222 
1223  size = CurrentFontSize()/1.2;
1224  numer = getBraceParam();
1225  denom = getBraceParam();
1226  diagnostics(4, "CmdStackrel() ... \\stackrel{%s}{%s}", numer,denom);
1227 
1228  if (g_fields_use_EQ) {
1229  fprintRTF(" \\\\a ({\\fs%d ",size);
1230  ConvertString(numer);
1231  fprintRTF("}%c", g_field_separator);
1232  ConvertString(denom);
1233  fprintRTF(") ");
1234 
1235  } else {
1236  diagnostics(WARNING__,"sorry stackrel requires fields");
1237  fprintRTF("{");
1238  ConvertString(numer);
1239  fprintRTF(" ");
1240  ConvertString(denom);
1241  fprintRTF("}");
1242  }
1243 
1244  free(numer);
1245  free(denom);
1246 }
1247 
1248 
#define strdup
Definition: Utility.h:167
#define no_limits
#define width(a)
Definition: aptex-macros.h:198
#define name
#define limits
#define denominator
#define numerator
static char * texname
Definition: cjklatex.c:85
#define n
Definition: t4ht.c:1290
#define b
Definition: jpegint.h:372
#define MODE_HORIZONTAL
Definition: convert.h:2
#define MODE_MATH
Definition: convert.h:4
#define MODE_VERTICAL
Definition: convert.h:6
#define MODE_DISPLAYMATH
Definition: convert.h:5
void incrementCounter(char *s)
Definition: counters.c:78
void setCounter(char *s, int n)
Definition: counters.c:93
int getCounter(char *s)
Definition: counters.c:108
@ pre
Definition: ctie-k.c:71
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
#define free(a)
Definition: decNumber.cpp:310
int command
Definition: t4ht.c:934
#define fopen
Definition: xxstdio.h:21
char * strncpy()
int strcmp()
Definition: coll.cpp:143
long power[32]
Definition: dvi2xx.h:609
char * strcpy()
char tmp_dir[255]
Definition: dvi2xx.h:526
void CmdFraction(int code)
Definition: equation.c:750
int script_size(void)
Definition: equation.c:53
static void FinishRtfEquation(int code, int EQ_Needed)
Definition: equation.c:417
void WriteLatexAsBitmap(char *pre, char *eq, char *post)
Definition: equation.c:277
void CmdArray(int code)
Definition: equation.c:1169
static char * SlurpDollarEquation(void)
Definition: equation.c:69
void CmdSubscript(int code)
Definition: equation.c:1072
static void ConvertOverToFrac(char **equation)
Definition: equation.c:573
void CmdMatrix(int code)
Definition: equation.c:1201
void CmdRoot(int code)
Definition: equation.c:714
static void WriteEquationAsRTF(int code, char **eq)
Definition: equation.c:624
void CmdSuperscript(int code)
Definition: equation.c:1049
static void WriteEquationAsComment(char *pre, char *eq, char *post)
Definition: equation.c:215
void CmdLeftRight(int code)
Definition: equation.c:1095
void CmdNonumber(int code)
Definition: equation.c:59
static char * SaveEquationAsFile(char *pre, char *eq_with_spaces, char *post)
Definition: equation.c:228
int script_shift(void)
Definition: equation.c:48
void CmdStackrel(int code)
Definition: equation.c:1215
static void PrepareRtfEquation(int code, int EQ_Needed)
Definition: equation.c:309
void CmdEquation(int code)
Definition: equation.c:640
int g_equation_column
Definition: equation.c:46
void CmdLim(int code)
Definition: equation.c:837
void CmdIntegral(int code)
Definition: equation.c:884
static void SlurpEquation(int code, char **pre, char **eq, char **post)
Definition: equation.c:109
void CmdArrows(int code)
Definition: equation.c:787
static int EquationNeedsFields(char *eq)
Definition: equation.c:188
void SubSupWorker(bool big)
Definition: equation.c:993
#define EQN_EQUATION
Definition: equation.h:8
#define EQN_DOLLAR
Definition: equation.h:1
#define EQN_BRACKET_OPEN
Definition: equation.h:3
#define EQN_DISPLAYMATH
Definition: equation.h:11
#define LEFT_RIGHT
Definition: equation.h:15
#define LEFT_LEFT
Definition: equation.h:19
#define EQN_ARRAY_STAR
Definition: equation.h:7
#define RIGHT_LEFT
Definition: equation.h:16
#define EQN_DOLLAR_DOLLAR
Definition: equation.h:12
#define EQN_MATH
Definition: equation.h:10
#define LONG_RIGHTLEFT
Definition: equation.h:18
#define EQN_RND_OPEN
Definition: equation.h:2
#define EQN_ARRAY
Definition: equation.h:6
#define LONG_LEFTRIGHT
Definition: equation.h:17
#define EQN_EQUATION_STAR
Definition: equation.h:9
#define RIGHT_RIGHT
Definition: equation.h:20
void CmdIndent(int code)
Definition: funct1.c:339
void CmdEndParagraph(int code)
Definition: funct1.c:146
#define INDENT_INHIBIT
Definition: funct1.h:45
mpz_t * f
Definition: gen-fib.c:34
#define s
Definition: afcover.h:80
#define t
Definition: afcover.h:96
#define c(n)
Definition: gpos-common.c:150
#define a(n)
Definition: gpos-common.c:148
int file_number
Definition: hbf2gf.c:272
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
#define ERROR(string)
Definition: error.h:36
char * strstr()
#define fclose
Definition: debug.h:100
void ConvertString(char *string)
Definition: convert.c:103
void SetTexMode(int mode)
Definition: convert.c:78
bool g_suppress_equation_number
Definition: main.c:89
void diagnostics(int level, char *format,...)
Definition: main.c:469
bool g_equation_inline_rtf
Definition: main.c:109
bool g_show_equation_number
Definition: main.c:87
double g_png_figure_scale
Definition: main.c:115
void fprintRTF(char *format,...)
Definition: main.c:722
bool g_equation_display_rtf
Definition: main.c:108
int g_processing_fields
Definition: main.c:85
char g_field_separator
Definition: main.c:105
bool g_equation_display_bitmap
Definition: main.c:111
double g_png_equation_scale
Definition: main.c:114
char * g_preamble
Definition: main.c:104
bool g_equation_inline_bitmap
Definition: main.c:110
bool g_equation_comment
Definition: main.c:112
bool g_processing_eqnarray
Definition: main.c:83
char * getTmpPath(void)
Definition: main.c:762
int g_processing_arrays
Definition: main.c:84
bool g_fields_use_EQ
Definition: main.c:95
void putRtfChar(char cThis)
Definition: main.c:703
#define WARNING__
Definition: main.h:32
char * g_equation_label
Definition: xref.c:41
bool g_processing_tabular
Definition: tables.c:57
int PushSource(char *filename, char *string)
Definition: parser.c:139
#define fprintf
Definition: mendex.h:64
#define root
Definition: ctangleboot.c:69
#define malloc
Definition: alloca.c:91
#define post
Definition: tie.c:144
int strncmp()
#define snprintf
Definition: snprintf.c:41
int RtfFontNumber(char *Fname)
Definition: l2r_fonts.c:103
int CurrentFontSize(void)
Definition: l2r_fonts.c:665
void skipSpaces(void)
char * getLeftRightParam(void)
char getTexChar(void)
char * getSimpleCommand(void)
char getNonSpace(void)
void ungetTexChar(char c)
char * getTexUntil(char *target, int raw)
char * getBraceParam(void)
char * getBracketParam(void)
char getNonBlank(void)
int getLength(char *s)
Definition: lengths.c:99
integer nptr[3999]
Definition: pmxab.c:511
double scale
Definition: pnmhistmap.c:38
static int32_t last
Definition: ppagelist.c:29
static int32_t first
Definition: ppagelist.c:29
static int size
Definition: ppmlabel.c:24
#define isalpha(ch)
Definition: utype.h:82
Definition: inftrees.h:24
Definition: ttf.h:449
Definition: dvips.h:235
int number
Definition: t1part.c:207
#define FILE
Definition: t1stdio.h:34
*job_name strlen((char *) job_name) - 4)
static int braces
Definition: tex2xindy.c:663
return() int(((double) *(font_tbl[cur_fnt].wtbl+(int)(*(font_tbl[cur_fnt].char_wi+(int)(ch - font_tbl[cur_fnt].char_f)% 256)))/(double)(1L<< 20)) *(double) font_tbl[cur_fnt].scale)
void PutLatexFile(char *s, double scale, char *pre)
Definition: graphics.c:1090
char * strdup_noendblanks(char *s)
Definition: util.c:190
int even(int n)
Definition: util.c:43
char * strdup_together(char *s, char *t)
Definition: util.c:95
@ ON
Definition: ubidiimp.h:55
void InsertBookmark(char *name, char *text)
Definition: xref.c:372
#define return(val)