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


 185         { NULL, pre_em, post_percent, NULL, NULL }, /* %I */
 186         { NULL, pre_em, post_percent, NULL, NULL }, /* %J */
 187         { NULL, NULL, post_percent, NULL, NULL }, /* %N */
 188         { NULL, NULL, post_percent, NULL, NULL }, /* %O */
 189         { NULL, NULL, post_percent, NULL, NULL }, /* %P */
 190         { NULL, NULL, post_percent, NULL, NULL }, /* %R */
 191         { NULL, pre__t, post__t, NULL, NULL }, /* %T */
 192         { NULL, NULL, post_percent, NULL, NULL }, /* %V */
 193         { NULL, NULL, NULL, NULL, NULL }, /* Ac */
 194         { cond_body, pre_aq, post_aq, NULL, NULL }, /* Ao */
 195         { cond_body, pre_aq, post_aq, NULL, NULL }, /* Aq */
 196         { NULL, NULL, NULL, NULL, NULL }, /* At */
 197         { NULL, NULL, NULL, NULL, NULL }, /* Bc */
 198         { NULL, pre_bf, post_bf, NULL, NULL }, /* Bf */
 199         { cond_body, pre_enc, post_enc, "[", "]" }, /* Bo */
 200         { cond_body, pre_enc, post_enc, "[", "]" }, /* Bq */
 201         { NULL, pre_bk, post_bk, NULL, NULL }, /* Bsx */
 202         { NULL, pre_bk, post_bk, NULL, NULL }, /* Bx */
 203         { NULL, pre_skip, NULL, NULL, NULL }, /* Db */
 204         { NULL, NULL, NULL, NULL, NULL }, /* Dc */
 205         { cond_body, pre_enc, post_enc, "\\(Lq", "\\(Rq" }, /* Do */
 206         { cond_body, pre_enc, post_enc, "\\(Lq", "\\(Rq" }, /* Dq */
 207         { NULL, NULL, NULL, NULL, NULL }, /* Ec */
 208         { NULL, NULL, NULL, NULL, NULL }, /* Ef */
 209         { NULL, pre_em, post_font, NULL, NULL }, /* Em */
 210         { cond_body, pre_eo, post_eo, NULL, NULL }, /* Eo */
 211         { NULL, pre_bk, post_bk, NULL, NULL }, /* Fx */
 212         { NULL, pre_sy, post_font, NULL, NULL }, /* Ms */
 213         { NULL, pre_no, NULL, NULL, NULL }, /* No */
 214         { NULL, pre_ns, NULL, NULL, NULL }, /* Ns */
 215         { NULL, pre_bk, post_bk, NULL, NULL }, /* Nx */
 216         { NULL, pre_bk, post_bk, NULL, NULL }, /* Ox */
 217         { NULL, NULL, NULL, NULL, NULL }, /* Pc */
 218         { NULL, NULL, post_pf, NULL, NULL }, /* Pf */
 219         { cond_body, pre_enc, post_enc, "(", ")" }, /* Po */
 220         { cond_body, pre_enc, post_enc, "(", ")" }, /* Pq */
 221         { NULL, NULL, NULL, NULL, NULL }, /* Qc */
 222         { cond_body, pre_enc, post_enc, "\\(oq", "\\(cq" }, /* Ql */
 223         { cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qo */
 224         { cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qq */
 225         { NULL, NULL, NULL, NULL, NULL }, /* Re */
 226         { cond_body, pre_rs, NULL, NULL, NULL }, /* Rs */


 593 }
 594 
 595 void
 596 man_man(void *arg, const struct roff_man *man)
 597 {
 598 
 599         /*
 600          * Dump the keep buffer.
 601          * We're guaranteed by now that this exists (is non-NULL).
 602          * Flush stdout afterward, just in case.
 603          */
 604         fputs(mparse_getkeep(man_mparse(man)), stdout);
 605         fflush(stdout);
 606 }
 607 
 608 void
 609 man_mdoc(void *arg, const struct roff_man *mdoc)
 610 {
 611         struct roff_node *n;
 612 








 613         printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n",
 614             mdoc->meta.title,
 615             (mdoc->meta.msec == NULL ? "" : mdoc->meta.msec),
 616             mdoc->meta.date, mdoc->meta.os, mdoc->meta.vol);
 617 
 618         /* Disable hyphenation and if nroff, disable justification. */
 619         printf(".nh\n.if n .ad l");
 620 
 621         outflags = MMAN_nl | MMAN_Sm;
 622         if (0 == fontqueue.size) {
 623                 fontqueue.size = 8;
 624                 fontqueue.head = fontqueue.tail = mandoc_malloc(8);
 625                 *fontqueue.tail = 'R';
 626         }
 627         for (n = mdoc->first->child; n != NULL; n = n->next)
 628                 print_node(&mdoc->meta, n);
 629         putchar('\n');
 630 }
 631 
 632 static void
 633 print_node(DECL_ARGS)
 634 {
 635         const struct manact     *act;
 636         struct roff_node        *sub;
 637         int                      cond, do_sub;
 638 
 639         if (n->flags & NODE_NOPRT)
 640                 return;
 641 
 642         /*
 643          * Break the line if we were parsed subsequent the current node.
 644          * This makes the page structure be more consistent.
 645          */
 646         if (MMAN_spc & outflags && NODE_LINE & n->flags)
 647                 outflags |= MMAN_nl;


1391         const struct roff_node *bln;
1392 
1393         switch (n->type) {
1394         case ROFFT_HEAD:
1395                 outflags |= MMAN_PP | MMAN_nl;
1396                 bln = n->parent->parent;
1397                 if (0 == bln->norm->Bl.comp ||
1398                     (NULL == n->parent->prev &&
1399                      NULL == bln->parent->prev))
1400                         outflags |= MMAN_sp;
1401                 outflags &= ~MMAN_br;
1402                 switch (bln->norm->Bl.type) {
1403                 case LIST_item:
1404                         return 0;
1405                 case LIST_inset:
1406                 case LIST_diag:
1407                 case LIST_ohang:
1408                         if (bln->norm->Bl.type == LIST_diag)
1409                                 print_line(".B \"", 0);
1410                         else
1411                                 print_line(".R \"", 0);
1412                         outflags &= ~MMAN_spc;
1413                         return 1;
1414                 case LIST_bullet:
1415                 case LIST_dash:
1416                 case LIST_hyphen:
1417                         print_width(&bln->norm->Bl, NULL);
1418                         TPremain = 0;
1419                         outflags |= MMAN_nl;
1420                         font_push('B');
1421                         if (LIST_bullet == bln->norm->Bl.type)
1422                                 print_word("\\(bu");
1423                         else
1424                                 print_word("-");
1425                         font_pop();
1426                         outflags |= MMAN_nl;
1427                         return 0;
1428                 case LIST_enum:
1429                         print_width(&bln->norm->Bl, NULL);
1430                         TPremain = 0;
1431                         outflags |= MMAN_nl;


1530                         break;
1531                 }
1532                 break;
1533         default:
1534                 break;
1535         }
1536 }
1537 
1538 static void
1539 post_lb(DECL_ARGS)
1540 {
1541 
1542         if (SEC_LIBRARY == n->sec)
1543                 outflags |= MMAN_br;
1544 }
1545 
1546 static int
1547 pre_lk(DECL_ARGS)
1548 {
1549         const struct roff_node *link, *descr, *punct;
1550         int display;
1551 
1552         if ((link = n->child) == NULL)
1553                 return 0;
1554 
1555         /* Find beginning of trailing punctuation. */
1556         punct = n->last;
1557         while (punct != link && punct->flags & NODE_DELIMC)
1558                 punct = punct->prev;
1559         punct = punct->next;
1560 
1561         /* Link text. */
1562         if ((descr = link->next) != NULL && descr != punct) {
1563                 font_push('I');
1564                 while (descr != punct) {
1565                         print_word(descr->string);
1566                         descr = descr->next;
1567                 }
1568                 font_pop();
1569                 print_word(":");
1570         }
1571 
1572         /* Link target. */
1573         display = man_strlen(link->string) >= 26;
1574         if (display) {
1575                 print_line(".RS", MMAN_Bk_susp);
1576                 print_word("6n");
1577                 outflags |= MMAN_nl;
1578         }
1579         font_push('B');
1580         print_word(link->string);
1581         font_pop();
1582 
1583         /* Trailing punctuation. */
1584         while (punct != NULL) {
1585                 print_word(punct->string);
1586                 punct = punct->next;
1587         }
1588         if (display)
1589                 print_line(".RE", MMAN_nl);
1590         return 0;
1591 }
1592 
1593 static void
1594 pre_onearg(DECL_ARGS)
1595 {
1596         outflags |= MMAN_nl;
1597         print_word(".");
1598         outflags &= ~MMAN_spc;
1599         print_word(roff_name[n->tok]);
1600         if (n->child != NULL)
1601                 print_word(n->child->string);
1602         outflags |= MMAN_nl;
1603         if (n->tok == ROFF_ce)
1604                 for (n = n->child->next; n != NULL; n = n->next)
1605                         print_node(meta, n);
1606 }
1607 
1608 static int
1609 pre_li(DECL_ARGS)


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


 185         { NULL, pre_em, post_percent, NULL, NULL }, /* %I */
 186         { NULL, pre_em, post_percent, NULL, NULL }, /* %J */
 187         { NULL, NULL, post_percent, NULL, NULL }, /* %N */
 188         { NULL, NULL, post_percent, NULL, NULL }, /* %O */
 189         { NULL, NULL, post_percent, NULL, NULL }, /* %P */
 190         { NULL, NULL, post_percent, NULL, NULL }, /* %R */
 191         { NULL, pre__t, post__t, NULL, NULL }, /* %T */
 192         { NULL, NULL, post_percent, NULL, NULL }, /* %V */
 193         { NULL, NULL, NULL, NULL, NULL }, /* Ac */
 194         { cond_body, pre_aq, post_aq, NULL, NULL }, /* Ao */
 195         { cond_body, pre_aq, post_aq, NULL, NULL }, /* Aq */
 196         { NULL, NULL, NULL, NULL, NULL }, /* At */
 197         { NULL, NULL, NULL, NULL, NULL }, /* Bc */
 198         { NULL, pre_bf, post_bf, NULL, NULL }, /* Bf */
 199         { cond_body, pre_enc, post_enc, "[", "]" }, /* Bo */
 200         { cond_body, pre_enc, post_enc, "[", "]" }, /* Bq */
 201         { NULL, pre_bk, post_bk, NULL, NULL }, /* Bsx */
 202         { NULL, pre_bk, post_bk, NULL, NULL }, /* Bx */
 203         { NULL, pre_skip, NULL, NULL, NULL }, /* Db */
 204         { NULL, NULL, NULL, NULL, NULL }, /* Dc */
 205         { cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Do */
 206         { cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Dq */
 207         { NULL, NULL, NULL, NULL, NULL }, /* Ec */
 208         { NULL, NULL, NULL, NULL, NULL }, /* Ef */
 209         { NULL, pre_em, post_font, NULL, NULL }, /* Em */
 210         { cond_body, pre_eo, post_eo, NULL, NULL }, /* Eo */
 211         { NULL, pre_bk, post_bk, NULL, NULL }, /* Fx */
 212         { NULL, pre_sy, post_font, NULL, NULL }, /* Ms */
 213         { NULL, pre_no, NULL, NULL, NULL }, /* No */
 214         { NULL, pre_ns, NULL, NULL, NULL }, /* Ns */
 215         { NULL, pre_bk, post_bk, NULL, NULL }, /* Nx */
 216         { NULL, pre_bk, post_bk, NULL, NULL }, /* Ox */
 217         { NULL, NULL, NULL, NULL, NULL }, /* Pc */
 218         { NULL, NULL, post_pf, NULL, NULL }, /* Pf */
 219         { cond_body, pre_enc, post_enc, "(", ")" }, /* Po */
 220         { cond_body, pre_enc, post_enc, "(", ")" }, /* Pq */
 221         { NULL, NULL, NULL, NULL, NULL }, /* Qc */
 222         { cond_body, pre_enc, post_enc, "\\(oq", "\\(cq" }, /* Ql */
 223         { cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qo */
 224         { cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qq */
 225         { NULL, NULL, NULL, NULL, NULL }, /* Re */
 226         { cond_body, pre_rs, NULL, NULL, NULL }, /* Rs */


 593 }
 594 
 595 void
 596 man_man(void *arg, const struct roff_man *man)
 597 {
 598 
 599         /*
 600          * Dump the keep buffer.
 601          * We're guaranteed by now that this exists (is non-NULL).
 602          * Flush stdout afterward, just in case.
 603          */
 604         fputs(mparse_getkeep(man_mparse(man)), stdout);
 605         fflush(stdout);
 606 }
 607 
 608 void
 609 man_mdoc(void *arg, const struct roff_man *mdoc)
 610 {
 611         struct roff_node *n;
 612 
 613         printf(".\\\" Automatically generated from an mdoc input file."
 614             "  Do not edit.\n");
 615         for (n = mdoc->first->child; n != NULL; n = n->next) {
 616                 if (n->type != ROFFT_COMMENT)
 617                         break;
 618                 printf(".\\\"%s\n", n->string);
 619         }
 620 
 621         printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n",
 622             mdoc->meta.title,
 623             (mdoc->meta.msec == NULL ? "" : mdoc->meta.msec),
 624             mdoc->meta.date, mdoc->meta.os, mdoc->meta.vol);
 625 
 626         /* Disable hyphenation and if nroff, disable justification. */
 627         printf(".nh\n.if n .ad l");
 628 
 629         outflags = MMAN_nl | MMAN_Sm;
 630         if (0 == fontqueue.size) {
 631                 fontqueue.size = 8;
 632                 fontqueue.head = fontqueue.tail = mandoc_malloc(8);
 633                 *fontqueue.tail = 'R';
 634         }
 635         for (; n != NULL; n = n->next)
 636                 print_node(&mdoc->meta, n);
 637         putchar('\n');
 638 }
 639 
 640 static void
 641 print_node(DECL_ARGS)
 642 {
 643         const struct manact     *act;
 644         struct roff_node        *sub;
 645         int                      cond, do_sub;
 646 
 647         if (n->flags & NODE_NOPRT)
 648                 return;
 649 
 650         /*
 651          * Break the line if we were parsed subsequent the current node.
 652          * This makes the page structure be more consistent.
 653          */
 654         if (MMAN_spc & outflags && NODE_LINE & n->flags)
 655                 outflags |= MMAN_nl;


1399         const struct roff_node *bln;
1400 
1401         switch (n->type) {
1402         case ROFFT_HEAD:
1403                 outflags |= MMAN_PP | MMAN_nl;
1404                 bln = n->parent->parent;
1405                 if (0 == bln->norm->Bl.comp ||
1406                     (NULL == n->parent->prev &&
1407                      NULL == bln->parent->prev))
1408                         outflags |= MMAN_sp;
1409                 outflags &= ~MMAN_br;
1410                 switch (bln->norm->Bl.type) {
1411                 case LIST_item:
1412                         return 0;
1413                 case LIST_inset:
1414                 case LIST_diag:
1415                 case LIST_ohang:
1416                         if (bln->norm->Bl.type == LIST_diag)
1417                                 print_line(".B \"", 0);
1418                         else
1419                                 print_line(".BR \\& \"", 0);
1420                         outflags &= ~MMAN_spc;
1421                         return 1;
1422                 case LIST_bullet:
1423                 case LIST_dash:
1424                 case LIST_hyphen:
1425                         print_width(&bln->norm->Bl, NULL);
1426                         TPremain = 0;
1427                         outflags |= MMAN_nl;
1428                         font_push('B');
1429                         if (LIST_bullet == bln->norm->Bl.type)
1430                                 print_word("\\(bu");
1431                         else
1432                                 print_word("-");
1433                         font_pop();
1434                         outflags |= MMAN_nl;
1435                         return 0;
1436                 case LIST_enum:
1437                         print_width(&bln->norm->Bl, NULL);
1438                         TPremain = 0;
1439                         outflags |= MMAN_nl;


1538                         break;
1539                 }
1540                 break;
1541         default:
1542                 break;
1543         }
1544 }
1545 
1546 static void
1547 post_lb(DECL_ARGS)
1548 {
1549 
1550         if (SEC_LIBRARY == n->sec)
1551                 outflags |= MMAN_br;
1552 }
1553 
1554 static int
1555 pre_lk(DECL_ARGS)
1556 {
1557         const struct roff_node *link, *descr, *punct;

1558 
1559         if ((link = n->child) == NULL)
1560                 return 0;
1561 
1562         /* Find beginning of trailing punctuation. */
1563         punct = n->last;
1564         while (punct != link && punct->flags & NODE_DELIMC)
1565                 punct = punct->prev;
1566         punct = punct->next;
1567 
1568         /* Link text. */
1569         if ((descr = link->next) != NULL && descr != punct) {
1570                 font_push('I');
1571                 while (descr != punct) {
1572                         print_word(descr->string);
1573                         descr = descr->next;
1574                 }
1575                 font_pop();
1576                 print_word(":");
1577         }
1578 
1579         /* Link target. */






1580         font_push('B');
1581         print_word(link->string);
1582         font_pop();
1583 
1584         /* Trailing punctuation. */
1585         while (punct != NULL) {
1586                 print_word(punct->string);
1587                 punct = punct->next;
1588         }


1589         return 0;
1590 }
1591 
1592 static void
1593 pre_onearg(DECL_ARGS)
1594 {
1595         outflags |= MMAN_nl;
1596         print_word(".");
1597         outflags &= ~MMAN_spc;
1598         print_word(roff_name[n->tok]);
1599         if (n->child != NULL)
1600                 print_word(n->child->string);
1601         outflags |= MMAN_nl;
1602         if (n->tok == ROFF_ce)
1603                 for (n = n->child->next; n != NULL; n = n->next)
1604                         print_node(meta, n);
1605 }
1606 
1607 static int
1608 pre_li(DECL_ARGS)