+\f
+/* Similar to LOOKING_AT but does not use notinname, does not skip */
+#define LOOKING_AT_NOCASE(cp, kw) /* kw is a constant string */ \
+ (strncaseeq ((cp), kw, sizeof(kw)-1) /* cp points at kw */ \
+ && ((cp) += sizeof(kw)-1)) /* skip spaces */
+
+/*
+ * HTML support.
+ * Contents of <title>, <h1>, <h2>, <h3> are tags.
+ * Contents of <a name=xxx> are tags with name xxx.
+ *
+ * Francesco Potortì, 2002.
+ */
+static void
+HTML_labels (inf)
+ FILE * inf;
+{
+ bool getnext = FALSE; /* next text outside of HTML tags is a tag */
+ bool ignoretag = FALSE; /* skip to the end of the current HTML tag */
+ bool inanchor = FALSE; /* inside an A HTML tag, looking for NAME= */
+ char *end;
+
+
+ linebuffer_setlen (&token_name, 0); /* no name in buffer */
+
+ LOOP_ON_INPUT_LINES (inf, lb, dbp)
+ {
+ for (;;) /* loop on the same line */
+
+ if (ignoretag) /* skip HTML tag */
+ {
+ while (*dbp != '\0' && *dbp != '>')
+ dbp++;
+ if (*dbp == '>')
+ {
+ dbp += 1;
+ ignoretag = FALSE;
+ continue; /* look on the same line */
+ }
+ break; /* go to next line */
+ }
+
+ else if (inanchor) /* look for "name=" */
+ {
+ while (*dbp != '\0' && *dbp != '>' && lowcase (*dbp) != 'n')
+ dbp++;
+ if (*dbp == '\0')
+ break; /* go to next line */
+ if (*dbp == '>')
+ {
+ dbp += 1;
+ inanchor = FALSE;
+ continue; /* look on the same line */
+ }
+ dbp += 1;
+ if (LOOKING_AT_NOCASE (dbp, "ame="))
+ {
+ bool quoted = (dbp[0] == '"');
+
+ if (quoted)
+ for (end = ++dbp; *end != '\0' && *end != '"'; end++)
+ continue;
+ else
+ for (end = dbp; *end != '\0' && intoken (*end); end++)
+ continue;
+ linebuffer_setlen (&token_name, end - dbp);
+ strncpy (token_name.buffer, dbp, end - dbp);
+ token_name.buffer[end - dbp] = '\0';
+
+ dbp = end;
+ inanchor = FALSE; /* we found what we looked for */
+ ignoretag = TRUE; /* skip to the end of the anchor */
+ getnext = TRUE; /* then grab the text */
+ continue; /* look on the same line */
+ }
+ }
+
+ else if (getnext) /* grab next tokens and tag them */
+ {
+ dbp = skip_spaces (dbp);
+ if (*dbp == '\0')
+ break; /* go to next line */
+ if (*dbp == '<')
+ {
+ if (lowcase (dbp[1]) == 'a' && !intoken (dbp[2]))
+ inanchor = TRUE;
+ else
+ ignoretag = TRUE;
+ continue; /* look on the same line */
+ }
+
+ for (end = dbp + 1; *end != '\0' && *end != '<'; end++)
+ continue;
+ make_tag (token_name.buffer, token_name.len, TRUE,
+ dbp, end - dbp, lineno, linecharno);
+ linebuffer_setlen (&token_name, 0); /* no name in buffer */
+ getnext = FALSE;
+ break; /* go to next line */
+ }
+
+ else /* look for an interesting HTML tag */
+ {
+ while (*dbp != '\0' && *dbp != '<')
+ dbp++;
+ if (*dbp == '\0')
+ break; /* go to next line */
+ dbp += 1;
+ if (lowcase (dbp[0]) == 'a' && !intoken (dbp[1]))
+ inanchor = TRUE;
+ else if (LOOKING_AT_NOCASE (dbp, "title>")
+ || LOOKING_AT_NOCASE (dbp, "h1>")
+ || LOOKING_AT_NOCASE (dbp, "h2>")
+ || LOOKING_AT_NOCASE (dbp, "h3>"))
+ {
+ getnext = TRUE;
+ continue; /* look on the same line */
+ }
+ }
+ }
+}
+