Print this page
9718 update mandoc to 1.14.4

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/mandoc/mdoc_html.c
          +++ new/usr/src/cmd/mandoc/mdoc_html.c
   1      -/*      $Id: mdoc_html.c,v 1.294 2017/07/15 17:57:51 schwarze Exp $ */
        1 +/*      $Id: mdoc_html.c,v 1.310 2018/07/27 17:49:31 schwarze Exp $ */
   2    2  /*
   3    3   * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
   4      - * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
        4 + * Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org>
   5    5   *
   6    6   * Permission to use, copy, modify, and distribute this software for any
   7    7   * purpose with or without fee is hereby granted, provided that the above
   8    8   * copyright notice and this permission notice appear in all copies.
   9    9   *
  10   10   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
  11   11   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12   12   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
  13   13   * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14   14   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
↓ open down ↓ 12 lines elided ↑ open up ↑
  27   27  #include <unistd.h>
  28   28  
  29   29  #include "mandoc_aux.h"
  30   30  #include "mandoc.h"
  31   31  #include "roff.h"
  32   32  #include "mdoc.h"
  33   33  #include "out.h"
  34   34  #include "html.h"
  35   35  #include "main.h"
  36   36  
  37      -#define INDENT           5
  38      -
  39   37  #define MDOC_ARGS         const struct roff_meta *meta, \
  40   38                            struct roff_node *n, \
  41   39                            struct html *h
  42   40  
  43   41  #ifndef MIN
  44   42  #define MIN(a,b)        ((/*CONSTCOND*/(a)<(b))?(a):(b))
  45   43  #endif
  46   44  
  47   45  struct  htmlmdoc {
  48   46          int             (*pre)(MDOC_ARGS);
  49   47          void            (*post)(MDOC_ARGS);
  50   48  };
  51   49  
  52   50  static  char             *cond_id(const struct roff_node *);
  53      -static  void              print_mdoc_head(MDOC_ARGS);
       51 +static  void              print_mdoc_head(const struct roff_meta *,
       52 +                                struct html *);
  54   53  static  void              print_mdoc_node(MDOC_ARGS);
  55   54  static  void              print_mdoc_nodelist(MDOC_ARGS);
  56   55  static  void              synopsis_pre(struct html *,
  57   56                                  const struct roff_node *);
  58   57  
  59      -static  void              mdoc_root_post(MDOC_ARGS);
  60      -static  int               mdoc_root_pre(MDOC_ARGS);
       58 +static  void              mdoc_root_post(const struct roff_meta *,
       59 +                                struct html *);
       60 +static  int               mdoc_root_pre(const struct roff_meta *,
       61 +                                struct html *);
  61   62  
  62   63  static  void              mdoc__x_post(MDOC_ARGS);
  63   64  static  int               mdoc__x_pre(MDOC_ARGS);
  64   65  static  int               mdoc_ad_pre(MDOC_ARGS);
  65   66  static  int               mdoc_an_pre(MDOC_ARGS);
  66   67  static  int               mdoc_ap_pre(MDOC_ARGS);
  67   68  static  int               mdoc_ar_pre(MDOC_ARGS);
  68   69  static  int               mdoc_bd_pre(MDOC_ARGS);
  69   70  static  int               mdoc_bf_pre(MDOC_ARGS);
  70   71  static  void              mdoc_bk_post(MDOC_ARGS);
↓ open down ↓ 206 lines elided ↑ open up ↑
 277  278                  /* FALLTHROUGH */
 278  279          default:
 279  280                  print_otag(h, TAG_BR, "");
 280  281                  break;
 281  282          }
 282  283  }
 283  284  
 284  285  void
 285  286  html_mdoc(void *arg, const struct roff_man *mdoc)
 286  287  {
 287      -        struct html     *h;
 288      -        struct tag      *t;
      288 +        struct html             *h;
      289 +        struct roff_node        *n;
      290 +        struct tag              *t;
 289  291  
 290  292          h = (struct html *)arg;
      293 +        n = mdoc->first->child;
 291  294  
 292  295          if ((h->oflags & HTML_FRAGMENT) == 0) {
 293  296                  print_gen_decls(h);
 294  297                  print_otag(h, TAG_HTML, "");
      298 +                if (n->type == ROFFT_COMMENT)
      299 +                        print_gen_comment(h, n);
 295  300                  t = print_otag(h, TAG_HEAD, "");
 296      -                print_mdoc_head(&mdoc->meta, mdoc->first->child, h);
      301 +                print_mdoc_head(&mdoc->meta, h);
 297  302                  print_tagq(h, t);
 298  303                  print_otag(h, TAG_BODY, "");
 299  304          }
 300  305  
 301      -        mdoc_root_pre(&mdoc->meta, mdoc->first->child, h);
      306 +        mdoc_root_pre(&mdoc->meta, h);
 302  307          t = print_otag(h, TAG_DIV, "c", "manual-text");
 303      -        print_mdoc_nodelist(&mdoc->meta, mdoc->first->child, h);
      308 +        print_mdoc_nodelist(&mdoc->meta, n, h);
 304  309          print_tagq(h, t);
 305      -        mdoc_root_post(&mdoc->meta, mdoc->first->child, h);
      310 +        mdoc_root_post(&mdoc->meta, h);
 306  311          print_tagq(h, NULL);
 307  312  }
 308  313  
 309  314  static void
 310      -print_mdoc_head(MDOC_ARGS)
      315 +print_mdoc_head(const struct roff_meta *meta, struct html *h)
 311  316  {
 312  317          char    *cp;
 313  318  
 314  319          print_gen_head(h);
 315  320  
 316  321          if (meta->arch != NULL && meta->msec != NULL)
 317  322                  mandoc_asprintf(&cp, "%s(%s) (%s)", meta->title,
 318  323                      meta->msec, meta->arch);
 319  324          else if (meta->msec != NULL)
 320  325                  mandoc_asprintf(&cp, "%s(%s)", meta->title, meta->msec);
↓ open down ↓ 16 lines elided ↑ open up ↑
 337  342                  n = n->next;
 338  343          }
 339  344  }
 340  345  
 341  346  static void
 342  347  print_mdoc_node(MDOC_ARGS)
 343  348  {
 344  349          int              child;
 345  350          struct tag      *t;
 346  351  
 347      -        if (n->flags & NODE_NOPRT)
      352 +        if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT)
 348  353                  return;
 349  354  
 350  355          child = 1;
 351  356          t = h->tag;
 352  357          n->flags &= ~NODE_ENDED;
 353  358  
 354  359          switch (n->type) {
 355  360          case ROFFT_TEXT:
 356  361                  /* No tables in this mode... */
 357  362                  assert(NULL == h->tblt);
↓ open down ↓ 64 lines elided ↑ open up ↑
 422  427                      n->flags & NODE_ENDED)
 423  428                          break;
 424  429                  (*mdocs[n->tok].post)(meta, n, h);
 425  430                  if (n->end != ENDBODY_NOT)
 426  431                          n->body->flags |= NODE_ENDED;
 427  432                  break;
 428  433          }
 429  434  }
 430  435  
 431  436  static void
 432      -mdoc_root_post(MDOC_ARGS)
      437 +mdoc_root_post(const struct roff_meta *meta, struct html *h)
 433  438  {
 434  439          struct tag      *t, *tt;
 435  440  
 436  441          t = print_otag(h, TAG_TABLE, "c", "foot");
 437  442          tt = print_otag(h, TAG_TR, "");
 438  443  
 439  444          print_otag(h, TAG_TD, "c", "foot-date");
 440  445          print_text(h, meta->date);
 441  446          print_stagq(h, tt);
 442  447  
 443  448          print_otag(h, TAG_TD, "c", "foot-os");
 444  449          print_text(h, meta->os);
 445  450          print_tagq(h, t);
 446  451  }
 447  452  
 448  453  static int
 449      -mdoc_root_pre(MDOC_ARGS)
      454 +mdoc_root_pre(const struct roff_meta *meta, struct html *h)
 450  455  {
 451  456          struct tag      *t, *tt;
 452  457          char            *volume, *title;
 453  458  
 454  459          if (NULL == meta->arch)
 455  460                  volume = mandoc_strdup(meta->vol);
 456  461          else
 457  462                  mandoc_asprintf(&volume, "%s (%s)",
 458  463                      meta->vol, meta->arch);
 459  464  
↓ open down ↓ 28 lines elided ↑ open up ↑
 488  493  {
 489  494          if (n->child != NULL &&
 490  495              n->child->type == ROFFT_TEXT &&
 491  496              (n->prev == NULL ||
 492  497               (n->prev->type == ROFFT_TEXT &&
 493  498                strcmp(n->prev->string, "|") == 0)) &&
 494  499              (n->parent->tok == MDOC_It ||
 495  500               (n->parent->tok == MDOC_Xo &&
 496  501                n->parent->parent->prev == NULL &&
 497  502                n->parent->parent->parent->tok == MDOC_It)))
 498      -                return html_make_id(n);
      503 +                return html_make_id(n, 1);
 499  504          return NULL;
 500  505  }
 501  506  
 502  507  static int
 503  508  mdoc_sh_pre(MDOC_ARGS)
 504  509  {
 505  510          char    *id;
 506  511  
 507  512          switch (n->type) {
 508  513          case ROFFT_HEAD:
 509      -                id = html_make_id(n);
      514 +                id = html_make_id(n, 1);
 510  515                  print_otag(h, TAG_H1, "cTi", "Sh", id);
 511  516                  if (id != NULL)
 512      -                        print_otag(h, TAG_A, "chR", "selflink", id);
 513      -                free(id);
      517 +                        print_otag(h, TAG_A, "chR", "permalink", id);
 514  518                  break;
 515  519          case ROFFT_BODY:
 516  520                  if (n->sec == SEC_AUTHORS)
 517  521                          h->flags &= ~(HTML_SPLIT|HTML_NOSPLIT);
 518  522                  break;
 519  523          default:
 520  524                  break;
 521  525          }
 522  526          return 1;
 523  527  }
 524  528  
 525  529  static int
 526  530  mdoc_ss_pre(MDOC_ARGS)
 527  531  {
 528  532          char    *id;
 529  533  
 530  534          if (n->type != ROFFT_HEAD)
 531  535                  return 1;
 532  536  
 533      -        id = html_make_id(n);
      537 +        id = html_make_id(n, 1);
 534  538          print_otag(h, TAG_H2, "cTi", "Ss", id);
 535  539          if (id != NULL)
 536      -                print_otag(h, TAG_A, "chR", "selflink", id);
 537      -        free(id);
      540 +                print_otag(h, TAG_A, "chR", "permalink", id);
 538  541          return 1;
 539  542  }
 540  543  
 541  544  static int
 542  545  mdoc_fl_pre(MDOC_ARGS)
 543  546  {
 544  547          char    *id;
 545  548  
 546  549          if ((id = cond_id(n)) != NULL)
 547      -                print_otag(h, TAG_A, "chR", "selflink", id);
 548      -        print_otag(h, TAG_B, "cTi", "Fl", id);
 549      -        free(id);
      550 +                print_otag(h, TAG_A, "chR", "permalink", id);
      551 +        print_otag(h, TAG_CODE, "cTi", "Fl", id);
 550  552  
 551  553          print_text(h, "\\-");
 552  554          if (!(n->child == NULL &&
 553  555              (n->next == NULL ||
 554  556               n->next->type == ROFFT_TEXT ||
 555  557               n->next->flags & NODE_LINE)))
 556  558                  h->flags |= HTML_NOSPACE;
 557  559  
 558  560          return 1;
 559  561  }
 560  562  
 561  563  static int
 562  564  mdoc_cm_pre(MDOC_ARGS)
 563  565  {
 564  566          char    *id;
 565  567  
 566  568          if ((id = cond_id(n)) != NULL)
 567      -                print_otag(h, TAG_A, "chR", "selflink", id);
 568      -        print_otag(h, TAG_B, "cTi", "Cm", id);
 569      -        free(id);
      569 +                print_otag(h, TAG_A, "chR", "permalink", id);
      570 +        print_otag(h, TAG_CODE, "cTi", "Cm", id);
 570  571          return 1;
 571  572  }
 572  573  
 573  574  static int
 574  575  mdoc_nd_pre(MDOC_ARGS)
 575  576  {
 576  577          if (n->type != ROFFT_BODY)
 577  578                  return 1;
 578  579  
 579      -        /* XXX: this tag in theory can contain block elements. */
 580      -
 581  580          print_text(h, "\\(em");
 582      -        print_otag(h, TAG_SPAN, "cT", "Nd");
      581 +        /* Cannot use TAG_SPAN because it may contain blocks. */
      582 +        print_otag(h, TAG_DIV, "cT", "Nd");
 583  583          return 1;
 584  584  }
 585  585  
 586  586  static int
 587  587  mdoc_nm_pre(MDOC_ARGS)
 588  588  {
 589  589          switch (n->type) {
 590  590          case ROFFT_HEAD:
 591  591                  print_otag(h, TAG_TD, "");
 592  592                  /* FALLTHROUGH */
 593  593          case ROFFT_ELEM:
 594      -                print_otag(h, TAG_B, "cT", "Nm");
      594 +                print_otag(h, TAG_CODE, "cT", "Nm");
 595  595                  return 1;
 596  596          case ROFFT_BODY:
 597  597                  print_otag(h, TAG_TD, "");
 598  598                  return 1;
 599  599          default:
 600  600                  break;
 601  601          }
 602  602          synopsis_pre(h, n);
 603  603          print_otag(h, TAG_TABLE, "c", "Nm");
 604  604          print_otag(h, TAG_TR, "");
↓ open down ↓ 49 lines elided ↑ open up ↑
 654  654  {
 655  655          print_otag(h, TAG_SPAN, "c", "Ux");
 656  656          return 1;
 657  657  }
 658  658  
 659  659  static int
 660  660  mdoc_it_pre(MDOC_ARGS)
 661  661  {
 662  662          const struct roff_node  *bl;
 663  663          struct tag              *t;
 664      -        const char              *cattr;
 665  664          enum mdoc_list           type;
 666  665  
 667  666          bl = n->parent;
 668  667          while (bl->tok != MDOC_Bl)
 669  668                  bl = bl->parent;
 670  669          type = bl->norm->Bl.type;
 671  670  
 672  671          switch (type) {
 673  672          case LIST_bullet:
 674      -                cattr = "It-bullet";
 675      -                break;
 676  673          case LIST_dash:
 677  674          case LIST_hyphen:
 678      -                cattr = "It-dash";
 679      -                break;
 680  675          case LIST_item:
 681      -                cattr = "It-item";
 682      -                break;
 683  676          case LIST_enum:
 684      -                cattr = "It-enum";
 685      -                break;
 686      -        case LIST_diag:
 687      -                cattr = "It-diag";
 688      -                break;
 689      -        case LIST_hang:
 690      -                cattr = "It-hang";
 691      -                break;
 692      -        case LIST_inset:
 693      -                cattr = "It-inset";
 694      -                break;
 695      -        case LIST_ohang:
 696      -                cattr = "It-ohang";
 697      -                break;
 698      -        case LIST_tag:
 699      -                cattr = "It-tag";
 700      -                break;
 701      -        case LIST_column:
 702      -                cattr = "It-column";
 703      -                break;
 704      -        default:
 705      -                break;
 706      -        }
 707      -
 708      -        switch (type) {
 709      -        case LIST_bullet:
 710      -        case LIST_dash:
 711      -        case LIST_hyphen:
 712      -        case LIST_item:
 713      -        case LIST_enum:
 714  677                  switch (n->type) {
 715  678                  case ROFFT_HEAD:
 716  679                          return 0;
 717  680                  case ROFFT_BODY:
 718      -                        print_otag(h, TAG_LI, "c", cattr);
      681 +                        print_otag(h, TAG_LI, "");
 719  682                          break;
 720  683                  default:
 721  684                          break;
 722  685                  }
 723  686                  break;
 724  687          case LIST_diag:
 725  688          case LIST_hang:
 726  689          case LIST_inset:
 727  690          case LIST_ohang:
 728  691                  switch (n->type) {
 729  692                  case ROFFT_HEAD:
 730      -                        print_otag(h, TAG_DT, "c", cattr);
 731      -                        if (type == LIST_diag)
 732      -                                print_otag(h, TAG_B, "c", cattr);
      693 +                        print_otag(h, TAG_DT, "");
 733  694                          break;
 734  695                  case ROFFT_BODY:
 735      -                        print_otag(h, TAG_DD, "csw*+l", cattr,
 736      -                            bl->norm->Bl.width);
      696 +                        print_otag(h, TAG_DD, "");
 737  697                          break;
 738  698                  default:
 739  699                          break;
 740  700                  }
 741  701                  break;
 742  702          case LIST_tag:
 743  703                  switch (n->type) {
 744  704                  case ROFFT_HEAD:
 745  705                          if (h->style != NULL && !bl->norm->Bl.comp &&
 746  706                              (n->parent->prev == NULL ||
 747  707                               n->parent->prev->body == NULL ||
 748  708                               n->parent->prev->body->child != NULL)) {
 749      -                                t = print_otag(h, TAG_DT, "csw*+-l",
 750      -                                    cattr, bl->norm->Bl.width);
      709 +                                t = print_otag(h, TAG_DT, "");
 751  710                                  print_text(h, "\\ ");
 752  711                                  print_tagq(h, t);
 753      -                                t = print_otag(h, TAG_DD, "c", cattr);
      712 +                                t = print_otag(h, TAG_DD, "");
 754  713                                  print_text(h, "\\ ");
 755  714                                  print_tagq(h, t);
 756  715                          }
 757      -                        print_otag(h, TAG_DT, "csw*+-l", cattr,
 758      -                            bl->norm->Bl.width);
      716 +                        print_otag(h, TAG_DT, "");
 759  717                          break;
 760  718                  case ROFFT_BODY:
 761  719                          if (n->child == NULL) {
 762      -                                print_otag(h, TAG_DD, "css?", cattr,
 763      -                                    "width", "auto");
      720 +                                print_otag(h, TAG_DD, "s", "width", "auto");
 764  721                                  print_text(h, "\\ ");
 765  722                          } else
 766      -                                print_otag(h, TAG_DD, "c", cattr);
      723 +                                print_otag(h, TAG_DD, "");
 767  724                          break;
 768  725                  default:
 769  726                          break;
 770  727                  }
 771  728                  break;
 772  729          case LIST_column:
 773  730                  switch (n->type) {
 774  731                  case ROFFT_HEAD:
 775  732                          break;
 776  733                  case ROFFT_BODY:
 777      -                        print_otag(h, TAG_TD, "c", cattr);
      734 +                        print_otag(h, TAG_TD, "");
 778  735                          break;
 779  736                  default:
 780      -                        print_otag(h, TAG_TR, "c", cattr);
      737 +                        print_otag(h, TAG_TR, "");
 781  738                  }
 782  739          default:
 783  740                  break;
 784  741          }
 785  742  
 786  743          return 1;
 787  744  }
 788  745  
 789  746  static int
 790  747  mdoc_bl_pre(MDOC_ARGS)
 791  748  {
 792      -        char             cattr[21];
 793      -        struct tag      *t;
      749 +        char             cattr[28];
 794  750          struct mdoc_bl  *bl;
 795      -        size_t           i;
 796  751          enum htmltag     elemtype;
 797  752  
 798      -        bl = &n->norm->Bl;
 799      -
 800  753          switch (n->type) {
 801  754          case ROFFT_BODY:
 802  755                  return 1;
 803      -
 804  756          case ROFFT_HEAD:
 805      -                if (bl->type != LIST_column || bl->ncols == 0)
 806      -                        return 0;
 807      -
 808      -                /*
 809      -                 * For each column, print out the <COL> tag with our
 810      -                 * suggested width.  The last column gets min-width, as
 811      -                 * in terminal mode it auto-sizes to the width of the
 812      -                 * screen and we want to preserve that behaviour.
 813      -                 */
 814      -
 815      -                t = print_otag(h, TAG_COLGROUP, "");
 816      -                for (i = 0; i < bl->ncols - 1; i++)
 817      -                        print_otag(h, TAG_COL, "sw+w", bl->cols[i]);
 818      -                print_otag(h, TAG_COL, "swW", bl->cols[i]);
 819      -                print_tagq(h, t);
 820  757                  return 0;
 821      -
 822  758          default:
 823  759                  break;
 824  760          }
 825  761  
      762 +        bl = &n->norm->Bl;
 826  763          switch (bl->type) {
 827  764          case LIST_bullet:
 828  765                  elemtype = TAG_UL;
 829  766                  (void)strlcpy(cattr, "Bl-bullet", sizeof(cattr));
 830  767                  break;
 831  768          case LIST_dash:
 832  769          case LIST_hyphen:
 833  770                  elemtype = TAG_UL;
 834  771                  (void)strlcpy(cattr, "Bl-dash", sizeof(cattr));
 835  772                  break;
↓ open down ↓ 16 lines elided ↑ open up ↑
 852  789          case LIST_inset:
 853  790                  elemtype = TAG_DL;
 854  791                  (void)strlcpy(cattr, "Bl-inset", sizeof(cattr));
 855  792                  break;
 856  793          case LIST_ohang:
 857  794                  elemtype = TAG_DL;
 858  795                  (void)strlcpy(cattr, "Bl-ohang", sizeof(cattr));
 859  796                  break;
 860  797          case LIST_tag:
 861  798                  if (bl->offs)
 862      -                        print_otag(h, TAG_DIV, "cswl", "Bl-tag", bl->offs);
 863      -                print_otag(h, TAG_DL, "csw*+l", bl->comp ?
 864      -                    "Bl-tag Bl-compact" : "Bl-tag", bl->width);
      799 +                        print_otag(h, TAG_DIV, "c", "Bd-indent");
      800 +                print_otag(h, TAG_DL, "c", bl->comp ?
      801 +                    "Bl-tag Bl-compact" : "Bl-tag");
 865  802                  return 1;
 866  803          case LIST_column:
 867  804                  elemtype = TAG_TABLE;
 868  805                  (void)strlcpy(cattr, "Bl-column", sizeof(cattr));
 869  806                  break;
 870  807          default:
 871  808                  abort();
 872  809          }
      810 +        if (bl->offs != NULL)
      811 +                (void)strlcat(cattr, " Bd-indent", sizeof(cattr));
 873  812          if (bl->comp)
 874  813                  (void)strlcat(cattr, " Bl-compact", sizeof(cattr));
 875      -        print_otag(h, elemtype, "cswl", cattr, bl->offs);
      814 +        print_otag(h, elemtype, "c", cattr);
 876  815          return 1;
 877  816  }
 878  817  
 879  818  static int
 880  819  mdoc_ex_pre(MDOC_ARGS)
 881  820  {
 882  821          if (n->prev)
 883  822                  print_otag(h, TAG_BR, "");
 884  823          return 1;
 885  824  }
↓ open down ↓ 11 lines elided ↑ open up ↑
 897  836          print_otag(h, TAG_I, "cT", "Em");
 898  837          return 1;
 899  838  }
 900  839  
 901  840  static int
 902  841  mdoc_d1_pre(MDOC_ARGS)
 903  842  {
 904  843          if (n->type != ROFFT_BLOCK)
 905  844                  return 1;
 906  845  
 907      -        print_otag(h, TAG_DIV, "c", "D1");
      846 +        print_otag(h, TAG_DIV, "c", "Bd Bd-indent");
 908  847  
 909  848          if (n->tok == MDOC_Dl)
 910  849                  print_otag(h, TAG_CODE, "c", "Li");
 911  850  
 912  851          return 1;
 913  852  }
 914  853  
 915  854  static int
 916  855  mdoc_sx_pre(MDOC_ARGS)
 917  856  {
 918  857          char    *id;
 919  858  
 920      -        id = html_make_id(n);
      859 +        id = html_make_id(n, 0);
 921  860          print_otag(h, TAG_A, "cThR", "Sx", id);
 922  861          free(id);
 923  862          return 1;
 924  863  }
 925  864  
 926  865  static int
 927  866  mdoc_bd_pre(MDOC_ARGS)
 928  867  {
 929      -        int                      comp, offs, sv;
      868 +        int                      comp, sv;
 930  869          struct roff_node        *nn;
 931  870  
 932  871          if (n->type == ROFFT_HEAD)
 933  872                  return 0;
 934  873  
 935  874          if (n->type == ROFFT_BLOCK) {
 936  875                  comp = n->norm->Bd.comp;
 937  876                  for (nn = n; nn && ! comp; nn = nn->parent) {
 938  877                          if (nn->type != ROFFT_BLOCK)
 939  878                                  continue;
↓ open down ↓ 4 lines elided ↑ open up ↑
 944  883                  }
 945  884                  if ( ! comp)
 946  885                          print_paragraph(h);
 947  886                  return 1;
 948  887          }
 949  888  
 950  889          /* Handle the -offset argument. */
 951  890  
 952  891          if (n->norm->Bd.offs == NULL ||
 953  892              ! strcmp(n->norm->Bd.offs, "left"))
 954      -                offs = 0;
 955      -        else if ( ! strcmp(n->norm->Bd.offs, "indent"))
 956      -                offs = INDENT;
 957      -        else if ( ! strcmp(n->norm->Bd.offs, "indent-two"))
 958      -                offs = INDENT * 2;
      893 +                print_otag(h, TAG_DIV, "c", "Bd");
 959  894          else
 960      -                offs = -1;
      895 +                print_otag(h, TAG_DIV, "c", "Bd Bd-indent");
 961  896  
 962      -        if (offs == -1)
 963      -                print_otag(h, TAG_DIV, "cswl", "Bd", n->norm->Bd.offs);
 964      -        else
 965      -                print_otag(h, TAG_DIV, "cshl", "Bd", offs);
 966      -
 967  897          if (n->norm->Bd.type != DISP_unfilled &&
 968  898              n->norm->Bd.type != DISP_literal)
 969  899                  return 1;
 970  900  
 971  901          print_otag(h, TAG_PRE, "c", "Li");
 972  902  
 973  903          /* This can be recursive: save & set our literal state. */
 974  904  
 975  905          sv = h->flags & HTML_LITERAL;
 976  906          h->flags |= HTML_LITERAL;
↓ open down ↓ 30 lines elided ↑ open up ↑
1007  937  
1008  938          if (0 == sv)
1009  939                  h->flags &= ~HTML_LITERAL;
1010  940  
1011  941          return 0;
1012  942  }
1013  943  
1014  944  static int
1015  945  mdoc_pa_pre(MDOC_ARGS)
1016  946  {
1017      -        print_otag(h, TAG_I, "cT", "Pa");
      947 +        print_otag(h, TAG_SPAN, "cT", "Pa");
1018  948          return 1;
1019  949  }
1020  950  
1021  951  static int
1022  952  mdoc_ad_pre(MDOC_ARGS)
1023  953  {
1024      -        print_otag(h, TAG_I, "c", "Ad");
      954 +        print_otag(h, TAG_SPAN, "c", "Ad");
1025  955          return 1;
1026  956  }
1027  957  
1028  958  static int
1029  959  mdoc_an_pre(MDOC_ARGS)
1030  960  {
1031  961          if (n->norm->An.auth == AUTH_split) {
1032  962                  h->flags &= ~HTML_NOSPLIT;
1033  963                  h->flags |= HTML_SPLIT;
1034  964                  return 0;
↓ open down ↓ 11 lines elided ↑ open up ↑
1046  976                  h->flags |= HTML_SPLIT;
1047  977  
1048  978          print_otag(h, TAG_SPAN, "cT", "An");
1049  979          return 1;
1050  980  }
1051  981  
1052  982  static int
1053  983  mdoc_cd_pre(MDOC_ARGS)
1054  984  {
1055  985          synopsis_pre(h, n);
1056      -        print_otag(h, TAG_B, "cT", "Cd");
      986 +        print_otag(h, TAG_CODE, "cT", "Cd");
1057  987          return 1;
1058  988  }
1059  989  
1060  990  static int
1061  991  mdoc_dv_pre(MDOC_ARGS)
1062  992  {
1063  993          char    *id;
1064  994  
1065  995          if ((id = cond_id(n)) != NULL)
1066      -                print_otag(h, TAG_A, "chR", "selflink", id);
      996 +                print_otag(h, TAG_A, "chR", "permalink", id);
1067  997          print_otag(h, TAG_CODE, "cTi", "Dv", id);
1068      -        free(id);
1069  998          return 1;
1070  999  }
1071 1000  
1072 1001  static int
1073 1002  mdoc_ev_pre(MDOC_ARGS)
1074 1003  {
1075 1004          char    *id;
1076 1005  
1077 1006          if ((id = cond_id(n)) != NULL)
1078      -                print_otag(h, TAG_A, "chR", "selflink", id);
     1007 +                print_otag(h, TAG_A, "chR", "permalink", id);
1079 1008          print_otag(h, TAG_CODE, "cTi", "Ev", id);
1080      -        free(id);
1081 1009          return 1;
1082 1010  }
1083 1011  
1084 1012  static int
1085 1013  mdoc_er_pre(MDOC_ARGS)
1086 1014  {
1087 1015          char    *id;
1088 1016  
1089 1017          id = n->sec == SEC_ERRORS &&
1090 1018              (n->parent->tok == MDOC_It ||
1091 1019               (n->parent->tok == MDOC_Bq &&
1092 1020                n->parent->parent->parent->tok == MDOC_It)) ?
1093      -            html_make_id(n) : NULL;
     1021 +            html_make_id(n, 1) : NULL;
1094 1022  
1095 1023          if (id != NULL)
1096      -                print_otag(h, TAG_A, "chR", "selflink", id);
     1024 +                print_otag(h, TAG_A, "chR", "permalink", id);
1097 1025          print_otag(h, TAG_CODE, "cTi", "Er", id);
1098      -        free(id);
1099 1026          return 1;
1100 1027  }
1101 1028  
1102 1029  static int
1103 1030  mdoc_fa_pre(MDOC_ARGS)
1104 1031  {
1105 1032          const struct roff_node  *nn;
1106 1033          struct tag              *t;
1107 1034  
1108 1035          if (n->parent->tok != MDOC_Fo) {
↓ open down ↓ 26 lines elided ↑ open up ↑
1135 1062          char            *buf, *cp;
1136 1063  
1137 1064          synopsis_pre(h, n);
1138 1065  
1139 1066          if (NULL == (n = n->child))
1140 1067                  return 0;
1141 1068  
1142 1069          assert(n->type == ROFFT_TEXT);
1143 1070  
1144 1071          if (strcmp(n->string, "#include")) {
1145      -                print_otag(h, TAG_B, "cT", "Fd");
     1072 +                print_otag(h, TAG_CODE, "cT", "Fd");
1146 1073                  return 1;
1147 1074          }
1148 1075  
1149      -        print_otag(h, TAG_B, "cT", "In");
     1076 +        print_otag(h, TAG_CODE, "cT", "In");
1150 1077          print_text(h, n->string);
1151 1078  
1152 1079          if (NULL != (n = n->next)) {
1153 1080                  assert(n->type == ROFFT_TEXT);
1154 1081  
1155 1082                  if (h->base_includes) {
1156 1083                          cp = n->string;
1157 1084                          if (*cp == '<' || *cp == '"')
1158 1085                                  cp++;
1159 1086                          buf = mandoc_strdup(cp);
↓ open down ↓ 65 lines elided ↑ open up ↑
1225 1152                          sz = MIN((int)(ep - sp), BUFSIZ - 1);
1226 1153                          (void)memcpy(nbuf, sp, (size_t)sz);
1227 1154                          nbuf[sz] = '\0';
1228 1155                          print_text(h, nbuf);
1229 1156                          sp = ++ep;
1230 1157                          ep = strchr(sp, ' ');
1231 1158                  }
1232 1159                  print_tagq(h, t);
1233 1160          }
1234 1161  
1235      -        t = print_otag(h, TAG_B, "cT", "Fn");
     1162 +        t = print_otag(h, TAG_CODE, "cT", "Fn");
1236 1163  
1237 1164          if (sp)
1238 1165                  print_text(h, sp);
1239 1166  
1240 1167          print_tagq(h, t);
1241 1168  
1242 1169          h->flags |= HTML_NOSPACE;
1243 1170          print_text(h, "(");
1244 1171          h->flags |= HTML_NOSPACE;
1245 1172  
1246 1173          for (n = n->child->next; n; n = n->next) {
1247 1174                  if (NODE_SYNPRETTY & n->flags)
1248      -                        t = print_otag(h, TAG_VAR, "cTss?", "Fa",
     1175 +                        t = print_otag(h, TAG_VAR, "cTs", "Fa",
1249 1176                              "white-space", "nowrap");
1250 1177                  else
1251 1178                          t = print_otag(h, TAG_VAR, "cT", "Fa");
1252 1179                  print_text(h, n->string);
1253 1180                  print_tagq(h, t);
1254 1181                  if (n->next) {
1255 1182                          h->flags |= HTML_NOSPACE;
1256 1183                          print_text(h, ",");
1257 1184                  }
1258 1185          }
↓ open down ↓ 109 lines elided ↑ open up ↑
1368 1295                  return 1;
1369 1296          } else if (n->type == ROFFT_BLOCK) {
1370 1297                  synopsis_pre(h, n);
1371 1298                  return 1;
1372 1299          }
1373 1300  
1374 1301          if (n->child == NULL)
1375 1302                  return 0;
1376 1303  
1377 1304          assert(n->child->string);
1378      -        t = print_otag(h, TAG_B, "cT", "Fn");
     1305 +        t = print_otag(h, TAG_CODE, "cT", "Fn");
1379 1306          print_text(h, n->child->string);
1380 1307          print_tagq(h, t);
1381 1308          return 0;
1382 1309  }
1383 1310  
1384 1311  static void
1385 1312  mdoc_fo_post(MDOC_ARGS)
1386 1313  {
1387 1314  
1388 1315          if (n->type != ROFFT_BODY)
↓ open down ↓ 3 lines elided ↑ open up ↑
1392 1319          h->flags |= HTML_NOSPACE;
1393 1320          print_text(h, ";");
1394 1321  }
1395 1322  
1396 1323  static int
1397 1324  mdoc_in_pre(MDOC_ARGS)
1398 1325  {
1399 1326          struct tag      *t;
1400 1327  
1401 1328          synopsis_pre(h, n);
1402      -        print_otag(h, TAG_B, "cT", "In");
     1329 +        print_otag(h, TAG_CODE, "cT", "In");
1403 1330  
1404 1331          /*
1405 1332           * The first argument of the `In' gets special treatment as
1406 1333           * being a linked value.  Subsequent values are printed
1407 1334           * afterward.  groff does similarly.  This also handles the case
1408 1335           * of no children.
1409 1336           */
1410 1337  
1411 1338          if (NODE_SYNPRETTY & n->flags && NODE_LINE & n->flags)
1412 1339                  print_text(h, "#include");
↓ open down ↓ 24 lines elided ↑ open up ↑
1437 1364  
1438 1365          return 0;
1439 1366  }
1440 1367  
1441 1368  static int
1442 1369  mdoc_ic_pre(MDOC_ARGS)
1443 1370  {
1444 1371          char    *id;
1445 1372  
1446 1373          if ((id = cond_id(n)) != NULL)
1447      -                print_otag(h, TAG_A, "chR", "selflink", id);
1448      -        print_otag(h, TAG_B, "cTi", "Ic", id);
1449      -        free(id);
     1374 +                print_otag(h, TAG_A, "chR", "permalink", id);
     1375 +        print_otag(h, TAG_CODE, "cTi", "Ic", id);
1450 1376          return 1;
1451 1377  }
1452 1378  
1453 1379  static int
1454 1380  mdoc_va_pre(MDOC_ARGS)
1455 1381  {
1456 1382          print_otag(h, TAG_VAR, "cT", "Va");
1457 1383          return 1;
1458 1384  }
1459 1385  
↓ open down ↓ 11 lines elided ↑ open up ↑
1471 1397  mdoc_bf_pre(MDOC_ARGS)
1472 1398  {
1473 1399          const char      *cattr;
1474 1400  
1475 1401          if (n->type == ROFFT_HEAD)
1476 1402                  return 0;
1477 1403          else if (n->type != ROFFT_BODY)
1478 1404                  return 1;
1479 1405  
1480 1406          if (FONT_Em == n->norm->Bf.font)
1481      -                cattr = "Em";
     1407 +                cattr = "Bf Em";
1482 1408          else if (FONT_Sy == n->norm->Bf.font)
1483      -                cattr = "Sy";
     1409 +                cattr = "Bf Sy";
1484 1410          else if (FONT_Li == n->norm->Bf.font)
1485      -                cattr = "Li";
     1411 +                cattr = "Bf Li";
1486 1412          else
1487      -                cattr = "No";
     1413 +                cattr = "Bf No";
1488 1414  
1489      -        /*
1490      -         * We want this to be inline-formatted, but needs to be div to
1491      -         * accept block children.
1492      -         */
1493      -
1494      -        print_otag(h, TAG_DIV, "css?hl", cattr, "display", "inline", 1);
     1415 +        /* Cannot use TAG_SPAN because it may contain blocks. */
     1416 +        print_otag(h, TAG_DIV, "c", cattr);
1495 1417          return 1;
1496 1418  }
1497 1419  
1498 1420  static int
1499 1421  mdoc_ms_pre(MDOC_ARGS)
1500 1422  {
1501 1423          char *id;
1502 1424  
1503 1425          if ((id = cond_id(n)) != NULL)
1504      -                print_otag(h, TAG_A, "chR", "selflink", id);
1505      -        print_otag(h, TAG_B, "cTi", "Ms", id);
1506      -        free(id);
     1426 +                print_otag(h, TAG_A, "chR", "permalink", id);
     1427 +        print_otag(h, TAG_SPAN, "cTi", "Ms", id);
1507 1428          return 1;
1508 1429  }
1509 1430  
1510 1431  static int
1511 1432  mdoc_igndelim_pre(MDOC_ARGS)
1512 1433  {
1513 1434  
1514 1435          h->flags |= HTML_IGNDELIM;
1515 1436          return 1;
1516 1437  }
↓ open down ↓ 18 lines elided ↑ open up ↑
1535 1456          print_otag(h, TAG_CITE, "cT", "Rs");
1536 1457          return 1;
1537 1458  }
1538 1459  
1539 1460  static int
1540 1461  mdoc_no_pre(MDOC_ARGS)
1541 1462  {
1542 1463          char *id;
1543 1464  
1544 1465          if ((id = cond_id(n)) != NULL)
1545      -                print_otag(h, TAG_A, "chR", "selflink", id);
     1466 +                print_otag(h, TAG_A, "chR", "permalink", id);
1546 1467          print_otag(h, TAG_SPAN, "ci", "No", id);
1547      -        free(id);
1548 1468          return 1;
1549 1469  }
1550 1470  
1551 1471  static int
1552 1472  mdoc_li_pre(MDOC_ARGS)
1553 1473  {
1554 1474          char    *id;
1555 1475  
1556 1476          if ((id = cond_id(n)) != NULL)
1557      -                print_otag(h, TAG_A, "chR", "selflink", id);
     1477 +                print_otag(h, TAG_A, "chR", "permalink", id);
1558 1478          print_otag(h, TAG_CODE, "ci", "Li", id);
1559      -        free(id);
1560 1479          return 1;
1561 1480  }
1562 1481  
1563 1482  static int
1564 1483  mdoc_sy_pre(MDOC_ARGS)
1565 1484  {
1566 1485          print_otag(h, TAG_B, "cT", "Sy");
1567 1486          return 1;
1568 1487  }
1569 1488  
↓ open down ↓ 135 lines elided ↑ open up ↑
1705 1624                  print_text(h, "\\(lC");
1706 1625                  break;
1707 1626          case MDOC_Bo:
1708 1627          case MDOC_Bq:
1709 1628                  print_text(h, "\\(lB");
1710 1629                  break;
1711 1630          case MDOC_Oo:
1712 1631          case MDOC_Op:
1713 1632                  print_text(h, "\\(lB");
1714 1633                  h->flags |= HTML_NOSPACE;
1715      -                print_otag(h, TAG_SPAN, "c", "Op");
     1634 +                /* Cannot use TAG_SPAN because it may contain blocks. */
     1635 +                print_otag(h, TAG_IDIV, "c", "Op");
1716 1636                  break;
1717 1637          case MDOC_En:
1718 1638                  if (NULL == n->norm->Es ||
1719 1639                      NULL == n->norm->Es->child)
1720 1640                          return 1;
1721 1641                  print_text(h, n->norm->Es->child->string);
1722 1642                  break;
1723 1643          case MDOC_Do:
1724 1644          case MDOC_Dq:
1725 1645          case MDOC_Qo:
↓ open down ↓ 117 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX