Chapter 11
Font Information from Htf Tables

   11.1 Load Characters
      Aliases
   11.2 Merge Tables
   11.3 Scan Characters
   11.4 Use of Characters
      Script class-fmt
      File Names for Gifs
      Script for Translation into Gifs
      Script lg file Seperator
      Default Format for Pictures
      Encoding for Dos Font Names
      Other
   11.5 Css Trace on Characters
      4: Src Prefix
      5: Alt Prefix
      6: Img-CLASS Prefix
      s: Img-CLASS Size
      m: Img-CLASS Magnitude
      o: Img-CLASS Ord
      7: End Image
      Htf-based Classes
      Font Properties

The htf fonts are used only within the text part of the html files.

Each char code i in a font may be assigned a string representation and a gif option. When the gif option is provided, the character is taken to be a picture with ALT getting the string for nongraphical reviewers.

For character code i, 0 i 255, we maintain

In the ‘.htf’ files, uses line entries of the form ‘string1string2...’, where the strings have the same arbitrary open and close delimiters. An empty second string indicate no-option gif.

<..entries for html chars in font-tbl..>
 char *name, *gif_on, *ch_str, ch255;  2000
 unsigned U_CHAR **str, *ch, *gif1;
 -_-_-

The following provides a value for characters of missing fonts out of the range 32–127. Within that range, the character codes are being used.

<..get ignored chars..>
 char *digit = p+2;
 ignore_ch = 0;
 while( *digit != ’\0’ ){
   if( (*digit < ’0’) || (*digit > ’9’) ){
     ignore_ch = 0; break;
   }
   ignore_ch = 10 * ignore_ch + (*digit - ’0’);
   if( ignore_ch > 255 ){ ignore_ch = 0; break; }
   digit++;
 }
 -_-_-

<..vars..>+
 static int ignore_ch = 0;
 -_-_-

11.1 Load Characters

In case of shared htf fonts, we can have much more sharing below.

Lynx introduces a space before and after each figure.

<..get html characters..>
 {      U_CHAR str[256];
        int i, design_n, n_gif;
        <.font looping variables.>
    n_gif = new_font.char_l - new_font.char_f + 1;
    new_font.ch255 = 0;
    <.initiate gif flags.>
    <.initiate htf accents.>
    new_font.ch = m_alloc(unsigned char, n_gif );
    <.set default characters.>
    new_font.str =  m_alloc(unsigned char*, n_gif);
    new_font.str[0] = &null_str;
    design_n = 0;
       <.load file of characters.>
    new_font.str = (unsigned U_CHAR **) r_alloc((void *)   new_font.str,
                      (size_t) ( (design_n?design_n:1) * sizeof(char *)) );
    <.merge new html font with old ones.>
 }
 -_-_-

A value 0 corresponds to an empty string. A value greater than 0 points to a character string. ‘ design_n = 0;’ had value 1 earlier. Probably because we had ‘design_n’, and not ‘(design_n?design_n:1)’, which asked for allocation of memory of size 0. This caused a problem to mallocate, because it produced a non-valid 0 ( ‘insuffient memory’) error

<..vars..>+
 static unsigned  U_CHAR  null_str = ’\0’;     /*NEW*/ 
 -_-_-

<..initiate gif flags..>
 {     int n_gif_bytes;
    n_gif_bytes = (n_gif + 7) / 8;
    new_font.gif_on = m_alloc(char, n_gif_bytes );
    new_font.ch_str = m_alloc(char, n_gif_bytes );
    <.memory for math classes.>
    for( i=n_gif_bytes; i--; ) {
      <.init math-closing.> new_font.ch_str[i] = new_font.gif_on[i] = 0;
    }
    new_font.gif1 = m_alloc(unsigned char, n_gif );
    for( i=n_gif; i--; ) {
        <.init math.> new_font.gif1[i] = 0;
 }  }
 -_-_-

<..set default characters..>
 for( i = new_font.char_f; i <= new_font.char_l ; i++ ){
   new_font.ch[i - new_font.char_f] =
                  (char)  (((31<i) && (i<128))? i : ignore_ch);
 }
 -_-_-

The first iteration searches for the font directly. The second iteration searches for aliased font.

<..load file of characters..>
 {  char search_font_name [256];
   (IGNORED) strcpy((char *) search_font_name, (char *) new_font.name);
   while( 1 ){                         BOOL flag;
      <.font looping test.>
      flag = TRUE;
      for( ; font_name_n; font_name_n-- ){  FILE* file;
                                            int   char_f, char_l;
        new_font_name[font_name_n] = ’\0’;
        <.file = .htf file.>
        if( file != NULL){
                                            INTEGER x_char_l;
          <.scan header line in html font file.>
          if( x_char_l == HTF_ALIAS) {
            <.scan aliased htf file.>
            (IGNORED) fclose(file);  flag = FALSE; break;
          }
          <.scan info of html font file.>
          <.scan trailer line in html font file.>
          htf_to_lg(html_font,  new_font_name, fonts_n, file);
          <.trace htf files.>
          (IGNORED) fclose(file);  break;
      } }
      if( flag ){ break; }
   }
   if( font_name_n == 0 ){
      if( errCode == 0 ){ errCode= 21; }
      warn_i_str(21,search_font_name);
      (IGNORED) fprintf(stderr,
                "%d--%d)\n", new_font.char_f, new_font.char_l);
      dump_env();
   } else { <.trace env file.> }
 }
 -_-_-

<..font looping variables..>
 int loopBound = 0;
 U_CHAR loopName[256];
 loopName[0] = ’\0’;
 -_-_-

<..font looping test..>
 if( eq_str( new_font_name, loopName) ){
      U_CHAR name[256];
    (IGNORED) sprintf(name, "%s.htf", new_font_name);
     err_i_str(1, name);
 } else {
    (IGNORED) strcpy((char *) loopName, (char *) new_font_name);
 }
 loopBound++;
 if( loopBound > 10 ){
    U_CHAR name[256];
    (IGNORED) sprintf(name, "%s.htf", new_font_name);
    err_i_str(1, name);
 }
 -_-_-

Aliases

<..if alias return 0..>
 if( ( name == new_font_name ) && (n == 19) && (ch==’.’) ){
    return HTF_ALIAS;
 }
 -_-_-

<..defines..>+
 #define  HTF_ALIAS 10000000
 -_-_-

[more]

<..scan aliased htf file..>
 {                                 int chr;
   font_name_n=0;
   while( (chr = get_html_ch(file)) != ’\n’ ){
     if( chr !=   ) search_font_name[font_name_n++] = chr;
   }
   search_font_name[font_name_n]  = ’\0’;
   if( eq_str( search_font_name, new_font_name) ){ err_i_str(20, new_font_name); }
   (IGNORED) printf("Searching ‘%s.htf’ for ‘%s.htf’\n",
                                         search_font_name, new_font.name);
   htf_to_lg(html_font, new_font_name, fonts_n, file);
   new_font_name = (char *)  r_alloc((void *) new_font_name,
                                   (size_t) (font_name_n+1));
   (IGNORED) strcpy((char *) new_font_name, (char *) search_font_name);
   font_name_n = strlen((char *) new_font_name);
 }
 -_-_-

<..get replacement fontNO..>
 if( dot_file ){           BOOL  tag;
    (IGNORED) fseek(dot_file, 0L, <.abs file addr.>);
    tag = TRUE;
    while( tag ){
      switch( getc(dot_file) ){
        case  EOF: { j++;  tag = FALSE;  break; } no replacement
        case ’a’: { <.scan replacement font.>   }
         default: {                    int ch;
                    do ch = getc(dot_file);
                    while( (ch != ’\n’) && (ch != EOF) );
                    break; }
 }  } }
 -_-_-

<..scan replacement fontNO..>
    int   chr;
    U_CHAR *ch;
 ch = new_font.name;
 while( *ch++ == (chr = getc(dot_file)) );
 if( chr==’  ){
   tag = FALSE;
   while( (new_font_name[0] = getc(dot_file)) ==   );
   font_name_n=1;
   while( (chr = getc(dot_file)) != ’\n’ )
     if( chr !=   ) new_font_name[font_name_n++] = chr;
   new_font_name[font_name_n]  = ’\0’;
   (IGNORED) printf("Loading ‘%s.htf’ for ‘%s.htf’\n",
                                 new_font_name, new_font.name);
 }
 -_-_-

11.2 Merge Tables

Don’t we loose some vital info here? Were this comes from?

<..merge new html font with old ones..>
 for( i = fonts_n; i--; )
   if( eq_str(html_font[i].name, new_font_name) ){       int k;
      k = html_font[i].i;
      free((void *)  new_font.gif1 ); new_font.gif1= font_tbl[ k ].gif1;
      free((void *)  new_font.ch );   new_font.ch  = font_tbl[ k ].ch;
      free((void *)  new_font.str );  new_font.str = font_tbl[ k ].str;
      free((void *)  new_font.ch_str );
                                new_font.ch_str = font_tbl[ k ].ch_str;
      <.merge math entries.>
      break;     }
 if( i < 0 ){ <.record new tex4ht font.> }
 -_-_-

<..record new tex4ht font..>
 html_font = fonts_n? (struct html_font_rec *) r_alloc((void *) html_font,
                  (size_t) ((fonts_n+1) * sizeof(struct html_font_rec) ))
                    :  m_alloc(struct html_font_rec, 1);
 html_font[fonts_n].name = m_alloc(char, font_name_n + 1);
 (IGNORED) strcpy((char *) html_font[fonts_n].name, (char *) new_font_name);
 html_font[fonts_n].i    = font_tbl_size;
 fonts_n++;
 -_-_-

<..scan fonts vars..>
 int fonts_n;
 struct html_font_rec *html_font=0;
 -_-_-

<..init scan fonts vars..>
 fonts_n = 0;
 -_-_-

<..free html font memory..>
 if( html_font ){
   while( fonts_n-- )  free((void *)  html_font[fonts_n].name);
   free((void *)  html_font );
 }
 -_-_-

EXPLAIN THE CONTENT OF THE FOLLOWING

<..types..>+
 struct html_font_rec{  char* name;
                        int   i;     };
 -_-_-

11.3 Scan Characters

<..scan info of html font file..>
 if( char_f <= new_font.char_l ){      U_CHAR  del;
                                       int  j, n;
    <.skip front part in font file.>
    n =  ((char_l < new_font.char_l)? char_l : new_font.char_l)
         - char_f + 1;
    for( i = char_f - new_font.char_f; i < n; i++ ){
       <.scan html char in font file.>
       <.store html character.>                     }
    <.skip back part of font file.>
 }
 -_-_-

<..skip front part in font file..>
 while( char_f < new_font.char_f ){
   while( get_html_ch(file) != ’\n’ );
   char_f++;   }
 -_-_-

<..skip back part of font file..>
 while( char_l > new_font.char_l ){
   while( get_html_ch(file) != ’\n’ );
   char_l--;   }
 -_-_-

We should consider characters having representations of ‘\decimal digits\’, ‘\x hexadecimal digits\’, and ‘\o octal digits\’.

<..scan html char in font file..>
 {      int indirect_ch, base=0, value=0, digit, ch1, ch2;
   indirect_ch = 0;
   del = get_html_ch(file);   j=0;
   while( (str[j++] = get_html_ch(file)) != del )
     { <.check for encoded chars.> };
   str[j-1] = ’\0’;
   while( get_html_ch(file) != del );
   ch1 = 0;
   while( ((ch = (int) get_html_ch(file)) != del) ){
      if( (ch < ’0’) || (ch > ’9’) ) break;
      ch1 = ch1 * 10 + ch - ’0’; }
   <.propagate 4hf info into htf.>
   new_font.gif1[i] = ch1 % 256;
   do{
     if( (ch = get_html_ch(file)) == del ){
       <.scan htf accent.>  break;
     }
   } while( ch != ’\n’ );
   if( ch != ’\n’ ){
     do{
       if( (ch = get_html_ch(file)) == del ){
         <.scan htf accented.>  break;
       }
     } while( ch != ’\n’ );
   }
   if( ch != ’\n’ )
   { while( get_html_ch(file) != ’\n’ ); }
 }
 -_-_-

<..check for encoded chars..>
 if( (digit=str[j-1]) == ’\\’ )
   if( (indirect_ch = !indirect_ch) != 0) {
     switch( value=get_html_ch(file) ){
       case ’x’: { base = 16; value = 0;  j--; break; }
       case ’o’: { base = 8;  value = 0;  j--; break; }
       default: {
         if( (value < ’0’) || (value > ’9’) ) {
           indirect_ch = !indirect_ch;   str[j-1] = value;
         } else { value -= ’0’;  base = 10; j--; }
   } } }
   else{ if( value>255 ){
             warn_i_int(28,value);
             value = 32;  dump_htf( file );
         }
         str[j-1] = value;
   }
 else if ( indirect_ch ){
   j--;   digit -=  (digit>’9’)?  ’A’-10 : ’0’;
   if( (digit<0) || (digit>=base) ){
       warn_i_int(29, str[j]);
       digit = 0; dump_htf( file );
   }
   value = value*base + digit;
 } else if ( str[j-1]==10 ){
    dump_htf( file );
    err_i_int(48, i+1);
 }
 -_-_-

We might be able in the following to share strings by comparing with corresponding characters in other fonts.

The variable j holds the number of characters in the string plus one.

<..store html character..>
 add_bit( new_font.ch_str, i, j!=2 );
 switch( j ){
   case 1: { new_font.ch[i] = 0;    break; }
   case 2: { new_font.ch[i] = *str; break; }
   default: {                           unsigned U_CHAR  *p;
     new_font.str[design_n] = p = m_alloc(unsigned char, j);
     if( design_n>255 ){ design_n--; warn_i(35);}
     if( i==255 ){
        if( design_n == 255 ){
                 new_font.ch[i] = 0;           new_font.ch255 = 1;
        } else { new_font.ch[i] = ++design_n;  }
     } else {    new_font.ch[i] = ++design_n; }
     while( j-- )  p[j] = str[j];  2000
 } }
 -_-_-

<..header functions..>+
 static int get_html_ch( ARG_I(FILE*) );
 -_-_-

<..functions..>+
 
 static int get_html_ch( file )   FILE*  file
 
 ;{                        int ch;
   if( (ch = (int) getc(file)) == EOF ) {
      dump_htf( file );
      err_i_str(20, new_font_name);
   }
   return ch;
 }
 -_-_-

<..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 void dump_htf( ARG_I(FILE*) );
 -_-_-

<..functions..>+
 
 static void dump_htf( file )   FILE*  file
 
 ;{       int i, j, ch, chr=0;
   (IGNORED) fseek(file, 0L, 0);
   i=-1; j=0;
   while( (ch = getc(file)) != EOF  ){
     if( !j ){  chr = ch; }
     j += ch==chr;
     (IGNORED)  putc(ch,stderr);
     if( ch == ’\n’ ){
        if( (i>-1 ) && (j<4) && (dump_htf_files<2) ){
           (IGNORED) printf("missing delimiter \n");
        }
        (IGNORED) fprintf(stderr,"%d:  ",++i);
        j=0;
 } } }
 -_-_-

<..vars..>+
 static short dump_htf_files = 0;
 static BOOL dump_env_files = FALSE;
 -_-_-

<..dump htf files..>
 dump_htf_files = 1;
 -_-_-

<..dump env file..>
 dump_env_files = TRUE;
 -_-_-

<..trace htf files..>
 if( dump_htf_files ){
    dump_htf_files++;  dump_htf( file );  dump_htf_files--;
 }
 -_-_-

<..trace env file..>
 if( dump_env_files ){ dump_env(); }
 -_-_-

<..header functions..>+
 static void dump_env( ARG_I(void) );
 -_-_-

<..functions..>+
 static void dump_env( MYVOID )
 {
                              int ch;
   if( !dumped_env ){
     dumped_env = TRUE;
     (IGNORED) fseek(dot_file, 0L, <.abs file addr.>);
     (IGNORED) fprintf(stderr,
      "\n----------------------------------------------------\n");
     (IGNORED) fprintf(stderr, "environment file\n");
     (IGNORED) fprintf(stderr,
      "----------------------------------------------------\n");
     while( (ch = getc(dot_file)) != EOF  ){
       (IGNORED)  putc(ch,stderr);
     }
     (IGNORED) fprintf(stderr,
      "----------------------------------------------------\n");
 }  }
 -_-_-

<..vars..>+
 static BOOL dumped_env = FALSE;
 -_-_-

<..header functions..>+
 static void htf_to_lg( ARG_IV(struct html_font_rec*,char*,int,FILE*));
 -_-_-

<..functions..>+
 
 static void htf_to_lg(html_font,  new_font_name, fonts_n, file)
 
                       struct html_font_rec*   html_font;
                       char* new_font_name;
                       int     fonts_n;
                       FILE* file
 ;{
                                               int ch, i;
   for( i = 0  ; i<fonts_n; ){
      if( eq_str(html_font[i].name, new_font_name) ){  break; }
      i++;
   }
   if( i == fonts_n ){
                                               BOOL content;
                                               int prev_ch;
      prev_ch = ’\n’;  content = FALSE;
      while( (ch = (int) getc(file)) != EOF ) {
        if( (ch != ’\n’) || (prev_ch != ’\n’) ){
          (void)  putc( ch, log_file );
          prev_ch = ch;  content = TRUE;
      } }
      if( content && (prev_ch != ’\n’) ){
         (void)  putc( ’\n’, log_file );
      }
 } }
 -_-_-

<..scan header line in html font file..>
 x_char_l =
       get_html_file_id(file, new_font.char_f, new_font.char_l, 19);
 if( x_char_l != HTF_ALIAS) {
      char_f = (int) (x_char_l / 1000.0 + 0.5) + new_font.char_f;
      x_char_l -= (char_f-new_font.char_f) * 1000 - new_font.char_l;
      char_l = (int) x_char_l;
 }
 -_-_-

<..scan trailer line in html font file..>
 (void) get_html_file_id(file, new_font.char_f, new_font.char_l, 18);
 -_-_-

<..header functions..>+
 static INTEGER get_html_file_id( ARG_IV(FILE*, int, int, int) );
 -_-_-

<..functions..>+
 
 static  INTEGER get_html_file_id(file, first, last, n)
                             FILE* file;
                             int first; int last; int n
 
 ;{                          int ch, i, bound, cnt;
                             INTEGER  diff;
                             char* name;
    name = new_font_name;
    while( *name == (ch = get_html_ch(file)) )  name++;
    <.if alias return 0.>
    if( (*name != ’\0’) || (ch !=  ’) )  warn_i_str(n, name);
    bound = first;  diff = 0;
    for( cnt = 0; cnt < 2; cnt++ ){
       while( ch ==   )  ch = get_html_ch(file);
       i = 0;
       while( (ch >= ’0’) && (ch <= ’9’) ){
          i = i * 10 + ch - ’0’;  ch = get_html_ch(file);  }
       if( i != bound ){
          <.warning(22.>, new_font_name, i, bound); show_err_context();
          diff = diff * 1000 + i - bound;    }
       bound = last;  }
    while( ch != ’\n’ ) ch = get_html_ch(file);
    return diff;
 }
 -_-_-

<..defines..>+
 #ifndef TRUE
 #define TRUE 1
 #endif
 #ifndef FALSE
 #define FALSE 0
 #endif
 #ifndef BOOL
 #define BOOL int
 #endif
 -_-_-

11.4 Use of Characters

When next_char is not equal to -1, there is a character waiting to replace the current character.

<..insert ch to text..>
 <.set begin accents.>
 <.css for chars.> <.trace dvi char.>
 <.left class del.> <.pos dvi ch.>
 <.mark accented ch.>
 if( <.next-char.> != -1 ) {
    <.open output file.>
    (IGNORED) put_4ht_ch( <.next-char.>, cur_o_file );
    <.next-char.> = -1;
 } else if( <.next-str.> ) {
    <.current char for forwarded string.>
    print_f_4ht(next_str); free((void *) next_str);
    next_str = (char *) 0;
 } else {
    if( verb_ch ){
       <.open output file.>
       (IGNORED) put_4ht_ch( ch, cur_o_file );
    } else {  <.insert font char.> }
 }
 <.end mark accented ch.>
 <.end pos dvi ch.> <.right class del.>
 <.end trace dvi char.> <.end css for chars.>
 <.set end accents.>
 -_-_-

Does ‘verb_ch’ correspond to \Char?

<..insert font char..>
    int gif_flag, chr, r_ch;
     BOOL  ch_str_flag;
 r_ch = ch - font_tbl[cur_fnt].char_f;
 gif_flag = font_tbl[cur_fnt].gif1[r_ch];
 ch_str_flag = get_bit( font_tbl[cur_fnt].ch_str, r_ch);
 chr = ((r_ch == 255) && font_tbl[cur_fnt].ch255 )? 256 :
                          *(font_tbl[cur_fnt].ch + r_ch);
 if( (gif_flag % 2) || ch_str_flag ){      design_ch = ch;
              { <.insert design chr.> } design_ch = 0;    }
 else { <.insert standard char.> }
 -_-_-

<..vars..>+
 static BOOL verb_ch = FALSE;
 -_-_-

A design character is either a picture (gif_flag) or a string character (ch_str_flag).

<..insert design chr..>
       U_CHAR  str[256], *p;
       BOOL sv;
       int mag;
 sv = special_on;   special_on = TRUE;
 if( gif_ch && (gif_flag % 2) ){
    <.open output file.>
    if( !gif_open[gif_flag] ){
      <.img char without template.>
    } else if( !get_bit( class_on, gif_flag ) ) {
       notify_class_info(gif_flag);
       store_bit_I( class_on, gif_flag );
    }
    <.<IMG SRC="....>
    <...."ALT="....>
    <...."CLASS="family....>
    <....gif font size....>
    <....gif font mag....>
    <....gif sym ord....>
    <...."/IMG>.>
 } else  { <.insert string char.> }
 special_on = sv;
 -_-_-

<..header functions..>+
 static void notify_class_info( ARG_I(int) );
 -_-_-

<..functions..>+
 
 static void notify_class_info( gif_flag )   int gif_flag
 ;{                        U_CHAR str[256], *p;
    str[0] = ’\0’;
    p = gif_open[gif_flag];
    if( p )
      if( *p ) (IGNORED) strct(str,p);
    p = gif_alt[gif_flag];
    if( p )
      if( *p ) (IGNORED) strct(str,p);
    p = gif_class[gif_flag];
    if( p )
      if( *p ) (IGNORED) strct(str,p);
    p = gif_size[gif_flag];
    if( p )
      if( *p ) (IGNORED) strct(str,p);
    p = gif_mag[gif_flag];
    if( p )
      if( *p ) (IGNORED) strct(str,p);
    p = gif_ord[gif_flag];
    if( p )
      if( *p ) (IGNORED) strct(str,p);
    p = gif_end[gif_flag];
    if( p )
      if( *p ) (IGNORED) strct(str,p);
    p = str;
    while( *p ){
      if( *p == ’\n’ ) *p =  ’;
      p++;
    }
    (IGNORED) fprintf(log_file, class_fmt,
       gif_flag,
       gif_id[gif_flag]? gif_id[gif_flag] : "",
       str);
 }
 -_-_-

For some reason, bordlan cc+ complains if the ‘p = gif_open[gif_flag]’ are placed within the if’s.

configuration for class %d’ below stands for ‘\\special{t4ht;|%d...}

<..img char without template..>
 (IGNORED) sprintf(str,
    "configuration for htf class %d (char %d of %s.htf)",
    gif_flag, ch,font_tbl[cur_fnt].name
   );
 warn_i_str(50,str);
 -_-_-

<..img char without template..>+
 gif_open[gif_flag] = m_alloc(char,
    <.1 + strlen((char *) <IMG SRC="+"ALT="+++++">+).>);
 (IGNORED) strcpy((char *) gif_open[gif_flag],
            <.<IMG SRC="+"ALT="+++++">+.>);
 gif_alt[gif_flag] = gif_open[gif_flag]+11;
   *(gif_alt[gif_flag] - 1) = ’\0’;
 gif_class[gif_flag] = gif_open[gif_flag]+19;
   *(gif_class[gif_flag] - 1) = ’\0’;
 gif_size[gif_flag] = gif_open[gif_flag]+20;
   *(gif_size[gif_flag] - 1) = ’\0’;
 gif_mag[gif_flag] = gif_open[gif_flag]+21;
   *(gif_mag[gif_flag] - 1) = ’\0’;
 gif_ord[gif_flag] = gif_open[gif_flag]+22;
   *(gif_ord[gif_flag] - 1) = ’\0’;
 gif_end[gif_flag] = gif_open[gif_flag]+23;
   *(gif_end[gif_flag] - 1) = ’\0’;
 gif_id[gif_flag] = gif_open[gif_flag]+28;
   *(gif_id[gif_flag] - 1) = ’\0’;
 -_-_-

<..<IMG SRC="+"ALT="+++++">+..>
 "<img src=\"+\" alt=\"+++++\" />+"
 -_-_-

<..1 + strlen((char *) <IMG SRC="+"ALT="+++++">+)..>
 29
 -_-_-

What is the difference between the following two cases?

<..insert standard char..>
 if( !gif_flag || (gif_flag % 2) || ch_map_flag ) {  put_char(chr);
 } else{ <.put char(chr).> }
 -_-_-

If ‘gif_flag % 2’ is the case we have a picture which we want to insert for it just the string part. (The !gif˙flag is for text with pattermn 0?)

<..insert string char..>
 if( !gif_flag || (gif_flag % 2)  || ch_map_flag ) {
    put_alt_ch(chr,ch_str_flag);  }
 else{ <.put string-char(chr).> }
 -_-_-

Script class-fmt

Font information, e.g., for style files.

<..h-defines..>+
 #ifndef LGCLS
 #define LGCLS "Font_Class(%d,\"%s\"): %s\n"
 #endif
 -_-_-

<..vars..>+
 static U_CHAR *class_fmt = NULL;
 -_-_-

<..get from tex4ht.env file..>+
 class_fmt = (char *) get_script(class_fmt,LGCLS,’c’);
 -_-_-

File Names for Gifs

Symbol i from base font x gets into file ‘x-i.gif’, and from c-magnified font goes into ‘x-c-i.gif’. In old LaTeX, ‘\documentstyle[...12p..]{..}’ gives a based-10 font magnified into 12.

<..defines..>+
 #define GIF_I      "-%x%s"
 #define GIF_II  "-%x-%x%s"
 #define GIF_VII       "%s"
 -_-_-

<..h-defines 2..>
 #ifdef DOS
 #define HTM
 #endif
 -_-_-

<..defines..>+
 #ifdef HTM
 #define DOS_GIF_FILE
 #endif
 -_-_-

<..insert gif symbol to html file..>
 if( !dos_file_names ){
    print_f(font_tbl[cur_fnt].name);
    if( mag == 10 )  (IGNORED) sprintf(str, GIF_I,   design_ch, gif);
    else             (IGNORED) sprintf(str, GIF_II,  mag, design_ch, gif);
 }
 -_-_-

<..insert gif symbol to lg file..>
 if( !dos_file_names ){
    if( mag == 10 ) (IGNORED) sprintf(str, "%s-%x%s",
                         font_tbl[cur_fnt].name, ch, gif);
    else            (IGNORED) sprintf(str, "%s-%x-%x%s",
      font_tbl[cur_fnt].name, mag, ch, gif);
 }
 -_-_-

Transform long file names to 8 characters.

<..insert gif symbol to html file..>+
 
 #ifdef DOS_GIF_FILE
 

 if( dos_file_names ){
    dos_gif_file(str, mag, design_ch);
    print_f(str);
    (IGNORED) sprintf(str, GIF_VII, gif);
 }
 
 #endif
 

 -_-_-

<..insert gif symbol to lg file..>+
 
 #ifdef DOS_GIF_FILE
 

 if( dos_file_names ){
    (IGNORED) strcpy((char *) str, (char *) font_tbl[cur_fnt].name);
    dos_gif_file(str, mag, ch);
    strct(str,gif);
 }
 
 #endif
 

 -_-_-

The following writes into the ‘.lg’ file. The ‘templt’ ends with a percent (%\0). The algorithm collects the characters until a % is encountered. Then it prints out the segment of characters accumulated, and goes to process whatever follows the ‘%’.

<..header functions..>+
 static void script( ARG_IV(char *, U_CHAR *, int, U_CHAR *) );
 -_-_-

<..functions..>+
 
 static void script(templt, job, page, font)
       U_CHAR *templt;
       U_CHAR *job;
       int  page;
       U_CHAR *font
 
 ;{    U_CHAR *ch, *p;
       U_CHAR fmt[256];
    job[ (int) strlen((char *) job) - 1 ] =’\0’;
    p = ch = templt;
    while( TRUE ){
      if( *ch == ’%’ ){
        <.print segment of templet.>
        <.get format of output.>
        switch( *(++ch) ){
           case ’1’:{ *p = ’s’;
                      (IGNORED) fprintf(log_file, fmt, job);  break;}
           case ’2’:{ *p = ’d’;
                      (IGNORED) fprintf(log_file, fmt, page); break;}
           case ’3’:{ *p = ’s’;
                      (IGNORED) fprintf(log_file, fmt, font); break;}
           case ’%’:{ *p = ’c’;
                      (IGNORED) fprintf(log_file, fmt, ’%’);  break;}
            default:{ job[ (int) strlen((char *) job) ] =’.’;         return;}
        }
        p = ++ch;
      }else ch++;
 } }
 -_-_-

<..print segment of templet..>
 *ch = ’\0’;  (IGNORED) fprintf(log_file, "%s", p);
 *(ch++) = ’%’;
 -_-_-

The jobname var contains a period at the end, removed temporarily for the script. The default case above should have been an error, or at least a warning.

<..get format of output..>
 p=fmt;  *(p++) = ’%’;
 if( *ch == ’\0’ ){ job[ (int) strlen((char *) job) ] =’.’;  return; }
 while( *ch != ’%’ ){  *(p++) = *(ch ++);  }
 *(p+1) = ’\0’;
 -_-_-

 
 > Instead of a single-line script 
 
 >      scall convert %1 %2 %3\nif errorlevel 1 goto end 
 
 > you are allowed also to have multi-lines scripts 
 
 >      scall convert %1 %2 %3 
 >      sif errorlevel 1 goto end 
 
 > Would this work?  If ’\n’ is a superior solution I 
 > see no problems implementing it. 
 
  Yes, this works fine for the "if errorlevel" problem. However, I have 
found out in the meantime (RTMF is always a good idea ;-) that the 
emTeX driver can create _all_ pcx files in one run, giving them names 
like out01.gif, out02.gif, ... (or out001.gif, out002.gif, ... - it 
depends on command line options). Display has a similar option. This 
would significantly reduce the total conversion time, so I’m inclined to 
use this option. (I think it may even outweigh the advantage of not 
recreating the gifs after the b line, although I may be able to 
implement that anyway with a little trickery). Since DOS has no way to 
increase counters, I’d like to see the page numbers tex4ht gives also as 
"01" (or "001"), etc. This would make it easy for me to use the emTeX 
functionality. I’ve implemented this in tex4ht.c by changing the page 
number format from %d to %03d. I assume this won’t break anything else? 
 
 
 > I didn’t get the idea. 
 
  The emTeX dvidot driver, when given an output filename like ’out???’, 
creates an output file for each page in the dvi file in one run, named 
out001, out002, out003, etc. If the page numbers tex4ht produces are of 
the same form (001 instead of 1), I can simply append them to ’out’ like 
this: out%2. This makes it easier to process the created files further. 
 
 > The change is in the following line? 
 
 >           case ’2’:{ (IGNORED) fprintf(log_file, "%d", page); break;} 
 
  Yes. 
 
 > Is  %03d  the same as  %0.3d?  If not, what is the difference? 
 
  For integers, yes; it is also the same as %.3d. I just prefer the 
first form, as it makes more sense to me (things after the dot are 
called the precision specifier, and I don’t want to specify precision 
but field width). 

Script for Translation into Gifs

<..h-defines..>+
 #ifndef LGPIC
 #define LGPIC "--- needs --- %%1.idv[%%2] ==> %%3 ---\n%"
 #endif
 -_-_-

<..vars..>+
 static U_CHAR *font_gif = NULL;
 -_-_-

<..get gif script from com ln..>
 font_gif = p+2;
 -_-_-

<..get from tex4ht.env file..>+
 font_gif = (char *) get_script(font_gif,LGPIC,’s’);
 <.inser percent-ch at end of s-script.>
 -_-_-

<..inser percent-ch at end of s-script..>
 {    int n;
   n = (int) strlen((char *) font_gif);
   if( font_gif[n-1] != ’%’ ){ font_gif[n] = ’%’; font_gif[n+1] = ’\0’; }
 }
 -_-_-

Script lg file Seperator

Separates general picturs from symbols.

<..h-defines..>+
 #ifndef LGSEP
 #define LGSEP "--- characters ---\n"
 #endif
 -_-_-

<..vars..>+
 static U_CHAR *begin_char_gif = NULL;
 -_-_-

<..get start char-gif from com ln..>
 begin_char_gif = p+2;
 -_-_-

<..get from tex4ht.env file..>+
 begin_char_gif = (char *) get_script(begin_char_gif,LGSEP,’b’);
 -_-_-

Default Format for Pictures

<..h-defines..>+
 #ifndef LGTYP
 #define LGTYP ".png"
 #endif
 -_-_-

<..vars..>+
 static U_CHAR *gif = NULL;
 -_-_-

<..get gif-type from com ln..>
 gif = p+2;
 -_-_-

In the extension name we don’t want the line break at the end.

<..get from tex4ht.env file..>+
 gif = (char *) get_script(gif,LGTYP,’g’);
 {              int n;
    n = (int) strlen((char *) gif) - 1;
    if( gif[n] == ’%’ ){  gif[n] = ’%’; }
    else if( gif[n] == ’\n’ ) {  gif[n] = ’\0’; }
 }
 -_-_-

Encoding for Dos Font Names

We set font name + mag (2 chars) + ch number (2 ch). If the length is no greater than 8, we are done. Otherwise, we take the first n-2 characters and map them to a string of length 4. They are the most stable in the names, so they minimize replacements.

<..header functions..>+
 
 #ifdef DOS_GIF_FILE
 

 static void  dos_gif_file( ARG_III(char *, int, int) );
 
 #endif
 

 -_-_-

<..functions..>+
 
 #ifdef DOS_GIF_FILE
 

 
 static void  dos_gif_file(str, mag, design_ch)
         U_CHAR *str;
         int  mag;
         int  design_ch
 
 ;{      int  n, m, i;
         struct gif_file_rec * p, * q;
         U_CHAR *ch;
   m = n = (int) strlen((char *) str);
   if( n > 4 ){
     <.p = prefix of font file.>
     if( p == NULL ){ <.p = new prefix font file.> }
     gif_file = p;
     for( n=0; n<4; n++ )   str[n] = xeh[(int)(*(p->code + n))];
   }
   str[n++] = xeh[mag<16? 0: mag / 16];
   str[n++] = xeh[mag % 16];
   str[n++] = xeh[design_ch<16? 0: design_ch / 16];
   str[n++] = xeh[design_ch % 16];
   str[n] = ’\0’;
 }
 
 #endif
 

 -_-_-

We keep collisions table to ensure agains collisions. We do it in circular linked list so that last visited in previous turn will be the first to be visited now. The prefix, and its suggested

<..types..>+
 
 #ifdef DOS_GIF_FILE
 

 struct gif_file_rec{
     U_CHAR                code[4];
     U_CHAR                *name;
     struct gif_file_rec *next;     };
 
 #endif
 

 -_-_-

<..vars..>+
 
 #ifdef DOS_GIF_FILE
 

 static struct gif_file_rec *   gif_file = (struct gif_file_rec *) 0;
 
 #endif
 

 -_-_-

<..p = prefix of font file..>
 if( (p = gif_file) != NULL ){
   while( TRUE ){
     if( eq_str( str, p->name ) ) break;
     if( (p = p->next) == gif_file ){ p = NULL;  break; }
 } }
 -_-_-

<..p = new prefix font file..>
 p =  m_alloc(struct gif_file_rec, 1);
 <.get tentative prefix replacement.>
 <.adjust prefix replacement.>
 (IGNORED) printf("\nRenaming ‘%s____%s’ to ‘%c%c%c%c____%s’\n",
             str, gif,
                  xeh[(int)(ch[0])], xeh[(int)(ch[1])],
                  xeh[(int)(ch[2])], xeh[(int)(ch[3])]
                , gif);
 p->name = m_alloc(char,m+1);
 (IGNORED) strcpy((char *)  p->name, (char *) str );
 if( gif_file ){  p->next = gif_file->next;   gif_file->next = p;  }
           else   p->next = p;
 -_-_-

We choose the scheme ‘sum(char codes of str) / 4’ to find a number i, and then we cycle around hex in jumps of i to choose four characters not starting with digit.

<..get tentative prefix replacement..>
 for(i=str[n]; n; ){ i+=str[--n];  if( i > (INT_MAX / 8) ) i/=2; }
 if( (n=i % BASE) <10 ) n+= 10 + i%(BASE-20);
 *(ch = p->code)= n; n += i;
 ch[1]          = n%BASE; n += i;
 ch[2]          = n%BASE; n += i;
 ch[3]          = n%BASE;
 -_-_-

To allow for adjustments, we srtoe indexes of xeh, and not the characters themselve. We allow BASE3 options of adjustments!!!

<..adjust prefix replacement..>
 if( gif_file ){
    q = gif_file->next;
    while( TRUE ){
      if( (*(q->code) == *ch)   && (*(q->code+1) == ch[1]) &&
          (*(q->code) == ch[2]) && (*(q->code+2) == ch[3])  ){
         ch[3] ++;  ch[2] += ch[3]/ BASE;  ch[3] = ch[3] % BASE;
                    ch[1] += ch[2]/ BASE;  ch[2] = ch[2] % BASE;
                                           ch[1] = ch[1] % BASE;
         q = gif_file;
      } else if( q == gif_file ) break;
      q = q->next;
 }  }
 -_-_-

Instead of hex we take xeh.

<..defines..>+
 #define BASE  36
 -_-_-

<..vars..>+
 
 #ifdef DOS_GIF_FILE
 

 static U_CHAR xeh[]="0123456789abcdefghijklmnopqrstuvxyz";
 
 #endif
 

 -_-_-

Other

<<’ is NOT a safe operation, beyond char size, for transporting across platforms.

<..defines..>+
 #define store_bit_I(ch,i)  ch[(i)/8]|=(1<<((i)%8));
 #define store_bit_Z(ch,i)  ch[(i)/8]&=~(1<<((i)%8))
 #define add_bit(ch,i,b)   ch[(i)/8] |= ((b) << ((i)%8))
 #define get_bit(ch,i)     ((ch[(i)/8] >> ((i)%8)) & 1)
 -_-_-

<..header functions..>+
 static void put_alt_ch( ARG_II( int, BOOL) );
 -_-_-

<..functions..>+
 
 static void  put_alt_ch(chr,ch_str_flag)
       int  chr;
       BOOL ch_str_flag
 ;{
    if( !ch_str_flag ) put_char( chr );
    else if( chr > 0 ){ <.put htf char string.> }
 }
 -_-_-

The ‘gif_ch’ is true when we put the character outside of ‘\special{t4ht|}...\special{t4ht|}’, and is false inside that range. Within that range, used in ALT’s, we want to eliminate the html comamnds ‘<...>’ and the delimiter characters ‘"’.

<..put htf char string..>
     unsigned U_CHAR * p;
 p = font_tbl[cur_fnt].str[chr-1];
 if( gif_ch )  print_f( (char *) p );   /*new*/
 else while( *p ){
   switch( *p ){
     case ’<’:  { while( *p && (*p != ’>’) )  p++;  break; }
     case ’>’:
     case ’"’:  { p++;  break; }
    case ’\’’:  { p++;  break; }
     default:   { put_char( (int) *p  ) ; p++; }
 } }
 -_-_-

<..vars..>+
 static BOOL gif_ch = TRUE;
 static int design_ch = 0;
 -_-_-

11.5 Css Trace on Characters

\Configure{characters}{<SPAN\:newlnch NAME="}{">}{</SPAN>} {<IMG SRC="}{"ALT="}{"NAME="}{">}

<..css for characters..>
         int n, code;
         U_CHAR *p, *q;
 code = get_char();
 n = 1 + ((--special_n>254)? 254 : special_n);
 q = p = m_alloc(char, (int) n);
 while( special_n > 254 ){ (void) get_char(); special_n--; }
 while( special_n-- ) { *(q++) = get_char(); }
 *q = ’\0’;  q = p;
 switch ( code ){
   case ’8’: {  pause_style--; break; }
   case ’9’: {  pause_style++;  break; }
   case ’-’: {  default_font = font_tbl[cur_fnt].num;
                base_font_size = font_tbl[cur_fnt].scale / 100;
                break; }
   case ’+’: {  default_font = -1;                    break; }
   case ’%’: { <.insert font size.>  break; }
   case ’=’: { <.insert css name of ch.>  break; }
   case ’|’: { <.record string for htf class.>  break; }
   case ’,’: { <.don’t report next htf class to lg.>  break; }
   default: { warn_i_int( 36, code); }
 }
 span_on = span_name_on && !pause_style;
 if( q ) free((void *)  q);
 -_-_-

Since htf fonts are shred within tex fonts, and since they can easily be modified by scripts in the output html files, changes of their classes from within the 4ht files is not supported.

By taking integer for ‘pause_style’ we allow for nested pausing of fonts.

<..vars..>+
 static int    pause_style = 0, default_font = -1, base_font_size=6533;
 static BOOL
   span_name_on = FALSE,
   span_on = FALSE;
 -_-_-

4: Src Prefix

<..record img-srcOUT..>
 q = img_src;  img_src = p;
 -_-_-

<..varsOUT..>
 static U_CHAR *  img_src;
 -_-_-

<..main’s initOUT..>
 img_src = m_alloc(char, (int) 12);
 (IGNORED) strcpy((char *) img_src, "<img \nsrc=\"" );
 -_-_-

<..<IMG SRC=".....>
 p= gif_open[gif_flag];
 if( p )
 if( *p ){
    print_f(p); (IGNORED) strcpy((char *) str, (char *) font_tbl[cur_fnt].name);
    mag = (int) ((double) font_tbl[cur_fnt].scale /
                 font_tbl[cur_fnt].design_sz  * 10 );
    <.insert gif symbol to html file.>
    print_f(str);
    add_bit( font_tbl[cur_fnt].gif_on, r_ch, 1 );
 }
 -_-_-

5: Alt Prefix

<..record img-altOUT..>
 q = img_alt;  img_alt = p;
 -_-_-

<..varsOUT..>+
 static U_CHAR *  img_alt;
 -_-_-

<..main’s initOUT..>+
 img_alt = m_alloc(char, (int) 7);
 (IGNORED) strcpy((char *) img_alt, "\"alt=\"" );
 -_-_-

<....."ALT=".....>
 p = gif_alt[gif_flag];
 if( p )
   if( *p ){
      print_f(p);  put_alt_ch(chr,ch_str_flag);
 }
 -_-_-

6: Img-CLASS Prefix

<....."CLASS="family.....>
 p = gif_class[gif_flag];
 if( p )
   if( *p ){
     (IGNORED) fprintf(cur_o_file, p,
                    font_tbl[cur_fnt].family_name);  }
 -_-_-

s: Img-CLASS Size

<.....gif font size.....>
 p = gif_size[gif_flag];
 if( p )
   if( *p ){
      (IGNORED) fprintf(cur_o_file, p,
                    font_tbl[cur_fnt].font_size);  }
 -_-_-

m: Img-CLASS Magnitude

<.....gif font mag.....>
 p = gif_mag[gif_flag];
 if( p )
   if( *p && (font_tbl[cur_fnt].mag != 100) ){
      (IGNORED) fprintf(cur_o_file, p, font_tbl[cur_fnt].mag);
 }
 -_-_-

o: Img-CLASS Ord

<.....gif sym ord.....>
 p = gif_ord[gif_flag];
 if( p )
   if( *p ){
     (IGNORED) fprintf(cur_o_file, p, ch);
 }
 -_-_-

7: End Image

<....."/IMG>..>
 p = gif_end[gif_flag];
 if( p )
   if( *p ){ print_f( p ); }
 -_-_-

Htf-based Classes

<..record string for htf class..>
 {                 int bad_str, m;
                   U_CHAR ch, *t[<.n spans.>], err_str[256];
 bad_str=<.n spans-1.>;   (IGNORED) strcpy((char *) err_str, (char *) p);
 if( n><.n spans+2.> ){
    m = 100*( *p-’0’ ) + 10*( *(p+1)-’0’ )+ *(p+2)-’0’;
    if( (m>-1) && (m<256) ){
       ch = *(p + 3);  t[0]=p;
       while( (*p = *(p+4)) != ’\0’ ){
         if( ch == *p ){ *p = ’\0’;
           if( bad_str-- > 0 ) t[<.n spans-1.> - bad_str] = p+1;
         }
         p++;
    }  }
    if( !bad_str ){
       if( m==0 ){ span_name_on = n><.n spans+3.>; }
       q = span_open[m];     span_open[m] = t[0];
       span_name[m] = t[1];  span_size[m] = t[2];
       span_mag[m]  = t[3];  span_ord[m]  = t[4];
       span_ch[m]   = t[5];  end_span[m]  = t[6];
       gif_id[m]   = t[7];
       if( not_notify ) {
         store_bit_I( class_on, m );
         not_notify = FALSE;
       } else   store_bit_Z( class_on, m );
    }
 }
 if( bad_str ){  warn_i_str(37,err_str); }
 }
 -_-_-

<..don’t report next htf class to lg..>
 not_notify = TRUE;
 -_-_-

<..vars..>+
 static BOOL not_notify = FALSE;
 -_-_-

<..n spans..>
 8-_-_-

<..n spans-1..>
 7-_-_-

<..n spans+2..>
 10-_-_-

<..n spans+3..>
 11-_-_-

<..vars..>+
 static U_CHAR * span_name[256], * span_open[256], * span_size[256],
      * span_mag[256],  * span_ch[256],   * end_span[256],
      * span_ord[256],  * gif_id[256];
 static U_CHAR class_on[32];
 -_-_-

<..main’s init..>+
 {   int i;  i=256; while( i-- ) {
      span_name[i] = span_open[i] = span_size[i] =
      span_mag[i]  = span_ch[i]   = end_span[i]  =
      span_ord[i]  = gif_id[i] = NULL;
        if( (i>0) && !(i%2) ) {  store_bit_Z( class_on, i ); }
        else {   store_bit_I( class_on, i ); }
     }
 }
 -_-_-

<..defines..>+
 #define gif_open  span_open
 #define gif_alt   span_name
 #define gif_class span_size
 #define gif_size  span_mag
 #define gif_mag   span_ord
 #define gif_ord   span_ch
 #define gif_end   end_span
 -_-_-

0’: character without decoration; ‘1’ gif without decoration. Even numbers (‘...0’) are reserved for ch with decoration, and odd numbers (‘...1’) are for gifs with decoration.

A character template takes the form: +open + family-format + size-format + mag-format + ord + close +after-font-info; The delimiter can be +, or any other character.

<..put char(chr)..>
 <.open output file.>
 <.ensure for chr.>
 if( span_on ){
    <.open for chr.>
    <.font-family of chr.>
    <.font-size of chr.>
    <.font-mag of chr.>
    <.ord of chr.>
    <.close for chr.>
 }
 put_char(chr);
 if( span_on ){
    <.end for chr.>
 }
 -_-_-

<..put string-char(chr)..>
 <.ensure for chr.>
 if( span_on ){
    <.open for chr.>
    <.font-family of chr.>
    <.font-size of chr.>
    <.font-mag of chr.>
    <.ord of chr.>
    <.close for chr.>
 }
 put_alt_ch(chr,ch_str_flag);
 if( span_on ){
    <.end for chr.>
 }
 -_-_-

<..ensure for chr..>
 if( gif_flag && !get_bit( class_on, gif_flag ) ) {
   notify_class_info(gif_flag);
   store_bit_I( class_on, gif_flag );
 }
 -_-_-

<..open for chr..>
 if( span_open[gif_flag] )
   if( *span_open[gif_flag] ){
      print_f( span_open[gif_flag] );
 }
 -_-_-

<..end for chr..>
 if( end_span[gif_flag] )
   if( *end_span[gif_flag] ){
      print_f( end_span[gif_flag] );
 }
 -_-_-

<..close for chr..>
 if( span_ch[gif_flag] )
   if( *span_ch[gif_flag] ){
     print_f( span_ch[gif_flag] );
 }
 -_-_-

<..font-family of chr..>
 if( span_name[gif_flag] )
   if( *span_name[gif_flag] ){
     (IGNORED) fprintf(cur_o_file, span_name[gif_flag],
                         font_tbl[cur_fnt].family_name);
 }
 -_-_-

<..font-size of chr..>
 if( span_size[gif_flag] )
   if( *span_size[gif_flag] ){
     (IGNORED) fprintf(cur_o_file, span_size[gif_flag],
                         font_tbl[cur_fnt].font_size);
 }
 -_-_-

<..font-mag of chr..>
 if( span_mag[gif_flag] )
   if( *span_mag[gif_flag] ){
     (IGNORED) fprintf(cur_o_file, span_mag[gif_flag],
                         font_tbl[cur_fnt].mag);
 }
 -_-_-

<..ord of chr..>
 if( span_ord[gif_flag] )
   if( *span_ord[gif_flag] ){
     (IGNORED) fprintf(cur_o_file, span_ord[gif_flag], chr);
 }
 -_-_-

Font Properties

<..insert font size..>
    int f;
 f = 0; while( *p ){ f = 10*f + *(p++) - ’0’; }
 <.open output file.>
 (IGNORED) fprintf(cur_o_file, "%d",
   (font_tbl[cur_fnt].scale / base_font_size - 100) * f / 100 +100
    );
 -_-_-

<..insert css name of ch..>
 <.open output file.>
 (IGNORED) fprintf(cur_o_file, "%s", font_tbl[cur_fnt].name);
 if( font_tbl[cur_fnt].mag != 100 ){
    (IGNORED) fprintf(cur_o_file,"_%d", font_tbl[cur_fnt].mag);
 }
 -_-_-