Print this page
5051 import mdocml-1.12.3
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Approved by: TBD

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/mandoc/mdoc_term.c
          +++ new/usr/src/cmd/mandoc/mdoc_term.c
   1      -/*      $Id: mdoc_term.c,v 1.238 2011/11/13 13:15:14 schwarze Exp $ */
        1 +/*      $Id: mdoc_term.c,v 1.258 2013/12/25 21:24:12 schwarze Exp $ */
   2    2  /*
   3    3   * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
   4      - * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org>
        4 + * Copyright (c) 2010, 2012, 2013 Ingo Schwarze <schwarze@openbsd.org>
        5 + * Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
   5    6   *
   6    7   * Permission to use, copy, modify, and distribute this software for any
   7    8   * purpose with or without fee is hereby granted, provided that the above
   8    9   * copyright notice and this permission notice appear in all copies.
   9   10   *
  10   11   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11   12   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12   13   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13   14   * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14   15   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
↓ open down ↓ 19 lines elided ↑ open up ↑
  34   35  #include "mdoc.h"
  35   36  #include "main.h"
  36   37  
  37   38  struct  termpair {
  38   39          struct termpair  *ppair;
  39   40          int               count;
  40   41  };
  41   42  
  42   43  #define DECL_ARGS struct termp *p, \
  43   44                    struct termpair *pair, \
  44      -                  const struct mdoc_meta *m, \
  45      -                  const struct mdoc_node *n
       45 +                  const struct mdoc_meta *meta, \
       46 +                  struct mdoc_node *n
  46   47  
  47   48  struct  termact {
  48   49          int     (*pre)(DECL_ARGS);
  49   50          void    (*post)(DECL_ARGS);
  50   51  };
  51   52  
  52   53  static  size_t    a2width(const struct termp *, const char *);
  53   54  static  size_t    a2height(const struct termp *, const char *);
  54   55  static  size_t    a2offs(const struct termp *, const char *);
  55   56  
↓ open down ↓ 6 lines elided ↑ open up ↑
  62   63  static  void      print_mdoc_foot(struct termp *, const void *);
  63   64  static  void      synopsis_pre(struct termp *, 
  64   65                          const struct mdoc_node *);
  65   66  
  66   67  static  void      termp____post(DECL_ARGS);
  67   68  static  void      termp__t_post(DECL_ARGS);
  68   69  static  void      termp_an_post(DECL_ARGS);
  69   70  static  void      termp_bd_post(DECL_ARGS);
  70   71  static  void      termp_bk_post(DECL_ARGS);
  71   72  static  void      termp_bl_post(DECL_ARGS);
  72      -static  void      termp_d1_post(DECL_ARGS);
       73 +static  void      termp_fd_post(DECL_ARGS);
  73   74  static  void      termp_fo_post(DECL_ARGS);
  74   75  static  void      termp_in_post(DECL_ARGS);
  75   76  static  void      termp_it_post(DECL_ARGS);
  76   77  static  void      termp_lb_post(DECL_ARGS);
  77   78  static  void      termp_nm_post(DECL_ARGS);
  78   79  static  void      termp_pf_post(DECL_ARGS);
  79   80  static  void      termp_quote_post(DECL_ARGS);
  80   81  static  void      termp_sh_post(DECL_ARGS);
  81   82  static  void      termp_ss_post(DECL_ARGS);
  82   83  
↓ open down ↓ 10 lines elided ↑ open up ↑
  93   94  static  int       termp_bx_pre(DECL_ARGS);
  94   95  static  int       termp_cd_pre(DECL_ARGS);
  95   96  static  int       termp_d1_pre(DECL_ARGS);
  96   97  static  int       termp_ex_pre(DECL_ARGS);
  97   98  static  int       termp_fa_pre(DECL_ARGS);
  98   99  static  int       termp_fd_pre(DECL_ARGS);
  99  100  static  int       termp_fl_pre(DECL_ARGS);
 100  101  static  int       termp_fn_pre(DECL_ARGS);
 101  102  static  int       termp_fo_pre(DECL_ARGS);
 102  103  static  int       termp_ft_pre(DECL_ARGS);
 103      -static  int       termp_igndelim_pre(DECL_ARGS);
 104  104  static  int       termp_in_pre(DECL_ARGS);
 105  105  static  int       termp_it_pre(DECL_ARGS);
 106  106  static  int       termp_li_pre(DECL_ARGS);
 107  107  static  int       termp_lk_pre(DECL_ARGS);
 108  108  static  int       termp_nd_pre(DECL_ARGS);
 109  109  static  int       termp_nm_pre(DECL_ARGS);
 110  110  static  int       termp_ns_pre(DECL_ARGS);
 111  111  static  int       termp_quote_pre(DECL_ARGS);
 112  112  static  int       termp_rs_pre(DECL_ARGS);
 113  113  static  int       termp_rv_pre(DECL_ARGS);
↓ open down ↓ 8 lines elided ↑ open up ↑
 122  122  static  int       termp_xx_pre(DECL_ARGS);
 123  123  
 124  124  static  const struct termact termacts[MDOC_MAX] = {
 125  125          { termp_ap_pre, NULL }, /* Ap */
 126  126          { NULL, NULL }, /* Dd */
 127  127          { NULL, NULL }, /* Dt */
 128  128          { NULL, NULL }, /* Os */
 129  129          { termp_sh_pre, termp_sh_post }, /* Sh */
 130  130          { termp_ss_pre, termp_ss_post }, /* Ss */ 
 131  131          { termp_sp_pre, NULL }, /* Pp */ 
 132      -        { termp_d1_pre, termp_d1_post }, /* D1 */
 133      -        { termp_d1_pre, termp_d1_post }, /* Dl */
      132 +        { termp_d1_pre, termp_bl_post }, /* D1 */
      133 +        { termp_d1_pre, termp_bl_post }, /* Dl */
 134  134          { termp_bd_pre, termp_bd_post }, /* Bd */
 135  135          { NULL, NULL }, /* Ed */
 136  136          { termp_bl_pre, termp_bl_post }, /* Bl */
 137  137          { NULL, NULL }, /* El */
 138  138          { termp_it_pre, termp_it_post }, /* It */
 139  139          { termp_under_pre, NULL }, /* Ad */ 
 140  140          { termp_an_pre, termp_an_post }, /* An */
 141  141          { termp_under_pre, NULL }, /* Ar */
 142  142          { termp_cd_pre, NULL }, /* Cd */
 143  143          { termp_bold_pre, NULL }, /* Cm */
 144  144          { NULL, NULL }, /* Dv */ 
 145  145          { NULL, NULL }, /* Er */ 
 146  146          { NULL, NULL }, /* Ev */ 
 147  147          { termp_ex_pre, NULL }, /* Ex */
 148  148          { termp_fa_pre, NULL }, /* Fa */ 
 149      -        { termp_fd_pre, NULL }, /* Fd */ 
      149 +        { termp_fd_pre, termp_fd_post }, /* Fd */ 
 150  150          { termp_fl_pre, NULL }, /* Fl */
 151  151          { termp_fn_pre, NULL }, /* Fn */ 
 152  152          { termp_ft_pre, NULL }, /* Ft */ 
 153  153          { termp_bold_pre, NULL }, /* Ic */ 
 154  154          { termp_in_pre, termp_in_post }, /* In */ 
 155  155          { termp_li_pre, NULL }, /* Li */
 156  156          { termp_nd_pre, NULL }, /* Nd */ 
 157  157          { termp_nm_pre, termp_nm_post }, /* Nm */ 
 158  158          { termp_quote_pre, termp_quote_post }, /* Op */
 159  159          { NULL, NULL }, /* Ot */
↓ open down ↓ 27 lines elided ↑ open up ↑
 187  187          { NULL, NULL }, /* Db */
 188  188          { NULL, NULL }, /* Dc */
 189  189          { termp_quote_pre, termp_quote_post }, /* Do */
 190  190          { termp_quote_pre, termp_quote_post }, /* Dq */
 191  191          { NULL, NULL }, /* Ec */ /* FIXME: no space */
 192  192          { NULL, NULL }, /* Ef */
 193  193          { termp_under_pre, NULL }, /* Em */ 
 194  194          { termp_quote_pre, termp_quote_post }, /* Eo */
 195  195          { termp_xx_pre, NULL }, /* Fx */
 196  196          { termp_bold_pre, NULL }, /* Ms */
 197      -        { termp_igndelim_pre, NULL }, /* No */
      197 +        { NULL, NULL }, /* No */
 198  198          { termp_ns_pre, NULL }, /* Ns */
 199  199          { termp_xx_pre, NULL }, /* Nx */
 200  200          { termp_xx_pre, NULL }, /* Ox */
 201  201          { NULL, NULL }, /* Pc */
 202      -        { termp_igndelim_pre, termp_pf_post }, /* Pf */
      202 +        { NULL, termp_pf_post }, /* Pf */
 203  203          { termp_quote_pre, termp_quote_post }, /* Po */
 204  204          { termp_quote_pre, termp_quote_post }, /* Pq */
 205  205          { NULL, NULL }, /* Qc */
 206  206          { termp_quote_pre, termp_quote_post }, /* Ql */
 207  207          { termp_quote_pre, termp_quote_post }, /* Qo */
 208  208          { termp_quote_pre, termp_quote_post }, /* Qq */
 209  209          { NULL, NULL }, /* Re */
 210  210          { termp_rs_pre, NULL }, /* Rs */
 211  211          { NULL, NULL }, /* Sc */
 212  212          { termp_quote_pre, termp_quote_post }, /* So */
↓ open down ↓ 22 lines elided ↑ open up ↑
 235  235          { termp_quote_pre, termp_quote_post }, /* Brq */ 
 236  236          { termp_quote_pre, termp_quote_post }, /* Bro */ 
 237  237          { NULL, NULL }, /* Brc */ 
 238  238          { NULL, termp____post }, /* %C */ 
 239  239          { NULL, NULL }, /* Es */ /* TODO */
 240  240          { NULL, NULL }, /* En */ /* TODO */
 241  241          { termp_xx_pre, NULL }, /* Dx */ 
 242  242          { NULL, termp____post }, /* %Q */ 
 243  243          { termp_sp_pre, NULL }, /* br */
 244  244          { termp_sp_pre, NULL }, /* sp */ 
 245      -        { termp_under_pre, termp____post }, /* %U */ 
      245 +        { NULL, termp____post }, /* %U */ 
 246  246          { NULL, NULL }, /* Ta */ 
 247  247  };
 248  248  
 249  249  
 250  250  void
 251  251  terminal_mdoc(void *arg, const struct mdoc *mdoc)
 252  252  {
 253  253          const struct mdoc_node  *n;
 254      -        const struct mdoc_meta  *m;
      254 +        const struct mdoc_meta  *meta;
 255  255          struct termp            *p;
 256  256  
 257  257          p = (struct termp *)arg;
 258  258  
 259  259          if (0 == p->defindent)
 260  260                  p->defindent = 5;
 261  261  
 262  262          p->overstep = 0;
 263  263          p->maxrmargin = p->defrmargin;
 264  264          p->tabwidth = term_len(p, 5);
 265  265  
 266  266          if (NULL == p->symtab)
 267  267                  p->symtab = mchars_alloc();
 268  268  
 269  269          n = mdoc_node(mdoc);
 270      -        m = mdoc_meta(mdoc);
      270 +        meta = mdoc_meta(mdoc);
 271  271  
 272      -        term_begin(p, print_mdoc_head, print_mdoc_foot, m);
      272 +        term_begin(p, print_mdoc_head, print_mdoc_foot, meta);
 273  273  
 274  274          if (n->child)
 275      -                print_mdoc_nodelist(p, NULL, m, n->child);
      275 +                print_mdoc_nodelist(p, NULL, meta, n->child);
 276  276  
 277  277          term_end(p);
 278  278  }
 279  279  
 280  280  
 281  281  static void
 282  282  print_mdoc_nodelist(DECL_ARGS)
 283  283  {
 284  284  
 285      -        print_mdoc_node(p, pair, m, n);
      285 +        print_mdoc_node(p, pair, meta, n);
 286  286          if (n->next)
 287      -                print_mdoc_nodelist(p, pair, m, n->next);
      287 +                print_mdoc_nodelist(p, pair, meta, n->next);
 288  288  }
 289  289  
 290  290  
 291  291  /* ARGSUSED */
 292  292  static void
 293  293  print_mdoc_node(DECL_ARGS)
 294  294  {
 295  295          int              chld;
 296      -        const void      *font;
 297  296          struct termpair  npair;
 298  297          size_t           offset, rmargin;
 299  298  
 300  299          chld = 1;
 301  300          offset = p->offset;
 302  301          rmargin = p->rmargin;
 303      -        font = term_fontq(p);
      302 +        n->prev_font = term_fontq(p);
 304  303  
 305  304          memset(&npair, 0, sizeof(struct termpair));
 306  305          npair.ppair = pair;
 307  306  
 308  307          /*
 309  308           * Keeps only work until the end of a line.  If a keep was
 310  309           * invoked in a prior line, revert it to PREKEEP.
 311      -         *
 312      -         * Also let SYNPRETTY sections behave as if they were wrapped
 313      -         * in a `Bk' block.
 314  310           */
 315  311  
 316      -        if (TERMP_KEEP & p->flags || MDOC_SYNPRETTY & n->flags) {
 317      -                if (n->prev && n->prev->line != n->line) {
      312 +        if (TERMP_KEEP & p->flags) {
      313 +                if (n->prev ? (n->prev->lastline != n->line) :
      314 +                    (n->parent && n->parent->line != n->line)) {
 318  315                          p->flags &= ~TERMP_KEEP;
 319  316                          p->flags |= TERMP_PREKEEP;
 320      -                } else if (NULL == n->prev) {
 321      -                        if (n->parent && n->parent->line != n->line) {
 322      -                                p->flags &= ~TERMP_KEEP;
 323      -                                p->flags |= TERMP_PREKEEP;
 324      -                        }
 325  317                  }
 326  318          }
 327  319  
 328  320          /*
 329      -         * Since SYNPRETTY sections aren't "turned off" with `Ek',
 330      -         * we have to intuit whether we should disable formatting.
 331      -         */
 332      -
 333      -        if ( ! (MDOC_SYNPRETTY & n->flags) &&
 334      -            ((n->prev   && MDOC_SYNPRETTY & n->prev->flags) ||
 335      -             (n->parent && MDOC_SYNPRETTY & n->parent->flags)))
 336      -                p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
 337      -
 338      -        /*
 339  321           * After the keep flags have been set up, we may now
 340  322           * produce output.  Note that some pre-handlers do so.
 341  323           */
 342  324  
 343  325          switch (n->type) {
 344  326          case (MDOC_TEXT):
 345  327                  if (' ' == *n->string && MDOC_LINE & n->flags)
 346  328                          term_newln(p);
 347  329                  if (MDOC_DELIMC & n->flags)
 348  330                          p->flags |= TERMP_NOSPACE;
↓ open down ↓ 3 lines elided ↑ open up ↑
 352  334                  break;
 353  335          case (MDOC_EQN):
 354  336                  term_eqn(p, n->eqn);
 355  337                  break;
 356  338          case (MDOC_TBL):
 357  339                  term_tbl(p, n->span);
 358  340                  break;
 359  341          default:
 360  342                  if (termacts[n->tok].pre && ENDBODY_NOT == n->end)
 361  343                          chld = (*termacts[n->tok].pre)
 362      -                                (p, &npair, m, n);
      344 +                                (p, &npair, meta, n);
 363  345                  break;
 364  346          }
 365  347  
 366  348          if (chld && n->child)
 367      -                print_mdoc_nodelist(p, &npair, m, n->child);
      349 +                print_mdoc_nodelist(p, &npair, meta, n->child);
 368  350  
 369      -        term_fontpopq(p, font);
      351 +        term_fontpopq(p,
      352 +            (ENDBODY_NOT == n->end ? n : n->pending)->prev_font);
 370  353  
 371  354          switch (n->type) {
 372  355          case (MDOC_TEXT):
 373  356                  break;
 374  357          case (MDOC_TBL):
 375  358                  break;
 376  359          case (MDOC_EQN):
 377  360                  break;
 378  361          default:
 379  362                  if ( ! termacts[n->tok].post || MDOC_ENDED & n->flags)
 380  363                          break;
 381      -                (void)(*termacts[n->tok].post)(p, &npair, m, n);
      364 +                (void)(*termacts[n->tok].post)(p, &npair, meta, n);
 382  365  
 383  366                  /*
 384  367                   * Explicit end tokens not only call the post
 385  368                   * handler, but also tell the respective block
 386  369                   * that it must not call the post handler again.
 387  370                   */
 388  371                  if (ENDBODY_NOT != n->end)
 389  372                          n->pending->flags |= MDOC_ENDED;
 390  373  
 391  374                  /*
↓ open down ↓ 10 lines elided ↑ open up ↑
 402  385                  p->flags |= TERMP_SENTENCE;
 403  386  
 404  387          p->offset = offset;
 405  388          p->rmargin = rmargin;
 406  389  }
 407  390  
 408  391  
 409  392  static void
 410  393  print_mdoc_foot(struct termp *p, const void *arg)
 411  394  {
 412      -        const struct mdoc_meta *m;
      395 +        const struct mdoc_meta *meta;
 413  396  
 414      -        m = (const struct mdoc_meta *)arg;
      397 +        meta = (const struct mdoc_meta *)arg;
 415  398  
 416  399          term_fontrepl(p, TERMFONT_NONE);
 417  400  
 418  401          /* 
 419  402           * Output the footer in new-groff style, that is, three columns
 420  403           * with the middle being the manual date and flanking columns
 421  404           * being the operating system:
 422  405           *
 423  406           * SYSTEM                  DATE                    SYSTEM
 424  407           */
 425  408  
 426  409          term_vspace(p);
 427  410  
 428  411          p->offset = 0;
 429  412          p->rmargin = (p->maxrmargin - 
 430      -                        term_strlen(p, m->date) + term_len(p, 1)) / 2;
      413 +                        term_strlen(p, meta->date) + term_len(p, 1)) / 2;
      414 +        p->trailspace = 1;
 431  415          p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
 432  416  
 433      -        term_word(p, m->os);
      417 +        term_word(p, meta->os);
 434  418          term_flushln(p);
 435  419  
 436  420          p->offset = p->rmargin;
 437      -        p->rmargin = p->maxrmargin - term_strlen(p, m->os);
      421 +        p->rmargin = p->maxrmargin - term_strlen(p, meta->os);
 438  422          p->flags |= TERMP_NOSPACE;
 439  423  
 440      -        term_word(p, m->date);
      424 +        term_word(p, meta->date);
 441  425          term_flushln(p);
 442  426  
 443  427          p->offset = p->rmargin;
 444  428          p->rmargin = p->maxrmargin;
      429 +        p->trailspace = 0;
 445  430          p->flags &= ~TERMP_NOBREAK;
 446  431          p->flags |= TERMP_NOSPACE;
 447  432  
 448      -        term_word(p, m->os);
      433 +        term_word(p, meta->os);
 449  434          term_flushln(p);
 450  435  
 451  436          p->offset = 0;
 452  437          p->rmargin = p->maxrmargin;
 453  438          p->flags = 0;
 454  439  }
 455  440  
 456  441  
 457  442  static void
 458  443  print_mdoc_head(struct termp *p, const void *arg)
 459  444  {
 460  445          char            buf[BUFSIZ], title[BUFSIZ];
 461  446          size_t          buflen, titlen;
 462      -        const struct mdoc_meta *m;
      447 +        const struct mdoc_meta *meta;
 463  448  
 464      -        m = (const struct mdoc_meta *)arg;
      449 +        meta = (const struct mdoc_meta *)arg;
 465  450  
 466  451          /*
 467  452           * The header is strange.  It has three components, which are
 468  453           * really two with the first duplicated.  It goes like this:
 469  454           *
 470  455           * IDENTIFIER              TITLE                   IDENTIFIER
 471  456           *
 472  457           * The IDENTIFIER is NAME(SECTION), which is the command-name
 473  458           * (if given, or "unknown" if not) followed by the manual page
 474  459           * section.  These are given in `Dt'.  The TITLE is a free-form
 475  460           * string depending on the manual volume.  If not specified, it
 476  461           * switches on the manual section.
 477  462           */
 478  463  
 479  464          p->offset = 0;
 480  465          p->rmargin = p->maxrmargin;
 481  466  
 482      -        assert(m->vol);
 483      -        strlcpy(buf, m->vol, BUFSIZ);
      467 +        assert(meta->vol);
      468 +        strlcpy(buf, meta->vol, BUFSIZ);
 484  469          buflen = term_strlen(p, buf);
 485  470  
 486      -        if (m->arch) {
      471 +        if (meta->arch) {
 487  472                  strlcat(buf, " (", BUFSIZ);
 488      -                strlcat(buf, m->arch, BUFSIZ);
      473 +                strlcat(buf, meta->arch, BUFSIZ);
 489  474                  strlcat(buf, ")", BUFSIZ);
 490  475          }
 491  476  
 492      -        snprintf(title, BUFSIZ, "%s(%s)", m->title, m->msec);
      477 +        snprintf(title, BUFSIZ, "%s(%s)", meta->title, meta->msec);
 493  478          titlen = term_strlen(p, title);
 494  479  
 495  480          p->flags |= TERMP_NOBREAK | TERMP_NOSPACE;
      481 +        p->trailspace = 1;
 496  482          p->offset = 0;
 497  483          p->rmargin = 2 * (titlen+1) + buflen < p->maxrmargin ?
 498  484              (p->maxrmargin -
 499  485               term_strlen(p, buf) + term_len(p, 1)) / 2 :
 500  486              p->maxrmargin - buflen;
 501  487  
 502  488          term_word(p, title);
 503  489          term_flushln(p);
 504  490  
 505  491          p->flags |= TERMP_NOSPACE;
 506  492          p->offset = p->rmargin;
 507  493          p->rmargin = p->offset + buflen + titlen < p->maxrmargin ?
 508  494              p->maxrmargin - titlen : p->maxrmargin;
 509  495  
 510  496          term_word(p, buf);
 511  497          term_flushln(p);
 512  498  
 513  499          p->flags &= ~TERMP_NOBREAK;
      500 +        p->trailspace = 0;
 514  501          if (p->rmargin + titlen <= p->maxrmargin) {
 515  502                  p->flags |= TERMP_NOSPACE;
 516  503                  p->offset = p->rmargin;
 517  504                  p->rmargin = p->maxrmargin;
 518  505                  term_word(p, title);
 519  506                  term_flushln(p);
 520  507          }
 521  508  
 522  509          p->flags &= ~TERMP_NOSPACE;
 523  510          p->offset = 0;
↓ open down ↓ 196 lines elided ↑ open up ↑
 720  707           * values (bullet, dash/hyphen, enum).  Tags need a non-zero
 721  708           * offset.
 722  709           */
 723  710  
 724  711          switch (type) {
 725  712          case (LIST_bullet):
 726  713                  /* FALLTHROUGH */
 727  714          case (LIST_dash):
 728  715                  /* FALLTHROUGH */
 729  716          case (LIST_hyphen):
 730      -                if (width < term_len(p, 4))
 731      -                        width = term_len(p, 4);
 732      -                break;
      717 +                /* FALLTHROUGH */
 733  718          case (LIST_enum):
 734      -                if (width < term_len(p, 5))
 735      -                        width = term_len(p, 5);
      719 +                if (width < term_len(p, 2))
      720 +                        width = term_len(p, 2);
 736  721                  break;
 737  722          case (LIST_hang):
 738  723                  if (0 == width)
 739  724                          width = term_len(p, 8);
 740  725                  break;
 741  726          case (LIST_column):
 742  727                  /* FALLTHROUGH */
 743  728          case (LIST_tag):
 744  729                  if (0 == width)
 745  730                          width = term_len(p, 10);
↓ open down ↓ 34 lines elided ↑ open up ↑
 780  765          }
 781  766  
 782  767          /*
 783  768           * Pad and break control.  This is the tricky part.  These flags
 784  769           * are documented in term_flushln() in term.c.  Note that we're
 785  770           * going to unset all of these flags in termp_it_post() when we
 786  771           * exit.
 787  772           */
 788  773  
 789  774          switch (type) {
      775 +        case (LIST_enum):
      776 +                /*
      777 +                 * Weird special case.
      778 +                 * Very narrow enum lists actually hang.
      779 +                 */
      780 +                if (width == term_len(p, 2))
      781 +                        p->flags |= TERMP_HANG;
      782 +                /* FALLTHROUGH */
 790  783          case (LIST_bullet):
 791  784                  /* FALLTHROUGH */
 792  785          case (LIST_dash):
 793  786                  /* FALLTHROUGH */
 794      -        case (LIST_enum):
 795      -                /* FALLTHROUGH */
 796  787          case (LIST_hyphen):
 797      -                if (MDOC_HEAD == n->type)
 798      -                        p->flags |= TERMP_NOBREAK;
      788 +                if (MDOC_HEAD != n->type)
      789 +                        break;
      790 +                p->flags |= TERMP_NOBREAK;
      791 +                p->trailspace = 1;
 799  792                  break;
 800  793          case (LIST_hang):
 801      -                if (MDOC_HEAD == n->type)
 802      -                        p->flags |= TERMP_NOBREAK;
 803      -                else
      794 +                if (MDOC_HEAD != n->type)
 804  795                          break;
 805  796  
 806  797                  /*
 807  798                   * This is ugly.  If `-hang' is specified and the body
 808  799                   * is a `Bl' or `Bd', then we want basically to nullify
 809  800                   * the "overstep" effect in term_flushln() and treat
 810  801                   * this as a `-ohang' list instead.
 811  802                   */
 812  803                  if (n->next->child && 
 813  804                                  (MDOC_Bl == n->next->child->tok ||
 814  805                                   MDOC_Bd == n->next->child->tok))
 815      -                        p->flags &= ~TERMP_NOBREAK;
 816      -                else
 817      -                        p->flags |= TERMP_HANG;
      806 +                        break;
      807 +
      808 +                p->flags |= TERMP_NOBREAK | TERMP_HANG;
      809 +                p->trailspace = 1;
 818  810                  break;
 819  811          case (LIST_tag):
 820      -                if (MDOC_HEAD == n->type)
 821      -                        p->flags |= TERMP_NOBREAK | TERMP_TWOSPACE;
 822      -
 823  812                  if (MDOC_HEAD != n->type)
 824  813                          break;
      814 +
      815 +                p->flags |= TERMP_NOBREAK;
      816 +                p->trailspace = 2;
      817 +
 825  818                  if (NULL == n->next || NULL == n->next->child)
 826  819                          p->flags |= TERMP_DANGLE;
 827  820                  break;
 828  821          case (LIST_column):
 829  822                  if (MDOC_HEAD == n->type)
 830  823                          break;
 831  824  
 832      -                if (NULL == n->next)
      825 +                if (NULL == n->next) {
 833  826                          p->flags &= ~TERMP_NOBREAK;
 834      -                else
      827 +                        p->trailspace = 0;
      828 +                } else {
 835  829                          p->flags |= TERMP_NOBREAK;
      830 +                        p->trailspace = 1;
      831 +                }
 836  832  
 837  833                  break;
 838  834          case (LIST_diag):
 839      -                if (MDOC_HEAD == n->type)
 840      -                        p->flags |= TERMP_NOBREAK;
      835 +                if (MDOC_HEAD != n->type)
      836 +                        break;
      837 +                p->flags |= TERMP_NOBREAK;
      838 +                p->trailspace = 1;
 841  839                  break;
 842  840          default:
 843  841                  break;
 844  842          }
 845  843  
 846  844          /* 
 847  845           * Margin control.  Set-head-width lists have their right
 848  846           * margins shortened.  The body for these lists has the offset
 849  847           * necessarily lengthened.  Everybody gets the offset.
 850  848           */
↓ open down ↓ 131 lines elided ↑ open up ↑
 982  980          }
 983  981  
 984  982          /* 
 985  983           * Now that our output is flushed, we can reset our tags.  Since
 986  984           * only `It' sets these flags, we're free to assume that nobody
 987  985           * has munged them in the meanwhile.
 988  986           */
 989  987  
 990  988          p->flags &= ~TERMP_DANGLE;
 991  989          p->flags &= ~TERMP_NOBREAK;
 992      -        p->flags &= ~TERMP_TWOSPACE;
 993  990          p->flags &= ~TERMP_HANG;
      991 +        p->trailspace = 0;
 994  992  }
 995  993  
 996  994  
 997  995  /* ARGSUSED */
 998  996  static int
 999  997  termp_nm_pre(DECL_ARGS)
1000  998  {
1001  999  
1002      -        if (MDOC_BLOCK == n->type)
     1000 +        if (MDOC_BLOCK == n->type) {
     1001 +                p->flags |= TERMP_PREKEEP;
1003 1002                  return(1);
     1003 +        }
1004 1004  
1005 1005          if (MDOC_BODY == n->type) {
1006 1006                  if (NULL == n->child)
1007 1007                          return(0);
1008 1008                  p->flags |= TERMP_NOSPACE;
1009 1009                  p->offset += term_len(p, 1) +
1010      -                    (NULL == n->prev->child ? term_strlen(p, m->name) :
     1010 +                    (NULL == n->prev->child ?
     1011 +                     term_strlen(p, meta->name) :
1011 1012                       MDOC_TEXT == n->prev->child->type ?
1012      -                        term_strlen(p, n->prev->child->string) :
     1013 +                     term_strlen(p, n->prev->child->string) :
1013 1014                       term_len(p, 5));
1014 1015                  return(1);
1015 1016          }
1016 1017  
1017      -        if (NULL == n->child && NULL == m->name)
     1018 +        if (NULL == n->child && NULL == meta->name)
1018 1019                  return(0);
1019 1020  
1020 1021          if (MDOC_HEAD == n->type)
1021 1022                  synopsis_pre(p, n->parent);
1022 1023  
1023 1024          if (MDOC_HEAD == n->type && n->next->child) {
1024 1025                  p->flags |= TERMP_NOSPACE | TERMP_NOBREAK;
     1026 +                p->trailspace = 1;
1025 1027                  p->rmargin = p->offset + term_len(p, 1);
1026 1028                  if (NULL == n->child) {
1027      -                        p->rmargin += term_strlen(p, m->name);
     1029 +                        p->rmargin += term_strlen(p, meta->name);
1028 1030                  } else if (MDOC_TEXT == n->child->type) {
1029 1031                          p->rmargin += term_strlen(p, n->child->string);
1030 1032                          if (n->child->next)
1031 1033                                  p->flags |= TERMP_HANG;
1032 1034                  } else {
1033 1035                          p->rmargin += term_len(p, 5);
1034 1036                          p->flags |= TERMP_HANG;
1035 1037                  }
1036 1038          }
1037 1039  
1038 1040          term_fontpush(p, TERMFONT_BOLD);
1039 1041          if (NULL == n->child)
1040      -                term_word(p, m->name);
     1042 +                term_word(p, meta->name);
1041 1043          return(1);
1042 1044  }
1043 1045  
1044 1046  
1045 1047  /* ARGSUSED */
1046 1048  static void
1047 1049  termp_nm_post(DECL_ARGS)
1048 1050  {
1049 1051  
1050      -        if (MDOC_HEAD == n->type && n->next->child) {
     1052 +        if (MDOC_BLOCK == n->type) {
     1053 +                p->flags &= ~(TERMP_KEEP | TERMP_PREKEEP);
     1054 +        } else if (MDOC_HEAD == n->type && n->next->child) {
1051 1055                  term_flushln(p);
1052 1056                  p->flags &= ~(TERMP_NOBREAK | TERMP_HANG);
     1057 +                p->trailspace = 0;
1053 1058          } else if (MDOC_BODY == n->type && n->child)
1054 1059                  term_flushln(p);
1055 1060  }
1056 1061  
1057 1062                  
1058 1063  /* ARGSUSED */
1059 1064  static int
1060 1065  termp_fl_pre(DECL_ARGS)
1061 1066  {
1062 1067  
↓ open down ↓ 305 lines elided ↑ open up ↑
1368 1373          }
1369 1374  }
1370 1375  
1371 1376  
1372 1377  static int
1373 1378  termp_vt_pre(DECL_ARGS)
1374 1379  {
1375 1380  
1376 1381          if (MDOC_ELEM == n->type) {
1377 1382                  synopsis_pre(p, n);
1378      -                return(termp_under_pre(p, pair, m, n));
     1383 +                return(termp_under_pre(p, pair, meta, n));
1379 1384          } else if (MDOC_BLOCK == n->type) {
1380 1385                  synopsis_pre(p, n);
1381 1386                  return(1);
1382 1387          } else if (MDOC_HEAD == n->type)
1383 1388                  return(0);
1384 1389  
1385      -        return(termp_under_pre(p, pair, m, n));
     1390 +        return(termp_under_pre(p, pair, meta, n));
1386 1391  }
1387 1392  
1388 1393  
1389 1394  /* ARGSUSED */
1390 1395  static int
1391 1396  termp_bold_pre(DECL_ARGS)
1392 1397  {
1393 1398  
1394 1399          term_fontpush(p, TERMFONT_BOLD);
1395 1400          return(1);
1396 1401  }
1397 1402  
1398 1403  
1399 1404  /* ARGSUSED */
1400 1405  static int
1401 1406  termp_fd_pre(DECL_ARGS)
1402 1407  {
1403 1408  
1404 1409          synopsis_pre(p, n);
1405      -        return(termp_bold_pre(p, pair, m, n));
     1410 +        return(termp_bold_pre(p, pair, meta, n));
1406 1411  }
1407 1412  
1408 1413  
1409 1414  /* ARGSUSED */
     1415 +static void
     1416 +termp_fd_post(DECL_ARGS)
     1417 +{
     1418 +
     1419 +        term_newln(p);
     1420 +}
     1421 +
     1422 +
     1423 +/* ARGSUSED */
1410 1424  static int
1411 1425  termp_sh_pre(DECL_ARGS)
1412 1426  {
1413 1427  
1414 1428          /* No vspace between consecutive `Sh' calls. */
1415 1429  
1416 1430          switch (n->type) {
1417 1431          case (MDOC_BLOCK):
1418 1432                  if (n->prev && MDOC_Sh == n->prev->tok)
1419 1433                          if (NULL == n->prev->body->child)
1420 1434                                  break;
1421 1435                  term_vspace(p);
1422 1436                  break;
1423 1437          case (MDOC_HEAD):
1424 1438                  term_fontpush(p, TERMFONT_BOLD);
1425 1439                  break;
1426 1440          case (MDOC_BODY):
1427 1441                  p->offset = term_len(p, p->defindent);
     1442 +                if (SEC_AUTHORS == n->sec)
     1443 +                        p->flags &= ~(TERMP_SPLIT|TERMP_NOSPLIT);
1428 1444                  break;
1429 1445          default:
1430 1446                  break;
1431 1447          }
1432 1448          return(1);
1433 1449  }
1434 1450  
1435 1451  
1436 1452  /* ARGSUSED */
1437 1453  static void
↓ open down ↓ 53 lines elided ↑ open up ↑
1491 1507  
1492 1508          if (MDOC_BLOCK != n->type)
1493 1509                  return(1);
1494 1510          term_newln(p);
1495 1511          p->offset += term_len(p, p->defindent + 1);
1496 1512          return(1);
1497 1513  }
1498 1514  
1499 1515  
1500 1516  /* ARGSUSED */
1501      -static void
1502      -termp_d1_post(DECL_ARGS)
1503      -{
1504      -
1505      -        if (MDOC_BLOCK != n->type) 
1506      -                return;
1507      -        term_newln(p);
1508      -}
1509      -
1510      -
1511      -/* ARGSUSED */
1512 1517  static int
1513 1518  termp_ft_pre(DECL_ARGS)
1514 1519  {
1515 1520  
1516 1521          /* NB: MDOC_LINE does not effect this! */
1517 1522          synopsis_pre(p, n);
1518 1523          term_fontpush(p, TERMFONT_UNDER);
1519 1524          return(1);
1520 1525  }
1521 1526  
1522 1527  
1523 1528  /* ARGSUSED */
1524 1529  static int
1525 1530  termp_fn_pre(DECL_ARGS)
1526 1531  {
     1532 +        size_t           rmargin = 0;
1527 1533          int              pretty;
1528 1534  
1529 1535          pretty = MDOC_SYNPRETTY & n->flags;
1530 1536  
1531 1537          synopsis_pre(p, n);
1532 1538  
1533 1539          if (NULL == (n = n->child))
1534 1540                  return(0);
1535 1541  
     1542 +        if (pretty) {
     1543 +                rmargin = p->rmargin;
     1544 +                p->rmargin = p->offset + term_len(p, 4);
     1545 +                p->flags |= TERMP_NOBREAK | TERMP_HANG;
     1546 +        }
     1547 +
1536 1548          assert(MDOC_TEXT == n->type);
1537 1549          term_fontpush(p, TERMFONT_BOLD);
1538 1550          term_word(p, n->string);
1539 1551          term_fontpop(p);
1540 1552  
     1553 +        if (pretty) {
     1554 +                term_flushln(p);
     1555 +                p->flags &= ~(TERMP_NOBREAK | TERMP_HANG);
     1556 +                p->offset = p->rmargin;
     1557 +                p->rmargin = rmargin;
     1558 +        }
     1559 +
1541 1560          p->flags |= TERMP_NOSPACE;
1542 1561          term_word(p, "(");
1543 1562          p->flags |= TERMP_NOSPACE;
1544 1563  
1545 1564          for (n = n->next; n; n = n->next) {
1546 1565                  assert(MDOC_TEXT == n->type);
1547 1566                  term_fontpush(p, TERMFONT_UNDER);
     1567 +                if (pretty)
     1568 +                        p->flags |= TERMP_NBRWORD;
1548 1569                  term_word(p, n->string);
1549 1570                  term_fontpop(p);
1550 1571  
1551 1572                  if (n->next) {
1552 1573                          p->flags |= TERMP_NOSPACE;
1553 1574                          term_word(p, ",");
1554 1575                  }
1555 1576          }
1556 1577  
1557 1578          p->flags |= TERMP_NOSPACE;
1558 1579          term_word(p, ")");
1559 1580  
1560 1581          if (pretty) {
1561 1582                  p->flags |= TERMP_NOSPACE;
1562 1583                  term_word(p, ";");
     1584 +                term_flushln(p);
1563 1585          }
1564 1586  
1565 1587          return(0);
1566 1588  }
1567 1589  
1568 1590  
1569 1591  /* ARGSUSED */
1570 1592  static int
1571 1593  termp_fa_pre(DECL_ARGS)
1572 1594  {
1573 1595          const struct mdoc_node  *nn;
1574 1596  
1575 1597          if (n->parent->tok != MDOC_Fo) {
1576 1598                  term_fontpush(p, TERMFONT_UNDER);
1577 1599                  return(1);
1578 1600          }
1579 1601  
1580 1602          for (nn = n->child; nn; nn = nn->next) {
1581 1603                  term_fontpush(p, TERMFONT_UNDER);
     1604 +                p->flags |= TERMP_NBRWORD;
1582 1605                  term_word(p, nn->string);
1583 1606                  term_fontpop(p);
1584 1607  
1585      -                if (nn->next) {
     1608 +                if (nn->next || (n->next && n->next->tok == MDOC_Fa)) {
1586 1609                          p->flags |= TERMP_NOSPACE;
1587 1610                          term_word(p, ",");
1588 1611                  }
1589 1612          }
1590 1613  
1591      -        if (n->child && n->next && n->next->tok == MDOC_Fa) {
1592      -                p->flags |= TERMP_NOSPACE;
1593      -                term_word(p, ",");
1594      -        }
1595      -
1596 1614          return(0);
1597 1615  }
1598 1616  
1599 1617  
1600 1618  /* ARGSUSED */
1601 1619  static int
1602 1620  termp_bd_pre(DECL_ARGS)
1603 1621  {
1604 1622          size_t                   tabwidth, rm, rmax;
1605      -        const struct mdoc_node  *nn;
     1623 +        struct mdoc_node        *nn;
1606 1624  
1607 1625          if (MDOC_BLOCK == n->type) {
1608 1626                  print_bvspace(p, n, n);
1609 1627                  return(1);
1610 1628          } else if (MDOC_HEAD == n->type)
1611 1629                  return(0);
1612 1630  
1613 1631          if (n->norm->Bd.offs)
1614 1632                  p->offset += a2offs(p, n->norm->Bd.offs);
1615 1633  
↓ open down ↓ 11 lines elided ↑ open up ↑
1627 1645  
1628 1646          tabwidth = p->tabwidth;
1629 1647          if (DISP_literal == n->norm->Bd.type)
1630 1648                  p->tabwidth = term_len(p, 8);
1631 1649  
1632 1650          rm = p->rmargin;
1633 1651          rmax = p->maxrmargin;
1634 1652          p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
1635 1653  
1636 1654          for (nn = n->child; nn; nn = nn->next) {
1637      -                print_mdoc_node(p, pair, m, nn);
     1655 +                print_mdoc_node(p, pair, meta, nn);
1638 1656                  /*
1639 1657                   * If the printed node flushes its own line, then we
1640 1658                   * needn't do it here as well.  This is hacky, but the
1641 1659                   * notion of selective eoln whitespace is pretty dumb
1642 1660                   * anyway, so don't sweat it.
1643 1661                   */
1644 1662                  switch (nn->tok) {
1645 1663                  case (MDOC_Sm):
1646 1664                          /* FALLTHROUGH */
1647 1665                  case (MDOC_br):
↓ open down ↓ 96 lines elided ↑ open up ↑
1744 1762          case (MDOC_Nx):
1745 1763                  pp = "NetBSD";
1746 1764                  break;
1747 1765          case (MDOC_Ox):
1748 1766                  pp = "OpenBSD";
1749 1767                  break;
1750 1768          case (MDOC_Ux):
1751 1769                  pp = "UNIX";
1752 1770                  break;
1753 1771          default:
1754      -                break;
     1772 +                abort();
     1773 +                /* NOTREACHED */
1755 1774          }
1756 1775  
1757 1776          term_word(p, pp);
1758 1777          if (n->child) {
1759 1778                  flags = p->flags;
1760 1779                  p->flags |= TERMP_KEEP;
1761 1780                  term_word(p, n->child->string);
1762 1781                  p->flags = flags;
1763 1782          }
1764 1783          return(0);
1765 1784  }
1766 1785  
1767 1786  
1768 1787  /* ARGSUSED */
1769      -static int
1770      -termp_igndelim_pre(DECL_ARGS)
1771      -{
1772      -
1773      -        p->flags |= TERMP_IGNDELIM;
1774      -        return(1);
1775      -}
1776      -
1777      -
1778      -/* ARGSUSED */
1779 1788  static void
1780 1789  termp_pf_post(DECL_ARGS)
1781 1790  {
1782 1791  
1783 1792          p->flags |= TERMP_NOSPACE;
1784 1793  }
1785 1794  
1786 1795  
1787 1796  /* ARGSUSED */
1788 1797  static int
↓ open down ↓ 127 lines elided ↑ open up ↑
1916 1925          case (MDOC_Op):
1917 1926                  /* FALLTHROUGH */
1918 1927          case (MDOC_Bo):
1919 1928                  /* FALLTHROUGH */
1920 1929          case (MDOC_Bq):
1921 1930                  term_word(p, "[");
1922 1931                  break;
1923 1932          case (MDOC_Do):
1924 1933                  /* FALLTHROUGH */
1925 1934          case (MDOC_Dq):
1926      -                term_word(p, "``");
     1935 +                term_word(p, "\\(lq");
1927 1936                  break;
1928 1937          case (MDOC_Eo):
1929 1938                  break;
1930 1939          case (MDOC_Po):
1931 1940                  /* FALLTHROUGH */
1932 1941          case (MDOC_Pq):
1933 1942                  term_word(p, "(");
1934 1943                  break;
1935 1944          case (MDOC__T):
1936 1945                  /* FALLTHROUGH */
1937 1946          case (MDOC_Qo):
1938 1947                  /* FALLTHROUGH */
1939 1948          case (MDOC_Qq):
1940 1949                  term_word(p, "\"");
1941 1950                  break;
1942 1951          case (MDOC_Ql):
1943 1952                  /* FALLTHROUGH */
1944 1953          case (MDOC_So):
1945 1954                  /* FALLTHROUGH */
1946 1955          case (MDOC_Sq):
1947      -                term_word(p, "`");
     1956 +                term_word(p, "\\(oq");
1948 1957                  break;
1949 1958          default:
1950 1959                  abort();
1951 1960                  /* NOTREACHED */
1952 1961          }
1953 1962  
1954 1963          p->flags |= TERMP_NOSPACE;
1955 1964          return(1);
1956 1965  }
1957 1966  
↓ open down ↓ 24 lines elided ↑ open up ↑
1982 1991          case (MDOC_Op):
1983 1992                  /* FALLTHROUGH */
1984 1993          case (MDOC_Bo):
1985 1994                  /* FALLTHROUGH */
1986 1995          case (MDOC_Bq):
1987 1996                  term_word(p, "]");
1988 1997                  break;
1989 1998          case (MDOC_Do):
1990 1999                  /* FALLTHROUGH */
1991 2000          case (MDOC_Dq):
1992      -                term_word(p, "''");
     2001 +                term_word(p, "\\(rq");
1993 2002                  break;
1994 2003          case (MDOC_Eo):
1995 2004                  break;
1996 2005          case (MDOC_Po):
1997 2006                  /* FALLTHROUGH */
1998 2007          case (MDOC_Pq):
1999 2008                  term_word(p, ")");
2000 2009                  break;
2001 2010          case (MDOC__T):
2002 2011                  /* FALLTHROUGH */
2003 2012          case (MDOC_Qo):
2004 2013                  /* FALLTHROUGH */
2005 2014          case (MDOC_Qq):
2006 2015                  term_word(p, "\"");
2007 2016                  break;
2008 2017          case (MDOC_Ql):
2009 2018                  /* FALLTHROUGH */
2010 2019          case (MDOC_So):
2011 2020                  /* FALLTHROUGH */
2012 2021          case (MDOC_Sq):
2013      -                term_word(p, "'");
     2022 +                term_word(p, "\\(cq");
2014 2023                  break;
2015 2024          default:
2016 2025                  abort();
2017 2026                  /* NOTREACHED */
2018 2027          }
2019 2028  }
2020 2029  
2021 2030  
2022 2031  /* ARGSUSED */
2023 2032  static int
2024 2033  termp_fo_pre(DECL_ARGS)
2025 2034  {
     2035 +        size_t           rmargin = 0;
     2036 +        int              pretty;
2026 2037  
     2038 +        pretty = MDOC_SYNPRETTY & n->flags;
     2039 +
2027 2040          if (MDOC_BLOCK == n->type) {
2028 2041                  synopsis_pre(p, n);
2029 2042                  return(1);
2030 2043          } else if (MDOC_BODY == n->type) {
     2044 +                if (pretty) {
     2045 +                        rmargin = p->rmargin;
     2046 +                        p->rmargin = p->offset + term_len(p, 4);
     2047 +                        p->flags |= TERMP_NOBREAK | TERMP_HANG;
     2048 +                }
2031 2049                  p->flags |= TERMP_NOSPACE;
2032 2050                  term_word(p, "(");
2033 2051                  p->flags |= TERMP_NOSPACE;
     2052 +                if (pretty) {
     2053 +                        term_flushln(p);
     2054 +                        p->flags &= ~(TERMP_NOBREAK | TERMP_HANG);
     2055 +                        p->offset = p->rmargin;
     2056 +                        p->rmargin = rmargin;
     2057 +                }
2034 2058                  return(1);
2035      -        } 
     2059 +        }
2036 2060  
2037 2061          if (NULL == n->child)
2038 2062                  return(0);
2039 2063  
2040 2064          /* XXX: we drop non-initial arguments as per groff. */
2041 2065  
2042 2066          assert(n->child->string);
2043 2067          term_fontpush(p, TERMFONT_BOLD);
2044 2068          term_word(p, n->child->string);
2045 2069          return(0);
↓ open down ↓ 7 lines elided ↑ open up ↑
2053 2077  
2054 2078          if (MDOC_BODY != n->type) 
2055 2079                  return;
2056 2080  
2057 2081          p->flags |= TERMP_NOSPACE;
2058 2082          term_word(p, ")");
2059 2083  
2060 2084          if (MDOC_SYNPRETTY & n->flags) {
2061 2085                  p->flags |= TERMP_NOSPACE;
2062 2086                  term_word(p, ";");
     2087 +                term_flushln(p);
2063 2088          }
2064 2089  }
2065 2090  
2066 2091  
2067 2092  /* ARGSUSED */
2068 2093  static int
2069 2094  termp_bf_pre(DECL_ARGS)
2070 2095  {
2071 2096  
2072 2097          if (MDOC_HEAD == n->type)
2073 2098                  return(0);
2074      -        else if (MDOC_BLOCK != n->type)
     2099 +        else if (MDOC_BODY != n->type)
2075 2100                  return(1);
2076 2101  
2077 2102          if (FONT_Em == n->norm->Bf.font) 
2078 2103                  term_fontpush(p, TERMFONT_UNDER);
2079 2104          else if (FONT_Sy == n->norm->Bf.font) 
2080 2105                  term_fontpush(p, TERMFONT_BOLD);
2081 2106          else 
2082 2107                  term_fontpush(p, TERMFONT_NONE);
2083 2108  
2084 2109          return(1);
↓ open down ↓ 65 lines elided ↑ open up ↑
2150 2175  
2151 2176          term_fontpush(p, TERMFONT_NONE);
2152 2177          return(1);
2153 2178  }
2154 2179  
2155 2180  
2156 2181  /* ARGSUSED */
2157 2182  static int
2158 2183  termp_lk_pre(DECL_ARGS)
2159 2184  {
2160      -        const struct mdoc_node *nn, *sv;
     2185 +        const struct mdoc_node *link, *descr;
2161 2186  
2162      -        term_fontpush(p, TERMFONT_UNDER);
     2187 +        if (NULL == (link = n->child))
     2188 +                return(0);
2163 2189  
2164      -        nn = sv = n->child;
     2190 +        if (NULL != (descr = link->next)) {
     2191 +                term_fontpush(p, TERMFONT_UNDER);
     2192 +                while (NULL != descr) {
     2193 +                        term_word(p, descr->string);
     2194 +                        descr = descr->next;
     2195 +                }
     2196 +                p->flags |= TERMP_NOSPACE;
     2197 +                term_word(p, ":");
     2198 +                term_fontpop(p);
     2199 +        }
2165 2200  
2166      -        if (NULL == nn || NULL == nn->next)
2167      -                return(1);
2168      -
2169      -        for (nn = nn->next; nn; nn = nn->next) 
2170      -                term_word(p, nn->string);
2171      -
2172      -        term_fontpop(p);
2173      -
2174      -        p->flags |= TERMP_NOSPACE;
2175      -        term_word(p, ":");
2176      -
2177 2201          term_fontpush(p, TERMFONT_BOLD);
2178      -        term_word(p, sv->string);
     2202 +        term_word(p, link->string);
2179 2203          term_fontpop(p);
2180 2204  
2181 2205          return(0);
2182 2206  }
2183 2207  
2184 2208  
2185 2209  /* ARGSUSED */
2186 2210  static int
2187 2211  termp_bk_pre(DECL_ARGS)
2188 2212  {
↓ open down ↓ 29 lines elided ↑ open up ↑
2218 2242  static void
2219 2243  termp__t_post(DECL_ARGS)
2220 2244  {
2221 2245  
2222 2246          /*
2223 2247           * If we're in an `Rs' and there's a journal present, then quote
2224 2248           * us instead of underlining us (for disambiguation).
2225 2249           */
2226 2250          if (n->parent && MDOC_Rs == n->parent->tok &&
2227 2251                          n->parent->norm->Rs.quote_T)
2228      -                termp_quote_post(p, pair, m, n);
     2252 +                termp_quote_post(p, pair, meta, n);
2229 2253  
2230      -        termp____post(p, pair, m, n);
     2254 +        termp____post(p, pair, meta, n);
2231 2255  }
2232 2256  
2233 2257  /* ARGSUSED */
2234 2258  static int
2235 2259  termp__t_pre(DECL_ARGS)
2236 2260  {
2237 2261  
2238 2262          /*
2239 2263           * If we're in an `Rs' and there's a journal present, then quote
2240 2264           * us instead of underlining us (for disambiguation).
2241 2265           */
2242 2266          if (n->parent && MDOC_Rs == n->parent->tok &&
2243 2267                          n->parent->norm->Rs.quote_T)
2244      -                return(termp_quote_pre(p, pair, m, n));
     2268 +                return(termp_quote_pre(p, pair, meta, n));
2245 2269  
2246 2270          term_fontpush(p, TERMFONT_UNDER);
2247 2271          return(1);
2248 2272  }
2249 2273  
2250 2274  /* ARGSUSED */
2251 2275  static int
2252 2276  termp_under_pre(DECL_ARGS)
2253 2277  {
2254 2278  
2255 2279          term_fontpush(p, TERMFONT_UNDER);
2256 2280          return(1);
2257 2281  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX