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


 266 
 267         n = mdoc->first->child;
 268         if (p->synopsisonly) {
 269                 while (n != NULL) {
 270                         if (n->tok == MDOC_Sh && n->sec == SEC_SYNOPSIS) {
 271                                 if (n->child->next->child != NULL)
 272                                         print_mdoc_nodelist(p, NULL,
 273                                             &mdoc->meta,
 274                                             n->child->next->child);
 275                                 term_newln(p);
 276                                 break;
 277                         }
 278                         n = n->next;
 279                 }
 280         } else {
 281                 save_defindent = p->defindent;
 282                 if (p->defindent == 0)
 283                         p->defindent = 5;
 284                 term_begin(p, print_mdoc_head, print_mdoc_foot,
 285                     &mdoc->meta);
 286                 while (n != NULL && n->flags & NODE_NOPRT)


 287                         n = n->next;
 288                 if (n != NULL) {
 289                         if (n->tok != MDOC_Sh)
 290                                 term_vspace(p);
 291                         print_mdoc_nodelist(p, NULL, &mdoc->meta, n);
 292                 }
 293                 term_end(p);
 294                 p->defindent = save_defindent;
 295         }
 296 }
 297 
 298 static void
 299 print_mdoc_nodelist(DECL_ARGS)
 300 {
 301 
 302         while (n != NULL) {
 303                 print_mdoc_node(p, pair, meta, n);
 304                 n = n->next;
 305         }
 306 }
 307 
 308 static void
 309 print_mdoc_node(DECL_ARGS)
 310 {
 311         int              chld;
 312         struct termpair  npair;
 313         size_t           offset, rmargin;
 314 
 315         if (n->flags & NODE_NOPRT)
 316                 return;
 317 
 318         chld = 1;
 319         offset = p->tcol->offset;
 320         rmargin = p->tcol->rmargin;
 321         n->flags &= ~NODE_ENDED;
 322         n->prev_font = p->fonti;
 323 
 324         memset(&npair, 0, sizeof(struct termpair));
 325         npair.ppair = pair;
 326 
 327         /*
 328          * Keeps only work until the end of a line.  If a keep was
 329          * invoked in a prior line, revert it to PREKEEP.
 330          */
 331 
 332         if (p->flags & TERMP_KEEP && n->flags & NODE_LINE) {
 333                 p->flags &= ~TERMP_KEEP;
 334                 p->flags |= TERMP_PREKEEP;
 335         }


 550  */
 551 static void
 552 print_bvspace(struct termp *p,
 553         const struct roff_node *bl,
 554         const struct roff_node *n)
 555 {
 556         const struct roff_node  *nn;
 557 
 558         assert(n);
 559 
 560         term_newln(p);
 561 
 562         if (MDOC_Bd == bl->tok && bl->norm->Bd.comp)
 563                 return;
 564         if (MDOC_Bl == bl->tok && bl->norm->Bl.comp)
 565                 return;
 566 
 567         /* Do not vspace directly after Ss/Sh. */
 568 
 569         nn = n;
 570         while (nn->prev != NULL && nn->prev->flags & NODE_NOPRT)


 571                 nn = nn->prev;
 572         while (nn->prev == NULL) {
 573                 do {
 574                         nn = nn->parent;
 575                         if (nn->type == ROFFT_ROOT)
 576                                 return;
 577                 } while (nn->type != ROFFT_BLOCK);
 578                 if (nn->tok == MDOC_Sh || nn->tok == MDOC_Ss)
 579                         return;
 580                 if (nn->tok == MDOC_It &&
 581                     nn->parent->parent->norm->Bl.type != LIST_item)
 582                         break;
 583         }
 584 
 585         /* A `-column' does not assert vspace within the list. */
 586 
 587         if (MDOC_Bl == bl->tok && LIST_column == bl->norm->Bl.type)
 588                 if (n->prev && MDOC_It == n->prev->tok)
 589                         return;
 590 


1533                 p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
1534 }
1535 
1536 static void
1537 termp_pf_post(DECL_ARGS)
1538 {
1539 
1540         if ( ! (n->next == NULL || n->next->flags & NODE_LINE))
1541                 p->flags |= TERMP_NOSPACE;
1542 }
1543 
1544 static int
1545 termp_ss_pre(DECL_ARGS)
1546 {
1547         struct roff_node *nn;
1548 
1549         switch (n->type) {
1550         case ROFFT_BLOCK:
1551                 term_newln(p);
1552                 for (nn = n->prev; nn != NULL; nn = nn->prev)
1553                         if ((nn->flags & NODE_NOPRT) == 0)

1554                                 break;
1555                 if (nn != NULL)
1556                         term_vspace(p);
1557                 break;
1558         case ROFFT_HEAD:
1559                 term_fontpush(p, TERMFONT_BOLD);
1560                 p->tcol->offset = term_len(p, (p->defindent+1)/2);
1561                 break;
1562         case ROFFT_BODY:
1563                 p->tcol->offset = term_len(p, p->defindent);
1564                 term_tab_set(p, NULL);
1565                 term_tab_set(p, "T");
1566                 term_tab_set(p, ".5i");
1567                 break;
1568         default:
1569                 break;
1570         }
1571 
1572         return 1;
1573 }


1647         switch (n->tok) {
1648         case MDOC_Ao:
1649         case MDOC_Aq:
1650                 term_word(p, n->child != NULL && n->child->next == NULL &&
1651                     n->child->tok == MDOC_Mt ? "<" : "\\(la");
1652                 break;
1653         case MDOC_Bro:
1654         case MDOC_Brq:
1655                 term_word(p, "{");
1656                 break;
1657         case MDOC_Oo:
1658         case MDOC_Op:
1659         case MDOC_Bo:
1660         case MDOC_Bq:
1661                 term_word(p, "[");
1662                 break;
1663         case MDOC__T:
1664                 /* FALLTHROUGH */
1665         case MDOC_Do:
1666         case MDOC_Dq:
1667                 term_word(p, "\\(Lq");
1668                 break;
1669         case MDOC_En:
1670                 if (NULL == n->norm->Es ||
1671                     NULL == n->norm->Es->child)
1672                         return 1;
1673                 term_word(p, n->norm->Es->child->string);
1674                 break;
1675         case MDOC_Po:
1676         case MDOC_Pq:
1677                 term_word(p, "(");
1678                 break;
1679         case MDOC_Qo:
1680         case MDOC_Qq:
1681                 term_word(p, "\"");
1682                 break;
1683         case MDOC_Ql:
1684         case MDOC_So:
1685         case MDOC_Sq:
1686                 term_word(p, "\\(oq");
1687                 break;


1705         switch (n->tok) {
1706         case MDOC_Ao:
1707         case MDOC_Aq:
1708                 term_word(p, n->child != NULL && n->child->next == NULL &&
1709                     n->child->tok == MDOC_Mt ? ">" : "\\(ra");
1710                 break;
1711         case MDOC_Bro:
1712         case MDOC_Brq:
1713                 term_word(p, "}");
1714                 break;
1715         case MDOC_Oo:
1716         case MDOC_Op:
1717         case MDOC_Bo:
1718         case MDOC_Bq:
1719                 term_word(p, "]");
1720                 break;
1721         case MDOC__T:
1722                 /* FALLTHROUGH */
1723         case MDOC_Do:
1724         case MDOC_Dq:
1725                 term_word(p, "\\(Rq");
1726                 break;
1727         case MDOC_En:
1728                 if (n->norm->Es == NULL ||
1729                     n->norm->Es->child == NULL ||
1730                     n->norm->Es->child->next == NULL)
1731                         p->flags &= ~TERMP_NOSPACE;
1732                 else
1733                         term_word(p, n->norm->Es->child->next->string);
1734                 break;
1735         case MDOC_Po:
1736         case MDOC_Pq:
1737                 term_word(p, ")");
1738                 break;
1739         case MDOC_Qo:
1740         case MDOC_Qq:
1741                 term_word(p, "\"");
1742                 break;
1743         case MDOC_Ql:
1744         case MDOC_So:
1745         case MDOC_Sq:


1923         if (NULL == n->next) {
1924                 term_word(p, ".");
1925                 p->flags |= TERMP_SENTENCE;
1926         } else
1927                 term_word(p, ",");
1928 }
1929 
1930 static int
1931 termp_li_pre(DECL_ARGS)
1932 {
1933 
1934         termp_tag_pre(p, pair, meta, n);
1935         term_fontpush(p, TERMFONT_NONE);
1936         return 1;
1937 }
1938 
1939 static int
1940 termp_lk_pre(DECL_ARGS)
1941 {
1942         const struct roff_node *link, *descr, *punct;
1943         int display;
1944 
1945         if ((link = n->child) == NULL)
1946                 return 0;
1947 
1948         /* Find beginning of trailing punctuation. */
1949         punct = n->last;
1950         while (punct != link && punct->flags & NODE_DELIMC)
1951                 punct = punct->prev;
1952         punct = punct->next;
1953 
1954         /* Link text. */
1955         if ((descr = link->next) != NULL && descr != punct) {
1956                 term_fontpush(p, TERMFONT_UNDER);
1957                 while (descr != punct) {
1958                         if (descr->flags & (NODE_DELIMC | NODE_DELIMO))
1959                                 p->flags |= TERMP_NOSPACE;
1960                         term_word(p, descr->string);
1961                         descr = descr->next;
1962                 }
1963                 term_fontpop(p);
1964                 p->flags |= TERMP_NOSPACE;
1965                 term_word(p, ":");
1966         }
1967 
1968         /* Link target. */
1969         display = term_strlen(p, link->string) >= 26;
1970         if (display) {
1971                 term_newln(p);
1972                 p->tcol->offset += term_len(p, p->defindent + 1);
1973         }
1974         term_fontpush(p, TERMFONT_BOLD);
1975         term_word(p, link->string);
1976         term_fontpop(p);
1977 
1978         /* Trailing punctuation. */
1979         while (punct != NULL) {
1980                 p->flags |= TERMP_NOSPACE;
1981                 term_word(p, punct->string);
1982                 punct = punct->next;
1983         }
1984         if (display)
1985                 term_newln(p);
1986         return 0;
1987 }
1988 
1989 static int
1990 termp_bk_pre(DECL_ARGS)
1991 {
1992 
1993         switch (n->type) {
1994         case ROFFT_BLOCK:
1995                 break;
1996         case ROFFT_HEAD:
1997                 return 0;
1998         case ROFFT_BODY:
1999                 if (n->parent->args != NULL || n->prev->child == NULL)
2000                         p->flags |= TERMP_PREKEEP;
2001                 break;
2002         default:
2003                 abort();
2004         }
2005 


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


 266 
 267         n = mdoc->first->child;
 268         if (p->synopsisonly) {
 269                 while (n != NULL) {
 270                         if (n->tok == MDOC_Sh && n->sec == SEC_SYNOPSIS) {
 271                                 if (n->child->next->child != NULL)
 272                                         print_mdoc_nodelist(p, NULL,
 273                                             &mdoc->meta,
 274                                             n->child->next->child);
 275                                 term_newln(p);
 276                                 break;
 277                         }
 278                         n = n->next;
 279                 }
 280         } else {
 281                 save_defindent = p->defindent;
 282                 if (p->defindent == 0)
 283                         p->defindent = 5;
 284                 term_begin(p, print_mdoc_head, print_mdoc_foot,
 285                     &mdoc->meta);
 286                 while (n != NULL &&
 287                     (n->type == ROFFT_COMMENT ||
 288                      n->flags & NODE_NOPRT))
 289                         n = n->next;
 290                 if (n != NULL) {
 291                         if (n->tok != MDOC_Sh)
 292                                 term_vspace(p);
 293                         print_mdoc_nodelist(p, NULL, &mdoc->meta, n);
 294                 }
 295                 term_end(p);
 296                 p->defindent = save_defindent;
 297         }
 298 }
 299 
 300 static void
 301 print_mdoc_nodelist(DECL_ARGS)
 302 {
 303 
 304         while (n != NULL) {
 305                 print_mdoc_node(p, pair, meta, n);
 306                 n = n->next;
 307         }
 308 }
 309 
 310 static void
 311 print_mdoc_node(DECL_ARGS)
 312 {
 313         int              chld;
 314         struct termpair  npair;
 315         size_t           offset, rmargin;
 316 
 317         if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT)
 318                 return;
 319 
 320         chld = 1;
 321         offset = p->tcol->offset;
 322         rmargin = p->tcol->rmargin;
 323         n->flags &= ~NODE_ENDED;
 324         n->prev_font = p->fonti;
 325 
 326         memset(&npair, 0, sizeof(struct termpair));
 327         npair.ppair = pair;
 328 
 329         /*
 330          * Keeps only work until the end of a line.  If a keep was
 331          * invoked in a prior line, revert it to PREKEEP.
 332          */
 333 
 334         if (p->flags & TERMP_KEEP && n->flags & NODE_LINE) {
 335                 p->flags &= ~TERMP_KEEP;
 336                 p->flags |= TERMP_PREKEEP;
 337         }


 552  */
 553 static void
 554 print_bvspace(struct termp *p,
 555         const struct roff_node *bl,
 556         const struct roff_node *n)
 557 {
 558         const struct roff_node  *nn;
 559 
 560         assert(n);
 561 
 562         term_newln(p);
 563 
 564         if (MDOC_Bd == bl->tok && bl->norm->Bd.comp)
 565                 return;
 566         if (MDOC_Bl == bl->tok && bl->norm->Bl.comp)
 567                 return;
 568 
 569         /* Do not vspace directly after Ss/Sh. */
 570 
 571         nn = n;
 572         while (nn->prev != NULL &&
 573             (nn->prev->type == ROFFT_COMMENT ||
 574              nn->prev->flags & NODE_NOPRT))
 575                 nn = nn->prev;
 576         while (nn->prev == NULL) {
 577                 do {
 578                         nn = nn->parent;
 579                         if (nn->type == ROFFT_ROOT)
 580                                 return;
 581                 } while (nn->type != ROFFT_BLOCK);
 582                 if (nn->tok == MDOC_Sh || nn->tok == MDOC_Ss)
 583                         return;
 584                 if (nn->tok == MDOC_It &&
 585                     nn->parent->parent->norm->Bl.type != LIST_item)
 586                         break;
 587         }
 588 
 589         /* A `-column' does not assert vspace within the list. */
 590 
 591         if (MDOC_Bl == bl->tok && LIST_column == bl->norm->Bl.type)
 592                 if (n->prev && MDOC_It == n->prev->tok)
 593                         return;
 594 


1537                 p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
1538 }
1539 
1540 static void
1541 termp_pf_post(DECL_ARGS)
1542 {
1543 
1544         if ( ! (n->next == NULL || n->next->flags & NODE_LINE))
1545                 p->flags |= TERMP_NOSPACE;
1546 }
1547 
1548 static int
1549 termp_ss_pre(DECL_ARGS)
1550 {
1551         struct roff_node *nn;
1552 
1553         switch (n->type) {
1554         case ROFFT_BLOCK:
1555                 term_newln(p);
1556                 for (nn = n->prev; nn != NULL; nn = nn->prev)
1557                         if (nn->type != ROFFT_COMMENT &&
1558                             (nn->flags & NODE_NOPRT) == 0)
1559                                 break;
1560                 if (nn != NULL)
1561                         term_vspace(p);
1562                 break;
1563         case ROFFT_HEAD:
1564                 term_fontpush(p, TERMFONT_BOLD);
1565                 p->tcol->offset = term_len(p, (p->defindent+1)/2);
1566                 break;
1567         case ROFFT_BODY:
1568                 p->tcol->offset = term_len(p, p->defindent);
1569                 term_tab_set(p, NULL);
1570                 term_tab_set(p, "T");
1571                 term_tab_set(p, ".5i");
1572                 break;
1573         default:
1574                 break;
1575         }
1576 
1577         return 1;
1578 }


1652         switch (n->tok) {
1653         case MDOC_Ao:
1654         case MDOC_Aq:
1655                 term_word(p, n->child != NULL && n->child->next == NULL &&
1656                     n->child->tok == MDOC_Mt ? "<" : "\\(la");
1657                 break;
1658         case MDOC_Bro:
1659         case MDOC_Brq:
1660                 term_word(p, "{");
1661                 break;
1662         case MDOC_Oo:
1663         case MDOC_Op:
1664         case MDOC_Bo:
1665         case MDOC_Bq:
1666                 term_word(p, "[");
1667                 break;
1668         case MDOC__T:
1669                 /* FALLTHROUGH */
1670         case MDOC_Do:
1671         case MDOC_Dq:
1672                 term_word(p, "\\(lq");
1673                 break;
1674         case MDOC_En:
1675                 if (NULL == n->norm->Es ||
1676                     NULL == n->norm->Es->child)
1677                         return 1;
1678                 term_word(p, n->norm->Es->child->string);
1679                 break;
1680         case MDOC_Po:
1681         case MDOC_Pq:
1682                 term_word(p, "(");
1683                 break;
1684         case MDOC_Qo:
1685         case MDOC_Qq:
1686                 term_word(p, "\"");
1687                 break;
1688         case MDOC_Ql:
1689         case MDOC_So:
1690         case MDOC_Sq:
1691                 term_word(p, "\\(oq");
1692                 break;


1710         switch (n->tok) {
1711         case MDOC_Ao:
1712         case MDOC_Aq:
1713                 term_word(p, n->child != NULL && n->child->next == NULL &&
1714                     n->child->tok == MDOC_Mt ? ">" : "\\(ra");
1715                 break;
1716         case MDOC_Bro:
1717         case MDOC_Brq:
1718                 term_word(p, "}");
1719                 break;
1720         case MDOC_Oo:
1721         case MDOC_Op:
1722         case MDOC_Bo:
1723         case MDOC_Bq:
1724                 term_word(p, "]");
1725                 break;
1726         case MDOC__T:
1727                 /* FALLTHROUGH */
1728         case MDOC_Do:
1729         case MDOC_Dq:
1730                 term_word(p, "\\(rq");
1731                 break;
1732         case MDOC_En:
1733                 if (n->norm->Es == NULL ||
1734                     n->norm->Es->child == NULL ||
1735                     n->norm->Es->child->next == NULL)
1736                         p->flags &= ~TERMP_NOSPACE;
1737                 else
1738                         term_word(p, n->norm->Es->child->next->string);
1739                 break;
1740         case MDOC_Po:
1741         case MDOC_Pq:
1742                 term_word(p, ")");
1743                 break;
1744         case MDOC_Qo:
1745         case MDOC_Qq:
1746                 term_word(p, "\"");
1747                 break;
1748         case MDOC_Ql:
1749         case MDOC_So:
1750         case MDOC_Sq:


1928         if (NULL == n->next) {
1929                 term_word(p, ".");
1930                 p->flags |= TERMP_SENTENCE;
1931         } else
1932                 term_word(p, ",");
1933 }
1934 
1935 static int
1936 termp_li_pre(DECL_ARGS)
1937 {
1938 
1939         termp_tag_pre(p, pair, meta, n);
1940         term_fontpush(p, TERMFONT_NONE);
1941         return 1;
1942 }
1943 
1944 static int
1945 termp_lk_pre(DECL_ARGS)
1946 {
1947         const struct roff_node *link, *descr, *punct;

1948 
1949         if ((link = n->child) == NULL)
1950                 return 0;
1951 
1952         /* Find beginning of trailing punctuation. */
1953         punct = n->last;
1954         while (punct != link && punct->flags & NODE_DELIMC)
1955                 punct = punct->prev;
1956         punct = punct->next;
1957 
1958         /* Link text. */
1959         if ((descr = link->next) != NULL && descr != punct) {
1960                 term_fontpush(p, TERMFONT_UNDER);
1961                 while (descr != punct) {
1962                         if (descr->flags & (NODE_DELIMC | NODE_DELIMO))
1963                                 p->flags |= TERMP_NOSPACE;
1964                         term_word(p, descr->string);
1965                         descr = descr->next;
1966                 }
1967                 term_fontpop(p);
1968                 p->flags |= TERMP_NOSPACE;
1969                 term_word(p, ":");
1970         }
1971 
1972         /* Link target. */





1973         term_fontpush(p, TERMFONT_BOLD);
1974         term_word(p, link->string);
1975         term_fontpop(p);
1976 
1977         /* Trailing punctuation. */
1978         while (punct != NULL) {
1979                 p->flags |= TERMP_NOSPACE;
1980                 term_word(p, punct->string);
1981                 punct = punct->next;
1982         }


1983         return 0;
1984 }
1985 
1986 static int
1987 termp_bk_pre(DECL_ARGS)
1988 {
1989 
1990         switch (n->type) {
1991         case ROFFT_BLOCK:
1992                 break;
1993         case ROFFT_HEAD:
1994                 return 0;
1995         case ROFFT_BODY:
1996                 if (n->parent->args != NULL || n->prev->child == NULL)
1997                         p->flags |= TERMP_PREKEEP;
1998                 break;
1999         default:
2000                 abort();
2001         }
2002