summaryrefslogtreecommitdiffstats
path: root/contrib/texinfo/makeinfo/html.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/texinfo/makeinfo/html.c')
-rw-r--r--contrib/texinfo/makeinfo/html.c213
1 files changed, 207 insertions, 6 deletions
diff --git a/contrib/texinfo/makeinfo/html.c b/contrib/texinfo/makeinfo/html.c
index 51960fc..0c06c6c 100644
--- a/contrib/texinfo/makeinfo/html.c
+++ b/contrib/texinfo/makeinfo/html.c
@@ -1,7 +1,7 @@
/* html.c -- html-related utilities.
- $Id: html.c,v 1.8 2002/11/04 22:14:40 karl Exp $
+ $Id: html.c,v 1.18 2003/06/02 12:32:29 karl Exp $
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -26,14 +26,17 @@
HSTACK *htmlstack = NULL;
+static char *process_css_file (/* char * */);
+
/* See html.h. */
int html_output_head_p = 0;
int html_title_written = 0;
+
void
html_output_head ()
{
- static char *html_title = NULL;
+ static const char *html_title = NULL;
if (html_output_head_p)
return;
@@ -49,7 +52,7 @@ html_output_head ()
add_word ("<meta http-equiv=\"Content-Type\" content=\"text/html");
if (document_encoding_code != no_encoding)
add_word_args ("; charset=%s",
- encoding_table[document_encoding_code].ecname);
+ encoding_table[document_encoding_code].encname);
add_word ("\">\n");
if (!document_description)
@@ -59,8 +62,12 @@ html_output_head ()
document_description);
add_word_args ("<meta name=\"generator\" content=\"makeinfo %s\">\n",
VERSION);
+#if 0
+ /* let's not do this now, since it causes mozilla to put up a
+ navigation bar. */
add_word ("<link href=\"http://www.gnu.org/software/texinfo/\" \
rel=\"generator-home\">\n");
+#endif
if (copying_text)
{ /* copying_text has already been fully expanded in
@@ -73,6 +80,44 @@ rel=\"generator-home\">\n");
insert_string ("-->\n");
}
+ /* Put the style definitions in a comment for the sake of browsers
+ that don't support <style>. */
+ add_word ("<meta http-equiv=\"Content-Style-Type\" content=\"text/css\">\n");
+ add_word ("<style type=\"text/css\"><!--\n");
+
+ {
+ char *css_inline = NULL;
+
+ if (css_include)
+ /* This writes out any @import commands from the --css-file,
+ and returns any actual css code following the imports. */
+ css_inline = process_css_file (css_include);
+
+ /* This seems cleaner than adding <br>'s at the end of each line for
+ these "roman" displays. It's hardly the end of the world if the
+ browser doesn't do <style>s, in any case; they'll just come out in
+ typewriter. */
+#define CSS_FONT_INHERIT "font-family:inherit"
+ add_word_args (" pre.display { %s }\n", CSS_FONT_INHERIT);
+ add_word_args (" pre.format { %s }\n", CSS_FONT_INHERIT);
+
+ /* Alternatively, we could do <font size=-1> in insertion.c, but this
+ way makes it easier to override. */
+#define CSS_FONT_SMALLER "font-size:smaller"
+ add_word_args (" pre.smalldisplay { %s; %s }\n", CSS_FONT_INHERIT,
+ CSS_FONT_SMALLER);
+ add_word_args (" pre.smallformat { %s; %s }\n", CSS_FONT_INHERIT,
+ CSS_FONT_SMALLER);
+ add_word_args (" pre.smallexample { %s }\n", CSS_FONT_SMALLER);
+ add_word_args (" pre.smalllisp { %s }\n", CSS_FONT_SMALLER);
+
+ /* Write out any css code from the user's --css-file. */
+ if (css_inline)
+ add_word (css_inline);
+
+ add_word ("--></style>\n");
+ }
+
add_word ("</head>\n<body>\n");
if (title && !html_title_written && titlepage_cmd_present)
@@ -82,6 +127,158 @@ rel=\"generator-home\">\n");
}
}
+
+
+/* Append CHAR to BUFFER, (re)allocating as necessary. We don't handle
+ null characters. */
+
+typedef struct
+{
+ unsigned size; /* allocated */
+ unsigned length; /* used */
+ char *buffer;
+} buffer_type;
+
+
+static buffer_type *
+init_buffer ()
+{
+ buffer_type *buf = xmalloc (sizeof (buffer_type));
+ buf->length = 0;
+ buf->size = 0;
+ buf->buffer = NULL;
+
+ return buf;
+}
+
+
+static void
+append_char (buf, c)
+ buffer_type *buf;
+ int c;
+{
+ buf->length++;
+ if (buf->length >= buf->size)
+ {
+ buf->size += 100;
+ buf->buffer = xrealloc (buf->buffer, buf->size);
+ }
+ buf->buffer[buf->length - 1] = c;
+ buf->buffer[buf->length] = 0;
+}
+
+
+/* Read the cascading style-sheet file FILENAME. Write out any @import
+ commands, which must come first, by the definition of css. If the
+ file contains any actual css code following the @imports, return it;
+ else return NULL. */
+
+static char *
+process_css_file (filename)
+ char *filename;
+{
+ int c, lastchar;
+ FILE *f;
+ buffer_type *import_text = init_buffer ();
+ buffer_type *inline_text = init_buffer ();
+ unsigned lineno = 1;
+ enum { null_state, comment_state, import_state, inline_state } state
+ = null_state, prev_state;
+
+ /* read from stdin if `-' is the filename. */
+ f = STREQ (filename, "-") ? stdin : fopen (filename, "r");
+ if (!f)
+ {
+ error (_("%s: could not open --css-file: %s"), progname, filename);
+ return NULL;
+ }
+
+ /* Read the file. The @import statements must come at the beginning,
+ with only whitespace and comments allowed before any inline css code. */
+ while ((c = getc (f)) >= 0)
+ {
+ if (c == '\n')
+ lineno++;
+
+ switch (state)
+ {
+ case null_state: /* between things */
+ if (c == '@')
+ {
+ /* If there's some other @command, just call it an
+ import, it's all the same to us. So don't bother
+ looking for the `import'. */
+ append_char (import_text, c);
+ state = import_state;
+ }
+ else if (c == '/')
+ { /* possible start of a comment */
+ int nextchar = getc (f);
+ if (nextchar == '*')
+ state = comment_state;
+ else
+ {
+ ungetc (nextchar, f); /* wasn't a comment */
+ state = inline_state;
+ }
+ }
+ else if (isspace (c))
+ ; /* skip whitespace; maybe should use c_isspace? */
+
+ else
+ /* not an @import, not a comment, not whitespace: we must
+ have started the inline text. */
+ state = inline_state;
+
+ if (state == inline_state)
+ append_char (inline_text, c);
+
+ if (state != null_state)
+ prev_state = null_state;
+ break;
+
+ case comment_state:
+ if (c == '/' && lastchar == '*')
+ state = prev_state; /* end of comment */
+ break; /* else ignore this comment char */
+
+ case import_state:
+ append_char (import_text, c); /* include this import char */
+ if (c == ';')
+ { /* done with @import */
+ append_char (import_text, '\n'); /* make the output nice */
+ state = null_state;
+ prev_state = import_state;
+ }
+ break;
+
+ case inline_state:
+ /* No harm in writing out comments, so don't bother parsing
+ them out, just append everything. */
+ append_char (inline_text, c);
+ break;
+ }
+
+ lastchar = c;
+ }
+
+ /* Reached the end of the file. We should not be still in a comment. */
+ if (state == comment_state)
+ warning (_("%s:%d: --css-file ended in comment"), filename, lineno);
+
+ /* Write the @import text, if any. */
+ if (import_text->buffer)
+ {
+ add_word (import_text->buffer);
+ free (import_text->buffer);
+ free (import_text);
+ }
+
+ /* We're wasting the buffer struct memory, but so what. */
+ return inline_text->buffer;
+}
+
+
/* Escape HTML special characters in the string if necessary,
returning a pointer to a possibly newly-allocated one. */
@@ -139,6 +336,8 @@ escape_string (string)
free (string);
return newstring - newlen;
}
+
+
/* Save current tag. */
void
@@ -187,7 +386,7 @@ insert_html_tag (start_or_end, tag)
}
if (start_or_end != START)
- pop_tag (tag);
+ pop_tag ();
if (htmlstack)
old_tag = htmlstack->tag;
@@ -228,6 +427,8 @@ insert_html_tag (start_or_end, tag)
}
}
+
+
/* Output an HTML <link> to the filename for NODE, including the
other string as extra attributes. */
void
@@ -240,7 +441,7 @@ add_link (nodename, attributes)
add_word_args ("%s", attributes);
add_word_args (" href=\"");
add_anchor_name (nodename, 1);
- add_word ("\"></a>\n");
+ add_word ("\">\n");
}
}
OpenPOWER on IntegriCloud