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

Diff for /mandoc/html.c between version 1.256 and 1.264

version 1.256, 2019/08/02 17:06:04 version 1.264, 2020/03/13 15:32:28
Line 1 
Line 1 
 /*      $Id$ */  /* $Id$ */
 /*  /*
    * Copyright (c) 2011-2015, 2017-2020 Ingo Schwarze <schwarze@openbsd.org>
  * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2011-2015, 2017-2019 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 14 
  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  * 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.
    *
    * Common functions for mandoc(1) HTML formatters.
    * For use by individual formatters and by the main program.
  */   */
 #include "config.h"  #include "config.h"
   
Line 42 
Line 45 
 struct  htmldata {  struct  htmldata {
         const char       *name;          const char       *name;
         int               flags;          int               flags;
 #define HTML_NOSTACK     (1 << 0)  #define HTML_INPHRASE    (1 << 0)  /* Can appear in phrasing context. */
 #define HTML_AUTOCLOSE   (1 << 1)  #define HTML_TOPHRASE    (1 << 1)  /* Establishes phrasing context. */
 #define HTML_NLBEFORE    (1 << 2)  #define HTML_NOSTACK     (1 << 2)  /* Does not have an end tag. */
 #define HTML_NLBEGIN     (1 << 3)  #define HTML_NLBEFORE    (1 << 3)  /* Output line break before opening. */
 #define HTML_NLEND       (1 << 4)  #define HTML_NLBEGIN     (1 << 4)  /* Output line break after opening. */
 #define HTML_NLAFTER     (1 << 5)  #define HTML_NLEND       (1 << 5)  /* Output line break before closing. */
   #define HTML_NLAFTER     (1 << 6)  /* Output line break after closing. */
 #define HTML_NLAROUND    (HTML_NLBEFORE | HTML_NLAFTER)  #define HTML_NLAROUND    (HTML_NLBEFORE | HTML_NLAFTER)
 #define HTML_NLINSIDE    (HTML_NLBEGIN | HTML_NLEND)  #define HTML_NLINSIDE    (HTML_NLBEGIN | HTML_NLEND)
 #define HTML_NLALL       (HTML_NLAROUND | HTML_NLINSIDE)  #define HTML_NLALL       (HTML_NLAROUND | HTML_NLINSIDE)
 #define HTML_INDENT      (1 << 6)  #define HTML_INDENT      (1 << 7)  /* Indent content by two spaces. */
 #define HTML_NOINDENT    (1 << 7)  #define HTML_NOINDENT    (1 << 8)  /* Exception: never indent content. */
 };  };
   
 static  const struct htmldata htmltags[TAG_MAX] = {  static  const struct htmldata htmltags[TAG_MAX] = {
         {"html",        HTML_NLALL},          {"html",        HTML_NLALL},
         {"head",        HTML_NLALL | HTML_INDENT},          {"head",        HTML_NLALL | HTML_INDENT},
         {"body",        HTML_NLALL},          {"meta",        HTML_NOSTACK | HTML_NLALL},
         {"meta",        HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL},          {"link",        HTML_NOSTACK | HTML_NLALL},
           {"style",       HTML_NLALL | HTML_INDENT},
         {"title",       HTML_NLAROUND},          {"title",       HTML_NLAROUND},
           {"body",        HTML_NLALL},
         {"div",         HTML_NLAROUND},          {"div",         HTML_NLAROUND},
         {"div",         0},  
         {"section",     HTML_NLALL},          {"section",     HTML_NLALL},
         {"h1",          HTML_NLAROUND},  
         {"h2",          HTML_NLAROUND},  
         {"span",        0},  
         {"link",        HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL},  
         {"br",          HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL},  
         {"a",           0},  
         {"table",       HTML_NLALL | HTML_INDENT},          {"table",       HTML_NLALL | HTML_INDENT},
         {"tr",          HTML_NLALL | HTML_INDENT},          {"tr",          HTML_NLALL | HTML_INDENT},
         {"td",          HTML_NLAROUND},          {"td",          HTML_NLAROUND},
Line 79  static const struct htmldata htmltags[TAG_MAX] = {
Line 78  static const struct htmldata htmltags[TAG_MAX] = {
         {"dl",          HTML_NLALL | HTML_INDENT},          {"dl",          HTML_NLALL | HTML_INDENT},
         {"dt",          HTML_NLAROUND},          {"dt",          HTML_NLAROUND},
         {"dd",          HTML_NLAROUND | HTML_INDENT},          {"dd",          HTML_NLAROUND | HTML_INDENT},
         {"p",           HTML_NLAROUND | HTML_INDENT},          {"h1",          HTML_TOPHRASE | HTML_NLAROUND},
         {"pre",         HTML_NLALL | HTML_NOINDENT},          {"h2",          HTML_TOPHRASE | HTML_NLAROUND},
         {"var",         0},          {"p",           HTML_TOPHRASE | HTML_NLAROUND | HTML_INDENT},
         {"cite",        0},          {"pre",         HTML_TOPHRASE | HTML_NLALL | HTML_NOINDENT},
         {"b",           0},          {"a",           HTML_INPHRASE | HTML_TOPHRASE},
         {"i",           0},          {"b",           HTML_INPHRASE | HTML_TOPHRASE},
         {"code",        0},          {"cite",        HTML_INPHRASE | HTML_TOPHRASE},
         {"small",       0},          {"code",        HTML_INPHRASE | HTML_TOPHRASE},
         {"style",       HTML_NLALL | HTML_INDENT},          {"i",           HTML_INPHRASE | HTML_TOPHRASE},
         {"math",        HTML_NLALL | HTML_INDENT},          {"small",       HTML_INPHRASE | HTML_TOPHRASE},
           {"span",        HTML_INPHRASE | HTML_TOPHRASE},
           {"var",         HTML_INPHRASE | HTML_TOPHRASE},
           {"br",          HTML_INPHRASE | HTML_NOSTACK | HTML_NLALL},
           {"mark",        HTML_INPHRASE },
           {"math",        HTML_INPHRASE | HTML_NLALL | HTML_INDENT},
         {"mrow",        0},          {"mrow",        0},
         {"mi",          0},          {"mi",          0},
         {"mn",          0},          {"mn",          0},
Line 271  print_metaf(struct html *h)
Line 275  print_metaf(struct html *h)
 void  void
 html_close_paragraph(struct html *h)  html_close_paragraph(struct html *h)
 {  {
         struct tag      *t;          struct tag      *this, *next;
           int              flags;
   
         for (t = h->tag; t != NULL && t->closed == 0; t = t->next) {          this = h->tag;
                 switch(t->tag) {          for (;;) {
                 case TAG_P:                  next = this->next;
                 case TAG_PRE:                  flags = htmltags[this->tag].flags;
                         print_tagq(h, t);                  if (flags & (HTML_INPHRASE | HTML_TOPHRASE))
                           print_ctag(h, this);
                   if ((flags & HTML_INPHRASE) == 0)
                         break;                          break;
                 case TAG_A:                  this = next;
                         print_tagq(h, t);  
                         continue;  
                 default:  
                         continue;  
                 }  
                 break;  
         }          }
 }  }
   
Line 323  html_fillmode(struct html *h, enum roff_tok want)
Line 324  html_fillmode(struct html *h, enum roff_tok want)
         return had;          return had;
 }  }
   
   /*
    * Allocate a string to be used for the "id=" attribute of an HTML
    * element and/or as a segment identifier for a URI in an <a> element.
    * The function may fail and return NULL if the node lacks text data
    * to create the attribute from.
    * If the "unique" argument is 0, the caller is responsible for
    * free(3)ing the returned string after using it.
    * If the "unique" argument is non-zero, the "id_unique" ohash table
    * is used for de-duplication and owns the returned string, so the
    * caller must not free(3) it.  In this case, it will be freed
    * automatically by html_reset() or html_free().
    */
 char *  char *
 html_make_id(const struct roff_node *n, int unique)  html_make_id(const struct roff_node *n, int unique)
 {  {
Line 331  html_make_id(const struct roff_node *n, int unique)
Line 344  html_make_id(const struct roff_node *n, int unique)
         unsigned int             slot;          unsigned int             slot;
         int                      suffix;          int                      suffix;
   
         for (nch = n->child; nch != NULL; nch = nch->next)          if (n->string != NULL)
                 if (nch->type != ROFFT_TEXT)                  buf = mandoc_strdup(n->string);
                         return NULL;          else {
                   switch (n->tok) {
                   case MDOC_Sh:
                   case MDOC_Ss:
                   case MDOC_Sx:
                   case MAN_SH:
                   case MAN_SS:
                           for (nch = n->child; nch != NULL; nch = nch->next)
                                   if (nch->type != ROFFT_TEXT)
                                           return NULL;
                           buf = NULL;
                           deroff(&buf, n);
                           if (buf == NULL)
                                   return NULL;
                           break;
                   default:
                           if (n->child->type != ROFFT_TEXT)
                                   return NULL;
                           buf = mandoc_strdup(n->child->string);
                           break;
                   }
           }
   
         buf = NULL;  
         deroff(&buf, n);  
         if (buf == NULL)  
                 return NULL;  
   
         /*          /*
          * In ID attributes, only use ASCII characters that are           * In ID attributes, only use ASCII characters that are
          * permitted in URL-fragment strings according to the           * permitted in URL-fragment strings according to the
Line 584  print_otag(struct html *h, enum htmltag tag, const cha
Line 613  print_otag(struct html *h, enum htmltag tag, const cha
   
         tflags = htmltags[tag].flags;          tflags = htmltags[tag].flags;
   
           /* Flow content is not allowed in phrasing context. */
   
           if ((tflags & HTML_INPHRASE) == 0) {
                   for (t = h->tag; t != NULL; t = t->next) {
                           if (t->closed)
                                   continue;
                           assert((htmltags[t->tag].flags & HTML_TOPHRASE) == 0);
                           break;
                   }
   
           /*
            * Always wrap phrasing elements in a paragraph
            * unless already contained in some flow container;
            * never put them directly into a section.
            */
   
           } else if (tflags & HTML_TOPHRASE && h->tag->tag == TAG_SECTION)
                   print_otag(h, TAG_P, "c", "Pp");
   
         /* Push this tag onto the stack of open scopes. */          /* Push this tag onto the stack of open scopes. */
   
         if ((tflags & HTML_NOSTACK) == 0) {          if ((tflags & HTML_NOSTACK) == 0) {
Line 701  print_otag(struct html *h, enum htmltag tag, const cha
Line 749  print_otag(struct html *h, enum htmltag tag, const cha
   
         /* Accommodate for "well-formed" singleton escaping. */          /* Accommodate for "well-formed" singleton escaping. */
   
         if (HTML_AUTOCLOSE & htmltags[tag].flags)          if (htmltags[tag].flags & HTML_NOSTACK)
                 print_byte(h, '/');                  print_byte(h, '/');
   
         print_byte(h, '>');          print_byte(h, '>');
Line 719  print_otag(struct html *h, enum htmltag tag, const cha
Line 767  print_otag(struct html *h, enum htmltag tag, const cha
         return t;          return t;
 }  }
   
   /*
    * Print an element with an optional "id=" attribute.
    * If there is an "id=" attribute, also add a permalink:
    * outside if it's a phrasing element, or inside otherwise.
    */
   struct tag *
   print_otag_id(struct html *h, enum htmltag elemtype, const char *cattr,
       struct roff_node *n)
   {
           struct tag      *ret, *t;
           const char      *id;
   
           ret = NULL;
           id = NULL;
           if (n->flags & NODE_ID)
                   id = html_make_id(n, 1);
           if (id != NULL && htmltags[elemtype].flags & HTML_INPHRASE)
                   ret = print_otag(h, TAG_A, "chR", "permalink", id);
           t = print_otag(h, elemtype, "ci", cattr, id);
           if (ret == NULL) {
                   ret = t;
                   if (id != NULL)
                           print_otag(h, TAG_A, "chR", "permalink", id);
           }
           return ret;
   }
   
 static void  static void
 print_ctag(struct html *h, struct tag *tag)  print_ctag(struct html *h, struct tag *tag)
 {  {
Line 788  print_gen_comment(struct html *h, struct roff_node *n)
Line 863  print_gen_comment(struct html *h, struct roff_node *n)
 void  void
 print_text(struct html *h, const char *word)  print_text(struct html *h, const char *word)
 {  {
           /*
            * Always wrap text in a paragraph unless already contained in
            * some flow container; never put it directly into a section.
            */
   
           if (h->tag->tag == TAG_SECTION)
                   print_otag(h, TAG_P, "c", "Pp");
   
           /* Output whitespace before this text? */
   
         if (h->col && (h->flags & HTML_NOSPACE) == 0) {          if (h->col && (h->flags & HTML_NOSPACE) == 0) {
                 if ( ! (HTML_KEEP & h->flags)) {                  if ( ! (HTML_KEEP & h->flags)) {
                         if (HTML_PREKEEP & h->flags)                          if (HTML_PREKEEP & h->flags)
Line 797  print_text(struct html *h, const char *word)
Line 882  print_text(struct html *h, const char *word)
                         print_word(h, "&#x00A0;");                          print_word(h, "&#x00A0;");
         }          }
   
           /*
            * Print the text, optionally surrounded by HTML whitespace,
            * optionally manually switching fonts before and after.
            */
   
         assert(h->metaf == NULL);          assert(h->metaf == NULL);
         print_metaf(h);          print_metaf(h);
         print_indent(h);          print_indent(h);
Line 937  print_indent(struct html *h)
Line 1027  print_indent(struct html *h)
 {  {
         size_t   i;          size_t   i;
   
         if (h->col)          if (h->col || h->noindent)
                 return;                  return;
   
         if (h->noindent == 0) {          h->col = h->indent * 2;
                 h->col = h->indent * 2;          for (i = 0; i < h->col; i++)
                 for (i = 0; i < h->col; i++)                  putchar(' ');
                         putchar(' ');  
         }  
         h->flags &= ~HTML_NOSPACE;  
 }  }
   
 /*  /*

Legend:
Removed from v.1.256  
changed lines
  Added in v.1.264

CVSweb