Proposal for improving \left and \right handling

Enrico Forestieri <[email protected]> Tue, 15 Nov 2005 01:43:28 +0100
Newsgroups gmane.comp.tex.latex.latex2rtf.devel
Message-ID <[email protected]>
I noticed that latex2rtf does not correctly translate math constructs
such as \left\Vert ... \right\Vert  or  \left\langle ... \right\rangle.

Example:

\documentclass{article}
\begin{document}
$$
y=3D\left\Vert x \right\Vert^2
$$
\end{document}


I include here a patch for evaluation and possible inclusion in the sourc=
es.

Thank you.

Enrico


--- direct.h.orig   2005-11-09 15:24:04.000000000 +0100
+++ direct.h    2005-11-14 19:09:44.000000000 +0100
@@ -1,2 +1,3 @@
 bool TryDirectConvert(char *command);
 void WriteFontName(const char **buffpoint);
+char *GetLeftRightDelim(char *delim);


--- direct.c.orig       2005-11-09 15:23:22.000000000 +0100
+++ direct.c    2005-11-15 01:36:36.000000000 +0100
@@ -32,6 +32,7 @@
 #include "fonts.h"
 #include "cfg.h"
 #include "util.h"
+#include "parser.h"
=20
 #define MAXFONTLEN 100
=20
@@ -105,3 +106,67 @@
     free(TexCommand);
     return TRUE;
 }
+
+char *GetLeftRightDelim(char *delim)
+
+/***********************************************************************=
*******
+ purpose   : Handles command type delimeters for \left and \right
+ ***********************************************************************=
*******/
+{
+    char *texcmd;
+    char outbuf[128];
+    char fontname[MAXFONTLEN + 1];
+    const char *rtfcmd;
+    int i, fnumber, ir, io;
+
+    texcmd =3D getSimpleCommand();
+    if (strcmp(texcmd, "\\") =3D=3D 0) {
+       *delim =3D getTexChar();
+       free(texcmd);
+       return NULL;
+    } else {
+       rtfcmd =3D SearchRtfCmd(texcmd, DIRECT_A);
+       free(texcmd);
+       if (rtfcmd =3D=3D NULL) {
+           *delim =3D '?';       /* unknown delimiter */
+           return NULL;
+       } else {
+           ir =3D 0;
+           io =3D 0;
+           while (rtfcmd[ir] !=3D '\0') {
+               if (io >=3D sizeof(outbuf)-1) {
+                   diagnostics(ERROR, "Replacement string for \\left or =
\\right delimiter is too large.");
+                   break;
+               }
+               /* handle *FONTNAME* syntax in direct.cfg */
+               if (rtfcmd[ir] =3D=3D '*') {
+                   ir++;
+                   if (rtfcmd[ir] =3D=3D '*') {
+                       outbuf[io++] =3D rtfcmd[ir++];
+                   } else {
+                       i =3D 0;
+                       while (rtfcmd[ir] !=3D '*') {
+                           if ((i >=3D MAXFONTLEN) || (rtfcmd[ir] =3D=3D=
 '\0'))
+                               diagnostics(ERROR, "No terminating '*' in=
 font name\nFound in cfg file command <%s>", rtfcmd);
+                           fontname[i++] =3D rtfcmd[ir++];
+                       }
+                       ir++;
+                       fontname[i] =3D '\0';
+                       fnumber =3D RtfFontNumber(fontname);
+                       if (fnumber < 0)
+                           diagnostics(ERROR, "Unknown font <%s>\nFound =
in cfg file command <%s>", fontname, rtfcmd);
+                       else {
+                           if (io+5 > sizeof(outbuf)-1)
+                               diagnostics(ERROR, "Replacement string to=
o large.\nFound in cfg file command <%s>", rtfcmd);
+                           else
+                               io +=3D sprintf(outbuf+io, "%u", (unsigne=
d int) fnumber);
+                       }
+                   }
+               } else
+                   outbuf[io++] =3D rtfcmd[ir++];
+           }
+           outbuf[io] =3D '\0';
+       }
+    }
+    return strdup(outbuf);
+}



--- equation.c.orig     2005-11-09 20:17:48.000000000 +0100
+++ equation.c  2005-11-14 23:15:58.000000000 +0100
@@ -43,6 +43,7 @@
 #include "util.h"
 #include "graphics.h"
 #include "xref.h"
+#include "direct.h"
=20
 int g_equation_column =3D 1;
=20
@@ -1302,6 +1303,7 @@
  ***********************************************************************=
*******/
 {
     char ldelim, rdelim;
+    char *lstring =3D NULL, *rstring =3D NULL;
     char *contents;
=20
     diagnostics(4, "CmdLeftRight() ... ");
@@ -1312,21 +1314,31 @@
         PopSource();
         ldelim =3D getNonSpace();
      }
-    if (ldelim =3D=3D '\\')         /* might be \{ or \} */
-        ldelim =3D getTexChar();
+    if (ldelim =3D=3D '\\') {       /* might be \{ or \} or \Vert or ...=
 */
+        ungetTexChar(ldelim);
+       lstring =3D GetLeftRightDelim(&ldelim);
+    }
=20
-    diagnostics(4, "CmdLeftRight() ... \\left <%c> ", ldelim);
+    if (lstring)
+       diagnostics(4, "CmdLeftRight() ... \\left <%s> ", lstring);
+    else
+       diagnostics(4, "CmdLeftRight() ... \\left <%c> ", ldelim);
=20
     contents =3D getLeftRightParam();
     rdelim =3D getNonSpace();
=20
-    if (rdelim =3D=3D '\\')         /* might be \{ or \} */
-        rdelim =3D getTexChar();
+    if (rdelim =3D=3D '\\') {       /* might be \{ or \} or \Vert or ...=
 */
+        ungetTexChar(rdelim);
+       rstring =3D GetLeftRightDelim(&rdelim);
+    }
=20
     if (code =3D=3D 1)
         diagnostics(ERROR, "\\right without opening \\left");
=20
-    diagnostics(4, "CmdLeftRight() ... \\left <%c> \\right <%c>", ldelim=
, rdelim);
+    if (rstring)
+       diagnostics(4, "CmdLeftRight() ... \\right <%s>", rstring);
+    else
+       diagnostics(4, "CmdLeftRight() ... \\right <%c>", rdelim);
=20
     if (g_fields_use_EQ) {
=20
@@ -1349,17 +1361,25 @@
         if (ldelim =3D=3D '{' || ldelim =3D=3D '}') {
             fprintRTF("\\\\lc\\\\\\%c", ldelim);
         } else {
-            if (ldelim !=3D '.')
-                fprintRTF("\\\\lc\\\\%c", ldelim);
+            if (ldelim !=3D '.') {
+                if (lstring) {
+                   fprintRTF("\\\\lc\\\\");    /* two fprintRTF's needed=
    */
+                   fprintRTF("%s", lstring);   /* to allow PushFontSetti=
ngs */
+               } else
+                   fprintRTF("\\\\lc\\\\%c", ldelim);
+           }
         }
=20
         if (rdelim =3D=3D '{' || rdelim =3D=3D '}') {
-            fprintRTF("\\\\rc\\\\\\%c (", ldelim);
-
+            fprintRTF("\\\\rc\\\\\\%c (", rdelim);
         } else {
-            if (rdelim !=3D '.')
-                fprintRTF("\\\\rc\\\\%c (", ldelim);
-            else
+            if (rdelim !=3D '.') {
+                if (rstring) {
+                   fprintRTF("\\\\rc\\\\");    /* two fprintRTF's needed=
    */
+                   fprintRTF("%s (", rstring); /* to allow PushFontSetti=
ngs */
+               } else
+                   fprintRTF("\\\\rc\\\\%c (", rdelim);
+           } else
                 fprintRTF("(");
         }
=20
@@ -1370,12 +1390,21 @@
=20
     } else {                    /* g_fields_use_EQ */
=20
-        putRtfChar(ldelim);
+        if (lstring)
+           fprintRTF("%s", lstring);
+       else
+           putRtfChar(ldelim);
         ConvertString(contents);
-        putRtfChar(rdelim);
+        if (rstring)
+           fprintRTF("%s", rstring);
+       else
+           putRtfChar(rdelim);
     }
=20
-
+    if (lstring)
+       free(lstring);
+    if (rstring)
+       free(rstring);
 }
=20
 void CmdArray(int code)





-------------------------------------------------------
This SF.Net email is sponsored by the JBoss Inc.  Get Certified Today
Register for a JBoss Training Course.  Free Certification Exam
for All Training Attendees Through End of 2005. For more info visit:
http://ads.osdn.com/?ad_id=3D7628&alloc_id=3D16845&op=3Dclick