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

Diff for /mandoc/man_term.c between version 1.229 and 1.244

version 1.229, 2019/06/27 12:20:18 version 1.244, 2023/11/13 19:13:01
Line 1 
Line 1 
 /*      $Id$ */  /* $Id$ */
 /*  /*
    * Copyright (c) 2010-15,2017-20,2022-23 Ingo Schwarze <schwarze@openbsd.org>
  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>   * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-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.
    *
    * Plain text formatter for man(7), used by mandoc(1)
    * for ASCII, UTF-8, PostScript, and PDF output.
  */   */
 #include "config.h"  #include "config.h"
   
Line 27 
Line 30 
 #include <string.h>  #include <string.h>
   
 #include "mandoc_aux.h"  #include "mandoc_aux.h"
   #include "mandoc.h"
 #include "roff.h"  #include "roff.h"
 #include "man.h"  #include "man.h"
 #include "out.h"  #include "out.h"
 #include "term.h"  #include "term.h"
   #include "term_tag.h"
 #include "main.h"  #include "main.h"
   
 #define MAXMARGINS        64 /* maximum number of indented scopes */  #define MAXMARGINS        64 /* maximum number of indented scopes */
Line 62  static void    print_man_head(struct termp *,
Line 67  static void    print_man_head(struct termp *,
 static  void              print_man_foot(struct termp *,  static  void              print_man_foot(struct termp *,
                                 const struct roff_meta *);                                  const struct roff_meta *);
 static  void              print_bvspace(struct termp *,  static  void              print_bvspace(struct termp *,
                                 const struct roff_node *, int);                                  struct roff_node *, int);
   
 static  int               pre_B(DECL_ARGS);  static  int               pre_B(DECL_ARGS);
 static  int               pre_DT(DECL_ARGS);  static  int               pre_DT(DECL_ARGS);
 static  int               pre_HP(DECL_ARGS);  static  int               pre_HP(DECL_ARGS);
 static  int               pre_I(DECL_ARGS);  static  int               pre_I(DECL_ARGS);
 static  int               pre_IP(DECL_ARGS);  static  int               pre_IP(DECL_ARGS);
   static  int               pre_MR(DECL_ARGS);
 static  int               pre_OP(DECL_ARGS);  static  int               pre_OP(DECL_ARGS);
 static  int               pre_PD(DECL_ARGS);  static  int               pre_PD(DECL_ARGS);
 static  int               pre_PP(DECL_ARGS);  static  int               pre_PP(DECL_ARGS);
Line 78  static int    pre_SS(DECL_ARGS);
Line 84  static int    pre_SS(DECL_ARGS);
 static  int               pre_SY(DECL_ARGS);  static  int               pre_SY(DECL_ARGS);
 static  int               pre_TP(DECL_ARGS);  static  int               pre_TP(DECL_ARGS);
 static  int               pre_UR(DECL_ARGS);  static  int               pre_UR(DECL_ARGS);
 static  int               pre_abort(DECL_ARGS);  
 static  int               pre_alternate(DECL_ARGS);  static  int               pre_alternate(DECL_ARGS);
 static  int               pre_ign(DECL_ARGS);  static  int               pre_ign(DECL_ARGS);
 static  int               pre_in(DECL_ARGS);  static  int               pre_in(DECL_ARGS);
Line 98  static const struct man_term_act man_term_acts[MAN_MAX
Line 103  static const struct man_term_act man_term_acts[MAN_MAX
         { pre_SS, post_SH, 0 }, /* SS */          { pre_SS, post_SH, 0 }, /* SS */
         { pre_TP, post_TP, 0 }, /* TP */          { pre_TP, post_TP, 0 }, /* TP */
         { pre_TP, post_TP, 0 }, /* TQ */          { pre_TP, post_TP, 0 }, /* TQ */
         { pre_abort, NULL, 0 }, /* LP */          { pre_PP, NULL, 0 }, /* LP */
         { pre_PP, NULL, 0 }, /* PP */          { pre_PP, NULL, 0 }, /* PP */
         { pre_abort, NULL, 0 }, /* P */          { pre_PP, NULL, 0 }, /* P */
         { pre_IP, post_IP, 0 }, /* IP */          { pre_IP, post_IP, 0 }, /* IP */
         { pre_HP, post_HP, 0 }, /* HP */          { pre_HP, post_HP, 0 }, /* HP */
         { NULL, NULL, 0 }, /* SM */          { NULL, NULL, 0 }, /* SM */
Line 116  static const struct man_term_act man_term_acts[MAN_MAX
Line 121  static const struct man_term_act man_term_acts[MAN_MAX
         { pre_alternate, NULL, 0 }, /* RI */          { pre_alternate, NULL, 0 }, /* RI */
         { NULL, NULL, 0 }, /* RE */          { NULL, NULL, 0 }, /* RE */
         { pre_RS, post_RS, 0 }, /* RS */          { pre_RS, post_RS, 0 }, /* RS */
         { pre_DT, NULL, 0 }, /* DT */          { pre_DT, NULL, MAN_NOTEXT }, /* DT */
         { pre_ign, NULL, MAN_NOTEXT }, /* UC */          { pre_ign, NULL, MAN_NOTEXT }, /* UC */
         { pre_PD, NULL, MAN_NOTEXT }, /* PD */          { pre_PD, NULL, MAN_NOTEXT }, /* PD */
         { pre_ign, NULL, 0 }, /* AT */          { pre_ign, NULL, MAN_NOTEXT }, /* AT */
         { pre_in, NULL, MAN_NOTEXT }, /* in */          { pre_in, NULL, MAN_NOTEXT }, /* in */
         { pre_SY, post_SY, 0 }, /* SY */          { pre_SY, post_SY, 0 }, /* SY */
         { NULL, NULL, 0 }, /* YS */          { NULL, NULL, 0 }, /* YS */
Line 130  static const struct man_term_act man_term_acts[MAN_MAX
Line 135  static const struct man_term_act man_term_acts[MAN_MAX
         { NULL, NULL, 0 }, /* UE */          { NULL, NULL, 0 }, /* UE */
         { pre_UR, post_UR, 0 }, /* MT */          { pre_UR, post_UR, 0 }, /* MT */
         { NULL, NULL, 0 }, /* ME */          { NULL, NULL, 0 }, /* ME */
           { pre_MR, NULL, 0 }, /* MR */
 };  };
 static const struct man_term_act *man_term_act(enum roff_tok);  static const struct man_term_act *man_term_act(enum roff_tok);
   
Line 147  terminal_man(void *arg, const struct roff_meta *man)
Line 153  terminal_man(void *arg, const struct roff_meta *man)
         struct mtermp            mt;          struct mtermp            mt;
         struct termp            *p;          struct termp            *p;
         struct roff_node        *n, *nc, *nn;          struct roff_node        *n, *nc, *nn;
         size_t                   save_defindent;  
   
         p = (struct termp *)arg;          p = (struct termp *)arg;
         save_defindent = p->defindent;  
         if (p->synopsisonly == 0 && p->defindent == 0)  
                 p->defindent = 7;  
         p->tcol->rmargin = p->maxrmargin = p->defrmargin;          p->tcol->rmargin = p->maxrmargin = p->defrmargin;
         term_tab_set(p, NULL);          term_tab_set(p, NULL);
         term_tab_set(p, "T");          term_tab_set(p, "T");
         term_tab_set(p, ".5i");          term_tab_set(p, ".5i");
   
         memset(&mt, 0, sizeof(mt));          memset(&mt, 0, sizeof(mt));
         mt.lmargin[mt.lmargincur] = term_len(p, p->defindent);          mt.lmargin[mt.lmargincur] = term_len(p, 7);
         mt.offset = term_len(p, p->defindent);          mt.offset = term_len(p, p->defindent);
         mt.pardist = 1;          mt.pardist = 1;
   
Line 189  terminal_man(void *arg, const struct roff_meta *man)
Line 191  terminal_man(void *arg, const struct roff_meta *man)
                         print_man_nodelist(p, &mt, n, man);                          print_man_nodelist(p, &mt, n, man);
                 term_end(p);                  term_end(p);
         }          }
         p->defindent = save_defindent;  
 }  }
   
 /*  /*
Line 201  terminal_man(void *arg, const struct roff_meta *man)
Line 202  terminal_man(void *arg, const struct roff_meta *man)
  * first, print it.   * first, print it.
  */   */
 static void  static void
 print_bvspace(struct termp *p, const struct roff_node *n, int pardist)  print_bvspace(struct termp *p, struct roff_node *n, int pardist)
 {  {
         int      i;          struct roff_node        *nch;
           int                      i;
   
         term_newln(p);          term_newln(p);
   
         if (n->body != NULL && n->body->child != NULL)          if (n->body != NULL &&
                 if (n->body->child->type == ROFFT_TBL)              (nch = roff_node_child(n->body)) != NULL &&
                         return;              nch->type == ROFFT_TBL)
                   return;
   
         if (n->parent->type == ROFFT_ROOT || n->parent->tok != MAN_RS)          if (n->parent->tok != MAN_RS && roff_node_prev(n) == NULL)
                 if (n->prev == NULL)                  return;
                         return;  
   
         for (i = 0; i < pardist; i++)          for (i = 0; i < pardist; i++)
                 term_vspace(p);                  term_vspace(p);
 }  }
   
   
 static int  static int
 pre_abort(DECL_ARGS)  
 {  
         abort();  
 }  
   
 static int  
 pre_ign(DECL_ARGS)  pre_ign(DECL_ARGS)
 {  {
         return 0;          return 0;
Line 315  pre_alternate(DECL_ARGS)
Line 310  pre_alternate(DECL_ARGS)
                 assert(nn->type == ROFFT_TEXT);                  assert(nn->type == ROFFT_TEXT);
                 term_word(p, nn->string);                  term_word(p, nn->string);
                 if (nn->flags & NODE_EOS)                  if (nn->flags & NODE_EOS)
                         p->flags |= TERMP_SENTENCE;                          p->flags |= TERMP_SENTENCE;
                 if (nn->next != NULL)                  if (nn->next != NULL)
                         p->flags |= TERMP_NOSPACE;                          p->flags |= TERMP_NOSPACE;
         }          }
Line 330  pre_B(DECL_ARGS)
Line 325  pre_B(DECL_ARGS)
 }  }
   
 static int  static int
   pre_MR(DECL_ARGS)
   {
           term_fontrepl(p, TERMFONT_NONE);
           n = n->child;
           if (n != NULL) {
                   term_word(p, n->string);   /* name */
                   p->flags |= TERMP_NOSPACE;
           }
           term_word(p, "(");
           p->flags |= TERMP_NOSPACE;
           if (n != NULL && (n = n->next) != NULL) {
                   term_word(p, n->string);   /* section */
                   p->flags |= TERMP_NOSPACE;
           }
           term_word(p, ")");
           if (n != NULL && (n = n->next) != NULL) {
                   p->flags |= TERMP_NOSPACE;
                   term_word(p, n->string);   /* suffix */
           }
           return 0;
   }
   
   static int
 pre_OP(DECL_ARGS)  pre_OP(DECL_ARGS)
 {  {
         term_word(p, "[");          term_word(p, "[");
Line 481  pre_PP(DECL_ARGS)
Line 499  pre_PP(DECL_ARGS)
 {  {
         switch (n->type) {          switch (n->type) {
         case ROFFT_BLOCK:          case ROFFT_BLOCK:
                 mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);                  mt->lmargin[mt->lmargincur] = term_len(p, 7);
                 print_bvspace(p, n, mt->pardist);                  print_bvspace(p, n, mt->pardist);
                 break;                  break;
         case ROFFT_HEAD:          case ROFFT_HEAD:
Line 511  pre_IP(DECL_ARGS)
Line 529  pre_IP(DECL_ARGS)
                 p->trailspace = 1;                  p->trailspace = 1;
                 break;                  break;
         case ROFFT_BODY:          case ROFFT_BODY:
                 p->flags |= TERMP_NOSPACE;                  p->flags |= TERMP_NOSPACE | TERMP_NONEWLINE;
                 break;                  break;
         default:          default:
                 abort();                  abort();
Line 585  pre_TP(DECL_ARGS)
Line 603  pre_TP(DECL_ARGS)
                 p->trailspace = 1;                  p->trailspace = 1;
                 break;                  break;
         case ROFFT_BODY:          case ROFFT_BODY:
                 p->flags |= TERMP_NOSPACE;                  p->flags |= TERMP_NOSPACE | TERMP_NONEWLINE;
                 break;                  break;
         default:          default:
                 abort();                  abort();
Line 657  pre_SS(DECL_ARGS)
Line 675  pre_SS(DECL_ARGS)
   
         switch (n->type) {          switch (n->type) {
         case ROFFT_BLOCK:          case ROFFT_BLOCK:
                 mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);                  mt->lmargin[mt->lmargincur] = term_len(p, 7);
                 mt->offset = term_len(p, p->defindent);                  mt->offset = term_len(p, p->defindent);
   
                 /*                  /*
Line 665  pre_SS(DECL_ARGS)
Line 683  pre_SS(DECL_ARGS)
                  * and after an empty subsection.                   * and after an empty subsection.
                  */                   */
   
                 do {                  if ((n = roff_node_prev(n)) == NULL ||
                         n = n->prev;                      (n->tok == MAN_SS && roff_node_child(n->body) == NULL))
                 } while (n != NULL && n->tok >= MAN_TH &&  
                     man_term_act(n->tok)->flags & MAN_NOTEXT);  
                 if (n == NULL || n->type == ROFFT_COMMENT ||  
                     (n->tok == MAN_SS && n->body->child == NULL))  
                         break;                          break;
   
                 for (i = 0; i < mt->pardist; i++)                  for (i = 0; i < mt->pardist; i++)
Line 702  pre_SH(DECL_ARGS)
Line 716  pre_SH(DECL_ARGS)
   
         switch (n->type) {          switch (n->type) {
         case ROFFT_BLOCK:          case ROFFT_BLOCK:
                 mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);                  mt->lmargin[mt->lmargincur] = term_len(p, 7);
                 mt->offset = term_len(p, p->defindent);                  mt->offset = term_len(p, p->defindent);
   
                 /*                  /*
Line 710  pre_SH(DECL_ARGS)
Line 724  pre_SH(DECL_ARGS)
                  * and after an empty section.                   * and after an empty section.
                  */                   */
   
                 do {                  if ((n = roff_node_prev(n)) == NULL ||
                         n = n->prev;                      (n->tok == MAN_SH && roff_node_child(n->body) == NULL))
                 } while (n != NULL && n->tok >= MAN_TH &&  
                     man_term_act(n->tok)->flags & MAN_NOTEXT);  
                 if (n == NULL || n->type == ROFFT_COMMENT ||  
                     (n->tok == MAN_SH && n->body->child == NULL))  
                         break;                          break;
   
                 for (i = 0; i < mt->pardist; i++)                  for (i = 0; i < mt->pardist; i++)
Line 790  pre_RS(DECL_ARGS)
Line 800  pre_RS(DECL_ARGS)
         if (++mt->lmarginsz < MAXMARGINS)          if (++mt->lmarginsz < MAXMARGINS)
                 mt->lmargincur = mt->lmarginsz;                  mt->lmargincur = mt->lmarginsz;
   
         mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);          mt->lmargin[mt->lmargincur] = term_len(p, 7);
         return 1;          return 1;
 }  }
   
Line 821  pre_SY(DECL_ARGS)
Line 831  pre_SY(DECL_ARGS)
   
         switch (n->type) {          switch (n->type) {
         case ROFFT_BLOCK:          case ROFFT_BLOCK:
                 if (n->prev == NULL || n->prev->tok != MAN_SY)                  if ((nn = roff_node_prev(n)) == NULL || nn->tok != MAN_SY)
                         print_bvspace(p, n, mt->pardist);                          print_bvspace(p, n, mt->pardist);
                 return 1;                  return 1;
         case ROFFT_HEAD:          case ROFFT_HEAD:
Line 902  print_man_node(DECL_ARGS)
Line 912  print_man_node(DECL_ARGS)
         const struct man_term_act *act;          const struct man_term_act *act;
         int c;          int c;
   
           /*
            * In no-fill mode, break the output line at the beginning
            * of new input lines except after \c, and nowhere else.
            */
   
           if (n->flags & NODE_NOFILL) {
                   if (n->flags & NODE_LINE &&
                       (p->flags & TERMP_NONEWLINE) == 0)
                           term_newln(p);
                   p->flags |= TERMP_BRNEVER;
           } else {
                   if (n->flags & NODE_LINE)
                           term_tab_ref(p);
                   p->flags &= ~TERMP_BRNEVER;
           }
   
           if (n->flags & NODE_ID)
                   term_tag_write(n, p->line);
   
         switch (n->type) {          switch (n->type) {
         case ROFFT_TEXT:          case ROFFT_TEXT:
                 /*                  /*
Line 934  print_man_node(DECL_ARGS)
Line 963  print_man_node(DECL_ARGS)
                 return;                  return;
         case ROFFT_TBL:          case ROFFT_TBL:
                 if (p->tbl.cols == NULL)                  if (p->tbl.cols == NULL)
                         term_vspace(p);                          term_newln(p);
                 term_tbl(p, n->span);                  term_tbl(p, n->span);
                 return;                  return;
         default:          default:
Line 963  print_man_node(DECL_ARGS)
Line 992  print_man_node(DECL_ARGS)
                 term_fontrepl(p, TERMFONT_NONE);                  term_fontrepl(p, TERMFONT_NONE);
   
 out:  out:
         /*          if (n->parent->tok == MAN_HP && n->parent->type == ROFFT_BODY &&
          * If we're in a literal context, make sure that words              n->prev == NULL && n->flags & NODE_NOFILL) {
          * together on the same line stay together.  This is a                  term_newln(p);
          * POST-printing call, so we check the NEXT word.  Since                  p->tcol->offset = p->tcol->rmargin;
          * -man doesn't have nested macros, we don't need to be                  p->tcol->rmargin = p->maxrmargin;
          * more specific than this.  
          */  
         if (n->flags & NODE_NOFILL &&  
             ! (p->flags & (TERMP_NOBREAK | TERMP_NONEWLINE)) &&  
             (n->next == NULL || n->next->flags & NODE_LINE)) {  
                 p->flags |= TERMP_BRNEVER | TERMP_NOSPACE;  
                 if (n->string != NULL && *n->string != '\0')  
                         term_flushln(p);  
                 else  
                         term_newln(p);  
                 p->flags &= ~TERMP_BRNEVER;  
                 if (p->tcol->rmargin < p->maxrmargin &&  
                     n->parent->tok == MAN_HP) {  
                         p->tcol->offset = p->tcol->rmargin;  
                         p->tcol->rmargin = p->maxrmargin;  
                 }  
         }          }
         if (n->flags & NODE_EOS)          if (n->flags & NODE_EOS)
                 p->flags |= TERMP_SENTENCE;                  p->flags |= TERMP_SENTENCE;
Line 1020  print_man_foot(struct termp *p, const struct roff_meta
Line 1033  print_man_foot(struct termp *p, const struct roff_meta
          */           */
   
         if ( ! p->mdocstyle) {          if ( ! p->mdocstyle) {
                 if (meta->hasbody) {  
                         term_vspace(p);  
                         term_vspace(p);  
                 }  
                 mandoc_asprintf(&title, "%s(%s)",                  mandoc_asprintf(&title, "%s(%s)",
                     meta->title, meta->msec);                      meta->title, meta->msec);
         } else if (meta->os != NULL) {          } else if (meta->os != NULL) {
Line 1142  print_man_head(struct termp *p, const struct roff_meta
Line 1151  print_man_head(struct termp *p, const struct roff_meta
          */           */
   
         term_vspace(p);          term_vspace(p);
         if ( ! p->mdocstyle) {  
                 term_vspace(p);  
                 term_vspace(p);  
         }  
         free(title);          free(title);
 }  }

Legend:
Removed from v.1.229  
changed lines
  Added in v.1.244

CVSweb