");
}
static void html_begin_link (const uchar *database, int ref)
{
write_fmt ("",
database != NULL ? (const char *)database : "",
database != NULL ? ".html" : "", ref);
}
static void html_end_link (void)
{
write_string ("");
}
void html_elements (enum style style)
{
const struct element *ep;
enum style style_stack[STYLE_STACK_SIZE];
int style_sp, ignore_spaces;
uchar *p;
style_sp = 0;
style_stack[style_sp] = style;
ignore_spaces = FALSE;
for (ep = elements; ep->el != EL_END; ++ep)
switch (ep->el)
{
case EL_WORD:
case EL_PUNCT:
if (ep->n != 0)
{
if (ep->wp->database == NULL)
html_begin_link (NULL, ep->wp->ref);
else
html_begin_link (ep->wp->database->str, ep->wp->ref);
}
p = ep->wp->str;
if (ep->wp->special != NULL && ep->wp->special->html != NULL)
write_string (ep->wp->special->html);
else if (style_sp == 0 || style_stack[style_sp] == STYLE_NORMAL)
format_string (p, (ep->wp->style != STYLE_NORMAL
? ep->wp->style : style), FALSE);
else
format_string (p, style_stack[style_sp], FALSE);
if (ep->n != 0)
html_end_link ();
break;
case EL_SPACE:
if (ignore_spaces)
ignore_spaces = FALSE;
else
format_spaces (ep->n, style_stack[style_sp], TRUE);
break;
case EL_BREAK:
write_line ("
");
break;
case EL_STYLE:
if (style_sp + 1 >= STYLE_STACK_SIZE)
fatal ("%s:%d: Style stack overflow", input_fname, line_no);
style_stack[++style_sp] = ep->n;
break;
case EL_ENDSTYLE:
if (style_sp == 0)
fatal ("%s:%d: Style stack underflow", input_fname, line_no);
--style_sp;
break;
default:
abort ();
}
}
void html_start_hilite (void)
{
if (hl_stack[hl_sp] & HL_TT)
write_string ("");
else if (hl_stack[hl_sp] & HL_BF)
write_string ("");
else if (hl_stack[hl_sp] & (HL_SL | HL_EM))
write_string ("");
}
void html_end_hilite (void)
{
if (hl_stack[hl_sp] & HL_TT)
write_string ("");
else if (hl_stack[hl_sp] & HL_BF)
write_string ("");
else if (hl_stack[hl_sp] & (HL_SL | HL_EM))
write_string ("");
}
void html_end_env (void)
{
switch (env_stack[env_sp].env)
{
case ENV_DESCRIPTION:
case ENV_LIST:
write_break ();
write_line ("");
break;
case ENV_ENUMERATE:
write_break ();
write_line ("");
break;
case ENV_ITEMIZE:
write_break ();
write_line ("");
break;
case ENV_TYPEWRITER:
write_break ();
write_line ("");
break;
case ENV_INDENT:
write_break ();
write_line ("");
break;
default:
abort ();
}
}
void html_toc_start (void)
{
}
void html_toc_line (const uchar *s, const struct toc *tp)
{
format_string (s, STYLE_NORMAL, FALSE);
html_begin_link (NULL, tp->ref);
html_output (tp->title, FALSE);
html_end_link ();
write_line ("
");
}
void html_toc_end (void)
{
write_line ("
"); } void html_list (void) { write_break (); write_line (""); } void html_verbatim_start (enum tag tag_end) { write_break (); switch (tag_end) { case TAG_ENDHEADERS: html_para (); format_string ("Headers:", STYLE_BOLD, FALSE); break; case TAG_ENDSAMPLECODE: html_para (); format_string ("Example:", STYLE_BOLD, FALSE); write_line ("
"); break; case TAG_ENDEXAMPLE: html_para (); write_line (""); break; default: break; } write_break (); write_line (""); break; default: break; } } void html_description_item (const uchar *s) { write_break (); write_string (""); } void html_verbatim_line (void) { html_output (input, FALSE); write_nl (); } void html_verbatim_end (enum tag tag_end) { write_line (""); switch (tag_end) { case TAG_ENDEXAMPLE: case TAG_ENDSAMPLECODE: write_line ("- "); make_elements (s); html_elements (STYLE_NORMAL); write_string ("
- "); } void html_enumerate_item (void) { write_break (); write_line ("
- "); } void html_itemize_item (void) { write_break (); write_line ("
- "); } void html_list_item (const uchar *s) { write_break (); write_string ("
- "); make_elements (s); html_elements (STYLE_NORMAL); write_string ("
- "); } void html_copy (void) { if (para_flag) html_para (); switch (env_stack[env_sp].env) { case ENV_TYPEWRITER: html_elements (STYLE_TTY); break; default: html_elements (STYLE_NORMAL); break; } } void html_start (void) { write_line (""); if (title != NULL) { write_string ("
"); format_string (title, STYLE_NORMAL, FALSE); write_line (" "); } write_line (""); } void html_end (void) { if (index_count != 0) start_index (); if (out) { write_nl (); html_write_index (); write_line (""); } } void html_prototype_start (void) { if (para_flag) html_para (); format_string (function_count == 1 ? "Prototype:" : "Prototypes:", STYLE_BOLD, FALSE); write_break (); html_para (); } void html_prototype_end (uchar *compat) { html_elements (STYLE_TTY); html_para (); if (compat[0] != 0) { format_string ("Compatibility:", STYLE_BOLD, FALSE); html_para (); format_string (compat, STYLE_NORMAL, FALSE); html_para (); compat[0] = 0; } format_string ("Description:", STYLE_BOLD, FALSE); } void html_see_also_start (void) { if (para_flag) html_para (); format_string ("See also: ", STYLE_BOLD, FALSE); } void html_see_also_word (const uchar *word, const uchar *s) { struct word *wp; wp = use_reference (word); if (wp != NULL) { if (wp->database == NULL) html_begin_link (NULL, wp->ref); else html_begin_link (wp->database->str, wp->ref); html_output (word, FALSE); html_end_link (); } if (*s != 0) { write_string (","); if (output_x >= 60) write_nl (); else write_string (" "); } } void html_sample_file (const uchar *s) { html_libref_section ("Example"); format_string (" See ", STYLE_NORMAL, FALSE); format_string (s, STYLE_TTY, FALSE); para_flag = TRUE; } void html_libref_section (const uchar *s) { if (para_flag) html_para (); format_string (s, STYLE_BOLD, FALSE); write_string (":"); para_flag = TRUE; } void html_function_start (const struct toc *tp) { write_line ("
"); html_heading1 (tp->ref); write_string (""); html_output (tp->title, FALSE); write_line ("
"); } void html_function_function (const struct toc *tp, const uchar *s) { if (index_wp1 != NULL) html_index (tp, s, 2); } void html_minitoc (const struct toc *tp) { int level; if (tp == NULL) fatal ("%s:%d: Cannot build minitoc before the first heading", input_fname, line_no); if (para_flag) html_para (); level = tp->level; tp = tp->next; while (tp != NULL && tp->level >= level + 1) { if (tp->level == level + 1) { html_begin_link (NULL, tp->ref); format_output (tp->title, FALSE); html_end_link (); write_line ("
"); } tp = tp->next; } } void html_index (const struct toc *tp, const uchar *s, int level) { struct word *wp; switch (level) { case 0: wp = word_add (s); assert (tp != NULL); if (wp->idx == 0) { wp->idx = tp->ref; if (wp->subidx == NULL) ++index_count; } else if (wp->idx != tp->ref) warning (1, "%s:%d: Index entry multiply defined", input_fname, line_no); break; case 1: if (*s == 0) index_wp1 = NULL; else { wp = word_add (s); index_wp1 = wp; } break; case 2: if (index_wp1 == NULL) fatal ("%s:%d: %ci2 without %ci1", input_fname, line_no, escape, escape); if (index_wp1->subidx == NULL) { index_wp1->subidx = wt_new (37); if (index_wp1->idx == 0) ++index_count; } wp = wt_add (index_wp1->subidx, s); assert (tp != NULL); if (wp->idx == 0) wp->idx = tp->ref; else if (wp->idx != tp->ref) warning (1, "%s:%d: Index entry multiply defined", input_fname, line_no); break; default: abort (); } } static int index_add (struct word *wp) { if (wp->idx != 0 || wp->subidx != NULL) { assert (index_n < index_count); index_v[index_n++] = wp; } return 0; } static const uchar map_ascii[256] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" "\x40\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x5a\x5b\x5c\x5d\x5e\x5f" "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; static const uchar map_cp850[256] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" "\x40\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x5a\x5b\x5c\x5d\x5e\x5f" "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\xff" "\x63\x75\x65\x61\x61\x61\x61\x63\x65\x65\x65\x69\x69\x69\x61\x61" "\x65\x61\x61\x6f\x6f\x6f\x75\x75\x79\x6f\x75\x6f\xff\x6f\xff\xff" "\x61\x69\x6f\x75\x6e\x6e\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\x61\x61\x61\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\x61\x61\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\x65\x65\x65\xff\x69\x69\x69\xff\xff\xff\xff\xff\x69\xff" "\x6f\x80\x6f\x6f\x6f\x6f\xff\xff\xff\x75\x75\x75\x79\x79\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; static const uchar map_iso8859_1[256] = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" "\x40\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x5a\x5b\x5c\x5d\x5e\x5f" "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\x20\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" "\x61\x61\x61\x61\x61\x61\x61\x63\x65\x65\x65\x65\x69\x69\x69\x69" "\xff\x6e\x6f\x6f\x6f\x6f\x6f\xff\x6f\x75\x75\x75\x75\x79\xff\x80" "\x61\x61\x61\x61\x61\x61\x61\x63\x65\x65\x65\x65\x69\x69\x69\x69" "\xff\x6e\x6f\x6f\x6f\x6f\x6f\xff\x6f\x75\x75\x75\x75\x79\xff\x79"; static int compare1 (const uchar *s1, size_t n1, const uchar *s2, size_t n2, const uchar *map) { uchar c1, c2; int cmp; while (n1 != 0 && n2 != 0) { c1 = map[*s1]; c2 = map[*s2]; if (c1 != c2) { /* Special cases for \ss */ if (c1 == 0x80) { cmp = compare1 ("ss", 2, s2, n2 < 2 ? n2 : 2, map_ascii); if (cmp != 0) return cmp; ++s2; --n2; } else if (c2 == 0x80) { cmp = compare1 (s1, n1 < 2 ? n1 : 2, "ss", 2, map_ascii); if (cmp != 0) return cmp; ++s1; --n1; } else if (c1 < c2) return -1; else return 1; } ++s1; ++s2; --n1; --n2; } if (n1 != 0) return 1; if (n2 != 0) return -1; return 0; } static int index_compare (const void *p1, const void *p2) { const struct word *wp1 = *(const struct word **)p1; const struct word *wp2 = *(const struct word **)p2; int cmp = compare1 (wp1->str, strlen (wp1->str), wp2->str, strlen (wp2->str), index_map); if (cmp != 0) return cmp; return strcmp (wp1->str, wp2->str); } static void index_recurse (struct word_table *wt, int level) { int i, j, n; struct word **v; if (level != 0) index_count = wt_count (wt); n = index_count; index_v = xmalloc (n * sizeof (*index_v)); index_n = 0; wt_walk (wt, index_add); assert (index_n == n); v = index_v; index_count = 0; index_v = NULL; qsort (v, n, sizeof (*v), index_compare); for (i = 0; i < n; ++i) { struct word *wp = v[i]; assert (wp->idx != 0 || wp->subidx != NULL); for (j = 0; j < level; ++j) write_string (" "); if (wp->idx != 0) html_begin_link (NULL, wp->idx); html_output ((const char *)wp->str, FALSE); if (wp->idx != 0) html_end_link (); write_line ("
"); if (wp->subidx != NULL) index_recurse (wp->subidx, level + 1); } free (v); } static void html_write_index (void) { if (index_count != 0) { int n = index_count; if (output_encoding == ENC_ISO8859_1) index_map = map_iso8859_1; else index_map = map_cp850; index_recurse (word_top, 0); index_count = n; } } void html_fragment (const uchar *s) { write_break (); write_fmt ("", (const char *)s); write_nl (); }