Chapter 13
Accents

   13.1 Htf Font Info
   13.2 Integrated accents
   13.3 Remote Accents
      Open Accent
      Closure for Text Accent
      Tailoring
      Mark Accented Content

13.1 Htf Font Info

Each htf font has between 2 to 4 fields per entry. The first field is the textual representation, the second is the textual and pictorial flags and decorations, the third is an the accent code, and the fourth is a pointer into an accented code table (tex4ht.htf).

font.htf:

’text-rep’  ’text/pic-deco’  ’accent-code’  ’pointer to tex4ht.htf’ 

The accent code uses universaly agreed upon codes for accent symbols. For instance, 18 for \‘, and 94 for \^. 0 signify no pointer.

The accented code uses universaly agreed upon codes for accented symbols. We assume a unicode code-based system, but deviate from it when it is convinient.

tex4ht.c makes move the third and fourt entries of each font into arrays, and puts into the entries index-pointers to the array. By doing so, we can allocate just one byte to an entry.

|--------------|                 |---|  |---|  |---  |---|
|--  --  -- -- |         ----    --Aˆ   --ˆAˆ  |----  ----
|--  -- ||| ||||         |---  |-|||  |||-|  |||-  |-|||
|--  --  -||--||     |-||-A---|--ˆ--||-ˆˆ--||-----|----
|--  --  --||- ||    |   |---
|--  --  -- || ||||  |   ----
|--  --  -- -|||  || |
|--  --  -- -- ||  |-|-|---|--|---|
|--  --  -- -- ||| ---------------
|--  --  -- -- | ||
|--  --  -- -- |   ||
|              |   |---|---|--|---|
|---------------

The accented code matrix tex4ht.htf is the closest file to the font on the directory path from the root. Different paths may employ a different tex4ht.htf accent tables. An (accent-code,accented-code) pair maps to accented-code in the table, or the maping is undefined. Each accented-code in the matrix hold textual representation.

<..entries for html chars in font-tbl..>+
 unsigned U_CHAR *accent, *accented;
 unsigned int *accent_array, *accented_array, accent_N, accented_N;
 -_-_-

<..initiate htf accents..>
 new_font.accent = m_alloc(unsigned char, n_gif );
 new_font.accented = m_alloc(unsigned char, n_gif );
 new_font.accent_array = (unsigned int *) 0;
 new_font.accented_array = (unsigned int *) 0;
 new_font.accent_N = new_font.accented_N = 0;
 for( i=n_gif; i--; ) {
    new_font.accent[i] = new_font.accented[i] = 0;
 }
 -_-_-

<..scan htf accent..>
 ch1 = 0;
 while( ((ch = (int) get_html_ch(file)) != del) ){
      if( (ch < ’0’) || (ch > ’9’) ){ warn_i_int(48,i);  break; }
      ch1 = ch1 * 10 + ch - ’0’; }
 new_font.accent_array = new_font.accent_N++?
       (unsigned int *) r_alloc((void *) new_font.accent_array,
                  (size_t) (new_font.accent_N * sizeof(unsigned int)))
             :  m_alloc(unsigned int, 1);
 new_font.accent_array[new_font.accent_N - 1] = ch1;
 new_font.accent[i] = new_font.accent_N;
 -_-_-

<..scan htf accented..>
 ch1 = 0;
 while( ((ch = (int) get_html_ch(file)) != del) ){
      if( (ch < ’0’) || (ch > ’9’) ){ warn_i_int(48,i);  break; }
      ch1 = ch1 * 10 + ch - ’0’; }
 new_font.accented_array = new_font.accented_N++?
       (unsigned int *) r_alloc((void *) new_font.accented_array,
                  (size_t) (new_font.accented_N * sizeof(unsigned int)))
             :  m_alloc(unsigned int, 1);
 new_font.accented_array[new_font.accented_N - 1] = ch1;
 new_font.accented[i] = new_font.accented_N;
 -_-_-

13.2 Integrated accents

13.3 Remote Accents

If the accent character is for text (\accent), we’ll be looking for the next character to be the accented character. If the accent character is for math (\mathaccent), we’ll be looking for the next group of characters (i.e., subformula) to be the accented. If the subformula consists of a single character, we probably should assume an accented character instead of an accented subformula.

Open Accent

<..accent specials..>
 special_n--;
 switch ( get_char() ){
   case ’t’: { if( special_n ){
                 <.text accent template.>
               } else { <.text accent.> }
               break;
             }
   case ’m’: { if( special_n ){
                 <.math accent template.>
               } else { <.math accent.> }
               break;
             }
   case ’a’: { <.accented template.>
               break;
             }
   case ’i’: { <.accenting template.>
               break;
             }
    default: { <.consume unused specials.> }
 }
 -_-_-

A accent is a character from a given font. Given a content to be accented, the text/math accent marks it ‘#1 font #2 char-no #3 content #4’ according to the accent/mathaccent template. Each character in the content is marked by ‘#1 font #2 char-no #3 character #4’ according to the accented template.

Text accent can be on empty content or on character, and the accent itself is empty if it consists of a character code greater than 127. Math accent is placed on the center of a formula.

<..text accent..>
 needs_accent_sym = TRUE * 2;
 -_-_-

<..math accent..>
 needs_accent_sym = TRUE;
 -_-_-

<..accented = true..>
 needs_accented_sym++;
 -_-_-

The \special tells tex4ht where the accent starts, and tex4ht consumes the following character for a accent. At that place, tex4ht also place the opening tag of the element.

<..pre accent symbol..>
 if( in_accenting ){
   <.post accent symbol.>
 } else if( <.is accent char?.> ){
   if( needs_accent_sym ){
                                         BOOL needs_end_accent;
     needs_end_accent = (needs_accent_sym == 2 * TRUE);
     if( needs_end_accent && t_accent_template ){
       (IGNORED) fprintf(cur_o_file, "%s%s%s%d%s%d%s",
          t_accent_first,   font_tbl[cur_fnt].family_name,
          t_accent_second, ch, t_accent_third,
          font_tbl[cur_fnt].accent[ch]?
            font_tbl[cur_fnt].accent_array[font_tbl[cur_fnt].accent[ch]-1]
            : 0,
          t_accent_fourth);
     } else if( m_accent_template ){
       (IGNORED) fprintf(cur_o_file, "%s%s%s%d%s%d%s",
          m_accent_first,   font_tbl[cur_fnt].family_name,
          m_accent_second, ch, m_accent_third,
          font_tbl[cur_fnt].accent[ch]?
            font_tbl[cur_fnt].accent_array[font_tbl[cur_fnt].accent[ch]-1]
            : 0,
          m_accent_fourth);
     }
     if( i_accent_template ){
       (IGNORED) fprintf(cur_o_file, "%s", i_accent_first); }
     in_accenting = TRUE;
   }
 }
 -_-_-

<..post accent symbol..>
                                                long int width;
 if( i_accent_template ){
   (IGNORED) fprintf(cur_o_file, "%s", i_accent_second); }
 needs_end_accent = (needs_accent_sym == 2 * TRUE);
 if( needs_end_accent && t_accent_template )
 {  <.accented = true.> }
 else if( m_accent_template )
 {  <.accented = true.>  stack[stack_n-1].accented = TRUE; }
 needs_accent_sym = FALSE;
 width = (INTEGER)( <.(double) char_width( ch ).> );
 if( needs_end_accent ){  needs_end_accent = x_val + 9 * width / 10; }
 in_accenting = FALSE;
 -_-_-

<..main’s vars..>+
 BOOL in_accenting;
 -_-_-

<..main’s init..>+
 in_accenting = FALSE;
 -_-_-

The following needs to be fixed for cases that ch is greater than 127.

<..is accent char?..>
 needs_accent_sym && (ch < 128)
 -_-_-

Closure for Text Accent

<..end text accent..>
 if( needs_end_accent && t_accent_template ){
    <.end accented span.>
    (IGNORED) fprintf(cur_o_file, "%s", t_accent_fifth);
    needs_end_accent = FALSE; <.exit text accented.>
 }
 -_-_-

The following in needed for cases of text-accents on empty content, immeddiately followed by a character (e.g., ‘\^{}Xx’).

<..set begin accents..>
 if( x_val > needs_end_accent ){
   <.end text accent.>
 }
 -_-_-

The following takes care of closing a text accent after a character.

<..set end accents..>
 <.end text accent.>
 -_-_-

Tailoring

before-family-name, between-family-char-number, after char-number

<..text accent template..>
 (IGNORED) get_open_accent(&t_accent_template,
             &t_accent_first, &t_accent_second,
             &t_accent_third, &t_accent_fourth,
             &t_accent_fifth, &special_n);
 -_-_-

<..math accent template..>
 (IGNORED) get_open_accent(&m_accent_template,
             &m_accent_first, &m_accent_second,
             &m_accent_third, &m_accent_fourth,
             &m_accent_fifth, &special_n);
 -_-_-

<..vars..>+
 static BOOL needs_accent_sym = FALSE,  needs_end_accent = FALSE;
 static char  * t_accent_template = (char *) 0,
              * t_accent_first, * t_accent_second,
              * t_accent_third, * t_accent_fourth, * t_accent_fifth,
              * m_accent_template = (char *) 0,
              * m_accent_first, * m_accent_second,
              * m_accent_third, * m_accent_fourth, * m_accent_fifth;
 -_-_-

<..header functions..>+
 static void get_open_accent(
     ARG_VII(char**, char**, char**, char**, char**, char**, long int*));
 -_-_-

<..functions..>+
 
 static void get_open_accent(all,first,second,third,fourth,fifth,n)
       char   **all;
       char   **first;
       char   **second;
       char   **third;
       char   **fourth;
       char   **fifth;
       long int    *n
 ;{                              char *p, *q;
                                 int i;
    if( *all  ){ free((void *) *all);  }
    *all = p = get_str( (int) *n );  *n=0;
    i = 2;
    *first = q = p + 1;
    while ( TRUE ){
      if( *q == *p ){
        *q = ’\0’;
        switch( i ){
          case 2:{  *second = q+1; break; }
          case 3:{  *third  = q+1; break; }
          case 4:{  *fourth = q+1; break; }
          case 5:{  *fifth = q+1; break; }
        }
        if( i++ == 5 ){ break; }
      } else if( !*q ){
        free((void *) *all);  *all = (char *) 0;    break;
      }
      q++;
 } }
 -_-_-

Mark Accented Content

<..mark accented ch..>
 if( a_accent_template && needs_accented_sym ){
   (IGNORED) fprintf(cur_o_file, "%s%s%s%d%s%d%s",
      a_accent_first,   font_tbl[cur_fnt].family_name,
      a_accent_second, ch, a_accent_third,
      font_tbl[cur_fnt].accented[ch]?
        font_tbl[cur_fnt].accented_array[font_tbl[cur_fnt].accented[ch]-1]
        : 0,
      a_accent_fourth);
 }
 -_-_-

<..end mark accented ch..>
 if( a_accent_template && needs_accented_sym ){
    (IGNORED) fprintf(cur_o_file, "%s", a_accent_fifth);
 }
 -_-_-

Accents can be embedde, for instance, ‘\hat{a\hat b}’. Hence, needs_accented_sym is treated as a number.

The math accented end at the end of the group, sent there by ‘\special{t4ht~>...}’ in the sty file.

<..exit math accented..>
 needs_accented_sym--;
 -_-_-

<..exit text accented..>
 needs_accented_sym--;
 -_-_-

<..accented template..>
 (IGNORED) get_open_accent(&a_accent_template,
             &a_accent_first, &a_accent_second,
             &a_accent_third, &a_accent_fourth,
             &a_accent_fifth, &special_n);
 -_-_-

<..vars..>+
 static BOOL  needs_accented_sym = 0;
 static char  * a_accent_template = (char *) 0,
              * a_accent_first, * a_accent_second,
              * a_accent_third, * a_accent_fourth, * a_accent_fifth;
 -_-_-

<..accenting template..>
 (IGNORED) get_open_accent(&i_accent_template,
             &i_accent_first, &i_accent_second,
             &i_accent_third, &i_accent_fourth,
             &i_accent_fifth, &special_n);
 -_-_-

<..vars..>+
 static char  * i_accent_template = (char *) 0,
              * i_accent_first, * i_accent_second,
              * i_accent_third, * i_accent_fourth, * i_accent_fifth;
 -_-_-

* i_accent_second, * i_accent_third, * i_accent_fourth;’ are dummy provided for consistency.

<..BOOl stack accented..>
 accented
 -_-_-

<..end math accented..>
 if( stack[stack_n].accented ){
    <.exit math accented.>
    stack[stack_n].accented=FALSE;
 }
 -_-_-

<..init end math accented..>
 stack[stack_n].accented  = FALSE;
 -_-_-