1 /*      $Id: roff_html.c,v 1.11 2017/06/24 14:38:33 schwarze Exp $ */
   2 /*
   3  * Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv>
   4  * Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org>
   5  *
   6  * Permission to use, copy, modify, and distribute this software for any
   7  * purpose with or without fee is hereby granted, provided that the above
   8  * copyright notice and this permission notice appear in all copies.
   9  *
  10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17  */
  18 #include <sys/types.h>
  19 
  20 #include <assert.h>
  21 #include <stddef.h>
  22 
  23 #include "mandoc.h"
  24 #include "roff.h"
  25 #include "out.h"
  26 #include "html.h"
  27 
  28 #define ROFF_HTML_ARGS struct html *h, const struct roff_node *n
  29 
  30 typedef void    (*roff_html_pre_fp)(ROFF_HTML_ARGS);
  31 
  32 static  void      roff_html_pre_br(ROFF_HTML_ARGS);
  33 static  void      roff_html_pre_ce(ROFF_HTML_ARGS);
  34 static  void      roff_html_pre_sp(ROFF_HTML_ARGS);
  35 
  36 static  const roff_html_pre_fp roff_html_pre_acts[ROFF_MAX] = {
  37         roff_html_pre_br,  /* br */
  38         roff_html_pre_ce,  /* ce */
  39         NULL,  /* ft */
  40         NULL,  /* ll */
  41         NULL,  /* mc */
  42         NULL,  /* po */
  43         roff_html_pre_ce,  /* rj */
  44         roff_html_pre_sp,  /* sp */
  45         NULL,  /* ta */
  46         NULL,  /* ti */
  47 };
  48 
  49 
  50 void
  51 roff_html_pre(struct html *h, const struct roff_node *n)
  52 {
  53         assert(n->tok < ROFF_MAX);
  54         if (roff_html_pre_acts[n->tok] != NULL)
  55                 (*roff_html_pre_acts[n->tok])(h, n);
  56 }
  57 
  58 static void
  59 roff_html_pre_br(ROFF_HTML_ARGS)
  60 {
  61         struct tag      *t;
  62 
  63         t = print_otag(h, TAG_DIV, "");
  64         print_text(h, "\\~");  /* So the div isn't empty. */
  65         print_tagq(h, t);
  66 }
  67 
  68 static void
  69 roff_html_pre_ce(ROFF_HTML_ARGS)
  70 {
  71         for (n = n->child->next; n != NULL; n = n->next) {
  72                 if (n->type == ROFFT_TEXT) {
  73                         if (n->flags & NODE_LINE)
  74                                 roff_html_pre_br(h, n);
  75                         print_text(h, n->string);
  76                 } else
  77                         roff_html_pre(h, n);
  78         }
  79         roff_html_pre_br(h, n);
  80 }
  81 
  82 static void
  83 roff_html_pre_sp(ROFF_HTML_ARGS)
  84 {
  85         struct roffsu    su;
  86 
  87         SCALE_VS_INIT(&su, 1);
  88         if ((n = n->child) != NULL) {
  89                 if (a2roffsu(n->string, &su, SCALE_VS) == NULL)
  90                         su.scale = 1.0;
  91                 else if (su.scale < 0.0)
  92                         su.scale = 0.0;
  93         }
  94         print_otag(h, TAG_DIV, "suh", &su);
  95         print_text(h, "\\~");  /* So the div isn't empty. */
  96 }