chiark / gitweb /
split out disorder-server.deb
[disorder] / disobedience / help.c
index 09de980628c61ef653223a5246e31da71e7eb4a9..06691c797c8a90774a153d445d94125fbf2cef4e 100644 (file)
@@ -17,6 +17,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  * USA
  */
+/** @file disobedience/help.c
+ * @brief Help support
+ */
 
 #include "disobedience.h"
 #include "table.h"
@@ -37,21 +40,33 @@ struct tag {
   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  struct tag tags[] = {
   { "b", init_bold, 0 },
-  { "i", init_italic, 0 }
+  { "i", init_italic, 0 },
+  { "pre", init_pre, 0 }
 };
 
 /** @brief Number of known tags */
@@ -65,6 +80,12 @@ struct state {
   /** @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];
 
@@ -78,7 +99,9 @@ static void html_open(const char *tag,
   GtkTextIter iter[1];
 
   if(!strcmp(tag, "body"))
-    s->body = 1;
+    ++s->body;
+  else if(!strcmp(tag, "pre"))
+    ++s->pre;
   if(!s->body)
     return;
   /* push a mark for the start of the region */
@@ -99,7 +122,11 @@ static void html_close(const char *tag,
   int n;
 
   if(!strcmp(tag, "body"))
-    s->body = 0;
+    --s->body;
+  else if(!strcmp(tag, "pre")) {
+    --s->pre;
+    s->space = 0;
+  }
   if(!s->body)
     return;
   /* see if this is a known tag */
@@ -125,6 +152,24 @@ static void html_text(const char *text,
   /* 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++;
+      }
+    }
+    *t = 0;
+    text = formatted;
+  }
   gtk_text_buffer_insert_at_cursor(s->buffer, text, strlen(text));
 }
 
@@ -157,6 +202,7 @@ static void insert_html(GtkTextBuffer *buffer,
   html_parse(&insert_html_callbacks, html, s);
 }
 
+/** @brief Create a GtkTextBuffer with @p html rendered into it */
 static GtkTextBuffer *html_buffer(const char *html) {
   GtkTextBuffer *buffer = gtk_text_buffer_new(NULL);
 
@@ -164,8 +210,10 @@ static GtkTextBuffer *html_buffer(const char *html) {
   return buffer;
 }
 
+/** @brief The manual page window */
 static GtkWidget *help_window;
 
+/** @brief Pop up the manual page in a window */
 void popup_help(void) {
   GtkWidget *view;
   
@@ -176,11 +224,11 @@ void popup_help(void) {
   help_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   g_signal_connect(help_window, "destroy",
                   G_CALLBACK(gtk_widget_destroyed), &help_window);
-  gtk_window_set_title(GTK_WINDOW(help_window), "Disobedience Manual");
+  gtk_window_set_title(GTK_WINDOW(help_window), "Disobedience Manual Page");
   view = gtk_text_view_new_with_buffer(html_buffer(manual));
-  gtk_container_add(GTK_CONTAINER(help_window),
-                   scroll_widget(view,
-                                 "help"));
+  gtk_text_view_set_editable(GTK_TEXT_VIEW(view), FALSE);
+  gtk_container_add(GTK_CONTAINER(help_window), scroll_widget(view));
+  gtk_window_set_default_size(GTK_WINDOW(help_window), 512, 512);
   gtk_widget_show_all(help_window);
 }