[BACK]Return to eqn_html.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Diff for /mandoc/eqn_html.c between version 1.3 and 1.19

version 1.3, 2014/04/20 16:46:04 version 1.19, 2019/03/17 18:21:45
Line 1 
Line 1 
 /*      $Id$ */  /*      $Id$ */
 /*  /*
  * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
    * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 14 
Line 15 
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */   */
 #ifdef HAVE_CONFIG_H  
 #include "config.h"  #include "config.h"
 #endif  
   
   #include <sys/types.h>
   
 #include <assert.h>  #include <assert.h>
   #include <ctype.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
   
 #include "mandoc.h"  #include "mandoc.h"
   #include "roff.h"
   #include "eqn.h"
 #include "out.h"  #include "out.h"
 #include "html.h"  #include "html.h"
   
 static  const enum htmltag fontmap[EQNFONT__MAX] = {  static void
         TAG_SPAN, /* EQNFONT_NONE */  eqn_box(struct html *p, const struct eqn_box *bp)
         TAG_SPAN, /* EQNFONT_ROMAN */  {
         TAG_B, /* EQNFONT_BOLD */          struct tag      *post, *row, *cell, *t;
         TAG_B, /* EQNFONT_FAT */          const struct eqn_box *child, *parent;
         TAG_I /* EQNFONT_ITALIC */          const char      *cp;
 };          size_t           i, j, rows;
           enum htmltag     tag;
           enum eqn_fontt   font;
   
 static void     eqn_box(struct html *, const struct eqn_box *);          if (NULL == bp)
                   return;
   
           post = NULL;
   
 void          /*
 print_eqn(struct html *p, const struct eqn *ep)           * Special handling for a matrix, which is presented to us in
 {           * column order, but must be printed in row-order.
         struct htmlpair  tag;           */
         struct tag      *t;          if (EQN_MATRIX == bp->type) {
                   if (NULL == bp->first)
                           goto out;
                   if (bp->first->type != EQN_LIST ||
                       bp->first->expectargs == 1) {
                           eqn_box(p, bp->first);
                           goto out;
                   }
                   if (NULL == (parent = bp->first->first))
                           goto out;
                   /* Estimate the number of rows, first. */
                   if (NULL == (child = parent->first))
                           goto out;
                   for (rows = 0; NULL != child; rows++)
                           child = child->next;
                   /* Print row-by-row. */
                   post = print_otag(p, TAG_MTABLE, "");
                   for (i = 0; i < rows; i++) {
                           parent = bp->first->first;
                           row = print_otag(p, TAG_MTR, "");
                           while (NULL != parent) {
                                   child = parent->first;
                                   for (j = 0; j < i; j++) {
                                           if (NULL == child)
                                                   break;
                                           child = child->next;
                                   }
                                   cell = print_otag(p, TAG_MTD, "");
                                   /*
                                    * If we have no data for this
                                    * particular cell, then print a
                                    * placeholder and continue--don't puke.
                                    */
                                   if (NULL != child)
                                           eqn_box(p, child->first);
                                   print_tagq(p, cell);
                                   parent = parent->next;
                           }
                           print_tagq(p, row);
                   }
                   goto out;
           }
   
         PAIR_CLASS_INIT(&tag, "eqn");          switch (bp->pos) {
         t = print_otag(p, TAG_SPAN, 1, &tag);          case EQNPOS_TO:
                   post = print_otag(p, TAG_MOVER, "");
                   break;
           case EQNPOS_SUP:
                   post = print_otag(p, TAG_MSUP, "");
                   break;
           case EQNPOS_FROM:
                   post = print_otag(p, TAG_MUNDER, "");
                   break;
           case EQNPOS_SUB:
                   post = print_otag(p, TAG_MSUB, "");
                   break;
           case EQNPOS_OVER:
                   post = print_otag(p, TAG_MFRAC, "");
                   break;
           case EQNPOS_FROMTO:
                   post = print_otag(p, TAG_MUNDEROVER, "");
                   break;
           case EQNPOS_SUBSUP:
                   post = print_otag(p, TAG_MSUBSUP, "");
                   break;
           case EQNPOS_SQRT:
                   post = print_otag(p, TAG_MSQRT, "");
                   break;
           default:
                   break;
           }
   
         p->flags |= HTML_NONOSPACE;          if (bp->top || bp->bottom) {
         eqn_box(p, ep->root);                  assert(NULL == post);
         p->flags &= ~HTML_NONOSPACE;                  if (bp->top && NULL == bp->bottom)
                           post = print_otag(p, TAG_MOVER, "");
                   else if (bp->top && bp->bottom)
                           post = print_otag(p, TAG_MUNDEROVER, "");
                   else if (bp->bottom)
                           post = print_otag(p, TAG_MUNDER, "");
           }
   
         print_tagq(p, t);          if (EQN_PILE == bp->type) {
                   assert(NULL == post);
                   if (bp->first != NULL &&
                       bp->first->type == EQN_LIST &&
                       bp->first->expectargs > 1)
                           post = print_otag(p, TAG_MTABLE, "");
           } else if (bp->type == EQN_LIST && bp->expectargs > 1 &&
               bp->parent && bp->parent->type == EQN_PILE) {
                   assert(NULL == post);
                   post = print_otag(p, TAG_MTR, "");
                   print_otag(p, TAG_MTD, "");
           }
   
           if (bp->text != NULL) {
                   assert(post == NULL);
                   tag = TAG_MI;
                   cp = bp->text;
                   if (isdigit((unsigned char)cp[0]) ||
                       (cp[0] == '.' && isdigit((unsigned char)cp[1]))) {
                           tag = TAG_MN;
                           while (*++cp != '\0') {
                                   if (*cp != '.' &&
                                       isdigit((unsigned char)*cp) == 0) {
                                           tag = TAG_MI;
                                           break;
                                   }
                           }
                   } else if (*cp != '\0' && isalpha((unsigned char)*cp) == 0) {
                           tag = TAG_MO;
                           while (*cp != '\0') {
                                   if (cp[0] == '\\' && cp[1] != '\0') {
                                           cp++;
                                           mandoc_escape(&cp, NULL, NULL);
                                   } else if (isalnum((unsigned char)*cp)) {
                                           tag = TAG_MI;
                                           break;
                                   } else
                                           cp++;
                           }
                   }
                   font = bp->font;
                   if (bp->text[0] != '\0' &&
                       (((tag == TAG_MN || tag == TAG_MO) &&
                         font == EQNFONT_ROMAN) ||
                        (tag == TAG_MI && font == (bp->text[1] == '\0' ?
                         EQNFONT_ITALIC : EQNFONT_ROMAN))))
                           font = EQNFONT_NONE;
                   switch (font) {
                   case EQNFONT_NONE:
                           post = print_otag(p, tag, "");
                           break;
                   case EQNFONT_ROMAN:
                           post = print_otag(p, tag, "?", "fontstyle", "normal");
                           break;
                   case EQNFONT_BOLD:
                   case EQNFONT_FAT:
                           post = print_otag(p, tag, "?", "fontweight", "bold");
                           break;
                   case EQNFONT_ITALIC:
                           post = print_otag(p, tag, "?", "fontstyle", "italic");
                           break;
                   default:
                           abort();
                   }
                   print_text(p, bp->text);
           } else if (NULL == post) {
                   if (NULL != bp->left || NULL != bp->right)
                           post = print_otag(p, TAG_MFENCED, "??",
                               "open", bp->left == NULL ? "" : bp->left,
                               "close", bp->right == NULL ? "" : bp->right);
                   if (NULL == post)
                           post = print_otag(p, TAG_MROW, "");
                   else
                           print_otag(p, TAG_MROW, "");
           }
   
           eqn_box(p, bp->first);
   
   out:
           if (NULL != bp->bottom) {
                   t = print_otag(p, TAG_MO, "");
                   print_text(p, bp->bottom);
                   print_tagq(p, t);
           }
           if (NULL != bp->top) {
                   t = print_otag(p, TAG_MO, "");
                   print_text(p, bp->top);
                   print_tagq(p, t);
           }
   
           if (NULL != post)
                   print_tagq(p, post);
   
           eqn_box(p, bp->next);
 }  }
   
 static void  void
 eqn_box(struct html *p, const struct eqn_box *bp)  print_eqn(struct html *p, const struct eqn_box *bp)
 {  {
         struct tag      *t;          struct tag      *t;
   
         t = EQNFONT_NONE == bp->font ? NULL :          if (bp->first == NULL)
             print_otag(p, fontmap[(int)bp->font], 0, NULL);                  return;
   
         if (bp->left)          t = print_otag(p, TAG_MATH, "c", "eqn");
                 print_text(p, bp->left);  
   
         if (bp->text)          p->flags |= HTML_NONOSPACE;
                 print_text(p, bp->text);          eqn_box(p, bp);
           p->flags &= ~HTML_NONOSPACE;
   
         if (bp->first)          print_tagq(p, t);
                 eqn_box(p, bp->first);  
   
         if (NULL != t)  
                 print_tagq(p, t);  
         if (bp->right)  
                 print_text(p, bp->right);  
   
         if (bp->next)  
                 eqn_box(p, bp->next);  
 }  }

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.19

CVSweb