/* $Id: html.c,v 1.192 2016/01/04 12:45:29 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.h"
#include <assert.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "mandoc.h"
#include "mandoc_aux.h"
#include "out.h"
#include "html.h"
#include "manconf.h"
#include "main.h"
struct htmldata {
const char *name;
int flags;
};
{"h1", 0}, /* TAG_H1 */
{"h2", 0}, /* TAG_H2 */
{"span", 0}, /* TAG_SPAN */
{"a", 0}, /* TAG_A */
{"b", 0 }, /* TAG_B */
{"i", 0 }, /* TAG_I */
{"code", 0 }, /* TAG_CODE */
{"small", 0 }, /* TAG_SMALL */
{"mrow", 0}, /* TAG_MROW */
{"mi", 0}, /* TAG_MI */
{"mo", 0}, /* TAG_MO */
{"msup", 0}, /* TAG_MSUP */
{"msub", 0}, /* TAG_MSUB */
{"msubsup", 0}, /* TAG_MSUBSUP */
{"mfrac", 0}, /* TAG_MFRAC */
{"msqrt", 0}, /* TAG_MSQRT */
{"mfenced", 0}, /* TAG_MFENCED */
{"mtable", 0}, /* TAG_MTABLE */
{"mtr", 0}, /* TAG_MTR */
{"mtd", 0}, /* TAG_MTD */
{"munderover", 0}, /* TAG_MUNDEROVER */
{"munder", 0}, /* TAG_MUNDER*/
{"mover", 0}, /* TAG_MOVER*/
};
"name", /* ATTR_NAME */
"rel", /* ATTR_REL */
"href", /* ATTR_HREF */
"type", /* ATTR_TYPE */
"media", /* ATTR_MEDIA */
"class", /* ATTR_CLASS */
"style", /* ATTR_STYLE */
"id", /* ATTR_ID */
"colspan", /* ATTR_COLSPAN */
"charset", /* ATTR_CHARSET */
"open", /* ATTR_OPEN */
"close", /* ATTR_CLOSE */
"mathvariant", /* ATTR_MATHVARIANT */
};
"cm", /* SCALE_CM */
"in", /* SCALE_IN */
"pc", /* SCALE_PC */
"pt", /* SCALE_PT */
"em", /* SCALE_EM */
"em", /* SCALE_MM */
"ex", /* SCALE_EN */
"ex", /* SCALE_BU */
"em", /* SCALE_VS */
"ex", /* SCALE_FS */
};
static int print_escape(char);
static int print_encode(struct html *, const char *, int);
static void print_attr(struct html *, const char *, const char *);
void *
{
struct html *h;
h->oflags |= HTML_FRAGMENT;
return h;
}
void
html_free(void *p)
{
struct html *h;
h = (struct html *)p;
}
free(h);
}
void
{
struct tag *t;
/*
* Print a default style-sheet.
*/
print_text(h, "table.head, table.foot { width: 100%; }\n"
"td.head-rtitle, td.foot-os { text-align: right; }\n"
"td.head-vol { text-align: center; }\n"
"table.foot td { width: 50%; }\n"
"table.head td { width: 33%; }\n"
"div.spacer { margin: 1em 0; }\n");
print_tagq(h, t);
if (h->style) {
}
}
static void
{
switch (deco) {
case ESCAPE_FONTPREV:
break;
case ESCAPE_FONTITALIC:
break;
case ESCAPE_FONTBOLD:
break;
case ESCAPE_FONTBI:
font = HTMLFONT_BI;
break;
case ESCAPE_FONT:
case ESCAPE_FONTROMAN:
break;
default:
abort();
}
if (h->metaf) {
print_tagq(h, h->metaf);
}
switch (font) {
case HTMLFONT_ITALIC:
break;
case HTMLFONT_BOLD:
break;
case HTMLFONT_BI:
break;
default:
break;
}
}
int
{
/*
* Account for escaped sequences within string length
* calculations. This follows the logic in term_strlen() as we
* must calculate the width of produced strings.
* Assume that characters are always width of "1". This is
* hacky, but it gets the job done for approximation of widths.
*/
sz = 0;
skip = 0;
while (1) {
if (rsz) {
if (skip) {
skip = 0;
rsz--;
}
}
if ('\0' == *cp)
break;
cp++;
case ESCAPE_ERROR:
return sz;
case ESCAPE_UNICODE:
case ESCAPE_NUMBERED:
case ESCAPE_SPECIAL:
case ESCAPE_OVERSTRIKE:
if (skip)
skip = 0;
else
sz++;
break;
case ESCAPE_SKIPCHAR:
skip = 1;
break;
default:
break;
}
}
return sz;
}
static int
print_escape(char c)
{
switch (c) {
case '<':
printf("<");
break;
case '>':
printf(">");
break;
case '&':
printf("&");
break;
case '"':
printf(""");
break;
case ASCII_NBRSP:
printf(" ");
break;
case ASCII_HYPH:
putchar('-');
break;
case ASCII_BREAK:
break;
default:
return 0;
}
return 1;
}
static int
{
const char *seq;
nospace = 0;
while ('\0' != *p) {
h->flags &= ~HTML_SKIPCHAR;
p++;
continue;
}
p += (int)sz;
if ('\0' == *p)
break;
if (print_escape(*p++))
continue;
if (ESCAPE_ERROR == esc)
break;
switch (esc) {
case ESCAPE_FONT:
case ESCAPE_FONTPREV:
case ESCAPE_FONTBOLD:
case ESCAPE_FONTITALIC:
case ESCAPE_FONTBI:
case ESCAPE_FONTROMAN:
if (0 == norecurse)
print_metaf(h, esc);
continue;
case ESCAPE_SKIPCHAR:
h->flags |= HTML_SKIPCHAR;
continue;
default:
break;
}
if (h->flags & HTML_SKIPCHAR) {
h->flags &= ~HTML_SKIPCHAR;
continue;
}
switch (esc) {
case ESCAPE_UNICODE:
/* Skip past "u" header. */
break;
case ESCAPE_NUMBERED:
if (c < 0)
continue;
break;
case ESCAPE_SPECIAL:
if (c <= 0)
continue;
break;
case ESCAPE_NOSPACE:
if ('\0' == *p)
nospace = 1;
continue;
case ESCAPE_OVERSTRIKE:
if (len == 0)
continue;
break;
default:
continue;
}
if ((c < 0x20 && c != 0x09) ||
(c > 0x7E && c < 0xA0))
c = 0xFFFD;
if (c > 0x7E)
printf("&#%d;", c);
else if ( ! print_escape(c))
putchar(c);
}
return nospace;
}
static void
{
putchar('\"');
}
struct tag *
{
int i;
struct tag *t;
/* Push this tags onto the stack of open scopes. */
t = mandoc_malloc(sizeof(struct tag));
} else
t = NULL;
if ( ! (HTML_NOSPACE & h->flags))
/* Manage keeps! */
if (HTML_PREKEEP & h->flags)
putchar(' ');
} else
printf(" ");
}
if ( ! (h->flags & HTML_NONOSPACE))
h->flags &= ~HTML_NOSPACE;
else
h->flags |= HTML_NOSPACE;
/* Print out the tag name and attributes. */
for (i = 0; i < sz; i++)
/* Accommodate for "well-formed" singleton escaping. */
putchar('/');
putchar('>');
h->flags |= HTML_NOSPACE;
putchar('\n');
return t;
}
static void
{
/*
* Remember to close out and nullify the current
* meta-font and table, if applicable.
*/
h->flags |= HTML_NOSPACE;
putchar('\n');
}
}
void
{
puts("<!DOCTYPE html>");
}
void
{
if ( ! (HTML_NOSPACE & h->flags)) {
/* Manage keeps! */
if (HTML_PREKEEP & h->flags)
putchar(' ');
} else
printf(" ");
}
switch (h->metac) {
case HTMLFONT_ITALIC:
break;
case HTMLFONT_BOLD:
break;
case HTMLFONT_BI:
break;
default:
break;
}
if ( ! print_encode(h, word, 0)) {
if ( ! (h->flags & HTML_NONOSPACE))
h->flags &= ~HTML_NOSPACE;
h->flags &= ~HTML_NONEWLINE;
} else
if (h->metaf) {
print_tagq(h, h->metaf);
}
h->flags &= ~HTML_IGNDELIM;
}
void
{
print_ctag(h, tag);
return;
}
}
void
{
return;
print_ctag(h, tag);
}
}
void
{
struct tag *t;
print_tagq(h, t);
}
void
{
h->buf[0] = '\0';
h->buflen = 0;
}
void
{
bufcat(h, ":");
bufcat(h, ";");
}
void
{
/*
* XXX This is broken and not easy to fix.
* When using the -Oincludes option, buffmt_includes()
* may pass in strings overrunning BUFSIZ, causing a crash.
*/
}
void
{
}
static void
{
}
void
{
const char *p, *pp;
pp = h->base_includes;
bufinit(h);
switch (*(p + 1)) {
case'I':
break;
default:
bufncat(h, p, 2);
break;
}
pp = p + 2;
}
if (pp)
}
void
{
const char *p, *pp;
bufinit(h);
switch (*(p + 1)) {
case 'S':
break;
case 'N':
break;
default:
bufncat(h, p, 2);
break;
}
pp = p + 2;
}
if (pp)
}
void
{
double v;
v = 1.0;
v /= 24.0;
}
void
{
/* Cf. <http://www.w3.org/TR/html5/dom.html#the-id-attribute>. */
}