Print this page
9718 update mandoc to 1.14.4
   1 /*      $Id: man_term.c,v 1.209 2017/07/31 15:19:06 schwarze Exp $ */
   2 /*
   3  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
   4  * Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
   5  *
   6  * Permission to use, copy, modify, and distribute this software for any
   7  * purpose with or without fee is hereby granted, provided that the above
   8  * copyright notice and this permission notice appear in all copies.
   9  *
  10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
  11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
  13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17  */
  18 #include "config.h"
  19 
  20 #include <sys/types.h>
  21 
  22 #include <assert.h>
  23 #include <ctype.h>
  24 #include <limits.h>


 658 static int
 659 pre_SS(DECL_ARGS)
 660 {
 661         int      i;
 662 
 663         switch (n->type) {
 664         case ROFFT_BLOCK:
 665                 mt->fl &= ~MANT_LITERAL;
 666                 mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
 667                 mt->offset = term_len(p, p->defindent);
 668 
 669                 /*
 670                  * No vertical space before the first subsection
 671                  * and after an empty subsection.
 672                  */
 673 
 674                 do {
 675                         n = n->prev;
 676                 } while (n != NULL && n->tok >= MAN_TH &&
 677                     termacts[n->tok].flags & MAN_NOTEXT);
 678                 if (n == NULL || (n->tok == MAN_SS && n->body->child == NULL))

 679                         break;
 680 
 681                 for (i = 0; i < mt->pardist; i++)
 682                         term_vspace(p);
 683                 break;
 684         case ROFFT_HEAD:
 685                 term_fontrepl(p, TERMFONT_BOLD);
 686                 p->tcol->offset = term_len(p, 3);
 687                 p->tcol->rmargin = mt->offset;
 688                 p->trailspace = mt->offset;
 689                 p->flags |= TERMP_NOBREAK | TERMP_BRIND;
 690                 break;
 691         case ROFFT_BODY:
 692                 p->tcol->offset = mt->offset;
 693                 p->tcol->rmargin = p->maxrmargin;
 694                 p->trailspace = 0;
 695                 p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
 696                 break;
 697         default:
 698                 break;


 720 static int
 721 pre_SH(DECL_ARGS)
 722 {
 723         int      i;
 724 
 725         switch (n->type) {
 726         case ROFFT_BLOCK:
 727                 mt->fl &= ~MANT_LITERAL;
 728                 mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
 729                 mt->offset = term_len(p, p->defindent);
 730 
 731                 /*
 732                  * No vertical space before the first section
 733                  * and after an empty section.
 734                  */
 735 
 736                 do {
 737                         n = n->prev;
 738                 } while (n != NULL && n->tok >= MAN_TH &&
 739                     termacts[n->tok].flags & MAN_NOTEXT);
 740                 if (n == NULL || (n->tok == MAN_SH && n->body->child == NULL))

 741                         break;
 742 
 743                 for (i = 0; i < mt->pardist; i++)
 744                         term_vspace(p);
 745                 break;
 746         case ROFFT_HEAD:
 747                 term_fontrepl(p, TERMFONT_BOLD);
 748                 p->tcol->offset = 0;
 749                 p->tcol->rmargin = mt->offset;
 750                 p->trailspace = mt->offset;
 751                 p->flags |= TERMP_NOBREAK | TERMP_BRIND;
 752                 break;
 753         case ROFFT_BODY:
 754                 p->tcol->offset = mt->offset;
 755                 p->tcol->rmargin = p->maxrmargin;
 756                 p->trailspace = 0;
 757                 p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
 758                 break;
 759         default:
 760                 break;


 868 
 869         switch (n->type) {
 870         case ROFFT_TEXT:
 871                 /*
 872                  * If we have a blank line, output a vertical space.
 873                  * If we have a space as the first character, break
 874                  * before printing the line's data.
 875                  */
 876                 if (*n->string == '\0') {
 877                         if (p->flags & TERMP_NONEWLINE)
 878                                 term_newln(p);
 879                         else
 880                                 term_vspace(p);
 881                         return;
 882                 } else if (*n->string == ' ' && n->flags & NODE_LINE &&
 883                     (p->flags & TERMP_NONEWLINE) == 0)
 884                         term_newln(p);
 885 
 886                 term_word(p, n->string);
 887                 goto out;
 888 

 889         case ROFFT_EQN:
 890                 if ( ! (n->flags & NODE_LINE))
 891                         p->flags |= TERMP_NOSPACE;
 892                 term_eqn(p, n->eqn);
 893                 if (n->next != NULL && ! (n->next->flags & NODE_LINE))
 894                         p->flags |= TERMP_NOSPACE;
 895                 return;
 896         case ROFFT_TBL:
 897                 if (p->tbl.cols == NULL)
 898                         term_vspace(p);
 899                 term_tbl(p, n->span);
 900                 return;
 901         default:
 902                 break;
 903         }
 904 
 905         if (n->tok < ROFF_MAX) {
 906                 roff_term_pre(p, n);
 907                 return;
 908         }


1012 
1013         p->tcol->offset = p->tcol->rmargin;
1014         titlen = term_strlen(p, title);
1015         p->tcol->rmargin = p->maxrmargin > titlen ?
1016             p->maxrmargin - titlen : 0;
1017         p->flags |= TERMP_NOSPACE;
1018 
1019         term_word(p, meta->date);
1020         term_flushln(p);
1021 
1022         /* Bottom right corner: manual title and section. */
1023 
1024         p->flags &= ~TERMP_NOBREAK;
1025         p->flags |= TERMP_NOSPACE;
1026         p->trailspace = 0;
1027         p->tcol->offset = p->tcol->rmargin;
1028         p->tcol->rmargin = p->maxrmargin;
1029 
1030         term_word(p, title);
1031         term_flushln(p);












1032         free(title);
1033 }
1034 
1035 static void
1036 print_man_head(struct termp *p, const struct roff_meta *meta)
1037 {
1038         const char              *volume;
1039         char                    *title;
1040         size_t                   vollen, titlen;
1041 
1042         assert(meta->title);
1043         assert(meta->msec);
1044 
1045         volume = NULL == meta->vol ? "" : meta->vol;
1046         vollen = term_strlen(p, volume);
1047 
1048         /* Top left corner: manual title and section. */
1049 
1050         mandoc_asprintf(&title, "%s(%s)", meta->title, meta->msec);
1051         titlen = term_strlen(p, title);


   1 /*      $Id: man_term.c,v 1.211 2018/06/10 15:12:35 schwarze Exp $ */
   2 /*
   3  * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
   4  * Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org>
   5  *
   6  * Permission to use, copy, modify, and distribute this software for any
   7  * purpose with or without fee is hereby granted, provided that the above
   8  * copyright notice and this permission notice appear in all copies.
   9  *
  10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
  11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
  13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17  */
  18 #include "config.h"
  19 
  20 #include <sys/types.h>
  21 
  22 #include <assert.h>
  23 #include <ctype.h>
  24 #include <limits.h>


 658 static int
 659 pre_SS(DECL_ARGS)
 660 {
 661         int      i;
 662 
 663         switch (n->type) {
 664         case ROFFT_BLOCK:
 665                 mt->fl &= ~MANT_LITERAL;
 666                 mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
 667                 mt->offset = term_len(p, p->defindent);
 668 
 669                 /*
 670                  * No vertical space before the first subsection
 671                  * and after an empty subsection.
 672                  */
 673 
 674                 do {
 675                         n = n->prev;
 676                 } while (n != NULL && n->tok >= MAN_TH &&
 677                     termacts[n->tok].flags & MAN_NOTEXT);
 678                 if (n == NULL || n->type == ROFFT_COMMENT ||
 679                     (n->tok == MAN_SS && n->body->child == NULL))
 680                         break;
 681 
 682                 for (i = 0; i < mt->pardist; i++)
 683                         term_vspace(p);
 684                 break;
 685         case ROFFT_HEAD:
 686                 term_fontrepl(p, TERMFONT_BOLD);
 687                 p->tcol->offset = term_len(p, 3);
 688                 p->tcol->rmargin = mt->offset;
 689                 p->trailspace = mt->offset;
 690                 p->flags |= TERMP_NOBREAK | TERMP_BRIND;
 691                 break;
 692         case ROFFT_BODY:
 693                 p->tcol->offset = mt->offset;
 694                 p->tcol->rmargin = p->maxrmargin;
 695                 p->trailspace = 0;
 696                 p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
 697                 break;
 698         default:
 699                 break;


 721 static int
 722 pre_SH(DECL_ARGS)
 723 {
 724         int      i;
 725 
 726         switch (n->type) {
 727         case ROFFT_BLOCK:
 728                 mt->fl &= ~MANT_LITERAL;
 729                 mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
 730                 mt->offset = term_len(p, p->defindent);
 731 
 732                 /*
 733                  * No vertical space before the first section
 734                  * and after an empty section.
 735                  */
 736 
 737                 do {
 738                         n = n->prev;
 739                 } while (n != NULL && n->tok >= MAN_TH &&
 740                     termacts[n->tok].flags & MAN_NOTEXT);
 741                 if (n == NULL || n->type == ROFFT_COMMENT ||
 742                     (n->tok == MAN_SH && n->body->child == NULL))
 743                         break;
 744 
 745                 for (i = 0; i < mt->pardist; i++)
 746                         term_vspace(p);
 747                 break;
 748         case ROFFT_HEAD:
 749                 term_fontrepl(p, TERMFONT_BOLD);
 750                 p->tcol->offset = 0;
 751                 p->tcol->rmargin = mt->offset;
 752                 p->trailspace = mt->offset;
 753                 p->flags |= TERMP_NOBREAK | TERMP_BRIND;
 754                 break;
 755         case ROFFT_BODY:
 756                 p->tcol->offset = mt->offset;
 757                 p->tcol->rmargin = p->maxrmargin;
 758                 p->trailspace = 0;
 759                 p->flags &= ~(TERMP_NOBREAK | TERMP_BRIND);
 760                 break;
 761         default:
 762                 break;


 870 
 871         switch (n->type) {
 872         case ROFFT_TEXT:
 873                 /*
 874                  * If we have a blank line, output a vertical space.
 875                  * If we have a space as the first character, break
 876                  * before printing the line's data.
 877                  */
 878                 if (*n->string == '\0') {
 879                         if (p->flags & TERMP_NONEWLINE)
 880                                 term_newln(p);
 881                         else
 882                                 term_vspace(p);
 883                         return;
 884                 } else if (*n->string == ' ' && n->flags & NODE_LINE &&
 885                     (p->flags & TERMP_NONEWLINE) == 0)
 886                         term_newln(p);
 887 
 888                 term_word(p, n->string);
 889                 goto out;
 890         case ROFFT_COMMENT:
 891                 return;
 892         case ROFFT_EQN:
 893                 if ( ! (n->flags & NODE_LINE))
 894                         p->flags |= TERMP_NOSPACE;
 895                 term_eqn(p, n->eqn);
 896                 if (n->next != NULL && ! (n->next->flags & NODE_LINE))
 897                         p->flags |= TERMP_NOSPACE;
 898                 return;
 899         case ROFFT_TBL:
 900                 if (p->tbl.cols == NULL)
 901                         term_vspace(p);
 902                 term_tbl(p, n->span);
 903                 return;
 904         default:
 905                 break;
 906         }
 907 
 908         if (n->tok < ROFF_MAX) {
 909                 roff_term_pre(p, n);
 910                 return;
 911         }


1015 
1016         p->tcol->offset = p->tcol->rmargin;
1017         titlen = term_strlen(p, title);
1018         p->tcol->rmargin = p->maxrmargin > titlen ?
1019             p->maxrmargin - titlen : 0;
1020         p->flags |= TERMP_NOSPACE;
1021 
1022         term_word(p, meta->date);
1023         term_flushln(p);
1024 
1025         /* Bottom right corner: manual title and section. */
1026 
1027         p->flags &= ~TERMP_NOBREAK;
1028         p->flags |= TERMP_NOSPACE;
1029         p->trailspace = 0;
1030         p->tcol->offset = p->tcol->rmargin;
1031         p->tcol->rmargin = p->maxrmargin;
1032 
1033         term_word(p, title);
1034         term_flushln(p);
1035 
1036         /*
1037          * Reset the terminal state for more output after the footer:
1038          * Some output modes, in particular PostScript and PDF, print
1039          * the header and the footer into a buffer such that it can be
1040          * reused for multiple output pages, then go on to format the
1041          * main text.
1042          */
1043 
1044         p->tcol->offset = 0;
1045         p->flags = 0;
1046 
1047         free(title);
1048 }
1049 
1050 static void
1051 print_man_head(struct termp *p, const struct roff_meta *meta)
1052 {
1053         const char              *volume;
1054         char                    *title;
1055         size_t                   vollen, titlen;
1056 
1057         assert(meta->title);
1058         assert(meta->msec);
1059 
1060         volume = NULL == meta->vol ? "" : meta->vol;
1061         vollen = term_strlen(p, volume);
1062 
1063         /* Top left corner: manual title and section. */
1064 
1065         mandoc_asprintf(&title, "%s(%s)", meta->title, meta->msec);
1066         titlen = term_strlen(p, title);