html.c revision 56160
1/* html.c -- html-related utilities.
2   $Id: html.c,v 1.5 1999/09/18 19:27:41 karl Exp $
3
4   Copyright (C) 1999 Free Software Foundation, Inc.
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software Foundation,
18   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20#include "system.h"
21#include "cmds.h"
22#include "html.h"
23#include "lang.h"
24#include "makeinfo.h"
25#include "sectioning.h"
26
27/* See html.h.  */
28int html_output_head_p = 0;
29
30void
31html_output_head ()
32{
33  char *html_title;
34
35  if (html_output_head_p)
36    return;
37  html_output_head_p = 1;
38
39  /* The <title> should not have markup.  */
40  html_title = title ? text_expansion (title) : _("Untitled");
41
42  add_word_args ("<html lang=\"%s\"><head>\n<title>%s</title>\n",
43                 language_table[language_code].abbrev, html_title);
44
45  add_word ("<meta http-equiv=\"Content-Type\" content=\"text/html");
46  if (document_encoding)
47    add_word_args ("; charset=%s", document_encoding);
48  add_word ("\">\n");
49
50  add_word_args ("<meta name=description content=\"%s\">\n", html_title);
51  add_word_args ("<meta name=generator content=\"makeinfo %s\">\n", VERSION);
52  add_word ("<link href=\"http://texinfo.org/\" rel=generator-home>\n");
53  add_word ("</head><body>\n\n");
54}
55
56
57/* Escape HTML special characters in the string if necessary,
58   returning a pointer to a possibly newly-allocated one. */
59char *
60escape_string (string)
61     char * string;
62{
63  int i=0, newlen=0;
64  char * newstring;
65
66  do
67    {
68      /* Find how much to allocate. */
69      switch (string[i])
70        {
71        case '&':
72          newlen += 5;          /* `&amp;' */
73          break;
74        case '<':
75        case '>':
76          newlen += 4;          /* `&lt;', `&gt;' */
77          break;
78        default:
79          newlen++;
80        }
81      i++;
82    }
83  while (string[i]);
84
85  if (newlen == i) return string; /* Already OK. */
86
87  newstring = xmalloc (newlen + 2);
88  i = 0;
89  do
90    {
91      switch (string[i])
92        {
93        case '&':
94          strcpy (newstring, "&amp;");
95          newstring += 5;
96          break;
97        case '<':
98          strcpy (newstring, "&lt;");
99          newstring += 4;
100          break;
101        case '>':
102          strcpy (newstring, "&gt;");
103          newstring += 4;
104          break;
105        default:
106          newstring[0] = string[i];
107          newstring++;
108        }
109    }
110  while (string[i++]);
111  free (string);
112  return newstring - newlen -1;
113}
114
115/* Open or close TAG according to START_OR_END. */
116void
117insert_html_tag (start_or_end, tag)
118     int start_or_end;
119     char *tag;
120{
121  if (!paragraph_is_open && (start_or_end == START))
122    {
123      /* Need to compensate for the <p> we are about to insert, or
124	 else cm_xxx functions that call us will get wrong text
125	 between START and END.  */
126      adjust_braces_following (output_paragraph_offset, 3);
127      add_word ("<p>");
128    }
129  add_char ('<');
130  if (start_or_end != START)
131    add_char ('/');
132  add_word (tag);
133  add_char ('>');
134}
135
136/* Output an HTML <link> to the filename for NODE, including the
137   other string as extra attributes. */
138void
139add_link (node, attributes)
140     char *node, *attributes;
141{
142  if (node)
143    {
144      add_word_args ("<link %s href=\"", attributes);
145      add_anchor_name (node, 1);
146      add_word ("\">\n");
147    }
148}
149
150/* Output NAME with characters escaped as appropriate for an anchor
151   name, i.e., escape URL special characters as %<n>.  */
152void
153add_escaped_anchor_name (name)
154     char *name;
155{
156  for (; *name; name++)
157    {
158      if (*name == '&')
159        add_word ("&amp;");
160      else if (! URL_SAFE_CHAR (*name))
161        /* Cast so characters with the high bit set are treated as >128,
162           for example o-umlaut should be 246, not -10.  */
163        add_word_args ("%%%x", (unsigned char) *name);
164      else
165        add_char (*name);
166    }
167}
168
169/* Insert the text for the name of a reference in an HTML anchor
170   appropriate for NODENAME.  If HREF is nonzero, it will be
171   appropriate for a href= attribute, rather than name= i.e., including
172   the `#' if it's an internal reference. */
173void
174add_anchor_name (nodename, href)
175     char *nodename;
176     int href;
177{
178  if (href)
179    add_char ('#');
180
181  add_escaped_anchor_name (nodename);
182}
183