-#include "html.h"
-#include "manual.h"
-
-VECTOR_TYPE(markstack, GtkTextMark *, xrealloc);
-
-/** @brief Known tag type */
-struct tag {
- /** @brief HTML tag name */
- const char *name;
-
- /** @brief Called to set up the tag */
- void (*init)(GtkTextTag *tag);
-
-};
-
-/** @brief Initialize the bold tag
- *
- * This doesn't seem to work on OS X though the italic and monospace tags are
- * fine, and bold is OK on Linux, even connecting to the Apple X swerver.
- */
-static void init_bold(GtkTextTag *tag) {
- g_object_set(G_OBJECT(tag), "weight", PANGO_WEIGHT_BOLD, (char *)0);
-}
-
-/** @brief Initialize the italic tag */
-static void init_italic(GtkTextTag *tag) {
- g_object_set(G_OBJECT(tag), "style", PANGO_STYLE_ITALIC, (char *)0);
-}
-
-/** @brief Initialize the pre tag */
-static void init_pre(GtkTextTag *tag) {
- g_object_set(G_OBJECT(tag), "family", "monospace", (char *)0);
-}
-
-/** @brief Table of known tags
- *
- * Keep in alphabetical order
- */
-static const struct tag tags[] = {
- { "b", init_bold },
- { "i", init_italic },
- { "pre", init_pre }
-};
-
-/** @brief Number of known tags */
-#define NTAGS (sizeof tags / sizeof *tags)
-
-/** @brief State structure for insert_html() */
-struct state {
- /** @brief The buffer to insert into */
- GtkTextBuffer *buffer;
-
- /** @brief The buffer's tag table */
- GtkTextTagTable *tagtable;
-
- /** @brief True if we are inside <body> */
- int body;
-
- /** @brief True if inside <pre> */
- int pre;
-
- /** @brief True if a space is required before any non-space */
- int space;
-
- /** @brief Stack of marks corresponding to tags */
- struct markstack marks[1];
-
-};
-
-/** @brief Called for an open tag */
-static void html_open(const char *tag,
- hash attribute((unused)) *attrs,
- void *u) {
- struct state *const s = u;
- GtkTextIter iter[1];
-
- if(!strcmp(tag, "body"))
- ++s->body;
- else if(!strcmp(tag, "pre"))
- ++s->pre;
- if(!s->body)
- return;
- /* push a mark for the start of the region */
- gtk_text_buffer_get_iter_at_mark(s->buffer, iter,
- gtk_text_buffer_get_insert(s->buffer));
- markstack_append(s->marks,
- gtk_text_buffer_create_mark(s->buffer,
- 0/* mark_name */,
- iter,
- TRUE/*left_gravity*/));
-}
-
-/** @brief Called for a close tag */
-static void html_close(const char *tag,
- void *u) {
- struct state *const s = u;
- GtkTextIter start[1], end[1];
- GtkTextTag *texttag;
-
- if(!strcmp(tag, "body"))
- --s->body;
- else if(!strcmp(tag, "pre")) {
- --s->pre;
- s->space = 0;
- }
- if(!s->body)
- return;
- /* see if this is a known tag */
- texttag = gtk_text_tag_table_lookup(s->tagtable, tag);
- if(!texttag)
- return;
- /* pop the mark at the start of the region */
- assert(s->marks->nvec > 0);
- gtk_text_buffer_get_iter_at_mark(s->buffer, start,
- s->marks->vec[--s->marks->nvec]);
- gtk_text_buffer_get_iter_at_mark(s->buffer, end,
- gtk_text_buffer_get_insert(s->buffer));
- /* apply the tag */
- gtk_text_buffer_apply_tag(s->buffer, texttag, start, end);
- /* don't need the start mark any more */
- gtk_text_buffer_delete_mark(s->buffer, s->marks->vec[s->marks->nvec]);
-}
-
-/** @brief Called for text */
-static void html_text(const char *text,
- void *u) {
- struct state *const s = u;
-
- /* ignore header */
- if(!s->body)
- return;
- if(!s->pre) {
- char *formatted = xmalloc(strlen(text) + 1), *t = formatted;
- /* normalize spacing */
- while(*text) {
- if(isspace((unsigned char)*text)) {
- s->space = 1;
- ++text;
- } else {
- if(s->space) {
- *t++ = ' ';
- s->space = 0;
- }
- *t++ = *text++;
- }
+#include <sys/wait.h>
+#include <unistd.h>
+
+/** @brief Display the manual page */
+void popup_help(const char *what) {
+ char *path;
+ pid_t pid;
+ int w;
+
+ if(!what)
+ what = "index.html";
+#if __APPLE__
+ if(!strcmp(browser, "open"))
+ /* Apple's open(1) isn't really a web browser so needs some extra hints
+ * that it should see the argument as a URL. Otherwise it doesn't treat #
+ * specially. A better answer would be to identify the system web browser
+ * and invoke it directly. */
+ byte_xasprintf(&path, "file:///%s/%s", dochtmldir, what);
+ else
+#endif
+ byte_xasprintf(&path, "%s/%s", dochtmldir, what);
+ if(!(pid = xfork())) {
+ exitfn = _exit;
+ if(!xfork()) {
+ execlp(browser, browser, path, (char *)0);
+ disorder_fatal(errno, "error executing %s", browser);