From bcdf6c829c6761de02484473ebe43fa3760adcaa Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Wed, 12 May 2021 03:01:15 +0000
Subject: CTAN sync 202105120301

---
 support/TeX4ht/source/tex4ht-t4ht.tex | 4521 +++++++++++++++++++++++++++++++++
 1 file changed, 4521 insertions(+)
 create mode 100644 support/TeX4ht/source/tex4ht-t4ht.tex

(limited to 'support/TeX4ht/source/tex4ht-t4ht.tex')

diff --git a/support/TeX4ht/source/tex4ht-t4ht.tex b/support/TeX4ht/source/tex4ht-t4ht.tex
new file mode 100644
index 0000000000..9b534c9490
--- /dev/null
+++ b/support/TeX4ht/source/tex4ht-t4ht.tex
@@ -0,0 +1,4521 @@
+% $Id: tex4ht-t4ht.tex 418 2018-07-03 17:37:07Z karl $
+% tex tex4ht-t4ht   or   ht tex tex4ht-t4ht
+%
+% Copyright 2009-2018 TeX Users Group
+% Copyright 1998-2009 Eitan M. Gurari
+% Released under LPPL 1.3c+.
+% See tex4ht-cpright.tex for license text.
+
+% bcc32 -DBCC32 t4ht.c
+% gcc -O2 -DKPATHSEA -I/usr/local/teTeX/include -L/usr/local/teTeX/lib -o t4ht t4ht.c -DHAVE_DIRENT_H -lkpathsea
+
+\input common.tex
+\input tex4ht.sty    
+
+\Preamble{xhtml,th4,sections+,xhtml}\EndPreamble    
+
+   \input ProTex.sty
+   \AlProTex{c,<<<>>>,`,title,list,_^,CodeLineNo}
+
+%\input tex4ht-cpright.tex
+
+\Comment{   
+}{}
+\def\CodeId#1#2{}
+
+
+\def\UnderLine#1{\ifHtml
+   \HCode{<strong>}#1\HCode{</strong>}\else\underbar{#1}\fi}
+\let\CModifyShowCode=\ModifyShowCode
+\let\CModifyOutputCode=\ModifyOutputCode
+\def\ModifyShowCode{\def\[##1({##1\UnderLine{(}}\def
+                        \;{\UnderLine{;}}\CModifyShowCode}
+   \catcode`\^=7  \catcode`\@=6  \catcode`\#=12 \catcode`\^^M=13\relax%
+\def\ModifyOutputCode{%
+\def\;{ SEP }%
+\def\[@@1(@@2)@@3;{@@1
+#ifdef ANSI
+#define SEP  ,
+(@@3)
+#undef  SEP  
+#else
+#define SEP  ;
+(@@2)@@3;
+#undef  SEP  
+#endif
+}%
+\CModifyOutputCode}%
+   \catcode`\^^M=5 \catcode`\@=12 \catcode`\#=6 \catcode`\^=13
+
+
+
+
+\let\'=\Verb
+\def\`{\expandafter\expandafter\expandafter\qts\Verb}
+\def\qts#1{`#1\aftergroup'}
+
+\def\FTP{http://www.cis.ohio-state.edu/\string~gurari/tpf/}
+
+\TocAt{Section,SubSection}
+\CutAt{Section}
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\LikeChapter{t4ht: postprocessor for tex4ht}
+
+The compilation of this file requires the packages
+\Link[\FTP ProTex.sty]{}{}Pro\TeX\EndLink{}
+and \Link[\FTP AlProTex.sty]{}{}AlPro\TeX\EndLink.
+
+\TableOfContents[Section,SubSection] 
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\Section{Outline}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{The Cases}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+The post-processor \`'tex4ht.c' prepares a \`'.lg' file in which it
+lists the pictures that need to be generated, and the entries
+encountered in \''\Needs{...}'.  The \`'.log' file contains the entries
+encountered in the \''\Needs-{...}'.  The t4ht program (used to be a
+Perl script?) treats as commands the entries that are enclosed between
+double-quote (\''"') characters, and the other entries as comments. It
+first works on the \`'.lg' file and then on the \`'.log' file.
+The main output is a new \`'.css'.
+
+
+\<main's body\><<<
+`<load env file`>
+lg_file = open_file(lg_name,LG_EXT);
+if( lg_file ) {
+   `<mark start lg file`>
+   `<rewind lg file`>  `<stop, if tex4ht.c err`>
+   `<rewind lg file`>  `<CopyTo files`>
+   `<rewind lg file`>  `<htfcss from lg`>
+   `<rewind lg file`>  `<font=(...) from lg`>
+   `<rewind lg file`>  `<identify the empty pictures`>
+   `<rewind lg file`>  `<process gif's`>
+   `<rewind lg file`>  `<process css`>
+   `<rewind lg file`>  `<post-process ext files`>
+   `<rewind lg file`>  `<post-process files`>
+   `<rewind lg file`>  `<mv lg/File to dir and chmod`>
+   `<rewind lg file`>  `<process user commands`>
+   (IGNORED) fclose(lg_file);    
+}
+>>>
+
+\<mv lg/File to dir and chmod\><<<
+eoln_ch = (int) 'x';
+while( eoln_ch != EOF ) {              
+   status = scan_str("File: ", TRUE, lg_file);
+   status = scan_until_end_str("", 1, status, lg_file);
+   status = status && !eq_str(match[1],tmp_name);
+   if( status ){
+                    FILE* file;
+     file = fopen(match[1], READ_TEXT_FLAGS);
+     if( file ){
+        (IGNORED) fclose(file);
+     } else { status = FALSE; }
+   }
+   if( status ){
+      if( dir ){                          
+         (void) execute_script(copy_script, match[1], 
+                               dir? dir :"",".","");
+      }
+      if( ch_mod ){
+         (void) execute_script(chmod_script, ch_mod,
+                               dir? dir:"",match[1], "");
+      }
+}  }
+>>>
+
+% Need to input tex4ht-cpright.tex at this point,
+% if not, it causes an error while expanding the
+% macros like `jobname.tex, `version, ...
+% Still greek to me. :(  CVR/2010/02/11
+% 
+\input tex4ht-cpright.tex
+
+
+\<t4ht.c\><<<
+/* t4ht.c (`version), generated from `jobname.tex
+   Copyright (C) 2009-2018 TeX Users Group
+   Copyright (C) `CopyYear.1998. Eitan M. Gurari
+`<TeX4ht copyright`> 
+*/
+`<t4ht.h`>
+`<defines`>
+`<vars`>
+`<header functions`>
+`<functions`>
+`[
+int `<CDECL`> main(argc, argv)
+       int  argc`;  
+       Q_CHAR **argv
+;{ `<main's vars`> 
+   `<resplit argv for windows`>
+   `<set signals`>
+   `<program signature`>
+   `<main's init`> 
+
+  `<scan job args`>
+   `<main's body`>  
+   return 0;
+}
+>>>
+
+
+\<program signature\><<<
+(IGNORED) printf("----------------------------\n");
+#ifndef KPATHSEA
+#ifdef PLATFORM
+   (IGNORED) printf("t4ht.c (`version %s)\n",PLATFORM);
+#else
+   (IGNORED) printf("t4ht.c (`version)\n");
+#endif
+#else
+#ifdef PLATFORM
+   (IGNORED) printf("t4ht.c (`version %s kpathsea)\n",PLATFORM);
+#else
+   (IGNORED) printf("t4ht.c (`version kpathsea)\n");
+#endif
+#endif
+
+`<handle quoted arguments`>
+{ int i;  
+  for(i=0; i<argc; i++){ 
+    (IGNORED) printf("%s%s ", (i>1)?"\n  " : "", argv[i]); }
+  (IGNORED) printf("\n");
+}
+>>>
+
+
+
+\SubSection{char, signed char, unsigned char (gcc man)}:
+
+
+ Each kind of machine has a default for what char should
+          be.  It is either like unsigned char by default or like
+          signed char by default.
+
+          Ideally, a portable program should  always  use  signed
+          char or unsigned char when it depends on the signedness
+          of an object.  But many programs have been  written  to
+          use plain char and expect it to be signed, or expect it
+          to be unsigned, depending on  the  machines  they  were
+          written  for.   This  option,  and its inverse, let you
+          make such a program work with the opposite default.
+
+          The type char is always a distinct type  from  each  of
+          signed char and unsigned char, even though its behavior
+          is always just like one of those two.
+
+
+
+
+\<definesNO\><<<
+#define Q_CHAR signed char
+#define U_CHAR unsigned char
+#define C_CHAR char
+#define Q_NULL (Q_CHAR *) 0
+#define U_NULL (U_CHAR *) 0
+#define C_NULL (C_CHAR *) 0
+>>>
+
+Pointers to strings must use  \`'C_CHAR', since we don't 
+know how string constants are treated there.
+
+
+\<defines\><<<
+#define Q_CHAR char
+#define U_CHAR char
+#define C_CHAR char
+#define Q_NULL (Q_CHAR *) 0
+#define U_NULL (U_CHAR *) 0
+#define C_NULL (C_CHAR *) 0
+>>>
+
+\SubSection{EOF Character}
+
+
+\<vars\><<<
+static int eoln_ch;
+>>>
+
+\Verbatim
+OBTW: when compiling t4ht.c, I get messages about the uselessness of comparing
+chars (which are unsigned, at least on a IRIX 6.5) to EOF which is defined as
+-1 in stdio.h).... and indeed it program loops endlessly.
+Adding the lines
+   #undef EOF
+   #define EOF 255
+after the last #include gets the effect that you probably want (or perhaps
+better would be to define a constant EOFCHAR or something.)
+\EndVerbatim
+
+The getc returns the next character as an unsigned char converted to int.
+This is so to allow all characters to be return as well as end-of-file
+indicators (-1 in stdio) and error indicator.
+
+
+
+
+%%%%%%%%%%%%%
+\Section{Stop on tex4ht.c Err}
+%%%%%%%%%%%%%
+
+
+
+\<stop, if tex4ht.c err\><<<
+if( check_tex4ht_c_err ){
+   eoln_ch = (int) 'x';
+   while( eoln_ch != EOF ) {              
+      status = scan_str("tex4ht.c error: ", TRUE, lg_file);
+      if( status ){
+          (IGNORED) fprintf(stderr,
+              "--- Error --- tex4ht.c ran into problems\n"
+           );
+           exit(EXIT_FAILURE);
+      }
+      status = scan_until_end_str("", 1, status, lg_file);
+}  }
+>>>
+
+
+
+
+\<vars\><<<
+static BOOL check_tex4ht_c_err = FALSE;
+>>>
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\Section{Platform-dependent Code}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+\SubSection{PreProcessor Directives}
+
+
+Symantec C++ for wid95:
+\''sc t4ht.c -mn -o+time -WA -3 -a8 -c -D_CONSOLE=1 -ot4ht.obj'
+
+
+\<defines\><<<
+#define IGNORED void
+>>>
+
+
+
+\<t4ht.h\><<<
+/* **********************************************
+    Compiler options                            *
+    (uncommented | command line)                *
+------------------------------------------------*
+       Classic C (CC)             default
+#define ANSI                      ansi-c, c++
+#define DOS_C
+#define HAVE_STRING_H             <string.h>
+#define HAVE_DIRENT_H             <dirent.h>
+#define HAVE_SYS_NDIR_H           <sys/ndir.h>
+#define HAVE_SYS_DIR_H            <sys/dir.h>
+#define HAVE_NDIR_H               <ndir.h>
+#define HAVE_IO_H                 <io.h>
+#define HAVE_UNISTD_H             <unistd.h>
+#define WIN32
+#define KPATHSEA             
+#define SYSTEM_FUNCTION_OK 
+#define CDECL                    ..........
+#define BCC32                    bordland c++
+
+*************************************************
+    Tex4ht variables                            *
+    (uncommented | command line)                *
+----------------------------------------------- */
+`<h-defines`>
+/* ******************************************** */
+`<define MSVC-1-52`>
+`<bordland: bcc32 -DBCC32 t4ht`>
+`<bordland: bcc -DBCC tex4ht`>
+`<DJGPP`>
+#ifdef DOS_C
+#define DOS
+#endif
+#ifdef DOS
+#define DOS_WIN32
+#ifndef HAVE_STRING_H
+#define HAVE_STRING_H
+#endif
+#endif
+#ifdef WIN32
+#define DOS_WIN32
+#endif
+`<h-defines DOS-WIN32`>
+`<h-defines KWIN32`>
+`<h-include`>
+`<h-defines 2`>
+>>>
+
+
+\<bordland: bcc32 -DBCC32 t4ht\><<<
+#ifdef BCC32
+#define WIN32 
+#define ANSI       
+#define HAVE_IO_H
+#define HAVE_STRING_H
+#define PLATFORM "ms-win32"
+#endif
+>>>
+
+% 
+
+\<bordland: bcc -DBCC tex4ht\><<<
+#ifdef BCC
+#define DOS_C
+#define ANSI       
+#define HAVE_IO_H
+#define PLATFORM "ms-dos"
+#endif
+>>>
+
+
+\<h-include\><<<
+#ifdef KPATHSEA
+#include <kpathsea/config.h>
+#endif
+#include <stdio.h>   `% EOF, FILE `%
+#include <stdlib.h>  `% EXIT_FAILURE `%
+>>>
+
+
+
+  Under ANSI C, all malloc stuff is declared in \`'<stdlib.h>' (which you
+also include), hence this non-standard header is redundant.
+
+
+
+\<defines\><<<
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+>>>
+
+\<h-include\><<<
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+>>>
+
+
+
+
+\<h-defines DOS-WIN32\><<<
+#ifdef DOS_WIN32
+#define STRUCT_DIRENT
+#endif
+>>>
+
+
+\<h-include\><<<
+#ifdef HAVE_DIRENT_H
+`<needs dirent.h`>
+#else
+#ifndef STRUCT_DIRENT
+#define STRUCT_DIRECT
+#endif
+`<needs simulated dirent.h`>
+#endif 
+>>>
+
+
+
+\<needs dirent.h\><<<
+#include <dirent.h>
+>>>
+
+
+\<needs simulated dirent.h\><<<
+#ifdef HAVE_SYS_NDIR_H
+#include <sys/ndir.h>
+#endif
+#ifdef HAVE_SYS_DIR_H
+#include <sys/dir.h>
+#endif
+#ifdef HAVE_NDIR_H
+#include <ndir.h>
+#endif
+>>>
+
+
+REPLACE EXIT with somthing that DOS also accept.
+
+
+
+
+\<t4ht.h\><<<
+#ifdef DOS
+#define PROTOTYP
+#endif
+#ifdef ANSI
+#define PROTOTYP
+#endif
+#ifdef KWIN32
+#define PROTOTYP
+#endif
+>>>
+
+\<defines\><<<
+#ifdef PROTOTYP
+#define MYVOID void
+#define ARG_I(x) x
+#define ARG_II(x,y) x,y
+#define ARG_III(x,y,z) x,y,z
+#define ARG_IV(x,y,z,w) x,y,z,w
+#define ARG_V(x,y,z,w,u) x,y,z,w,u
+#else
+#define MYVOID 
+#define ARG_I(x) 
+#define ARG_II(x,y) 
+#define ARG_III(x,y,z) 
+#define ARG_IV(x,y,z,w) 
+#define ARG_V(x,y,z,w,u) 
+#endif
+>>>
+
+
+
+
+
+\SubSection{KPATHSEA}
+
+\<h-defines 2NO\><<<
+`<h-include before KPATHSEA`>
+#ifdef KPATHSEA
+#ifndef HAVE_STRCHR
+#define  strchr  index
+#endif
+#ifndef HAVE_STRRCHR
+#define  strrchr  rindex
+#endif
+#include <kpathsea/c-errno.h>
+#include <kpathsea/c-ctype.h>
+#include <kpathsea/c-fopen.h>
+#include <kpathsea/c-pathmx.h>
+#include <kpathsea/proginit.h>
+#include <kpathsea/tex-file.h>
+#include <kpathsea/tex-make.h>
+#include <kpathsea/variable.h>
+#include <signal.h>
+#if !defined(_AMIGA) && !defined(WIN32)
+#include <sys/time.h>
+#endif
+#include <fcntl.h>
+#include <setjmp.h>
+#endif `%/* KPATHSEA */`%
+`<h-include after KPATHSEA`>
+>>>
+
+\<h-defines 2\><<<
+`<h-include before KPATHSEA`>
+#ifdef KPATHSEA
+#include <kpathsea/c-errno.h>
+#include <kpathsea/c-ctype.h>
+#include <kpathsea/c-fopen.h>
+#include <kpathsea/c-pathmx.h>
+#include <kpathsea/proginit.h>
+#include <kpathsea/tex-file.h>
+#include <kpathsea/tex-make.h>
+#include <kpathsea/variable.h>
+#include <signal.h>
+#if !defined(_AMIGA) && !defined(WIN32)
+#include <sys/time.h>
+#endif
+#include <fcntl.h>
+#include <setjmp.h>
+#endif `%/* KPATHSEA */`%
+`<h-include after KPATHSEA`>
+>>>
+
+
+The \`'__cdecl' is defined in KPATHSEA: kpathsea/c-protos.h 
+is defined to nothing for compilers
+other than MS.
+
+\<t4ht.h\><<<
+#ifdef KPATHSEA
+#ifdef WIN32
+#undef CDECL
+#define CDECL                     __cdecl
+#else
+#define CDECL
+#endif
+#endif
+>>>
+
+\<h-defines KWIN32\><<<
+#ifdef KPATHSEA
+#ifdef WIN32
+#define KWIN32  
+#endif
+#endif
+>>>
+
+
+
+
+
+\SubSection{Compilers}
+
+
+\List{}
+\item {BCC32}  
+
+For Win 95.
+
+Options (\''bcc32' comamnd):
+
+\Verbatim
+Borland C++ 5.0 for Win32 Copyright (c) 1993, 1996 Borland International
+Syntax is: BCC32 [ options ] file[s]     * = default; -x- = turn switch x off
+  -3    * 80386 Instructions        -4      80486 Instructions
+  -Ax     Disable extensions        -B      Compile via assembly
+  -C      Allow nested comments     -Dxxx   Define macro
+  -Exxx   Alternate Assembler name  -Hxxx   Use pre-compiled headers
+  -Ixxx   Include files directory   -K      Default char is unsigned
+  -Lxxx   Libraries directory       -M      Generate link map
+  -N      Check stack overflow      -Ox     Optimizations
+  -P      Force C++ compile         -R      Produce browser info
+  -RT   * Generate RTTI             -S      Produce assembly output
+  -Txxx   Set assembler option      -Uxxx   Undefine macro
+  -Vx     Virtual table control     -X      Suppress autodep. output
+  -aN     Align on N bytes          -b    * Treat enums as integers
+  -c      Compile only              -d      Merge duplicate strings
+  -exxx   Executable file name      -fxx    Floating point options
+  -gN     Stop after N warnings     -iN     Max. identifier length
+  -jN     Stop after N errors       -k    * Standard stack frame
+  -lx     Set linker option         -nxxx   Output file directory
+  -oxxx   Object file name          -p      Pascal calls
+  -tWxxx  Create Windows app        -u    * Underscores on externs
+  -v      Source level debugging    -wxxx   Warning control
+  -xxxx   Exception handling        -y      Produce line number info
+  -zxxx   Set segment names
+\EndVerbatim
+
+
+\item {BCC}
+
+For DOS.
+
+\item {MSVC++}
+
+For DOS.
+
+\`'c:\msvc\bin\cl  -Ic:\msvc\include -DDOS  t4ht.c'
+
+In tex-live \`' cl  -D_X86_=1 -DWINVER=0x0400 -DWIN32 -D_WIN32 
+-DWIN32_LEAN_AND_MEAN -D_MT -D_DLL  -DKPATHSEA 
+-D_IMPORT -DANSI -I. -I.   -I.. -IG:\fptex\source\web2c-7.2  -c -W3 
+-DCRTAPI1=_cdecl -DCRTAPI2=_cdecl -nologo  -O2x -G5rs -Gy  
+-c /Fodynamic\t4ht.obj .\t4ht.c'
+
+The following are the available flags (\''c:\msvc\bin\cl -help').
+
+\Verbatim
+                         C COMPILER OPTIONS
+
+                            -MEMORY MODEL-
+/AS small model (default)               /AC compact model
+/AM medium model                        /AL large model
+/AH huge model                          /AT tiny model (.COM files)
+/A<string> (custom memory model)
+                            -OPTIMIZATION-
+/O enable optimization (same as /Ot)    /O1 minimize space
+/O2 maximize speed                      /Oa assume no aliasing
+/Ob<n> inline expansion (default n=0)   /Oc local common subexpression opt.
+/Od disable optimization (default)      /Oe enable registers allocation
+/Of[-] toggle p-code quoting            /Og global common subexpression opt.
+/Oi enable intrinsic functions          /Ol enable loop optimizations
+/On disable ``unsafe'' optimizations      /Oo[-] toggle post code-gen. opt.
+/Op[-] improve floating-pt consistency  /Oq enable maximum p-code optimization
+/Or gen. common exit code (CodeView)    /Os favor code size
+/Ot favor code speed                    /Ov[-] toggle p-code frame sorting
+/OV<n> control inlining by func. size   /Ow assume cross-function aliasing
+/Ox maximum opts. (/Ob1cegilnot /Gs)    /Oz enable ``unsafe'' optimizations
+                          -CODE GENERATION-
+/G0 8086 instructions (default)         /G1  186 instructions
+/G2  286 instructions                   /G3  386 instructions
+  (press <return> to continue)
+/GA protected-mode Win entry/exit code  /GD protected-mode Win entry/exit code
+/GE<x> customize Windows entry/exit     /Gq backwards compatibility with v. 6
+/Gc Pascal style calling conventions    /Gd C style calling conventions
+/Ge use stack-check calls               /Gf enable string pooling
+/Ge use stack-check calls               /Gf enable string pooling
+/Gs remove stack-check calls            /Gn remove p-code native entry points
+/Gp<num> specify p-code entry tables    /Gr _fastcall style calling convention
+/Gt[num] data size threshold            /GW real-mode Windows entry/exit code
+/Gw real-mode Windows entry/exit code   /Gx assume that data is near
+/Gx- assume that data is far            /Gy separate functions for linker
+/Zr check null pointers (/f only)
+                            -OUTPUT FILES-
+/Fa[file] name assembly listing file    /Fc[file] name source/object listing
+/Fd[file] name .PDB filename            /Fe<file> name executable filename
+/Fl[file] name object listing filename  /Fm[file] name map filename
+/Fo<file> name object filename          /Fr[file] name .SBR filename
+/Fp<file> name .PCH filename            /FR[file] name extended .SBR filename
+/Fs[file] name source listing filename
+                            -PREPROCESSOR-
+/C don't strip comments                 /D<name>[=|#text] define macro
+/E preprocess to stdout                 /EP same as /E but no #line
+/I<directory> add #include path         /P preprocess to file
+/U<name> remove predefined macro        /u remove all defined macros
+  (press <return> to continue)
+/X ignore "standard places"
+                              -LANGUAGE-
+/vd{0|1} disable/enable vtordisp        /vm<x> type of pointers to members
+/Z7 C 7 style CodeView information      /Za disable extensions (implies /Op)
+/Zd line number information             /Ze enable extensions (default)
+/Zg generate function prototypes        /Zi prepare for debugging (CodeView)
+/Zl omit default library name in .OBJ   /Zp[n] pack structs on n-byte boundary
+/Zs check syntax only
+                           -FLOATING POINT-
+/FPa calls with altmath                 /FPc calls with emulator
+/FPc87 calls with 8087 library          /FPi inline with emulator (default)
+/FPi87 inline with 8087
+                          -SOURCE LISTING-
+/Sl<columns> set line width             /Sp<lines> set page length
+/St<string> set title string            /Ss<string> set subtitle string
+                           -MISCELLANEOUS-
+/batch specify batch mode compilation   /Bm<num> set compiler's available mem.
+/c compile only, no link                /H<num> external name length
+/J default char type is unsigned        /f select fast compiler (default)
+/f- select optimizing compiler          /Yc create .PCH file
+/Yd put debug info in .PCH file         /Yu use .PCH file
+/YX automatic precompiled header        /nologo suppress copyright message
+  (press <return> to continue)
+/Mq compile for QuickWin                /ND<name> name data segment
+/NM<name> name code segment             /NQ<name> combine p-code temp segments
+/NT<name> name code segment             /NV<name> name far v-table segment
+/Tc<file> compile file without .c       /Tp<file> compile file without .cpp
+/V<string> set version string           /W<n> warning level (default n=1)
+/w disable all warnings                 /WX treat all warnings as errors
+/Zn turn off SBRPACK for .SBR files
+                            -MASM SUPPORT-
+/MA<MASM switch>                        /Ta<file> assemble file without .asm
+                              -LINKING-
+/F <hex_num> stack size (hex. bytes)    /Lr append 'r' to default lib in .OBJ
+/link [lib] give lib name to linker     /Ln do not link CRT.LIB
+/Ld select dynamically-linked library   /Lw select statically-linked library
+\EndVerbatim
+
+
+\EndList
+
+\SubSection{DJGPP}
+
+
+
+
+\Verbatim
+
+        * tex4ht.c [__DJGPP__] (ANSI, DOS_GIF_FILE): Define.
+        (WRITE_BIN_FLAGS, READ_BIN_FLAGS): Use binary mode with DJGPP.
+        (dos_file_names): New variable.
+        (sig_err): If got fatal signal other than SIGINT or SIGQUIT, don't
+        return to caller, since the program will be aborted otherwise.
+        (main) [KPATHSEA]: If input is from stdin which is not a console
+        device, switch it to binary mode.  Set dos_file_names to TRUE for
+        all DOS platforms, FALSE on Unix and WIN32, and compute at runtime
+        for DJGPP.  Simplify logic of finding the init file by pushing
+        HOME=C: into environment if $HOME isn't defined on DOSISH systems.
+\EndVerbatim
+
+
+
+\<DJGPP\><<<
+#ifdef __DJGPP__
+#define DOS_WIN32
+#define ANSI
+#endif
+>>>
+
+
+
+
+\<DJGPP signals\><<<
+#ifdef __DJGPP__
+  if (s != SIGINT && s != SIGQUIT)
+    exit(EXIT_FAILURE);
+#endif
+>>>
+
+
+
+
+\SubSection{Slashes n Directory Pathes}
+
+
+
+
+\<defines\><<<
+#if defined(DOS_WIN32) || defined(__DJGPP__)
+#define dir_path_slash(str) (is_forward_slash(str)? '/' : '\\')
+#else
+#define dir_path_slash(str)  '/' 
+#endif
+>>>
+
+
+
+\<header functions\><<<
+#if defined(DOS_WIN32) || defined(__DJGPP__)
+   static BOOL is_forward_slash( ARG_I(Q_CHAR *) );
+#endif
+>>>
+
+\<functions\><<<
+#if defined(DOS_WIN32) || defined(__DJGPP__)
+`[ 
+static BOOL is_forward_slash(str)
+                                    Q_CHAR * str
+;{   
+   while( *str ){  if( *(str++) == '/' ) { return TRUE; } }
+   return FALSE;
+}
+#endif
+>>>
+
+
+
+
+
+
+
+
+\Section{Command-Line Options}
+
+
+\SubSection{Available Options}
+
+\List{disc}
+\item  \`'.../'---Directory where files should be sent
+\item \`'-mXXX'---\`'chmod XXX' for files
+\item \`'-e...'---Name of invisible gif 
+\item \`'-d'---Directory for config files
+\item \`'-p'---Ignore pictures (but not pictorial symbols)
+\item \`'-i'---Debugging info
+\item     Other---Name of dvi file
+\EndList
+
+
+\Verbatim
+   dvips -mode ibmvga -D 110 -f foo.idv -pp 92  > tmp.ps
+   convert -crop 0x0 -density 110x110 -transparent '#FFFFFF' tmp.ps foo.gif
+   mv foo.gif /WWW/temp/.
+   cp foo.html /WWW/temp/.
+   chmod 644 /WWW/temp/foo.*
+\EndVerbatim
+
+
+\<command line options\><<<
+"\n--------------------------------------------------------------------\n"
+"t4ht [-f<dir char>]filename ...\n"
+"  -b     ignore -d -m -M for bitmaps\n"
+"  -c...  choose named segment in env file\n"
+"  -d...  directory for output files       (default:  current)\n"
+"  -e...  location of tex4ht.env\n"
+"  -i     debugging info\n"
+"  -g     ignore errors in system calls\n"
+"  -m...  chmod ... of new output files (reused bitmaps excluded)\n"
+"  -p     don't convert pictures           (default:  convert)\n"
+"  -r     replace bitmaps of all glyphs    (default:  reuse old ones)\n"
+"  -M...  chmod ... of all output files\n"
+"  -Q     quit, if tex4ht.c had problems\n"
+"  -S...  permission for system calls: *-always, filter\n"
+"  -X...  content for field %%3 in X scripts\n"
+"  -....  content for field %%2 in . scripts\n\n"
+"Example: \n"
+"   t4ht name -d/WWW/temp/ -etex4ht-32.env -m644\n"
+"--------------------------------------------------------------------\n"
+>>>
+
+
+If option \`'-e' is present, empty pictures are replaced
+with the named file (e.g., \`'empty.gif').
+
+
+
+
+
+\SubSection{Scanning the Options}
+
+
+
+
+\<vars\><<<
+static Q_CHAR *ch_mod = Q_NULL;
+static Q_CHAR *debug = Q_NULL;
+static Q_CHAR *Xfield = Q_NULL;
+static Q_CHAR *Dotfield = Q_NULL;
+static Q_CHAR *dir = Q_NULL;
+static Q_CHAR *lg_name  = Q_NULL, tmp_name[255], job_name[255];
+static Q_CHAR *nopict = Q_NULL;
+static Q_CHAR *bitmaps_no_dm = Q_NULL;
+static BOOL newchmod = FALSE;
+static Q_CHAR *noreuse = Q_NULL;
+>>>
+
+
+\<scan job args\><<<
+{      int i;
+       Q_CHAR *p, *q;
+  `<kpathsea arg 0`>
+  `<default args`>
+  if( argc == 1 ){ bad_arg; }
+  for(i=1; i<argc; i++){
+    if( *( p=argv[i] ) == '-' ){ `<scan flaged args`> }
+    else 
+    {  lg_name = argv[i];  }
+  }
+  if( lg_name == NULL ){ bad_arg; }
+  `<set tmp file name`> 
+  `<set job file name`> 
+}
+>>>
+
+
+\<handle quoted arguments\><<<
+{ int i, count = 0;
+ for(i=0; i<argc; i++){ 
+   Q_CHAR *p = argv[i];
+   count++;
+   if( (*p == '\'') || (*p == '\"') ){ 
+     int cnt;
+     int len = 0;
+     for( cnt=i; cnt < argc; cnt++ ){
+       len += (int) strlen((char *) argv[cnt]);
+       if( *(argv[cnt] + (int) strlen((char *) argv[cnt]) -1) == *p ){
+           Q_CHAR * arg = m_alloc(char, len + cnt - i + 1);
+           Q_CHAR * toArg = arg;
+           Q_CHAR *pp;
+           i--;
+           do { 
+             pp = argv[++i];
+             while( *pp != '\0' ){
+                if( *pp != *p ){ *(toArg++) = *pp; } 
+                pp++;
+             }
+             *(toArg++) = ' ';
+           } while ( i != cnt );
+           *(toArg-1) = '\0';
+           argv[count-1] = arg;
+           break;
+ } } } } 
+ argc = count;
+}
+>>>
+
+
+
+
+\<set tmp file name\><<<
+{                                 Q_CHAR   *p, *q;
+                                  FILE*    file;
+   (IGNORED) strcpy((char *) (char *) tmp_name, (char *) (char *) lg_name);
+   p = q = tmp_name + strlen((char *)  tmp_name );
+   while( p != tmp_name ){
+      if( *p == '.' ){
+          if( eq_str( p+1,LG_EXT ) ) { *p = '\0'; }
+          else {  
+            (IGNORED) strct( tmp_name, LG_EXT);
+            file =  fopen( tmp_name, READ_TEXT_FLAGS );
+            if( file ){
+              (IGNORED) fclose(file); *q = '\0';
+            } else {  *p = '\0'; }
+          } 
+          break;
+      }
+      p--;
+   }
+   (IGNORED) strct(tmp_name, ".tmp");
+}
+>>>
+
+
+\<set job file name\><<<
+(IGNORED) strcpy((char *)  job_name, (char *) tmp_name); 
+*(job_name + strlen((char *) job_name) - 4) = '\0';
+>>>
+
+
+
+\Verbatim
+I found that I couldn't compile t4ht.c with KPATHSEA defined, and then noticed
+that it doesn't include any of the kpathsea headers.  So I have patched t4ht.c
+to create two versions:  one with the necessary kpathsea headers and one
+without.  This is the output produced by 'diff'.  Let me know if you want to
+merge my changes into your t4ht.c, and/or if you notice any errors!  I have
+changed the second argument of 'kpse_set_program_name' from NULL (which would
+effectively mean argv[0]) to 'tex4ht', as that saves having to add a
+'T4HTINPUTS' (or 'T4HTKINPUTS') variable into the kpathsea configuration file
+'texmf.cnf' pointing to the same place for 'tex4ht.env' as the 'TEX4HTINPUTS'
+variable.
+
+For t4ht.c, the kpathsea library is only useful for locating the tex4ht.env
+configuration file.  But as it can be used for this purpose for tex4ht.c, it
+seems a pity not to enable it for its companion program too.
+
+> 94a99,102
+> > #ifdef KPATHSEA
+> > #include <kpathsea/progname.h>
+> > #include <kpathsea/tex-file.h>
+> > #endif
+> 943c951
+> <    kpse_set_program_name (argv[0], NULL);
+> ---
+> >    kpse_set_program_name (argv[0], "tex4ht");
+\EndVerbatim
+
+\<kpathsea arg 0\><<<
+#ifdef KPATHSEA
+   kpse_set_program_name (argv[0], "tex4ht");
+#endif
+>>>
+
+
+
+If \`'strlen((char *)  argv[i] ) == 2' the switch is followed by a
+space to be deleted when more input is awaited.
+
+
+\<scan flaged args\><<<
+if( (int) strlen((char *)  argv[i] ) == 2 ){
+   if( `<not a single char option?`> )  
+     { if( ++i == argc ) bad_arg; }
+   q = argv[i]; 
+} else q = p+2;
+switch( *(p+1) ){
+  case 'M':{ ch_mod = q;  newchmod = TRUE; break; }
+  case 'S':{ `<permission for system calls`> break; }
+  case 'X':{ Xfield = q;  break;}
+  case 'b':{ bitmaps_no_dm = q-1;  break;}
+  case 'c':{ `<env blocks selector`>  break;}
+  case 'd':{ dir = (*q=='~')? abs_addr(q,NULL) : q;  break; }
+  case 'e':{ `<get .env directory from com ln`> break; }
+  case 'f':{ `<get file name wo dir`> break; }
+  case 'i':{ debug = q-1;  break;}
+  case 'g':{ always_call_sys = TRUE;  break;}
+  case 'm':{ ch_mod = q;  break; }
+  case 'p':{ nopict = q-1;  break;}
+  case 'Q':{ check_tex4ht_c_err = TRUE;  break;}
+  case 'r':{ noreuse = q-1;  break;}
+  case '.':{ Dotfield = q;  break;}
+   default:{ bad_arg;  }
+}
+>>>
+
+
+\<not a single char option?\><<<
+   (*(p+1) != 'i')  
+&& (*(p+1) != 'p') 
+&& (*(p+1) != 'r')
+&& (*(p+1) != 'b') 
+&& (*(p+1) != 'g') 
+&& (*(p+1) != 'Q') 
+>>>
+
+
+
+The following is to allow for commands \`'htlatex
+-f/../source/foo.tex' which draw files from other directories for
+latex, but use the current directory for tex4ht.c (and t4ht.c). The
+character immediately after \`'-f' is a directory indicator character.
+
+
+\<get file name wo dir\><<<
+p = p + 2;
+lg_name = p + (int) strlen((char *)  p );
+while( *lg_name != *p ){ lg_name--; }
+lg_name++;
+>>>
+
+
+
+
+
+\<header functions\><<<
+static char *  abs_addr( ARG_II( U_CHAR *, U_CHAR *) );
+>>>
+
+\<functions\><<<
+`[
+static char *  abs_addr( dir, base) 
+                                                 U_CHAR  *dir`;
+                                                 U_CHAR  *base
+
+;{                                         U_CHAR  *p;
+   p = m_alloc(char, (int) strlen((char *)  dir ) +
+                     (base? (int) strlen((char *)  base ):0) +
+                     (int) strlen((char *)  HOME_DIR  ));
+   *p = '\0';    
+   if( (*(dir+1) == '~') && base ){  
+     if( *base == '~' ){  
+       (IGNORED) strct(p, HOME_DIR);   
+       (IGNORED) strct(p, base+1);   
+     } else {
+       (IGNORED) strct(p, base);   
+     } 
+     (IGNORED) strct(p, dir+2);   
+   } else {
+     (IGNORED) strct(p, HOME_DIR);   
+     (IGNORED) strct(p, dir+1);   
+   }
+   return p;
+}
+>>>
+
+\<vars\><<<
+U_CHAR *HOME_DIR;
+>>>
+
+\<main's init\><<<
+HOME_DIR = getenv("HOME");
+>>>
+
+
+
+
+\Section{Identify the Empty Pictures}
+
+
+Messages about figures that don't exist are treated as requests for
+empty figures. Typically, they shouldn't be present unless they are
+programmed into \''\setbox'-like commands. tex4ht-c identifies in the
+\''.lg' file the empty figures it finds.
+
+The messages in the ``.lg'' file look like
+\`'--- empty picture --- aa.idv[1] ---'.
+
+
+
+\<identify the empty pictures\><<<
+{                             struct empty_pic_struct *last;    
+   last = empty_pic = (struct empty_pic_struct *) 0;
+   while( TRUE ) {              
+      status = scan_str("--- empty picture --- ", TRUE, lg_file);
+      status = scan_until_str( ".idv[" , 1, status, lg_file);
+      status = scan_until_end_str("] ---", 1, status, lg_file);
+      if( status ){ `<add empty pic`> } 
+      if ( eoln_ch == EOF ){ break; }      
+   }
+   `<add empty pic`>
+   last->next = (struct empty_pic_struct *) 0;
+   last->n = 100000;    
+}
+>>>
+
+
+\<add empty pic\><<<
+if( last == (struct empty_pic_struct *) 0 ){
+   last = empty_pic = (struct empty_pic_struct *) 
+                   m_alloc(struct empty_pic_struct, (int) 1);   
+} else { 
+   last = last->next = (struct empty_pic_struct *) 
+                   m_alloc(struct empty_pic_struct, (int) 1);   
+}
+last->next = (struct empty_pic_struct *) 0;
+last->n = get_long_int(match[1]);    
+>>>
+
+
+\<main's vars\><<<
+struct empty_pic_struct *empty_pic;    
+>>>
+  
+\<defines\><<<
+struct empty_pic_struct{
+  long int n;
+  struct empty_pic_struct *next;
+};
+>>>
+
+
+
+The list of empty pictures is stored in \`'emptypic'.
+
+%%%%%%%%%%%%%%%%%%%%%%%
+\Section{Process Gifs}
+%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{The Scripts}
+%%%%%%%%%%%%%%%%%%%%%%%
+
+\<script for dvigif\><<<
+if( debug ){ (IGNORED) printf(".......'G' script\n"); }
+dvigif_script = add_script(dvigif_script);
+>>>
+
+
+\Verbatim
+--- needs --- aa.idv[80] ==> aa79x.gif ---
+--- characters ---
+--- needs --- aa.idv[81] ==> foo.gif ---
+\EndVerbatim
+
+
+\<process gif's\><<<
+{                               BOOL characters, skip;
+   characters = skip = FALSE;
+   while( TRUE ) {              
+      status = scan_until_str("--- ", 1, TRUE, lg_file);
+      status = scan_until_str( " ---" , 2, status, lg_file);
+      if( status ) {
+        if( eq_str(match[1],"--- ") ){
+           if( eq_str(match[2],"needs ---") ){
+                `<--- needs ---...`>
+           } else if( eq_str(match[2],"characters ---") ){
+              `<--- characters ---...`>
+           } else { `<--- ??? ---...`> }
+        } else { `<???--- needs ---...`> }
+      }
+      if ( eoln_ch == EOF ){ break; }      
+}  }
+>>>
+
+
+\<--- ??? ---...\><<<
+status = scan_until_end_str("", 1, status, lg_file);
+>>>
+
+\<???--- ??? ---...\><<<
+status = scan_until_end_str("", 1, status, lg_file);
+>>>
+
+
+\<--- characters ---...\><<<
+status = scan_until_end_str("", 1, status, lg_file);
+characters = eq_str(match[1],"");
+>>>
+
+
+\SubSection{Identifying the requests}
+
+
+
+\<--- needs ---...\><<<
+status = scan_until_str(" ", 1, status, lg_file);
+status = scan_until_str(".idv", 1, status, lg_file);
+status = scan_until_str("[", 2, status, lg_file);
+status = scan_until_str("] ==> ", 2, status, lg_file);
+status = scan_until_str(" ", 3, status, lg_file);
+   *(match[3] + (int) strlen((char *) match[3]) - 1) = '\0';
+status = scan_until_end_str("---", 4, status, lg_file);
+if( status ) {
+               `<dvi2gif vars`>
+               long int gif_i;
+               Q_CHAR *p;
+   gif_i = get_long_int(match[2]);
+   p = match[2];  
+   *(p + (int) strlen((char *) p) - 6) = '\0';
+   if( characters ){
+      `<translate symbol gifs`>
+   } else { `<translate non-symbol gifs`> }
+}
+>>>
+
+
+\SubSection{General Pictures}
+
+
+\`'--- needs --- aa.idv[80] ==> aa79x.gif ---'
+
+\<translate non-symbol gifs\><<<
+if( gif_i == `<empty picture`> ) {
+  `<insert empty picture`>
+} else { `<insert non-empty picture`> }
+>>>
+
+
+\<insert non-empty picture\><<<
+if( !nopict && !skip ){
+   `<dvi into gif`>
+}
+>>>
+
+
+\<insert empty picture\><<<
+if( !skip ){
+   (void) execute_script(empty_fig_script,
+                           (dir && !bitmaps_no_dm )? dir :"", match[3],"","");
+   if( ch_mod && !bitmaps_no_dm && !system_return ){
+     (void) execute_script(chmod_script, ch_mod, 
+                           dir?dir:"",match[3], "");
+   }
+}
+empty_pic = empty_pic->next; 
+>>>
+
+
+
+\<empty picture\><<<
+empty_pic->n
+>>>
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Pictorial Symbols}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\<translate symbol gifs\><<<
+                  Q_CHAR filename[255];
+                  FILE* file;
+(IGNORED) strcpy((char *) filename, "");
+if( dir && !bitmaps_no_dm ){ (IGNORED) strct(filename, dir); }
+(IGNORED) strct(filename, match[3]);
+file  = fopen(filename, READ_TEXT_FLAGS);  
+if( !file || noreuse ){
+   `<dvi symbols into gif`>
+} else { 
+   (IGNORED) fclose(file);  
+   if( newchmod )
+   { `<chmod for glyphs`> }
+   (IGNORED) printf("%s already in %s\n", match[3], 
+                           dir? dir : "current directory" );
+}
+>>>
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{The Conversion Code}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\<dvi into gif\><<<
+filtered_dvigif_script = filterGifScript(dvigif_script, match[3]);
+(void) execute_script(
+  filtered_dvigif_script,match[1],match[2],match[3],job_name);
+(void) free_script( filtered_dvigif_script );
+if( dir && !bitmaps_no_dm && !system_return ){
+  (void) execute_script(move_script,match[3],dir,".","");
+}
+if( ch_mod && !bitmaps_no_dm && !system_return ){
+  (void) execute_script(chmod_script, ch_mod, dir?dir:"",match[3], "");
+}
+>>>
+
+\<dvi symbols into gif\><<<
+filtered_dvigif_script = dvigif_glyp_script? 
+   filterGifScript(dvigif_glyp_script, match[3]):
+   filterGifScript(dvigif_script, match[3]);
+(void) execute_script(
+    filtered_dvigif_script,match[1],match[2],match[3],job_name);
+(void) free_script( filtered_dvigif_script );
+if( dir && !bitmaps_no_dm && !system_return ){
+  (void) execute_script(move_script,match[3],dir,".","");
+`<chmod for glyphs`>
+}
+>>>
+
+
+\<chmod for glyphs\><<<
+if( ch_mod && !bitmaps_no_dm && !system_return ){
+  (void) execute_script(chmod_script, ch_mod, dir?dir:"",match[3], "");
+}
+>>>
+
+
+\<dvi2gif vars\><<<
+struct script_struct 
+    * filtered_dvigif_script = NULL_SCRIPT;
+>>>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+\<header functions\><<<
+static void execute_script( 
+  ARG_V(struct script_struct*,const Q_CHAR *,const Q_CHAR *,const Q_CHAR *,const Q_CHAR *) );
+>>>
+
+\<functions\><<<
+`[
+static void execute_script(script,match_1,match_2,match_3,match_4)  
+                    struct script_struct* script`;
+                    const Q_CHAR * match_1`;
+                    const Q_CHAR * match_2`;
+                    const Q_CHAR * match_3`;
+                    const Q_CHAR * match_4
+
+;{                               struct script_struct* temp;
+                                 Q_CHAR *p, *q;
+                                 const Q_CHAR *t;
+  `<texmf := ...`>
+   temp = script;  system_return = 0;
+   while( temp ){
+      `<command = temp-command`>
+      if( (command[0] != '\0') && !system_return ){
+         `<execute system command`> }
+      temp = temp->next;
+}  }
+>>>
+
+
+We went to \`'%%%', \`'%%1', ... instead of  \`'%%', \`'%1', ... 
+to accomodate some needds of dos.  Example (yet, where exactly the
+conflict is?):
+
+\Verbatim
+if exist %1.dvi goto yes_dvi
+goto end
+yes_dvi:
+DEL tmp.ps
+call dvips32  -f %1 -p %2 -l %2 -o tmp.ps  -mode ibmvga -D 110
+DEL %3
+call convert -crop 0x0 -density 110x110 -transparent '#FFFFFF' tmp.ps %3
+end:
+\EndVerbatim
+
+
+
+\<command = temp-command\><<<
+p = temp->command;
+q = command;
+while( *p != '\0' ){
+  *q = *(p++);
+  if( (*q == '%') && (*p == '%') 
+     && (    (*(p+1) == '%')  
+          || (*(p+1) == '~')  
+          || ( (*(p+1) >= '0') && (*(p+1) < '5') ) )
+  ){  p++;
+    switch( *(p++) ){
+      case '%':{  q++; break; }
+      case '0':{   t = job_name;
+            while( *t != '\0' ){ *(q++) = *(t++); }  break; }
+      case '1':{  t = match_1;
+            while( *t != '\0' ){ *(q++) = *(t++); }  break; }
+      case '2':{  t = match_2;
+            while( *t != '\0' ){ *(q++) = *(t++); }  break; }
+      case '3':{  t = match_3;
+            while( *t != '\0' ){ *(q++) = *(t++); }  break; }
+      case '4':{  t = match_4;
+            while( *t != '\0' ){ *(q++) = *(t++); }  break; }
+      case '~':{ `<q += texmf path`>          break; }
+      default: {  }
+  }} else { q++; }
+}
+*q = '\0';
+>>>
+
+The argument `\Verb=%%~=' is replaced with the value of
+\Verb=${TEXMFDIST}= under Kpathsea.  If such a value 
+is not available, the character `\Verb=~=' is used.   The variable
+offers the parent directory of where tex4ht resides, e.g.,
+\Verb=/usr/local/texlive/2018/texmf-dist=. We use TEXMFDIST in
+preference to SELFAUTOPARENT (as was done until June 2018), or
+TEXMFROOT, because in practice it works on both \TeX\ Live and MiK\TeX,
+while the others do not.
+
+\<texmf := ...\><<<
+#ifdef KPATHSEA   
+const char * texmf = kpse_var_value( "TEXMFDIST" );
+#endif
+>>>
+
+\<q += texmf path\><<<
+#ifdef KPATHSEA   
+   if( texmf ){
+      t = texmf;
+      while( *t != '\0' ){ *(q++) = *(t++); }
+   } else {
+      *(q++) = '~';
+   }
+#else
+   *(q++) = '~';
+#endif
+>>>
+
+
+
+
+\Verbatim
+
+>  > help tinkering with the code.  If you'll have a chance at some
+>  > point to pass on the kind of changes you are doing, I'll be interested
+>  > to hardwire them in the code as compile/run-time options.
+> for instance, I add -Pem to the dvips command line to access the EM
+> fonts instead of EC (faster)
+> 
+> i also change the name of "convert.exe" to "iconvert.exe" because it
+> conflicts with a native NT utility to convert file systems :-}
+
+\EndVerbatim
+
+\Verbatim
+dvips -mode $mf -D $density -f $_[0] -pp $_[1] > tmp.ps
+\EndVerbatim
+
+\<defines\><<<      
+#ifndef HTFDIR
+#define HTFDIR      ""
+#endif
+>>>
+
+
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Filter}
+%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+Three cases for `G' and `F' scripts.
+
+\List{}
+\item
+{The first record doesn't start with a period}
+Use the script until its end or a period command
+\item
+{The first record starts with a period without an extension}
+Use the script until its end or a period command
+\item
+{The first record starts with a period with an extension}
+Use the script until its end or a period command, if the extension
+fits the output figure.
+
+\EndList
+
+
+\<header functions\><<<
+static struct script_struct  * filterGifScript(
+        ARG_II( struct script_struct  *, Q_CHAR *) );
+>>>
+
+\<functions\><<<
+`[
+static struct script_struct * filterGifScript( script, file) 
+                                   struct script_struct *script`;
+                                                   Q_CHAR *file
+;{                                         
+                   struct script_struct *filtered_script, *scr,
+                                                   *old_script,
+                                                   *new_script;
+                                         Q_CHAR *command, *ext;
+   filtered_script = NULL_SCRIPT;
+   if( script == NULL_SCRIPT )
+       return filtered_script;
+   old_script = script;
+   command = old_script->command;
+   if( *command != '.' ){
+      `<script until dot`> 
+   } else {
+      `<script from dot`> 
+   }   
+}
+>>>
+
+\<script until dot\><<<
+new_script = NULL_SCRIPT;
+while( old_script != NULL_SCRIPT ){
+   command = old_script->command;
+   if( *command == '.' ){ return filtered_script; }
+   scr = (struct script_struct *)
+            m_alloc(struct script_struct, (int) 1);   
+   scr->command = old_script->command;
+   scr->next = NULL_SCRIPT;
+   if( new_script == NULL_SCRIPT ){
+     filtered_script = new_script = scr;
+   } else {
+     new_script = new_script->next = scr;
+   }
+   old_script = old_script->next;
+}
+return filtered_script;
+>>>
+
+\<script from dot\><<<
+`<ext = file ext`>
+while( TRUE ){ 
+  if( old_script == NULL_SCRIPT ){
+     return NULL_SCRIPT;
+  }
+  command = old_script->command;
+  if(*command != '.') {
+    old_script = old_script->next;
+    continue;
+  }
+  old_script = old_script->next;
+  if( (*(command+1) == '\0') || eq_str(ext,command) ){
+    break;
+  }
+}
+`<script until dot`> 
+>>>
+
+
+\<ext = file ext\><<<
+ext = file;
+while( *ext != '\0' ){ ext++; }
+while( (*ext != '.') && (ext != file) ){ ext--; }
+>>>
+
+
+\<header functions\><<<
+void free_script(
+        ARG_I( struct script_struct  *) );
+>>>
+
+\<functions\><<<
+`[
+void free_script(script) 
+                                   struct script_struct *script
+;{                                         
+                                   struct script_struct *temp;
+  while( script != NULL_SCRIPT ){
+    temp = script;
+    script = script->next;
+    free( temp );
+  }
+}
+>>>
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Ignore/Noignore Commands}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\<???--- ??? ---...\><<<
+status = scan_until_end_str("", 1, status, lg_file);
+>>>
+
+
+\Verbatim
+l. 10 --- needs --- ignore ---
+l. 11 --- needs --- end ignore ---
+\EndVerbatim
+
+
+We didn't check below the \`'l. dddd ' part.
+
+\<???--- needs ---...\><<<
+status = scan_until_end_str(" ignore ---", 2, status, lg_file);
+if( status ){
+  skip =  eq_str(match[2]," ignore ---") ? TRUE :
+            ( eq_str(match[2]," end ignore ---") ? FALSE : skip );
+}
+>>>
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%
+\Section{CopyTo files}
+%%%%%%%%%%%%%%%%%%%%%%%
+
+
+There are 6 supporting dvi variations of the 
+`CopyTo to-file op group'
+ dvi command:
+
+\List{}
+\item{From}    Start copying (at current address)
+\item{Until}   End copying   (at current address)
+\item{Skip}    Start skipping (from current address)
+\item{Cont}    End skipping (at current-address)
+\item{Addr integer-label} Associate current 
+      address with the integer-label of the given group
+\item{Set integer-label}   
+     Replace the `current address' in the following Skip/Cont (and
+     From/Until ?) commands with the address associated to the
+     integer-label of the given group  by an Addr command
+\EndList
+
+The code
+\Verbatim
+B0
+ \ht:special {t4ht@DCopyTo: \jobname-js.tex From bib }
+B1
+ \ht:special {t4ht@DCopyTo: \jobname-js.tex Skip bib }
+B2
+ \ht:special {t4ht@DCopyTo: \jobname-js.tex Addr1 bib }
+B3
+ \ht:special {t4ht@DCopyTo: \jobname-js.tex Addr2 bib }
+B4
+ \ht:special {t4ht@DCopyTo: \jobname-js.tex Set1 bib }
+ \ht:special {t4ht@DCopyTo: \jobname-js.tex Cont bib }
+ \ht:special {t4ht@DCopyTo: \jobname-js.tex Set2 bib }
+ \ht:special {t4ht@DCopyTo: \jobname-js.tex Skip bib }
+B5
+\ht:special {t4ht@DCopyTo: \jobname-js.tex Until bib }
+B6
+\EndVerbatim
+
+produces the string ` B1  B3 '.
+
+
+
+
+\<CopyTo files\><<<
+{     `<CopyTo vars`>
+   eoln_ch = (int) 'x';
+   while( eoln_ch != EOF ) {              
+      status = scan_str("CopyTo: ", TRUE, lg_file);
+      status = scan_until_str(" ", 1, status, lg_file);
+      status = scan_until_str(" ", 2, status, lg_file);
+      status = scan_until_str(" ", 3, status, lg_file);
+      status = scan_until_str(" ", 4, status, lg_file);
+      status = scan_until_end_str("", 5, status, lg_file);
+      if( status ){
+         if( debug ){
+            (IGNORED) printf("...CopyTo: %s%s%s%s%s...\n",
+                     match[1], match[2], match[3], match[4], match[5]);
+         }
+         rec_op = eq_str(match[2],"From ")?  From_op :
+                  ( eq_str(match[2],"Until ")? Until_op :
+                    ( eq_str(match[2],"Skip ")?  Skip_op :
+                      ( eq_str(match[2],"Cont ")?  Cont_op : No_op )));
+         if( rec_op == No_op ){ `<try Addr and Set ops`> }
+         if( rec_op == No_op ){
+            (IGNORED) fprintf(stderr,"--- warning --- ");
+            (IGNORED) fprintf(stderr,"CopyTo: %s%s%s%s%s?\n",
+                      match[1], match[2], match[3], match[4], match[5]);  
+         } else {
+            `<find file records`>
+            `<find to-from record`>
+            `<find group record`>
+            `<enter op record`>
+            `<act on op`>
+   }  }  }
+   `<release CopyTo resources`>
+}
+>>>
+
+
+\<try Addr and Set ops\><<<
+ch = match[2];
+if( (ch[0]=='S') && (ch[1]=='e') && (ch[2]=='t') ){
+  ch += 3; rec_op = Set_op;
+} else if( (ch[0]=='A') && (ch[1]=='d') && (ch[2]=='d') && (ch[3]=='r') ){
+  ch += 4; rec_op = Addr_op;
+}
+if( rec_op != No_op ){
+  addr = 0; while( (*ch>='0') && (*ch<='9') ){
+    addr = addr*10 + *ch - '0'; ch++;
+} }
+>>>
+
+\<release CopyTo resources\><<<
+for( p = opened_files; p != (struct files_rec*) 0; ){
+   (IGNORED) fclose(p->file);
+   free((void *)  p->name);  
+   `<free to-from records`>
+   p1= p;  p = p->right;    free((void *)  p1);  
+}
+>>>
+
+\<free to-from records\><<<
+for( p1 = p->down; p1 != (struct files_rec*) 0; ){
+   `<free group records`>
+   p2 = p1; p1 = p1->right;  free((void *)  p2);  
+}
+>>>
+
+\<free group records\><<<
+for( p2 = p1->down; p2 != (struct files_rec*) 0; ){
+   `<free op records`>
+   p3 = p2; p2 = p2->right;  free((void *)  p3);  
+}
+>>>
+
+\<free op records\><<<
+for( p3 = p2->down; p3 != (struct files_rec*) 0; ){
+  p4 = p3; p3 = p3->down; free((void *)  p4);  
+}
+>>>
+
+
+
+
+
+\<act on op\><<<
+if( rec_op == Until_op ){
+  for( p = to_rec->down;
+           p != (struct files_rec*) 0;  p = p->down ){
+    if( p->op == From_op ){ from_op = p; break; }
+  } 
+  if( p == (struct files_rec*) 0 ){
+    `<missing From for CopyTo`>
+  } else {
+    `<perform ops`>
+    `<remove ops`>
+  }  
+}
+>>>
+
+
+
+
+\<perform ops\><<<
+in_file = from_rec->file;
+out_file = to_rec->file;
+start_loc = from_op->loc;
+write_on = TRUE;
+(IGNORED) fseek(in_file, (long) start_loc, `<abs file addr`>);
+for( p= from_op;  p != to_rec; p = p->up ){
+  switch( p->op ){
+    case Until_op:{ `<Until op`> break; }
+    case  Skip_op:{ `<Skip op`>  break; }
+    case  Cont_op:{ `<Cont op`>  break; }
+    case   Set_op:{ `<Set op`>   break; }
+    default: {  }
+} }
+>>>
+
+
+\<Until op\><<<
+if( write_on ){
+   end_loc = p->loc;
+   for(; start_loc<end_loc; start_loc++) {
+      (IGNORED) putc( getc(in_file), out_file );
+}  }
+>>>
+
+
+\<Skip op\><<<
+if( write_on ){
+   end_loc = p->loc;
+   for(; start_loc<end_loc; start_loc++) {
+      (IGNORED) putc( getc(in_file), out_file );
+   } 
+}
+write_on = FALSE;
+>>>
+
+
+\<Cont op\><<<
+end_loc = p->loc;
+if( write_on ){
+   for(; start_loc<end_loc; start_loc++) {
+      (IGNORED) putc( getc(in_file), out_file );
+   } 
+} else { 
+   start_loc = end_loc;
+   (IGNORED) fseek(in_file, (long) end_loc, `<abs file addr`>); 
+}
+write_on = TRUE;
+>>>
+
+
+\<Set op\><<<
+addr = -1;
+for( p1 = from_op->up; p1 != to_rec;  p1 = p1->up ){  
+  if( (p1->op == Addr_op) && (p1->label == p->label) ){
+    addr = p1->loc; break;
+} }
+if( addr != -1 ){ (p->up)->loc = addr; }
+>>>
+
+
+\<remove ops\><<<
+to_rec->down = from_op->down;
+if( from_op->down != (struct files_rec*) 0){
+    (from_op->down)->up = to_rec;
+} 
+for( p = from_op; p != to_rec; ){
+  p1 = p;  p = p->up; free((void *)  p1);  
+}
+if( to_rec->down == (struct files_rec*) 0){
+  if( to_rec->left == (struct files_rec*) 0 ){
+    (to_rec->up)->down =  to_rec->right;
+  } else {
+    (to_rec->left)->right = to_rec->right;
+  }
+  if( to_rec->right != (struct files_rec*) 0 ){
+    (to_rec->right)->left = to_rec->left;
+  }
+  p1 = to_rec; to_rec = to_rec->up;  free((void *)  p1);
+}
+>>>
+
+\<missing From for CopyTo\><<<
+(IGNORED) fprintf(stderr,"%sMissing ``CopyTo From':\n", "--- warning --- ");
+for( p = to_rec->down; p != (struct files_rec*) 0;  p = p->down ){
+  (IGNORED) fprintf(stderr,"   %s %s%d %s\n", to_rec->name,
+          p->op == From_op ?  "From  " :
+             ( p->op == Until_op ?   "Until " :
+               ( p->op == Skip_op ?   "Skip  " :
+                 ( p->op == Cont_op?   "Cont " :
+                 ( p->op == Addr_op?   "Addr " :
+                 ( p->op == Set_op?   "Set " : "No_op " ))))),
+          p->loc, from_rec->name
+         );
+}
+>>>
+
+
+
+
+\<enter op record\><<<
+p = m_alloc(struct files_rec, 1);
+p->down = to_rec->down;  to_rec->down = p;
+p->up = to_rec;
+if( p->down != (struct files_rec*) 0 ){
+  (p->down)->up = p;
+}
+*(match[4] + (int) strlen((char *) match[4]) - 1) = '\0';
+p->loc = (int) get_long_int(match[4]);
+p->op  = rec_op;
+p->label = addr;
+>>>
+
+\<find group record\><<<
+if( to_rec->down == (struct files_rec*) 0 ){
+  `<add first group record`>
+} else {
+  to_rec = to_rec->down;
+  for( p = to_rec->right; p != (struct files_rec*) 0;  p = p->right ){
+    if( eq_str(to_rec->group,match[3]) ){ break; }
+    to_rec = p;
+  }
+  if( !eq_str(to_rec->group,match[3]) ){ 
+    `<add next group record`>
+} }
+>>>
+
+
+
+\<add first group record\><<<
+to_rec->down = p = m_alloc(struct files_rec, 1);  
+p->up = to_rec;
+p->right = p->left = p->down = (struct files_rec*) 0;
+p->name = to_rec->name;  
+p->file = to_rec->file;  
+p->from_rec = from_rec;  
+p->loc = -1;  
+p->op = No_op;
+p->group = m_alloc(char, (int) strlen((char *) match[3]) + 1);
+(IGNORED) strcpy((char *)  p->group, (char *) match[3] );
+to_rec = p;
+>>>
+
+\<add next group record\><<<
+to_rec->right = p = m_alloc(struct files_rec, 1);
+p->left = to_rec;
+p->right = p->down = (struct files_rec*) 0;
+p->up = to_rec->up;
+p->name = to_rec->name;  
+p->file = to_rec->file;  
+p->from_rec = from_rec;  
+p->loc = -1;  
+p->group = m_alloc(char, (int) strlen((char *) match[3]) + 1);
+(IGNORED) strcpy((char *)  p->group, (char *) match[3] );
+to_rec = p;
+>>>
+
+
+
+\<find to-from record\><<<
+if( to_rec->down == (struct files_rec*) 0 ){
+  `<add first to-from record`>
+} else {
+  to_rec = to_rec->down;
+  for( p = to_rec->right; p != (struct files_rec*) 0;  p = p->right ){
+    if( to_rec->from_rec == from_rec ){ break; }
+    to_rec = p;
+  }
+  if( to_rec->from_rec != from_rec ){ 
+    `<add next to-from record`>
+} }
+>>>
+
+\<add first to-from record\><<<
+to_rec->down = p = m_alloc(struct files_rec, 1);  
+p->up = to_rec;
+p->right = p->left = p->down = (struct files_rec*) 0;
+p->name = to_rec->name;  
+p->file = to_rec->file;  
+p->from_rec = from_rec;  
+p->loc = -1;  
+p->op = No_op;
+to_rec = p;
+>>>
+
+\<add next to-from record\><<<
+to_rec->right = p = m_alloc(struct files_rec, 1);
+p->left = to_rec;
+p->right = p->down = (struct files_rec*) 0;
+p->up = to_rec->up;
+p->name = to_rec->name;  
+p->file = to_rec->file;  
+p->from_rec = from_rec;  
+p->loc = -1;  
+to_rec = p;
+>>>
+
+
+\<find file records\><<<
+file_name = match[1];  
+*(file_name + (int) strlen((char *) file_name) - 1) = '\0';
+strcpy((char *) file_mode, WRITE_TEXT_FLAGS);
+for(i=1; i<=2; i++){
+  `<search CopyTo file`>
+  file_name = match[5];  
+  strcpy((char *) file_mode, `<CopyTo read flags`>);
+}
+>>>
+
+
+
+
+
+
+
+
+
+\<search CopyTo file\><<<
+for( p = opened_files; p != (struct files_rec*) 0;  p = p->right ){
+   if( eq_str(file_name,p->name) ) { break; }
+}
+if( p == (struct files_rec*) 0 ){
+  p = m_alloc(struct files_rec, 1);
+  p->right = opened_files;   opened_files = p;
+  p->down =  (struct files_rec*) 0;
+  strcpy((char *) p->file_mode, (char *) file_mode);
+  p->name = m_alloc(char, (int) strlen((char *) file_name) + 1);
+  (IGNORED) strcpy((char *)  p->name, (char *) file_name );
+  if( (p->file = fopen(file_name, file_mode)) == NULL )
+    { (IGNORED) warn_i_str(5,file_name); }
+} 
+to_rec = from_rec;  from_rec = p;
+>>>
+
+
+\<defines\><<<
+struct files_rec{
+  FILE* file;
+  char *name, *group, op;
+  Q_CHAR file_mode[5];
+  int loc, label;
+  struct files_rec  *from_rec, *right, *left, *down, *up;
+};
+#define No_op     0
+#define From_op   1
+#define Until_op  2
+#define Skip_op   3
+#define Cont_op   4
+#define Addr_op   5
+#define Set_op    6
+>>>
+
+\<CopyTo vars\><<<
+Q_CHAR *file_name, file_mode[5];
+int i, start_loc, end_loc, addr = 0;
+char rec_op, *ch;
+static struct files_rec *to_rec, *from_rec,
+   *opened_files = (struct files_rec *) 0,
+   *p, *p1, *p2, *p3, *p4, *from_op;
+FILE *in_file, *out_file;
+BOOL write_on;
+>>>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%
+\Section{post-process ext files}
+%%%%%%%%%%%%%%%%%%%%%%%
+
+\<post-process ext files\><<<
+if( `<ext-script`> ){
+  eoln_ch = (int) 'x';
+  while( eoln_ch != EOF ) {
+     status = scan_str("File: ", TRUE, lg_file);
+     status = scan_until_str(".", 1, status, lg_file);
+     status = scan_until_end_str("", 2, status, lg_file);
+     if( status ){                  Q_CHAR *ext;
+                      struct script_struct *cur_script;
+        ext = match[1];
+        (IGNORED) strct( ext, match[2] );
+        ext += strlen((char *) ext);
+        while( *(--ext) != '.' ){ ; }
+        *ext = '\0'; ext++;
+        `<get script for ext`>
+        (void) execute_script(cur_script, 
+                 match[1], Dotfield? Dotfield : "", "", "");  
+        `<release script for ext`>
+} }  }
+>>>
+
+
+\<get script for ext\><<<
+{
+            struct script_struct *cur, *add, *temp;
+            Q_CHAR extPlus[256];                     
+  cur = `<ext-script`>;
+  add = cur_script = NULL_SCRIPT;
+  while( cur ){
+     `<ext = ext + choise`>
+     if( strpre(extPlus, cur->command) ){
+        `<temp = ext command`>
+        if( cur_script == NULL_SCRIPT ){
+           cur_script = add = temp;
+        } else {
+           add = add->next = temp;
+     }  }
+     cur = cur->next;
+} }  
+>>>
+
+
+
+\<ext = ext + choise\><<<
+(IGNORED) strcpy((char *) extPlus, (char *) ext);
+/* 
+   if ( envChoice ) {
+      (IGNORED) strct ( extPlus, envChoice );
+   }
+*/
+(IGNORED) strct ( extPlus, " " );
+>>>
+ 
+\<temp = ext command\><<<
+temp = (struct script_struct *)
+            m_alloc(struct script_struct, (int) 1);
+temp->command = m_alloc(char, (int) strlen((char *) cur->command) + 1);
+temp->next =  NULL_SCRIPT;
+(IGNORED) strcpy((char *) temp->command, 
+                 (char *) cur->command + (int) strlen((char *) extPlus) );
+>>>
+
+\<release script for ext\><<<
+while(  cur_script != (struct script_struct*) 0 ){
+                          struct script_struct *temp;
+  temp = cur_script; cur_script = cur_script->next; free((void *) temp);  
+}
+>>>
+
+
+\<header functions\><<<
+static BOOL strpre( ARG_II(char *,char *) );
+>>>
+
+\<functions\><<<
+`[
+static BOOL strpre(s1,s2)  
+                    char * s1`;
+                    char * s2
+;{                   int i;
+  for( i=0; i < (int) strlen((char *) s1); i++){
+    if( *(s1+i) != *(s2+i) ){ return FALSE; }
+  }
+  return TRUE;
+}
+>>>
+
+
+
+\<ext-script\><<<
+ext_script
+>>>
+
+
+
+\<defines\><<<
+struct env_c_rec{
+  Q_CHAR *option;
+  struct env_c_rec  *next;
+};
+>>>
+
+\<vars\><<<
+static struct env_c_rec *envChoice
+       = (struct env_c_rec*) 0;
+>>>
+
+
+\<env blocks selector\><<<
+struct env_c_rec *temp = (struct env_c_rec*)
+                   m_alloc(struct env_c_rec, (int) 1);
+temp->option = q;
+temp->next = envChoice;
+envChoice = temp;
+>>>
+
+\<env-skip = skip segment match[1]\><<<
+if( envChoice == (struct env_c_rec*) 0  ){
+  env_skip = !eq_str(match[1], "default" );
+} else {
+               struct env_c_rec *p;
+  env_skip = TRUE;
+  for( p=envChoice; p!=(struct env_c_rec*) 0 ; p = p->next ){
+    if( eq_str(match[1], p->option ) ){ env_skip = FALSE; }
+} }
+>>>
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%
+\Section{post-process files}
+%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\<post-process files\><<<
+if( `<file-script`> ){
+   eoln_ch = (int) 'x';
+   while( eoln_ch != EOF ) {
+      status = scan_str("File: ", TRUE, lg_file);
+      status = scan_until_str(".", 1, status, lg_file);
+      status = scan_until_end_str("", 2, status, lg_file);
+      if( status ){                         Q_CHAR *p;
+         p = match[1];
+         (IGNORED) strct( p, match[2] );
+         p += strlen((char *) p);
+         while( *(--p) != '.' ){ ; }
+         *p = '\0'; p++;
+         (void) execute_script(file_script, match[1],
+                             p, Xfield? Xfield : "", "");
+}  }  }
+>>>
+
+\<file-script\><<<
+file_script
+>>>
+
+%%%%%%%%%%%%%%%%%%%%%%%
+\Section{User Commands}
+%%%%%%%%%%%%%%%%%%%%%%%
+
+\`'l. 10 --- needs --- "ls *" ---'
+
+\<process user commands\><<<
+eoln_ch = (int) 'x';
+while( eoln_ch != EOF ) {              Q_CHAR *command, ch;
+                                       int n;
+                                       struct sys_call_rec *p;
+                                       BOOL flag;
+   status = scan_str("l. ", TRUE, lg_file);
+   status = scan_until_str(" --- needs --- \"", 1, status, lg_file);
+   status = scan_until_str("\" ---", 2, status, lg_file);
+   if( status ){
+      command = match[2];
+      *(command + (int) strlen((char *) command) - 5) = '\0'; 
+      `<flag = permission for system calls`>
+      if( flag ){
+        `<execute system command`>
+      } else { (IGNORED) printf(
+          "No permission for system call: %s\n", command); }
+}  }
+>>>
+
+
+\<env permissions for system calls\><<<
+{     struct sys_call_rec *q;
+  q = m_alloc(struct sys_call_rec, 1);
+  q->next = system_calls;
+  q->filter = match[1];
+              match[1] = (Q_CHAR *) malloc(70);  max_match[1] = 70;
+  system_calls = q;
+if( debug ){  
+   (IGNORED) printf(".......'S' script: '%s'\n", 
+                                q->filter); }
+}
+>>>
+
+\<permission for system calls\><<<
+{     struct sys_call_rec *q;
+  q = m_alloc(struct sys_call_rec, 1);
+  q->next = system_calls;
+  q->filter = p + 2;
+  system_calls = q;
+}
+>>>
+
+
+\<flag = permission for system calls\><<<
+flag = FALSE;
+p = system_calls;
+while( p ){                    
+  if( (n = (int) strlen((char *) p->filter)) == 1 ) {
+     if( *(p->filter) == '*' ){
+         flag = TRUE; break;
+     }
+  } 
+  if( strlen((char *) command) >= (unsigned int) n ) {
+      ch = command[n]; command[n] = '\0';
+      flag = flag || eq_str(p->filter,command);
+      command[n] = ch;
+  }
+  p = p->next;
+}
+>>>
+
+\<defines\><<<
+struct sys_call_rec{
+  Q_CHAR * filter;
+  struct sys_call_rec *next;
+};
+>>>
+
+
+\<vars\><<<
+static BOOL system_yes;
+static struct sys_call_rec *system_calls = (struct sys_call_rec *) 0;
+>>>
+
+
+
+
+
+
+
+
+From log files \`'l. # --- needs --- "command" ---'
+
+
+
+
+
+
+
+
+
+
+%%%%%%%%%%%%%
+\Section{CSS}
+%%%%%%%%%%%%%
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Record HTFCSS Entries from the lg File}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+The htfcss records are stored in the following linked list, and used
+when the  font entries `Font("key","...","...","...")' are loaded
+(Section~'\Link{usehtfcc}{}\Ref{usehtfcc}\EndLink').
+
+\<vars\><<<
+static struct htf_struct *htf_rec = (struct htf_struct *) 0;
+>>>
+
+  
+\<defines\><<<
+struct htf_struct{
+  Q_CHAR *key,  *body, *media;
+  struct htf_struct *next;
+};
+>>>
+
+
+
+
+
+\<htfcss from lg\><<<
+{                     struct htf_struct *last_rec, *p;
+   last_rec = (struct htf_struct *) 0;
+   eoln_ch = (int) 'x';
+   while( eoln_ch != EOF ) {              
+      status = scan_str("htfcss: ", TRUE, lg_file);
+      status = scan_until_end_str("", 1, status, lg_file);
+      `<remove leading spaces`>
+      if( status ){            Q_CHAR *key, *body, *media;
+         media = body = key = match[1];  
+         `<process htfcss line`>
+   }  }
+}
+>>>
+
+\<remove leading spaces\><<<
+if( status ){
+            Q_CHAR *s, *t;
+            int i;
+   s = t = match[1];
+   for( i=0; *s == ' '; s++ ) { i++; }
+   if( i>0 ){
+      while( *s != 0 ){
+         *(t++) = *(s++);
+      }
+      *t = 0;
+}  }
+>>>
+
+
+?? How the case `append prev htfcss rec' can be reached ??
+
+\<process htfcss line\><<<
+while( *body && (*body != ' ') ){ body++; }
+if( *body == ' ' ){ media = body; *(body++) = '\0'; }
+`<extract media info`>
+if( *body ){  
+  if( *key ){ `<add new htfcss rec`> }
+#if 0 /* unreachable */
+  else if( last_rec ){ `<append prev htfcss rec`> }
+#endif /* 0, unreachable */
+}
+>>>
+
+\<extract media info\><<<
+if( (int) strlen((char *) body) > 6 ){
+   if(     (*(body) == '@')
+       &&  (*(body+1) == 'm')
+       &&  (*(body+2) == 'e')
+       &&  (*(body+3) == 'd')
+       &&  (*(body+4) == 'i')
+       &&  (*(body+5) == 'a') )
+     {
+    body += 6;
+    while( *body == ' ' ){ body++; }
+    media = body;
+    while( (*body != ' ') && (*body != '\0') ){ body++; }
+    if( *body == ' ' ){ *(body++) = '\0'; }
+    while( *body == ' ' ){ body++; }
+}  }
+>>>
+
+\<add new htfcss rec\><<<
+p = m_alloc(struct htf_struct, 1);
+p->next =  (struct htf_struct *) 0;
+p->key =   m_alloc(char, (int) strlen((char *) key) + 1);
+(IGNORED) strcpy((char *)  p->key, (char *) key );
+p->media =   m_alloc(char, (int) strlen((char *) media) + 1);
+(IGNORED) strcpy((char *)  p->media, (char *) media );
+p->body =   m_alloc(char, (int) strlen((char *) body) + 1);
+(IGNORED) strcpy((char *)  p->body, (char *) body );
+if( last_rec ){
+   last_rec->next = p;  last_rec = p;
+} else {
+   htf_rec = last_rec = p;
+}
+if( debug ){
+   (IGNORED) printf(".......%s...%s...%s\n", key, media, body);
+}
+>>>
+
+\<append prev htfcss rec\><<<
+last_rec->body = (Q_CHAR *)  r_alloc((void *) last_rec->body,
+      (size_t) strlen((char *) last_rec->body) 
+    + (size_t) strlen((char *) body) 
+    + 2);
+(IGNORED) strct(last_rec->body,"\n");
+(IGNORED) strct(last_rec->body,body);
+if( debug ){
+   (IGNORED) printf(".......%s\n", body);
+}
+>>>
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Font-Css-Plus Entries from The lg File}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+The command \`'\Configure{htf-css}{cmmi}{font-style: italic;}'
+provides in the lg file an entry of the form 
+\`'Font_Css_Plus cmmi font-style: italic;'.
+
+\<font=(...) from lg\><<<
+eoln_ch = (int) 'x';
+while( eoln_ch != EOF ) {              
+   status = scan_str("Font_Css_Plus ", TRUE, lg_file);
+   status = scan_until_str(" ", 1, status, lg_file);
+   status = scan_until_end_str("", 2, status, lg_file);
+   if( status ){                          Q_CHAR *key;
+      key = match[1];  
+      *(key + (int) strlen((char *) key) - 1) = '\0';
+      `<store font style of lg`>
+} } 
+>>>
+
+
+
+\<store font style of lg\><<<
+if( (*key != '\0') && (*key != '\n') ) { 
+                            struct htf_struct *p;    
+   p = m_alloc(struct htf_struct, 1);
+   p->next =  htf_rec;  
+   htf_rec = p;
+   p->key =   m_alloc(char, (int) strlen((char *) key) + 1);
+   (IGNORED) strcpy((char *)  p->key, (char *) key );
+   p->body =   m_alloc(char, (int) strlen((char *) match[2]) + 1);
+   (IGNORED) strcpy((char *)  p->body, (char *) match[2] );
+   if( debug ){
+      (IGNORED) printf(".......%s...%s\n", key, match[2]);
+} }
+>>>
+
+
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Imported Css  File}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+
+%Css: TD.caption{white-space: nowrap; }
+%Font("cmex","10","100")
+%Font("cmmi","10","100")
+%Font("cmmi","5","100")
+%Font("cmmi","7","100")
+%Font("cmr","10","100")
+%Font("cmr","5","100")
+%Font("cmr","7","100")
+%Font("cmsy","10","100")
+%Font("cmsy","7","100")
+%Font("cmti","10","100")
+%Font("cmtt","10","100")
+%Font_Class(1,""): <IMG SRC=""ALT=""CLASS="%s%s-%d--%x">
+%Font_Class(3,"mva"): <IMG SRC=""ALT=""CLASS="%s-%d--%x"ALIGN="MIDDLE">
+%Font_Class(6,"ul"): <SPAN CLASS="underline"></SPAN>
+%Font_Css("sc"): .small-caps{font-variant: small-caps; }
+% Font_Css("ul"): .underline{text-decoration:underline; }
+
+
+
+
+\<process css\><<<
+{
+                               Q_CHAR   css_name[255];
+                               FILE   *css_file, *tmp_file;
+                               BOOL   css_sty;
+   `<css-file = open file ...`>
+   if( css_file ){
+      (IGNORED) printf ("Entering %s\n", css_name);
+      tmp_file = fopen(tmp_name, WRITE_TEXT_FLAGS);
+      if( !tmp_file ) {
+         (IGNORED) warn_i_str(5,tmp_name);
+      } else { `<c: tex4ht.tmp := css file`> }
+      tmp_file = open_file(tmp_name, ".tmp");
+      css_file = fopen(css_name, WRITE_TEXT_FLAGS);
+      if( !tmp_file ) {
+         (IGNORED) warn_i_str(5,tmp_name);
+      } else if( !css_file ) {
+         (IGNORED) warn_i_str(5,css_name);
+      } else { 
+        `<c: css file = header of tex4ht.tmp`>
+        if( css_sty ){
+           `<css file = css.sty`>
+           `<css file = tail of tex4ht.tmp`>
+        }
+      }
+      (IGNORED) fclose(tmp_file);
+      (IGNORED) fclose(css_file);
+}  }
+>>>
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Preliminary Processing of the CSS File}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\<c: tex4ht.tmp := css file\><<<
+                   int ch;
+while( (ch = getc(css_file)) != EOF ) {
+  (IGNORED) putc( ch, tmp_file );        
+}
+(IGNORED) fclose(tmp_file);
+(IGNORED) fclose(css_file);
+>>>
+
+
+\<css-file = open file ...\><<<
+(IGNORED) strcpy((char *)  css_name, (char *) job_name);
+(IGNORED) strct(css_name, ".css");
+css_file = fopen(css_name, READ_TEXT_FLAGS);  
+>>>
+
+\SubSection{Cotributors to the Css File}
+
+Copy until insertion point:
+
+\`'/* css.sty */'
+
+\<c: css file = header of tex4ht.tmp\><<<
+css_sty = FALSE;
+eoln_ch = (int) 'x';
+while( eoln_ch != EOF ) {
+  status = scan_until_end_str("", 1, TRUE, tmp_file);
+  `<match[2] := compressed match[1]`>
+  if( eq_str(match[2], "/*css.sty*/") ){ css_sty = TRUE;  break; }
+  (IGNORED) fprintf(css_file, "%s\n", match[1]);
+}
+>>>
+
+\<vars\><<<
+static BOOL status;
+>>>
+
+
+
+\<match[2] := compressed match[1]\><<<
+{                          Q_CHAR *p, *q;
+                           int  n;
+  n = 0;  p = match[1];    q = match[2];  
+  while ( (*p != '\0') ){ 
+    if (n == 13) { *(q-10) = '\0';  break;}
+    if( *p != ' ' ){ *(q++) = *p; n++; }
+    p++;
+  }
+  *q = '\0';
+}
+>>>
+
+Contribution from lg File
+
+
+
+\<css file = css.sty\><<<
+(IGNORED) fprintf(css_file, "/* start css.sty */\n");
+`<rewind lg file`>  `<Font_css_base: ...`> 
+`<rewind lg file`>  `<process Font_Size: ...`> 
+`<rewind lg file`>  `<process Font(...)`> 
+`<rewind lg file`>  `<process Font_Css(...):...`> 
+`<rewind lg file`>  `<process Css:...`>
+(IGNORED) fprintf(css_file, "/* end css.sty */\n");
+>>>
+
+
+The \`'<process Css:...>' should be after the other two's to allow 
+the user to overide with \''\Css' commands the 
+other contributions.
+
+
+
+
+We want to remove the non-leading \`'/* css.sty */', just
+in case t4ht.perl is called consequtively more than once.
+
+\<css file = tail of tex4ht.tmp\><<<
+eoln_ch = (int) 'x';
+while( eoln_ch != EOF ) {
+  status = scan_until_end_str("", 1, TRUE, tmp_file);
+  `<match[2] := compressed match[1]`>
+  if( !eq_str(match[2], "/*css.sty*/") ){ 
+     (IGNORED) fprintf(css_file, "%s\n", match[1]);
+  }
+}
+>>>
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Contributions from /Css Commands}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\`'Css: P.noindent { text-indent: 0em }'
+
+\<process Css:...\><<<
+eoln_ch = (int) 'x';
+while( eoln_ch != EOF ) {              
+   status = scan_str("Css: ", TRUE, lg_file);
+   status = scan_until_end_str("", 1, status, lg_file);
+   if( status ){
+      (IGNORED) fprintf(css_file, "%s\n", match[1]);
+} } 
+>>>
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Contributions From Font-Size}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\`'\Needs{"Font_Size: 12"}'
+
+
+
+\<process Font_Size: ...\><<<
+eoln_ch = (int) 'x';
+while( eoln_ch != EOF ) {              
+   status = scan_str("Font_Size: ", TRUE, lg_file);
+   status = scan_until_end_str("", 1, status, lg_file);
+   if( status ){
+      base_font_size = (int) get_long_int(match[1]);
+} } 
+>>>
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Contributions to Fonts}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\Link{}{usehtfcc}\EndLink\Tag{usehtfcc}{Contributions to Fonts}
+
+\`'Font("family_name", "font_size", "design_sz * 100 / 655360 / 10", "mag")'
+(e.g., \`'Font("cmr","10","10","100")',
+\`'Font("aptmri","8t",??,"100")',
+\`'Font("ecti","1095","10","100")')
+
+
+
+
+
+
+
+\<process Font(...)\><<<
+eoln_ch = (int) 'x';
+while( eoln_ch != EOF ) {              
+   status = scan_str("Font(\"", TRUE, lg_file);
+   status = scan_until_str("\",\"", 1, status, lg_file);
+   status = scan_until_str("\",\"", 2, status, lg_file);
+   status = scan_until_str("\",\"", 3, status, lg_file);
+   status = scan_until_end_str("\")", 4, status, lg_file);
+   if( status ){
+                      Q_CHAR *p;
+                      struct htf_struct *font_sty;
+                      int second;
+      p = match[1]; 
+      *(p + (int) strlen((char *) p) - 3) = '\0'; 
+      p = match[2]; 
+      *(p + (int) strlen((char *) p) - 3) = '\0'; 
+      p = match[3]; 
+      *(p + (int) strlen((char *) p) - 3) = '\0'; 
+      p = match[4]; 
+      *(p + (int) strlen((char *) p) - 2) = '\0'; 
+      `<get font size`>
+      `<get font style`>
+}  }   
+>>>
+
+
+
+
+
+\<get font style\><<<
+font_sty = htf_rec;
+while ( font_sty  ) {
+  if( eq_str(font_sty->key,match[1]) ){          
+      if( *(font_sty->media) == '\0'  ){
+         `<print font style css`> 
+         second = 100;
+      } else {
+         `<print media style`>
+      }
+  }
+  font_sty = font_sty->next;
+}
+if( second != 100 ){ `<print font style css`> }
+>>>
+
+
+
+
+\<get font size\><<<
+{                                                  Q_CHAR *p;
+   second =   (int) 
+              (  (int) get_long_int(match[3])
+               * (int) get_long_int(match[4])
+               / base_font_size
+              );
+   while( second > 700 ){  second /= 10; }
+   p = match[3];
+   while( *p != '\0' ){
+     if( (*p < '0') || (*p > '9') ){ second = 100; break; }
+     p++;
+   }  
+   `<inspect font-size argument`>
+}
+>>>
+
+The following case handles cases like that of \`'Font("ecti","1095","10","100")', where
+\Verb=base_font_size= is 11.
+
+\<inspect font-size argument\><<<
+if(  (int) (  (double) get_long_int(match[2])
+            / (int) get_long_int(match[4])
+            + 0.5
+           )
+      == base_font_size
+){
+   second = 100;
+};
+>>>
+
+
+
+
+
+
+
+
+\<Font_css_base: ...\><<<
+eoln_ch = (int) 'x';
+while( eoln_ch != EOF ) {              
+   status = scan_str("Font_css_base: ", TRUE, lg_file);
+   status = scan_until_str("Font_css_mag: ", 1, status, lg_file);
+   status = scan_until_end_str("", 2, status, lg_file);
+   if( status ){
+      Font_css_base = match[1];  
+      *(Font_css_base + (int) strlen((char *) Font_css_base) - 14) = '\0';
+      match[1] = (Q_CHAR *) malloc(70);  max_match[1] = 70;
+      Font_css_mag = match[2];
+      match[2] = (Q_CHAR *) malloc(70);  max_match[2] = 70;
+} } 
+>>>
+
+
+
+
+\<vars\><<<
+static char *Font_css_base = NULL,
+            *Font_css_mag = NULL;
+static int base_font_size = 10;
+>>>
+
+
+
+\<print font style css\><<<
+(IGNORED) fprintf(css_file, 
+   (Font_css_base == NULL)? ".%s-%s" : Font_css_base,
+   match[1], match[2]);
+if( !eq_str(match[4],"100") ){ 
+   (IGNORED) fprintf(css_file,
+   (Font_css_mag == NULL)? "x-x-%s" : Font_css_mag,
+   match[4]);
+}
+(IGNORED) fprintf(css_file, "{");
+if( (second < 98) || (second > 102) ){
+   (IGNORED) fprintf(css_file, "font-size:%d%c;", second, '%');
+}
+if( font_sty  ) {
+   (IGNORED) fprintf(css_file, "%s", font_sty->body);
+}
+(IGNORED) fprintf(css_file, "}\n");
+>>>
+
+
+\<print media style\><<<
+(IGNORED) fprintf(css_file, "@media %s{", font_sty->media);
+(IGNORED) fprintf(css_file, 
+   (Font_css_base == NULL)? ".%s-%s" : Font_css_base,
+   match[1], match[2]);
+if( !eq_str(match[4],"100") ){ 
+   (IGNORED) fprintf(css_file,
+   (Font_css_mag == NULL)? "x-x-%s" : Font_css_mag,
+   match[4]);
+}
+(IGNORED) fprintf(css_file, "{");
+if( font_sty  ) {
+   (IGNORED) fprintf(css_file, "%s", font_sty->body);
+}
+(IGNORED) fprintf(css_file, "}}\n");
+>>>
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Font-Css Contributions}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\`'Font_Css("4"): .small-caps{font-variant: small-caps; }'
+
+\<process Font_Css(...):...\><<<
+{            char  *font_class [256];
+             int last_class;
+   `<find usage`>
+   eoln_ch = (int) 'x';
+   while( eoln_ch != EOF ) {              
+      status = scan_str("Font_Css(\"", TRUE, lg_file);
+      status = scan_until_str("\"): ", 1, status, lg_file);
+      status = scan_until_end_str("", 2, status, lg_file);
+      if( status ){            int i;
+        for(i=0; i<last_class; i++){
+          if( eq_str(match[1],font_class[i]) ){
+             (IGNORED) fprintf(css_file, "%s\n", match[2]);
+             break;
+}  }  } } }
+>>>
+
+
+
+\<find usage\><<<
+last_class = 0;
+eoln_ch = (int) 'x';   
+while( eoln_ch != EOF ) {              
+   status = scan_str("Font_Class(", TRUE, lg_file);
+   status = scan_until_str(",\"", 1, status, lg_file);
+   status = scan_until_str("\"): ", 1, status, lg_file);
+   status = scan_until_end_str("", 2, status, lg_file);
+   if( status ){
+      font_class[last_class++] = match[1];  
+      match[1] = (Q_CHAR *) malloc(7);  max_match[1] = 7;
+}  }
+`<rewind lg file`>
+>>>
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\Section{Load Env File}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Retrieve Info}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\<load env file\><<<
+{                                FILE* file;
+                                 U_CHAR  env_loc[512];
+   env_loc[0] = '\0';
+   `<find tex4ht.env`>
+   if( file ){  
+      `<get info from env file`>
+      (IGNORED) fclose(file);
+}  }
+>>>
+
+
+%       (IGNORED) printf("Entering %s\n", env_loc[0]? &env_loc[0] 
+%                                                  :"tex4ht.env"); 
+
+
+
+\<get info from env file\><<<
+eoln_ch = (int) 'x';
+while( eoln_ch != EOF ) {                Q_CHAR ch;
+  ch = (char) (eoln_ch = getc(file));          
+  if( eoln_ch != (int) '\n' ){
+     status = scan_until_end_str("", 1, TRUE, file);
+     if( status ){
+       switch( ch ){
+         case 'A':{ `<script for chmod`>  break;}
+         case 'C':{ `<script for copy`>  break;}
+         case 'E':{ `<script for empty gifs`>  break;}
+         case 'F':{ `<script for dvigif of glyps`>   break;}
+         case 'G':{ `<script for dvigif`>   break;}
+         case 'M':{ `<script for move`>  break;}
+         case 'S':{ `<env permissions for system calls`>  break;}
+         case 'X':{ `<script for file`>  break;}
+         case '.':{ `<script for file ext`>  break;}
+         case '<':{ `<env selector`>  break;}
+         default:{ }
+} }  }  }
+>>>
+
+
+
+
+
+\<script for dvigif of glyps\><<<
+if( debug ){  
+      (IGNORED) printf(".......'F' script\n"); }
+dvigif_glyp_script = add_script(dvigif_glyp_script);
+>>>
+
+
+\<script for move\><<<
+if( debug ){  
+      (IGNORED) printf(".......'M' script\n"); }
+move_script = add_script(move_script);
+>>>
+
+
+\<script for copy\><<<
+if( debug ){  
+      (IGNORED) printf(".......'C' script\n"); }
+copy_script = add_script(copy_script);
+>>>
+
+
+
+
+
+\<script for file\><<<
+if( debug ){  
+      (IGNORED) printf(".......'X' script\n"); }
+`<file-script`> = add_script(`<file-script`>);
+>>>
+
+\<script for file ext\><<<
+if( debug ){  
+      (IGNORED) printf(".......'.' script\n"); }
+`<ext-script`> = add_script(`<ext-script`>);
+>>>
+
+
+
+
+\<script for chmod\><<<
+if( debug ){  
+      (IGNORED) printf(".......'A' script\n"); }
+chmod_script = add_script(chmod_script);
+>>>
+
+\<script for empty gifs\><<<
+if( debug ){  
+      (IGNORED) printf(".......'E' script\n"); }
+empty_fig_script = add_script(empty_fig_script);
+>>>
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Utilities for Retrieving Info}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\<env selector\><<<
+if( *(match[1]) != '/' ){
+                         U_CHAR *p;
+                         BOOL env_skip;
+  for( p = match[1]; 
+      (*p != '>') && (*p != '\n') && (*p != EOF ) ;
+      p++ ){}
+  if( *p == '>' ){ *p = '\0'; }
+  `<env-skip = skip segment match[1]`>
+  if( env_skip ){
+     `<skip env segment`>
+  } else {
+     if( debug ){
+        (IGNORED) printf(".......   <%s>\n", match[1]); 
+     }
+  }
+} else if( debug ){
+   (IGNORED) printf(".......   <%s\n", match[1]); 
+}
+>>>
+
+\<skip env segment\><<<
+                         U_CHAR cur_block[90];                         
+if( debug ){
+   (IGNORED) printf(".......   <%s>  skipping ...\n", match[1]); 
+}
+(IGNORED) strcpy((char *)  cur_block, (char *) match[1]);
+status = FALSE;
+while( !status && (eoln_ch != EOF) ){
+  status = scan_str("</", TRUE, file);
+  status = scan_until_str(">", 1, status, file);
+  status = scan_until_end_str("", 2, status, file);
+  if( status ){ 
+      *(match[1] + strlen((char *) match[1]) - 1) = '\0';
+      status = eq_str(match[1], cur_block); 
+      if( debug ){
+         (IGNORED) printf(".......   </%s>\n", match[1]);
+} }   }
+>>>
+
+
+
+\<header functions\><<<
+static struct script_struct * add_script( ARG_I(struct script_struct *) );
+>>>
+
+\<functions\><<<
+`[
+static struct script_struct * add_script(script) 
+                           struct script_struct * script
+;{ 
+   struct script_struct* temp, * q;
+   temp = (struct script_struct *) 
+                      m_alloc(struct script_struct, (int) 1);   
+   temp->command = match[1];
+   if( debug ){  
+      (IGNORED) printf(".......   %s\n", temp->command); }
+   temp->next = NULL_SCRIPT;
+   match[1] = (Q_CHAR *) malloc(70);
+   max_match[1] = 70;
+   if( script ){
+      q = script;
+      while( q->next ){ q = q->next; }
+      q->next = temp;
+   } else {
+      script = temp;
+   }
+   return script;
+}
+>>>
+
+
+
+
+
+
+
+
+  
+\<defines\><<<
+struct script_struct{
+  Q_CHAR *command;
+  struct script_struct *next;
+};
+>>>
+
+\<vars\><<<
+static struct script_struct 
+    * dvigif_script = NULL_SCRIPT,
+    * dvigif_glyp_script = NULL_SCRIPT,
+    * move_script = NULL_SCRIPT,
+    * empty_fig_script = NULL_SCRIPT,
+    * copy_script = NULL_SCRIPT,
+    * `<file-script`> = NULL_SCRIPT,
+    * `<ext-script`> = NULL_SCRIPT,
+    * chmod_script = NULL_SCRIPT;
+>>>
+
+\<defines\><<<
+#define NULL_SCRIPT (struct script_struct *) 0
+>>>
+
+
+
+
+
+
+
+
+%          case 'H':{ `<env-htf-sty = htfcss.env file`> break;}
+% 
+% \<env-htf-sty = htfcss.env file\><<<
+% env_htf_sty = match[1];
+% match[1] = (Q_CHAR *) malloc(70);
+% max_match[1] = 70;
+% if( debug ){  
+%    (IGNORED) printf(".......'H' script: '%s'\n",
+%                             env_htf_sty); }
+% >>>
+% 
+% \<vars\><<<
+% static Q_CHAR* env_htf_sty = Q_NULL;
+% >>>
+
+
+
+\Verbatim
+%   dvips -mode ibmvga -D 110 -f foo.idv -pp 92  > tmp.ps
+%   convert -crop 0x0 -density 110x110 -transparent '#FFFFFF' tmp.ps foo.gif
+Gdvips -mode ibmvga -D 110 -f %1 -pp %2  > tmp.ps
+Gconvert -crop 0x0 -density 110x110 -transparent '#FFFFFF' tmp.ps %3
+% t4ht -d%2 
+Mmv %1 %2%3
+Ccp %1 %2%3
+% t4ht -d%2 -m%1 
+Achmod %1 %2%3
+H/n/gold/5/gurari/tex4ht.dir/
+\EndVerbatim
+
+
+
+\SubSection{Open Directory}
+
+\<env file at work dir\><<<
+if( !file ) {  
+   if( debug ){  
+      (IGNORED) printf("tex4ht.env?\n");
+   }
+   file = f_open("tex4ht.env", READ_TEXT_FLAGS);
+   (IGNORED) strcpy((char *) &env_loc[0], "tex4ht.env");
+   if( debug && file ){  
+      (IGNORED) printf(".......Open: ./tex4ht.env\n"); }
+}
+>>>
+
+\<find tex4ht.env\><<<
+{         Q_CHAR  str[512],
+                                                      *TEX4HTENV;
+   `<env file from command switch`>
+   `<env file at work dir`>
+   `<env file .tex4ht`>
+   `<TEX4HTENV env`>
+   `<env file at root dir`>
+   `<ENVFILE env`>
+   if( !file ) { `<env file from prog loc`> }
+   `<kpathsea env file`>
+   if( !file ) warn_i_str( 5, `<warn 1`>);
+}
+>>>
+
+
+
+
+
+
+
+
+\<TEX4HTENV env\><<<
+if( !file ){                
+  TEX4HTENV = getenv("TEX4HTENV");
+  if( TEX4HTENV ){ 
+     if( debug ){  
+         (IGNORED) printf("%s?\n", TEX4HTENV); 
+     }
+     file = f_home_open(TEX4HTENV,READ_TEXT_FLAGS); 
+  }
+}
+>>>
+
+
+
+
+
+
+\<env file .tex4ht\><<<
+#ifndef DOS_WIN32
+   if( !file ) {
+       if( debug ){  
+          (IGNORED) printf(".tex4ht?\n"); 
+       }
+       file = f_open(".tex4ht", READ_TEXT_FLAGS);
+       (IGNORED) strcpy((char *) &env_loc[0], ".tex4ht");
+       if( debug && file ){  
+         (IGNORED) printf(".......Open: ./.tex4ht\n"); }
+   }
+#endif
+>>>
+
+\<ENVFILE env\><<<
+#ifdef ENVFILE
+   if( !file ) {
+      if( debug ){  
+          (IGNORED) printf("%s?\n", ENVFILE); 
+      }
+      file = f_home_open( ENVFILE,READ_TEXT_FLAGS);
+       (IGNORED) strcpy((char *) &env_loc[0], (char *) ENVFILE);
+       if( debug && file ){  
+         (IGNORED) printf(".......Open: %s\n", ENVFILE); }
+   }
+#endif
+>>>
+
+
+
+\<h-defines\><<<
+#ifndef ENVFILE
+
+#endif
+>>>
+
+
+
+\<warn 1\><<<
+#ifdef  DOS_WIN32
+   "tex4ht.env"
+#endif
+#ifndef  DOS_WIN32
+   "tex4ht.env | .tex4ht" 
+#endif
+>>>
+
+
+
+
+\<kpathsea env file\><<<
+
+#ifdef KPATHSEA
+if( !file )  {               U_CHAR * envfile;
+                             char *arch, *p, str[256];
+   `<arch = tail of SELFAUTOLOC`>
+   envfile = (char *) 0;
+   `<envfile = kpse-find-file architecture/tex4ht.env`>
+   if ( !envfile ){ `<envfile = kpse-find-file tex4ht.env`> }
+   if ( !envfile ){ `<envfile = kpathsea tex4ht.env`> } 
+   if ( envfile ){
+      file = kpse_open_file (envfile, kpse_program_text_format);
+      (IGNORED) printf("(%s)\n",  envfile);
+   }   
+   if( debug && file ){  
+      (IGNORED) printf(".......Open kpathsea %s\n", envfile); 
+   }
+}
+if( debug ){
+                       U_CHAR *p, *q;
+  `<trace T4HTINPUTS`>
+}
+#endif
+>>>
+
+%%%<--
+
+\<arch = tail of SELFAUTOLOC\><<<
+p = arch = (char *) kpse_var_value( "SELFAUTOLOC" );
+while( *p != '\0' ){
+   if( (*p ==   '/') || (*p == '\\') ){
+      arch = p;
+   }
+   p++;
+}
+>>>
+
+
+\<envfile = kpse-find-file architecture/tex4ht.env\><<<
+if( arch ){
+  (IGNORED) sprintf(str,"%s%ctex4ht.env", arch+1, *arch);
+  if( debug ){ 
+    (IGNORED) printf(
+      "kpse_open_file (\"%s\", kpse_program_text_format)?\n", str ); 
+  }
+  envfile= kpse_find_file (str, kpse_program_text_format, 0);
+}
+>>>
+
+
+\<envfile = kpse-find-file tex4ht.env\><<<
+if( debug ){ 
+  (IGNORED) printf(
+    "kpse_open_file (\"tex4ht.env\", kpse_program_text_format)?\n"); 
+}
+envfile= kpse_find_file ("tex4ht.env", kpse_program_text_format, 0);
+>>>
+
+
+%   if( debug ){ 
+%      (IGNORED) printf( "kpse_open_file (\"tex4ht.env\", ...)?\n"); 
+%   }
+%   envfile= kpse_find_file ("tex4ht.env", kpse_program_text_format, 0);
+
+
+
+
+
+
+\<trace T4HTINPUTS\><<<
+p = (U_CHAR *) kpse_var_value( "T4HTINPUTS" );
+if( p ){
+   (IGNORED) printf("T4HTINPUTS = %s\n", p);
+}
+q = getenv("T4HTINPUTS");
+if( q ){  (IGNORED) printf(
+   "Environmet var T4HTINPUTS:  %s\n", q);
+}
+if( !p && !q ){
+   (IGNORED) printf( "Missing T4HTINPUTS for kpathsea\n" );
+}
+>>>
+
+
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{kpathsea vs kpse-find-file}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+The kpathsea utility might succeed where kpse-find-file fails.  Maybe due to:
+``Kpathsea's subdirectory searching has an
+     irremediable deficiency: If a directory D being searched for
+     subdirectories contains plain files and symbolic links to other
+     directories, but no true subdirectories, D will be considered a
+     leaf directory, i.e., the symbolic links will not be followed.'' 
+[\Link[http://www.tug.org/svn/texlive/trunk/Build/source/texk/kpathsea/kpathsea.info?view=markup]{}{}kpathsea.info\EndLink]
+
+
+
+
+\<envfile = kpathsea tex4ht.env\><<<
+if( system("kpsewhich --progname=tex4ht tex4ht.env > tex4ht.tmp") == 0 ){
+   `<fileaddr = read tex4ht.tmp`>
+   envfile= kpse_find_file (fileaddr, kpse_program_text_format, 0);
+}
+>>>
+
+
+
+Don't know how to avoid the use of intermediate file: popen(...) and
+fork() are not stadard utilities.  Also the redirection \Verb+>+ might
+need to be changed, e.g., to \Verb+>&+.
+
+\<fileaddr = read tex4ht.tmp\><<<
+char fileaddr [256];
+int loc = 0;
+FILE* file =  f_open("tex4ht.tmp", READ_TEXT_FLAGS);
+if( file ){
+  while( (fileaddr[loc] = getc(file)) >=0  ){
+    if( fileaddr[loc] == '\n' ){ fileaddr[loc] = '\0'; break; }
+    loc++;
+  }
+  (IGNORED) fclose(file);
+}  
+>>>
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Root Directory}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\<env file at root dir\><<<
+if( !file ){                
+  if( HOME_DIR ){ (IGNORED) sprintf(str,`<"s/tex4ht.env"`>, HOME_DIR);
+     if( debug ){  
+         (IGNORED) printf("%s?\n", str); 
+     }
+     file = f_open(str,READ_TEXT_FLAGS);     
+     (IGNORED) strcpy((char *) &env_loc[0], (char *) str);
+     if( debug && file ){  
+        (IGNORED) printf(".......Open: %s\n", str); }
+  }
+}
+#ifndef DOS_WIN32
+  if( !file ){        
+     if( HOME_DIR ){ 
+          (IGNORED) sprintf(str,"%s/.tex4ht", HOME_DIR);   
+          if( debug ){  
+             (IGNORED) printf("%s?\n", str); 
+          }
+          file = f_open(str,READ_TEXT_FLAGS);     
+          (IGNORED) strcpy((char *) &env_loc[0], (char *) str);
+          if( debug && file ){  
+             (IGNORED) printf(".......Open: %s\n", str); }
+      }
+  }
+#endif
+#if defined(DOS_WIN32) || defined(__MSDOS__)
+   if( !file ){                
+      if( debug ){  
+          (IGNORED) printf("C:/tex4ht.env?\n"); 
+      }
+      file = f_open("C:/tex4ht.env",READ_TEXT_FLAGS);     
+       (IGNORED) strcpy((char *) &env_loc[0], "C:/tex4ht.env");
+      if( debug && file ){  
+        (IGNORED) printf(".......Open: C:/tex4ht.env\n"); }
+   }
+#endif
+>>>
+
+\<"s/tex4ht.env"\><<<
+#if defined(DOS_WIN32) || defined(__DJGPP__)
+  is_forward_slash(HOME_DIR)?  "%s/tex4ht.env" :  "%s\\tex4ht.env"
+#else
+  "%s/tex4ht.env"
+#endif
+>>>
+
+
+
+
+
+
+
+
+
+
+
+\SubSection{Env File from Command Line}
+
+\<env file from command switch\><<<
+if( tex4ht_env_file ){
+   if( debug ){  
+      (IGNORED) printf("%s?\n", tex4ht_env_file); 
+   }
+   file = f_home_open( tex4ht_env_file, READ_TEXT_FLAGS );
+} else {
+   file = NULL;
+}
+if( tex4ht_env_file ){
+    (IGNORED) strcpy((char *) &env_loc[0], (char *) tex4ht_env_file);
+}
+if( debug && file ){  
+      (IGNORED) printf(".......Open: %s\n", tex4ht_env_file); }
+>>>
+
+\<env file from prog loc\><<<
+if( dos_env_file ){
+   if( debug ){  
+       (IGNORED) printf("%s?\n", dos_env_file); 
+   }
+   file =  f_open( dos_env_file, READ_TEXT_FLAGS ) ;
+   (IGNORED) strcpy((char *) &env_loc[0], (char *) dos_env_file);
+   if( debug && file ){  
+      (IGNORED) printf(".......Open: %s\n", dos_env_file); }
+}
+>>>
+
+
+
+Search along the path: command line file $\rightarrow$ work
+directory $\rightarrow$ home directory $\rightarrow$ system file.
+
+\<get .env directory from com ln\><<<
+tex4ht_env_file = q; 
+>>>
+
+% if( !access(p+2,F_OK) ) tex4ht_env_file = q; 
+% else warn_i_str(6,q);
+
+
+The function \`'int access(const char *pathname, int mode)', and the mode
+\`'F_OK' that tests for the existence of file, are defined in the
+following directory. The function returns 0 if ok and -1 on error .
+
+Where access comes from in dos?
+
+\<h-include before KPATHSEA\><<<
+#ifndef __DJGPP__         
+`<h-include near KPATHSEA`>
+#endif
+>>>
+
+
+
+The following is because \`'<unistd.h>
+defines F_OK in DJGPP'.
+
+\<h-include after KPATHSEA\><<<
+#ifdef __DJGPP__         
+`<h-include near KPATHSEA`>
+#endif
+>>>
+
+\<h-include near KPATHSEANO\><<<
+#ifndef F_OK
+#ifdef DOS_WIN32
+#define  F_OK 0               `% does file exist `%
+#endif
+#ifndef DOS_WIN32
+#define HAVE_UNISTD_H
+#endif
+#endif
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>    
+#endif
+>>>
+
+\<h-include near KPATHSEA\><<<
+#ifndef F_OK
+#ifdef DOS_WIN32
+#define  F_OK 0               `% does file exist `%
+#endif
+#ifndef KPATHSEA  
+#ifndef DOS_WIN32
+#define HAVE_UNISTD_H
+#endif
+#endif
+#endif
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+#ifndef KPATHSEA  
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>    
+#endif
+#endif
+>>>
+
+
+
+\SubSection{Env File from Location of t4ht.c}
+
+\<main's vars\><<<
+Q_CHAR * tex4ht_env_file = (Q_CHAR *) 0;
+Q_CHAR * dos_env_file =
+#if defined(__MSDOS__)
+  `<get dos env file`>;
+#endif
+#if !defined(__MSDOS__)
+  (Q_CHAR *) 0;
+#endif
+
+>>>
+
+  Under DOS, argv[0] usually includes the full path to the program -
+even if it wasn't typed in. This can be used to find the program's own
+directory, and hence the configuration file. I've implemented this
+already as follows:
+
+\<get dos env file\><<<
+get_env_dir(argv[0])
+>>>
+
+\<functions\><<<
+#if defined(__MSDOS__)
+`<get tex4ht.env in dos`>
+#endif
+>>>
+
+\<get tex4ht.env in dos\><<<
+`[
+static char *get_env_dir(progname) 
+      Q_CHAR *progname
+
+;{    int  i;
+      Q_CHAR *p;
+  if(! progname || ! *progname)  return NULL;  `% Safety `%
+  i = (int) strlen((char *) progname);
+  while( (progname[--i] != (int) dir_path_slash(progname) )
+        && i > 0) ;                               `%Search for slash`%
+  if(i == 0)  return NULL;                        `%Not found? Give up`%
+  p = (Q_CHAR *) malloc(i+12);
+  if(p == NULL)  return NULL;     `%Space for new extention after dot`%
+  strncpy(p, progname, i+1);                         `%Copy up to slash`%
+  (IGNORED) strcpy((char *) &p[i+1],
+                   "tex4ht.env");                    `%Append new extention`%
+  return p;
+}
+>>>
+
+
+
+
+
+
+The 12 above is for accomodating \''tex4ht.env'.
+
+  Then, in main(), I changed:
+
+\`''char* tex4ht_env_file = (Q_CHAR *) 0;'
+
+  to:
+
+\`'char* tex4ht_env_file = get_env_dir(argv[0]);'
+
+  This works like a charm here, and allows me to use tex4ht from a
+different directory without typing a single commandline option.
+
+
+
+
+\Section{Open Files}
+
+
+\<header functions\><<<
+static FILE* f_open( ARG_II(const char*,const char*) );
+>>>
+
+\<functions\><<<
+`[
+static FILE* f_open( name, flags ) 
+                          const char*  name `;
+                          const char*  flags                           
+;{                        FILE* file;
+  if( (file = fopen(name,flags) ) != NULL ) {
+     (IGNORED)  printf("(%s)\n",name);
+  }
+  return file;
+}
+>>>
+
+
+
+
+
+\<header functions\><<<
+static FILE* f_home_open( ARG_II(const char*,const char*) );
+>>>
+
+\<functions\><<<
+`[
+static FILE* f_home_open( name, flags ) 
+                          const char*  name `;
+                          const char*  flags                           
+;{                        FILE* file;
+                          U_CHAR *str;
+  if( *name == '~' ){
+     if( HOME_DIR ){ 
+         str = m_alloc(char, strlen((char *) HOME_DIR)+strlen(name));
+         (IGNORED) sprintf(str,"%s%s", HOME_DIR, name+1);
+         file = f_open(str,flags);     
+         free((void *)  str);
+         return file;
+     } else { return NULL; }
+  } else {     return f_open( name, flags );   } 
+}
+>>>
+
+
+
+
+
+
+\SubSection{General}
+
+\<header functions\><<<
+static FILE* open_file( ARG_II(const C_CHAR *, const C_CHAR *) );
+>>>
+
+\<functions\><<<
+`[
+static FILE* open_file(name,ext)     
+                         const C_CHAR *name`; const C_CHAR *ext
+;{                       FILE* file;
+                         C_CHAR filename[255], *p;
+   if( eq_str( ext,LG_EXT ) ) { 
+      (IGNORED) strcpy((char *) filename, (char *) job_name); 
+      (IGNORED) strct(filename, ext); 
+   } else {
+      (IGNORED) strcpy((char *)  filename, name );   
+      p = filename;
+      while( TRUE ){
+        if( *p == '.' ){  break; }
+        if( *p == '\0' ){ (IGNORED) strcpy((char *) p, ext); break; }
+        p++;
+      }
+   }
+   file  = fopen(filename, READ_TEXT_FLAGS);  
+   if( !file ) {
+      (IGNORED) warn_i_str(5,filename);
+   } else { (IGNORED) printf ("Entering %s\n", filename); }
+
+   return file;
+}
+>>>
+
+
+We have here a little inconsistency with tex4ht.c. There the input file
+name is appended with the extension .dvi, allowing double extensions. 
+Here, if an extension is present, we remove it before putting .lg on
+top of the name. Should we fix that?
+
+
+
+
+\<defines\><<<
+#define LG_EXT ".lg"
+>>>
+
+
+
+
+
+% 
+% \SubSection{htfcss.env}
+% 
+% 
+% \<file = open htfcss.env\><<<
+% if( htf_cfg ){
+%    file  = open_file(htf_cfg, ".env");  
+% } else {                                  C_CHAR filename[255];
+%    file  = fopen("htfcss.env", READ_TEXT_FLAGS);            
+%    if ( !file && env_htf_sty ){
+%       (IGNORED) strcpy((char *) filename, (char *) env_htf_sty);
+%       (IGNORED) strct(filename, "htfcss.env");
+%       file = fopen(filename, READ_TEXT_FLAGS);
+%    }
+%    if ( !file ){
+%       (IGNORED) strcpy((char *) filename, (char *) HTFDIR );
+%       (IGNORED) strct(filename, "htfcss.env");
+%       file = fopen(filename, READ_TEXT_FLAGS);
+%    }  
+%    `<htfcss.env in KPATHSEA`>
+%    if( !file ) { (IGNORED) warn_i_str(5,"htfcss.env"); }
+%    else { (IGNORED) printf ("Entering htfcss.env\n"); }
+% }
+% >>>
+% 
+% 
+
+
+
+\<mark start lg file\><<<
+begin_lg_file = ftell(lg_file);
+>>>
+
+\<rewind lg file\><<<
+(IGNORED)  fseek(lg_file, begin_lg_file, `<abs file addr`>);
+>>>
+
+\<abs file addr\><<<
+0>>>
+
+
+
+
+\<vars\><<<
+static FILE* lg_file;
+static long  begin_lg_file;
+>>>
+
+
+
+
+
+\''open(file, ..._FLAGS)': All
+text files should be opened with "r" or "w"; all binary files with "rb"
+or "wb". This is the portable way and will work both under Unix and DOS;
+as Unix doesn't distinguish between text and binary files, its compilers
+will simply ignore the "b" part.
+
+  On the subject of the .lg file: you open the tex4ht.env file in binary
+mode ("rb"), which results in strange line endings in the .lg file
+(CR/CR/LF). Changing the mode to "r" fixes this.
+
+
+\<t4ht.h\><<<
+#if defined(DOS_WIN32) || defined(__MSDOS__)
+#define READ_BIN_FLAGS "rb"
+#define READ_TEXT_FLAGS "r"
+#define WRITE_BIN_FLAGS "wb"
+#ifdef WIN32
+#define WRITE_TEXT_FLAGS "wb"
+#else
+#define WRITE_TEXT_FLAGS "w"
+#endif
+#else
+#define READ_BIN_FLAGS "r"
+#define READ_TEXT_FLAGS "r"
+#define WRITE_BIN_FLAGS "w"
+#define WRITE_TEXT_FLAGS "w"
+#endif
+>>>
+
+
+
+\Verbatim
+I've been held up a bit by a
+bug in tex4ht.c that caused emTeX to complain that the created .idv file
+was corrupt:
+
+*** Fatal error 2106: corrupt DVI file (postamble not found)
+
+  I found the cause, though: you open it with mode "w", which is text
+mode. Changing this to "wb" solved the problem.
+\EndVerbatim
+
+
+
+
+
+
+
+
+
+\Section{Utilities}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Error and Warning Messages}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\<signals messages: 2--4\><<<
+"Illegal storage address\n", `%2 segmentation`%
+"Floating-point\n",          `%3 `%
+"Interrupt with Cntr-C\n",   `%4 `% 
+>>>
+
+\<warn and err messages\><<<
+`<command line options`>,                            `%0`%
+"Insufficient memory\n",                                `%1`%
+`<signals messages: 2--4`>
+"Can't find/open file ``%s'\n",                         `%5`%
+>>>
+
+
+
+\<defines\><<<
+#define bad_arg            err_arg(0)
+#define bad_mem             err_i(1)
+>>>
+
+
+
+
+
+
+\<header functions\><<<
+static void err_i( ARG_I(int) );
+>>>
+
+\<functions\><<<
+`[
+static void err_i(n)      int  n
+
+;{  (IGNORED) fprintf(stderr,"--- error --- ");
+   (IGNORED) fprintf(stderr, "%s", warn_err_mssg[n]);
+   exit(EXIT_FAILURE);  
+}
+>>>
+
+
+
+\<header functions\><<<
+static void err_arg( ARG_I(int) );
+>>>
+
+\<functions\><<<
+`[
+static void err_arg(n)      int  n
+
+;{  (IGNORED) fprintf(stderr,"--- error --- ");
+   (IGNORED) fprintf(stderr, "%s", warn_err_mssg[n]);
+   exit(EXIT_FAILURE);  
+}
+>>>
+
+
+
+
+
+\<header functions\><<<
+static void warn_i_str( ARG_II(int,const Q_CHAR *) );
+>>>
+
+\<functions\><<<
+`[
+static void warn_i_str(n,str) 
+    int  n`;
+    const Q_CHAR *str
+
+;{  (IGNORED) fprintf(stderr,"--- warning --- ");
+   (IGNORED) fprintf(stderr,warn_err_mssg[n], str);
+}
+>>>
+
+
+% 
+% \<vars\><<<
+% static C_CHAR warning[] = "--- warning --- ";
+% >>>
+
+
+
+
+
+\<vars\><<<
+static const C_CHAR *warn_err_mssg[]={ `<warn and err messages`> "" };
+>>>
+
+\<resplit argv for windows\><<<
+#ifdef WIN32
+  /* See comments in tex4ht */
+  if (argc > 2) {
+    int  i, nargc;
+    char **nargv, **pnargv, **pargv;
+
+    nargv = (char **) xmalloc (2 * argc * sizeof (char *));
+    pnargv = nargv;
+    pargv = argv;
+    *pnargv++ = xstrdup (*pargv++);
+    *pnargv++ = xstrdup (*pargv++);
+    nargc = 2;
+
+    for (i=2; i < argc; i++) {
+      char *p, *q, *r;
+      p = q = *pargv++;
+      while (*p == ' ' || *p == '\t') {
+        p++;
+        q++;
+      }
+      while (*p != ' ' && *p != '\t' && *p) {
+        p++;
+        if (*p == '\0') {
+          *pnargv++ = xstrdup(q);
+          nargc++;
+        } else if (*p == ' ' || *p == '\t') {
+          r = p;
+          while (*p == ' ' || *p == '\t')
+            p++;
+          if (*p == '-' || *p == '\0') {
+            *r = '\0';
+            *pnargv++ = xstrdup(q);
+            nargc++;
+            q = p;
+          }
+        }
+      }
+    }
+ 
+    nargv[nargc] = NULL;
+    argv = nargv;
+    argc = nargc;
+  }
+#endif
+>>>
+
+
+
+\SubSection{Signals}
+
+\<h-include\><<<
+#include <signal.h>
+>>>
+
+\<header functions\><<<
+static void 
+`<CDECL`>
+sig_err(ARG_I(int));
+>>>
+
+
+
+
+\<functions\><<<
+`[
+static void
+`<CDECL`>
+sig_err(s)  int s
+;{
+  (void) signal(s,SIG_IGN);  `%ignore the signal`%
+  switch( s ){
+#ifdef SIGSEGV
+    case SIGSEGV: err_i(2); 
+#endif
+    case SIGFPE : err_i(3);  
+#if defined(SIGINT) && !defined(WIN32)
+    case SIGINT : err_i(4);
+#endif
+  } 
+  `<DJGPP signals`>
+}
+>>>
+
+
+
+
+Forgetting \`'_pascal' and \`'_cdecl' modifiers: Each C function may
+be either \`'_pascal' or \`'_cdecl'. This modifier defines how
+parameters are passed to it. Default for Smalltalk definition is
+\`'_cdecl'. Default for C functions depends on compiler settings, and
+you can use other types uncompatible with Smalltalk. In Windows API
+16-bit functions are \`'_pascal' and 32-bit \`'_cdecl'.
+ 
+
+
+\<CDECL\><<< 
+#ifdef CDECL
+CDECL
+#endif
+>>>
+ 
+
+
+
+\<set signals\><<<
+
+#ifdef SIGSEGV
+  (void) signal(SIGSEGV,sig_err);
+#endif
+  (void) signal(SIGFPE,sig_err);
+#ifdef KWIN32
+  `<KWIN32 signals`>
+#else 
+#ifdef SIGINT
+  (void) signal(SIGINT,sig_err);    `%Control-c, user interrupt`%
+#endif
+#endif
+>>>
+
+
+
+SIGFPE is handled by the C library, SIGSEGV too but not generated by
+the system, so it does nothing but is harmless 
+
+SetConsoleCtrlHandler is need to catch Ctrl+C and Ctrl+Break under
+Windows, SIGINT is not generated by the system.
+ 
+\<KWIN32 signals\><<<
+SetConsoleCtrlHandler((PHANDLER_ROUTINE)sigint_handler, TRUE);
+>>>
+
+
+
+SIGSEGV, SIGILL, SIGTERM not implemented in MS-DOS. They are supplied just for
+compatibility. Looks like that SIGINT is defined for windows but not for dos.
+\ifHtml[\HPage{more}\Verbatim
+    Eitan> I also wonder whether the WIN32 really needs to discard the
+    Eitan> following code fragment.
+
+signal() is supported through the standard libc, but is mostly
+ineffective. An example of the kind of code needed is attached.
+
+
+/* Interrupt handler. mt_exit() is a cleanup_and_exit function */
+#ifdef _WIN32
+BOOL sigint_handler(DWORD dwCtrlType)
+{
+  mt_exit(3);
+  return FALSE;      /* return value obligatory */
+}
+#else
+void sigint_handler (int sig)
+{
+  mt_exit(3);
+}
+#endif
+
+  /* Catch signals, so we clean up if the child is interrupted.
+     This emulates "trap 'whatever' 1 2 15".  */
+#ifdef _WIN32
+  SetConsoleCtrlHandler((PHANDLER_ROUTINE)sigint_handler, TRUE);
+#else
+# ifdef SIGINT
+  signal (SIGINT, sigint_handler);
+# endif
+# ifdef SIGHUP
+  signal (SIGHUP, sigint_handler);
+# endif
+# ifdef SIGTERM
+  signal (SIGTERM, sigint_handler);
+# endif
+#endif
+\EndVerbatim\EndHPage{}]\fi
+
+Msvc recommends not using printf, but we ignoring this recommendation
+here with the assumption that the recommendation relates to I/O
+interrupts that are not considered here.
+
+
+
+
+\<header functions\><<<
+#ifdef KWIN32
+static BOOL sigint_handler(ARG_I(DWORD));
+#endif
+>>>
+
+\<functions\><<<
+#ifdef KWIN32
+`[
+static BOOL sigint_handler(dwCtrlType)     DWORD dwCtrlType
+;{
+  err_i(32);
+  return FALSE;      `% return value obligatory `%
+}
+#endif
+>>>
+
+
+\SubSection{System Calls}
+
+
+
+\<vars\><<<
+static Q_CHAR command[255];
+static int system_return;
+>>>
+
+
+The library \`'<stdlib.h>' includes a function
+\`'int system(const char *cmdstring);'.   When cmdstring is NULL,
+the return value is 0 iff the platform does not support system calls.
+
+
+\<vars\><<<
+static BOOL system_yes;
+>>>
+
+\<main's init\><<<
+{                   C_CHAR   *yes = NULL;
+  system_yes = (`<system exist?`>);
+}
+>>>
+
+
+Solaris-? issues the command \`'-c: bad option(s)' if we check for the
+presence of the system function.
+
+
+
+\<system exist?\><<<
+#ifdef SYSTEM_FUNCTION_OK
+0
+#else
+system( yes ) != 0
+#endif
+>>>
+
+\<execute system command\><<<
+(IGNORED) call_sys(command);
+>>>
+
+
+
+
+\<header functions\><<<
+static void call_sys(ARG_I(Q_CHAR *));
+>>>
+
+
+
+
+\<functions\><<<
+`[
+static void call_sys(command)  Q_CHAR * command
+;{
+   if( *command ){
+      (IGNORED) printf("System call: %s\n", command);
+      system_return = system_yes?  (int) system(command) : -1;
+      (IGNORED) printf("%sSystem return: %d\n",
+            system_return? "--- Warning --- " : "", system_return );
+      if( always_call_sys ){ system_return = 0; }
+   }
+}
+>>>
+
+
+\<vars\><<<
+static BOOL always_call_sys = FALSE;
+>>>
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Strings Concat and compare}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+
+\<defines\><<<
+#define eq_str(x,y) (!strcmp(x,y))
+>>>
+
+
+
+strcat should be in string.h, but c++ doesn't find it there.
+We use it just for concatenating an extension of 
+file name. Should have the interface
+\`'char *strcat( ARG_II(C_CHAR *, const Q_CHAR *) );'.
+
+\<header functions\><<<
+static void strct( ARG_II(C_CHAR *, const C_CHAR *) );
+>>>
+
+\<functions\><<<
+`[
+static void strct( str1, str2 ) 
+     C_CHAR * str1`;
+     const C_CHAR * str2
+
+;{   Q_CHAR * ch;
+   ch = str1 + (int) strlen((char *) str1);
+   (IGNORED) strcpy((char *)  ch, str2 );
+}
+>>>
+
+
+
+\SubSection{String into Int}
+
+\<header functions\><<<
+static long int get_long_int( ARG_I(Q_CHAR *) );
+>>>
+
+\<functions\><<<
+`[
+static long int get_long_int(str)     
+                         Q_CHAR   *str
+;{                  long int    i;
+                         Q_CHAR   *ch;
+   ch = str;   i = 0;
+   while( (*ch>= '0') && (*ch <='9') ){
+     i = 10*i + *(ch++) - '0';
+   }
+   return i;
+}
+>>>
+
+
+
+\SubSection{Dynamic Memory Alloc}
+
+
+\<defines\><<<
+#define m_alloc(typ,n) (typ *) malloc_chk((int) ((n) * sizeof(typ)))
+>>>
+
+
+
+\<header functions\><<<
+static void* malloc_chk(ARG_I(int));
+>>>
+
+\<functions\><<<
+`[
+static void* malloc_chk( n ) int n
+;{      void* p;
+   if((p = (void *) malloc( (size_t) n)) == NULL ) bad_mem;
+   return p;
+}
+>>>
+
+
+
+
+
+\<header functions\><<<
+static void* r_alloc(ARG_II(void *, size_t));
+>>>
+
+\<functions\><<<
+`[
+static void* r_alloc( q, n ) 
+      void   *q`;
+      size_t  n
+;{    void*   p;
+   if((p = (void *) realloc( q, (size_t) n)) == NULL) bad_mem;
+   return p;
+}
+>>>
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{myfseek}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ 
+ 
+The ftell() and fseek() are not consistent in ms-windows.  The ftell()
+accounts for \Verb=<cr>= and \Verb=<lf>= in the byte stream, where
+fseek() ignore the <cr> bytes.  A \Verb=READ_BIN_FLAGS= instead of
+\Verb=READ_TEXT_FLAGS= seems to solve the problem.
+
+\<CopyTo read flags\><<<
+READ_BIN_FLAGS
+>>>
+
+A possible alternative is to define a private fseek.
+
+
+ 
+% 
+% 
+% (IGNORED) myfseek(in_file, (long) end_loc, `<abs file addr`>);  
+% 
+% 
+% \<header functions\><<<
+% static BOOL scan_str( ARG_III(C_CHAR *, BOOL, FILE *) );
+% >>>
+% 
+% \<functions\><<<
+% `[
+% static BOOL  scan_str(str,flag,file)     
+%                          Q_CHAR   *str`;
+%                          BOOL   flag`;
+%                          FILE*  file
+% ;{                       Q_CHAR *p;
+% 
+% >>>
+% 
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\SubSection{Pattern Recognition Functions}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+When  failure (false \''status') arises, the input line is consumed to
+its end. 
+The \''_until' functions place in ''match[i]' the string found.
+
+\<header functions\><<<
+static BOOL scan_until_end_str( ARG_IV(const C_CHAR *, int, BOOL, FILE *) );
+>>>
+
+\<functions\><<<
+`[
+static BOOL  scan_until_end_str(str,n,flag,file)     
+                         const C_CHAR   *str`;
+                         int    n`;
+                         BOOL   flag`;
+                         FILE*  file
+;{                       Q_CHAR   *p; 
+                         int i;             
+   if( !flag ) { return flag; }
+   p = match[n];  i = 0;
+   while( TRUE ){
+     if( (i+1) >= max_match[n] ){
+        max_match[n] += 10;
+        p = match[n] = (Q_CHAR *)
+                     r_alloc((void *) match[n], (size_t) max_match[n]);
+     }
+     p[i] = (char) (eoln_ch = getc(file));
+     if( (eoln_ch == (int) '\n') || (eoln_ch == EOF) ){  break; }
+     i++;
+   }
+   p[i] = '\0';
+   i -= (int) strlen(str);
+   if( i>= 0 ){  return eq_str(p+i,str);   }
+   return FALSE;
+}
+>>>
+
+
+
+\<vars\><<<
+static Q_CHAR* match[10];
+static int   max_match[10];
+>>>
+
+
+\<main's init\><<<
+{          int i;
+  for( i=0;  i<=9; i++){
+    match[i] = (Q_CHAR *) malloc(70);
+    max_match[i] = 70;
+  }
+}
+>>>
+
+
+\<header functions\><<<
+static BOOL scan_until_str( ARG_IV(const C_CHAR *, int, BOOL, FILE *) );
+>>>
+
+\<functions\><<<
+`[
+static BOOL  scan_until_str(str,n,flag,file)     
+                         const C_CHAR   *str`;
+                         int    n`;
+                         BOOL   flag`;
+                         FILE*  file
+;{                       Q_CHAR   *p, ch;              
+                         int i, j;             
+   if( !flag ) { return flag; }
+   p = match[n];  i = 0;
+   while( TRUE ){
+     ch =  (char) (eoln_ch = getc(file));
+     if( (eoln_ch == (int) '\n') || (eoln_ch == EOF) ){  return FALSE; }
+     if( (i+1) >= max_match[n] ){
+        max_match[n] += 10;
+        p = match[n] = (Q_CHAR *)
+                     r_alloc((void *) match[n], (size_t) max_match[n]);
+     }
+     p[i++] = ch;
+     j =  i - (int) strlen(str);
+     if( j>= 0 ){
+       p[i] = '\0';
+       if( eq_str(p+j,str) ) { return TRUE;  }
+     }
+   }
+}
+>>>
+
+
+
+
+
+
+\<header functions\><<<
+static BOOL scan_str( ARG_III(const C_CHAR *, BOOL, FILE *) );
+>>>
+
+\<functions\><<<
+`[
+static BOOL  scan_str(str,flag,file)     
+                         const C_CHAR   *str`;
+                         BOOL   flag`;
+                         FILE*  file
+;{                        const Q_CHAR *p;
+                         int temp_eoln_ch;              
+   if( !flag ) { return flag; }
+   p = str;
+   while( *p != '\0' ){
+     if( *(p++) != (temp_eoln_ch = getc(file)) ) {
+        while( (temp_eoln_ch != (int) '\n')
+            && (temp_eoln_ch != EOF) ){ temp_eoln_ch = getc(file); }
+        eoln_ch = temp_eoln_ch;  return FALSE;
+     }
+   }
+   return TRUE;
+}
+>>>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+\SubSection{Shorthands and Mnemonics}
+
+
+
+\<defines\><<<
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef BOOL
+#define BOOL int
+#endif
+>>>
+
+
+
+\<defines\><<<
+#define eq_str(x,y) (!strcmp(x,y))
+>>>
+
+
+
+%----------------------------------------------------
+
+\OutputCodE\<t4ht.c\>
+
+\bye
+
+
+
-- 
cgit v1.2.3

