[tex-k] Patch to make Metapost work with groff.

Michail Vidiassov master at iaas.msu.ru
Mon Sep 22 18:56:11 CEST 2003


Dear All,

I suggest some patches to make Metapost work with groff.
 am not an expert in both, but "it works for me".

Background:
 Metapost can use troff for typesetting labels,
 I have found that useful, when I had to make
 a bunch of Metapost pictures with simple labels
 TeX-independent. But metapost did not like groff,
 and thus was patched by me.

It is well known that Metapost does not work with groff.
The "dmp invocation" node of web2c info doc told me:
>   DMP was written for one particular Troff implementation, and it
> unfortunately has many built-in assumptions about the output and fonts
> file formats used by Troff, which may not be satisfied in other
> environments.  In particular, GNU groff uses some extensions in its file
> formats described in groff_font(5) and groff_out(5) which make its
> output completely unusable for DMP.
>
> Any contributions to improve the portability of DMP or to make it
>  work with GNU groff are welcome, of course.
Or look for GROFF comments in mpware/dmp.c

The patches are to cure for the incompatibilities:
1) .lf request change
>From "Miscellaneous" node of groff info:
> - Request: .lf line filename
>      A debugging aid for documents which are split into many files,
>      then put together with `soelim' and other preprocessors.  The
>      second argument is the name of the file and the first argument is
>      the input line number in that file.  This way `gtroff' can produce
>      error messages which are intelligible to the user.
mpto uses word "line" in .lf request -> remove it.
--- texk/web2c/mpware/mpto.c.orig	Thu Nov  7 16:18:52 2002
+++ texk/web2c/mpware/mpto.c	Thu Nov  7 16:19:38 2002
@@ -59,11 +59,11 @@

 char*	troff_predoc = ".po 0\n";
 char*	troff_postdoc = "";
-char*	troff_pretex1 = ".lf line %d %s\n";	/* first instance */
-char*	troff_pretex = ".bp\n.lf line %d %s\n";	/* subsequent instances */
+char*	troff_pretex1 = ".lf %d %s\n";	/* first instance */
+char*	troff_pretex = ".bp\n.lf %d %s\n";	/* subsequent instances */
 char*	troff_posttex = "\n";
-char*	troff_preverb1 = ".lf line %d %s\n";
-char*	troff_preverb = ".lf line %d %s\n";
+char*	troff_preverb1 = ".lf %d %s\n";
+char*	troff_preverb = ".lf %d %s\n";
 char*	troff_postverb = "\n";

 char*	predoc;

----------------------------------------------------------------------
2) Font description and intermediate output format changes.
The main changes to deal with are the octal nubers in font descriptions
and the new "word output" command t in intermediate format

--- texk/web2c/mpware/dmp.c.orig	Mon Nov 19 23:17:08 2001
+++ texk/web2c/mpware/dmp.c	Wed Sep  3 16:12:20 2003
@@ -59,7 +59,7 @@
 #define FCOUNT	100	/* maximum number of fonts */
 #define SHIFTS	100	/* maximum number of characters with special shifts */
 #define line_length 79	/* maximum output line length (must be at least 60) */
-#define Hprime	307	/* much bigger than max(chars/font,fonts/job) */
+#define Hprime	507	/* much bigger than max(chars/font,fonts/job) */
 #define MAXCHARS 256	/* character codes fall in the range 0..MAXCHARS-1 */
 #define LLENGTH 1024	/* one more than maximum line length for troff output */

@@ -138,7 +138,14 @@
 {
     register int r;
     for(r=0; *s!=0; s++) {
-	r = (r<<1) + *s;
+/* GROFF - in font metrics file the character name may be 8bit
+   groff_font(5) told me:
+       Groff supports eight bit characters;
+   groff_out(5) told me:
+       Note that single characters can have the eighth  bit  set,
+       as can the names of fonts and special characters.
+   Thus convert to unsigned to avoid negative numbers */
+	r = (r<<1) + ( (unsigned char)*s );
 	while (r>=Hprime) r-=Hprime;
     }
     return r;
@@ -233,6 +240,23 @@
     return 0;
 }

+/* GROFF font description files use octal character codes
+   groff_font(5) told me:
+                  The code can be any integer.  If it starts with
+       a 0 it will be interpreted as octal; if it starts with  0x
+       or 0X it will be intepreted as hexadecimal.
+*/
+int get_int_map P1C(char *,s)
+{
+    register int i;
+    if (s==NULL) goto bad;
+    i=strtol(s,&arg_tail,0);
+    if (s==arg_tail) goto bad;
+    return i;
+bad:arg_tail = NULL;
+    return 0;
+}
+

 /* Troff output files contain few if any non-integers, but this program is
    prepared to read floats whenever they seem reasonable; i.e., when the
@@ -271,6 +295,24 @@
     return neg ? -x : x;
 }

+/* GROFF font description files have metrics field
+   of comma-separated integers. Traditional troff
+   have a float in this position. The value is not
+   used anyway - thus just skip the value,
+   eat all non-space chars.
+*/
+float get_float_map P1C(char *,s)
+{
+    if (s!=NULL) {
+       while (isspace(*s))
+            s++;
+       while (!isspace(*s) && *s)
+            s++;
+    }
+    arg_tail = s;
+    return 0;
+}
+


 /**************************************************************
@@ -436,9 +478,9 @@
     if (*lin=='"')
 	*hfind(s,charcodes[f]) = lastcode;
     else {
-	(void) get_float(lin);
+	(void) get_float_map(lin);
 	(void) get_int(arg_tail);
-	lastcode = get_int(arg_tail);
+	lastcode = get_int_map(arg_tail);
 	if (arg_tail==NULL) return 0;
 	*hfind(s,charcodes[f]) = lastcode;
 	if (lastcode<0 || lastcode>=MAXCHARS) return 0;
@@ -685,6 +727,21 @@
     str_h2 = hh + cursize*charwd[f][c];
 }

+void set_string P1C(char*,cname)
+{
+    float hh;  /* corrected version of h, current horisontal position */
+
+    if (!*cname) return;
+    hh = h;
+    set_num_char(curfont,*cname);
+    hh+= cursize*charwd[curfont][*cname];
+    while (*++cname){
+       print_char(*cname);
+       hh += cursize*charwd[curfont][*cname];
+    }
+    h = rint(hh);
+    finish_last_char();
+}

 /* The following initialization and clean-up is required.
 */
@@ -962,6 +1019,8 @@
 {
     float h1, v1, h2, v2;
     finish_last_char();
+    /* GROFF uses Fd to set fill color for solid drawing objects to the default, command ignored */
+    if (*s++ == 'F' && *s == 'd') return;
     gx = (float) h;
     gy = YCORR/unit - ((float) v);
     if (!graphics_used) prepare_graphics();
@@ -1056,6 +1115,17 @@
     case 'H':
 	while (*s!=' ' && *s!='\t') s++;
 	Xheight = get_float(s);
+	/* GROFF troff output is scaled
+	   groff_out(5) told me
+	   The argument to the s command is in scaled  points  (units
+	   of points/n, where n is the argument to the sizescale com-
+	   mand  in the DESC file.)  The  argument  to  the  x Height
+	   command is also in scaled points.
+
+	   sizescale for groff devps is 1000
+	*/
+	if(unit != 0.0) Xheight *= unit;
+	else Xheight /= 1000.0;
 	if (Xheight==cursize) Xheight=0.0;
 	break;
     case 'S':
@@ -1104,6 +1174,17 @@
 		break;
 	    case 's':
 		cursize = get_float(c+1);
+		/* GROFF troff output is scaled
+		   groff_out(5) told me
+		   The argument to the s command is in scaled  points  (units
+		   of points/n, where n is the argument to the sizescale com-
+		   mand  in the DESC file.)  The  argument  to  the  x Height
+		   command is also in scaled points.
+
+		   sizescale for groff devps is 1000
+		*/
+		if(unit != 0.0) cursize *= unit;
+		else cursize /= 1000.0;
 		goto iarg;
 	    case 'f':
 		change_font(get_int(c+1));
@@ -1152,6 +1233,25 @@
 		goto eoln;
 	    case '#':
 		goto eoln;
+	    case 'F':
+	    /* GROFF uses this command to report filename */
+		goto eoln;
+	    case 'm':
+	    /* GROFF uses this command to control color */
+		goto eoln;
+	    case 'u':
+	    /* GROFF uses this command to output a word with additional white space between characters, not implemented */
+		quit("Bad command in troff output\n",
+                "change the DESC file for your GROFF PostScript device, ",
+                "remove tcommand");
+	    case 't':
+	    /* GROFF uses this command to output a word */
+		cc=c; do cc++; while (*cc!=' ' && *cc!='\t' && *cc!='\0');
+		a= *cc; *cc='\0';
+	    	set_string(++c);
+	    	c = cc;
+	    	*c = a;
+	    	continue;
 	    default:
 		quit("Bad command in troff output","","");
 	    }
@@ -1177,8 +1277,8 @@
 {
     extern KPSEDLL char *kpse_bug_address;
     FILE *f = status == 0 ? stdout : stderr;
-    fputs ("Usage: dmp [OPTION]... DITROFFFILE [MPXFILE]\n\
-!   Translate DITROFFFILE to the MetaPost MPXFILE or standard output.\n\
+    fputs ("Usage: dmp [OPTION]... GNUTROFFFILE [MPXFILE]\n\
+!   Translate GNUTROFFFILE to the MetaPost MPXFILE or standard output.\n\
 ! \n\
 ! --help      display this help and exit\n\
 ! --version   output version information and exit\n", f);
------------------------------------------------------------------------
3) Device name for postscript is ps in groff, not post.
 It is also the default.

--- texk/web2c/mpware/makempx.in.orig	Sun Feb  9 17:30:48 2003
+++ texk/web2c/mpware/makempx.in	Fri Mar 14 00:44:42 2003
@@ -16,7 +16,7 @@
 : ${MPTOTR='mpto -troff'}
 : ${NEWER=newer}
 : ${TEX='tex --parse-first-line'}
-: ${TROFF='eqn -d\$\$ | troff -Tpost'}
+: ${TROFF='eqn -Tps -d\$\$ | troff -Tps'}

 # convert relative path to absolute in $MAKEMPX_BINDIR:
 case "$MAKEMPX_BINDIR" in

                 Sincerely, Michail
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mpgroff.tgz
Type: application/octet-stream
Size: 7092 bytes
Desc: 
Url : http://tug.org/pipermail/tex-k/attachments/20030922/5f0c8193/mpgroff.obj


More information about the tex-k mailing list