[patches] more tags for gzilla



Well, I spent some spare time this weekend writing some code for gzilla.
I should've been doing other things, but hey, it's my weekend, right?

This mail should have six patches attached to it.

gzilla-0.02-hr.patch: Added support for the <hr> tag.
gzilla-0.02-address.patch: Added <address> tag. (absolutely trivial)
gzilla-0.02-dl.patch: Added support for description lists.
gzilla-0.02-pre.patch: Added reasonable support for <pre> tags.
gzilla-0.02-jumbo1.patch: Everything up to this point in a single patch to 0.02.

Note that the <pre> tag support is mostly done, except that tabs
aren't handled properly.  There's a comment about it in the code... if
anyone can tell me the best way to solve it, I'd really like to know.

In any case, I noticed a few problems with gzilla while I was coding
this stuff.

Resize doesn't work at all.  When the window is resized, the text
remains the same size.  I presume you (Raph) already know that... just
thought I'd mention it.

Well, actually I suppose that was the only real problem I saw. :) It's
coming along quite nicely.. can't wait for the next code escape.

Thanks a bunch.

-- 
					-Otto.
--- gzilla/gzillahtml.c.hr	Sat May 17 00:14:43 1997
+++ gzilla/gzillahtml.c	Sun May 18 17:52:24 1997
@@ -587,6 +587,33 @@
   html->stack[html->num_states - 1].attr = gtk_page_find_attr (page, &attr);
 }
 
+/* gzilla_html_tag_open_hr() */
+static void
+gzilla_html_tag_open_hr(GzillaHtml *html, 
+			char *tag, 
+			gint tagsize)
+{
+  GtkWidget *hrule;
+  GtkRequisition size;
+  int width, height;
+
+  hrule = gtk_hseparator_new();
+  gtk_widget_size_request(html->bytesink.widget, &size);
+  width = size.width;
+  /* set the height to 0, since otherwise the hrule takes up quite a
+   * bit of space.. not sure why, but this works well.
+   */
+  height = 0;
+  gtk_widget_set_usize(hrule, width, height);
+
+  gtk_widget_show(hrule);
+
+  gtk_page_add_widget(GTK_PAGE(html->bytesink.widget), hrule,
+		      html->stack[html->num_states - 1].attr);
+  gtk_page_linebreak(GTK_PAGE(html->bytesink.widget));
+
+} /* end gzilla_html_tag_open_hr() */
+
 /* Default close for most tags - just pop the stack. */
 
 static void gzilla_html_tag_default_close (GzillaHtml *html,
@@ -639,7 +666,8 @@
     { "a", gzilla_html_tag_open_a, gzilla_html_tag_default_close },
     { "blockquote", gzilla_html_tag_open_blockquote, gzilla_html_tag_par_close },
     { "ul", gzilla_html_tag_open_ul, gzilla_html_tag_par_close },
-    { "li", gzilla_html_tag_open_li, gzilla_html_tag_default_close }
+    { "li", gzilla_html_tag_open_li, gzilla_html_tag_default_close },
+    { "hr", gzilla_html_tag_open_hr, gzilla_html_tag_nop_close }
   };
   gint i;
   gint n = sizeof (tags) / sizeof (tags[0]);
--- gzilla/gzillahtml.c.address	Sat May 17 23:44:50 1997
+++ gzilla/gzillahtml.c	Sun May 18 02:48:21 1997
@@ -668,7 +668,8 @@
     { "blockquote", gzilla_html_tag_open_blockquote, gzilla_html_tag_par_close },
     { "ul", gzilla_html_tag_open_ul, gzilla_html_tag_par_close },
     { "li", gzilla_html_tag_open_li, gzilla_html_tag_default_close },
-    { "hr", gzilla_html_tag_open_hr, gzilla_html_tag_nop_close }
+    { "hr", gzilla_html_tag_open_hr, gzilla_html_tag_nop_close },
+    { "address", gzilla_html_tag_open_i, gzilla_html_tag_par_close }
   };
   gint i;
   gint n = sizeof (tags) / sizeof (tags[0]);
--- gzilla/gzillahtml.c.dl	Sun May 18 17:58:54 1997
+++ gzilla/gzillahtml.c	Sun May 18 18:19:46 1997
@@ -450,6 +450,7 @@
   GtkPage *page;
   GtkPageFont font;
   GtkPageAttr attr;
+
   gzilla_html_push_tag (html, tag, tagsize);
 
   page = GTK_PAGE (html->bytesink.widget);
@@ -598,6 +599,7 @@
   int width, height;
 
   hrule = gtk_hseparator_new();
+  /* I don't -think- that space for the return arg, is allocated by this call */
   gtk_widget_size_request(html->bytesink.widget, &size);
   width = size.width;
   /* set the height to 0, since otherwise the hrule takes up quite a
@@ -614,6 +616,73 @@
 
 } /* end gzilla_html_tag_open_hr() */
 
+/* gzilla_html_tag_open_dl() */
+static void
+gzilla_html_tag_open_dl(GzillaHtml *html, 
+			char *tag, 
+			gint tagsize)
+{
+  /* may want to actually do some stuff here. */
+  gzilla_html_par_push_tag(html, tag, tagsize);
+
+} /* end gzilla_html_tag_open_dl() */
+
+/* gzilla_html_tag_open_dt() */
+static void
+gzilla_html_tag_open_dt(GzillaHtml *html, 
+			char *tag, 
+			gint tagsize)
+{
+  GtkPage *page;
+  GtkPageFont font;
+  GtkPageAttr attr;
+
+  gzilla_html_cleanup_tag(html, "dd>");
+  gzilla_html_cleanup_tag(html, "dt>");
+
+  gzilla_html_par_push_tag(html, tag, tagsize);
+
+  page = GTK_PAGE(html->bytesink.widget);
+  attr = page->attrs[html->stack[html->num_states - 1].attr];
+  font = page->fonts[attr.font];
+  font.bold = TRUE;
+  attr.font = gtk_page_find_font(page, &font);
+  html->stack[html->num_states - 1].attr = gtk_page_find_attr(page, &attr);
+
+  /* I really want less space between this and the description, but
+   * for some reason using gtk_page_linebreak doesn't work, so I've
+   * made the "close tag" function gzilla_html_par_close which, of
+   * course, gives me an awful lot of vertical space after a <dt>.
+   * Purely aesethic, I guess... it'd just be nice to know why.
+   */
+  
+} /* end gzilla_html_tag_open_dt() */
+
+/* gzilla_html_tag_open_dd() */
+static void
+gzilla_html_tag_open_dd(GzillaHtml *html, 
+			char *tag, 
+			gint tagsize)
+{
+  GtkPage *page;
+  GtkPageAttr attr;
+
+  gzilla_html_cleanup_tag(html, "dd>");
+  gzilla_html_cleanup_tag(html, "dt>");
+  
+  gzilla_html_par_push_tag(html, tag, tagsize);
+
+  page = GTK_PAGE (html->bytesink.widget);
+
+  attr = page->attrs[html->stack[html->num_states - 1].attr];
+  attr.left_indent_first = attr.left_indent_rest + 40;
+  attr.left_indent_rest += 40;
+  attr.right_indent += 40;
+  html->stack[html->num_states - 1].attr = gtk_page_find_attr (page, &attr);
+
+} /* end gzilla_html_tag_open_dd() */
+
+
 /* Default close for most tags - just pop the stack. */
 
 static void gzilla_html_tag_default_close (GzillaHtml *html,
@@ -668,7 +737,10 @@
     { "ul", gzilla_html_tag_open_ul, gzilla_html_tag_par_close },
     { "li", gzilla_html_tag_open_li, gzilla_html_tag_default_close },
     { "hr", gzilla_html_tag_open_hr, gzilla_html_tag_nop_close },
-    { "address", gzilla_html_tag_open_i, gzilla_html_tag_par_close }
+    { "address", gzilla_html_tag_open_i, gzilla_html_tag_par_close },
+    { "dl", gzilla_html_tag_open_dl, gzilla_html_tag_par_close },
+    { "dt", gzilla_html_tag_open_dt, gzilla_html_tag_par_close },
+    { "dd", gzilla_html_tag_open_dd, gzilla_html_tag_par_close }
   };
   gint i;
   gint n = sizeof (tags) / sizeof (tags[0]);
--- gzilla/gzillahtml.c.pre	Mon May 19 02:23:01 1997
+++ gzilla/gzillahtml.c	Mon May 19 02:25:02 1997
@@ -256,9 +256,26 @@
 				   gint size) {
   if (html->stack[html->num_states - 1].parse_mode !=
       GZILLA_HTML_PARSE_MODE_STASH)
-    gtk_page_add_text (GTK_PAGE (html->bytesink.widget),
-		       gzilla_html_parse_entities (word, size),
-		       html->stack[html->num_states - 1].attr);
+    {
+      if(word[0] == '\n')
+	gtk_page_linebreak(GTK_PAGE(html->bytesink.widget));
+
+      /* this works because of the same side-effect that causes the
+       * problem.  newlines (and tabs) passed in the string are
+       * basically ignored, no need to change the size and word
+       * pointer.
+       *
+       * right now, this support for <pre> tags ignore tabs entirely.
+       * I can't find a working way to insert more than one space
+       * (i.e., a tab).. when I tried inserting a string of spaces,
+       * the program would seg fault when it tried to follow a link. 
+       * Using gtk_page_add_space multiple times also failed. -Otto 
+       */
+
+      gtk_page_add_text (GTK_PAGE (html->bytesink.widget),
+			 gzilla_html_parse_entities (word, size),
+			 html->stack[html->num_states - 1].attr);
+    }
 }
 
 static void gzilla_html_process_space (GzillaHtml *html,
@@ -682,6 +699,30 @@
 
 } /* end gzilla_html_tag_open_dd() */
 
+/* gzilla_html_tag_open_pre() */
+static void
+gzilla_html_tag_open_pre(GzillaHtml *html,
+			 char *tag,
+			 gint tagsize)
+{
+  GtkPage *page;
+  GtkPageFont font;
+  GtkPageAttr attr;
+
+  gzilla_html_par_push_tag(html, tag, tagsize);
+
+  page = GTK_PAGE (html->bytesink.widget);
+  attr = page->attrs[html->stack[html->num_states - 1].attr];
+  font = page->fonts[attr.font];
+  font.name = "courier";
+  attr.font = gtk_page_find_font (page, &font);
+  html->stack[html->num_states - 1].attr = gtk_page_find_attr (page, &attr);
+
+  /* the placement of this statement right? */
+  html->stack[html->num_states - 1].parse_mode = GZILLA_HTML_PARSE_MODE_PRE;
+  
+} /* end gzilla_html_tag_open_pre() */
+
 
 /* Default close for most tags - just pop the stack. */
 
@@ -740,7 +781,8 @@
     { "address", gzilla_html_tag_open_i, gzilla_html_tag_par_close },
     { "dl", gzilla_html_tag_open_dl, gzilla_html_tag_par_close },
     { "dt", gzilla_html_tag_open_dt, gzilla_html_tag_par_close },
-    { "dd", gzilla_html_tag_open_dd, gzilla_html_tag_par_close }
+    { "dd", gzilla_html_tag_open_dd, gzilla_html_tag_par_close },
+    { "pre", gzilla_html_tag_open_pre, gzilla_html_tag_par_close }
   };
   gint i;
   gint n = sizeof (tags) / sizeof (tags[0]);
@@ -893,7 +935,10 @@
 
     /* invariant: buf_index == bufsize || token_start == buf_index */
 
-    if (isspace (buf[buf_index])) {
+    if (isspace (buf[buf_index])
+	&& (html->stack[html->num_states - 1].parse_mode
+	    != GZILLA_HTML_PARSE_MODE_PRE)) 
+      {
       /* whitespace : consume all available whitespace */
       do {
 	buf_index++;
--- gzilla/gzillahtml.h.pre	Mon May 19 02:22:56 1997
+++ gzilla/gzillahtml.h	Mon May 19 02:23:47 1997
@@ -21,7 +21,12 @@
 #define GZILLA_HTML_PARSE_MODE_INIT 0
 #define GZILLA_HTML_PARSE_MODE_STASH 1
 #define GZILLA_HTML_PARSE_MODE_BODY 2
+#define GZILLA_HTML_PARSE_MODE_PRE 3
 /* pre goes here */
+/* this is just the comment I was hoping for. :)  Might be useful to
+ * put all of these in an enum so the values are done automatically,
+ * don't you think? -Otto
+ */
 
 struct _GzillaHtmlState {
   char *tag;
--- gzilla/gzillahtml.c.jumbo1	Mon May 19 02:29:56 1997
+++ gzilla/gzillahtml.c	Mon May 19 02:30:44 1997
@@ -256,9 +256,26 @@
 				   gint size) {
   if (html->stack[html->num_states - 1].parse_mode !=
       GZILLA_HTML_PARSE_MODE_STASH)
-    gtk_page_add_text (GTK_PAGE (html->bytesink.widget),
-		       gzilla_html_parse_entities (word, size),
-		       html->stack[html->num_states - 1].attr);
+    {
+      if(word[0] == '\n')
+	gtk_page_linebreak(GTK_PAGE(html->bytesink.widget));
+
+      /* this works because of the same side-effect that causes the
+       * problem.  newlines (and tabs) passed in the string are
+       * basically ignored, no need to change the size and word
+       * pointer.
+       *
+       * right now, this support for <pre> tags ignore tabs entirely.
+       * I can't find a working way to insert more than one space
+       * (i.e., a tab).. when I tried inserting a string of spaces,
+       * the program would seg fault when it tried to follow a link. 
+       * Using gtk_page_add_space multiple times also failed. -Otto 
+       */
+
+      gtk_page_add_text (GTK_PAGE (html->bytesink.widget),
+			 gzilla_html_parse_entities (word, size),
+			 html->stack[html->num_states - 1].attr);
+    }
 }
 
 static void gzilla_html_process_space (GzillaHtml *html,
@@ -450,6 +467,7 @@
   GtkPage *page;
   GtkPageFont font;
   GtkPageAttr attr;
+
   gzilla_html_push_tag (html, tag, tagsize);
 
   page = GTK_PAGE (html->bytesink.widget);
@@ -587,6 +605,125 @@
   html->stack[html->num_states - 1].attr = gtk_page_find_attr (page, &attr);
 }
 
+/* gzilla_html_tag_open_hr() */
+static void
+gzilla_html_tag_open_hr(GzillaHtml *html, 
+			char *tag, 
+			gint tagsize)
+{
+  GtkWidget *hrule;
+  GtkRequisition size;
+  int width, height;
+
+  hrule = gtk_hseparator_new();
+  /* I don't -think- that space for the return arg, is allocated by this call */
+  gtk_widget_size_request(html->bytesink.widget, &size);
+  width = size.width;
+  /* set the height to 0, since otherwise the hrule takes up quite a
+   * bit of space.. not sure why, but this works well.
+   */
+  height = 0;
+  gtk_widget_set_usize(hrule, width, height);
+
+  gtk_widget_show(hrule);
+
+  gtk_page_add_widget(GTK_PAGE(html->bytesink.widget), hrule,
+		      html->stack[html->num_states - 1].attr);
+  gtk_page_linebreak(GTK_PAGE(html->bytesink.widget));
+
+} /* end gzilla_html_tag_open_hr() */
+
+/* gzilla_html_tag_open_dl() */
+static void
+gzilla_html_tag_open_dl(GzillaHtml *html, 
+			char *tag, 
+			gint tagsize)
+{
+  /* may want to actually do some stuff here. */
+  gzilla_html_par_push_tag(html, tag, tagsize);
+
+} /* end gzilla_html_tag_open_dl() */
+
+/* gzilla_html_tag_open_dt() */
+static void
+gzilla_html_tag_open_dt(GzillaHtml *html, 
+			char *tag, 
+			gint tagsize)
+{
+  GtkPage *page;
+  GtkPageFont font;
+  GtkPageAttr attr;
+
+  gzilla_html_cleanup_tag(html, "dd>");
+  gzilla_html_cleanup_tag(html, "dt>");
+
+  gzilla_html_par_push_tag(html, tag, tagsize);
+
+  page = GTK_PAGE(html->bytesink.widget);
+  attr = page->attrs[html->stack[html->num_states - 1].attr];
+  font = page->fonts[attr.font];
+  font.bold = TRUE;
+  attr.font = gtk_page_find_font(page, &font);
+  html->stack[html->num_states - 1].attr = gtk_page_find_attr(page, &attr);
+
+  /* I really want less space between this and the description, but
+   * for some reason using gtk_page_linebreak doesn't work, so I've
+   * made the "close tag" function gzilla_html_par_close which, of
+   * course, gives me an awful lot of vertical space after a <dt>.
+   * Purely aesethic, I guess... it'd just be nice to know why.
+   */
+  
+} /* end gzilla_html_tag_open_dt() */
+
+/* gzilla_html_tag_open_dd() */
+static void
+gzilla_html_tag_open_dd(GzillaHtml *html, 
+			char *tag, 
+			gint tagsize)
+{
+  GtkPage *page;
+  GtkPageAttr attr;
+
+  gzilla_html_cleanup_tag(html, "dd>");
+  gzilla_html_cleanup_tag(html, "dt>");
+  
+  gzilla_html_par_push_tag(html, tag, tagsize);
+
+  page = GTK_PAGE (html->bytesink.widget);
+
+  attr = page->attrs[html->stack[html->num_states - 1].attr];
+  attr.left_indent_first = attr.left_indent_rest + 40;
+  attr.left_indent_rest += 40;
+  attr.right_indent += 40;
+  html->stack[html->num_states - 1].attr = gtk_page_find_attr (page, &attr);
+
+} /* end gzilla_html_tag_open_dd() */
+
+/* gzilla_html_tag_open_pre() */
+static void
+gzilla_html_tag_open_pre(GzillaHtml *html,
+			 char *tag,
+			 gint tagsize)
+{
+  GtkPage *page;
+  GtkPageFont font;
+  GtkPageAttr attr;
+
+  gzilla_html_par_push_tag(html, tag, tagsize);
+
+  page = GTK_PAGE (html->bytesink.widget);
+  attr = page->attrs[html->stack[html->num_states - 1].attr];
+  font = page->fonts[attr.font];
+  font.name = "courier";
+  attr.font = gtk_page_find_font (page, &font);
+  html->stack[html->num_states - 1].attr = gtk_page_find_attr (page, &attr);
+
+  /* the placement of this statement right? */
+  html->stack[html->num_states - 1].parse_mode = GZILLA_HTML_PARSE_MODE_PRE;
+  
+} /* end gzilla_html_tag_open_pre() */
+
+
 /* Default close for most tags - just pop the stack. */
 
 static void gzilla_html_tag_default_close (GzillaHtml *html,
@@ -639,7 +776,13 @@
     { "a", gzilla_html_tag_open_a, gzilla_html_tag_default_close },
     { "blockquote", gzilla_html_tag_open_blockquote, gzilla_html_tag_par_close },
     { "ul", gzilla_html_tag_open_ul, gzilla_html_tag_par_close },
-    { "li", gzilla_html_tag_open_li, gzilla_html_tag_default_close }
+    { "li", gzilla_html_tag_open_li, gzilla_html_tag_default_close },
+    { "hr", gzilla_html_tag_open_hr, gzilla_html_tag_nop_close },
+    { "address", gzilla_html_tag_open_i, gzilla_html_tag_par_close },
+    { "dl", gzilla_html_tag_open_dl, gzilla_html_tag_par_close },
+    { "dt", gzilla_html_tag_open_dt, gzilla_html_tag_par_close },
+    { "dd", gzilla_html_tag_open_dd, gzilla_html_tag_par_close },
+    { "pre", gzilla_html_tag_open_pre, gzilla_html_tag_par_close }
   };
   gint i;
   gint n = sizeof (tags) / sizeof (tags[0]);
@@ -792,7 +935,10 @@
 
     /* invariant: buf_index == bufsize || token_start == buf_index */
 
-    if (isspace (buf[buf_index])) {
+    if (isspace (buf[buf_index])
+	&& (html->stack[html->num_states - 1].parse_mode
+	    != GZILLA_HTML_PARSE_MODE_PRE)) 
+      {
       /* whitespace : consume all available whitespace */
       do {
 	buf_index++;
--- gzilla/gzillahtml.h.jumbo1	Mon May 19 02:30:00 1997
+++ gzilla/gzillahtml.h	Mon May 19 02:30:44 1997
@@ -21,7 +21,12 @@
 #define GZILLA_HTML_PARSE_MODE_INIT 0
 #define GZILLA_HTML_PARSE_MODE_STASH 1
 #define GZILLA_HTML_PARSE_MODE_BODY 2
+#define GZILLA_HTML_PARSE_MODE_PRE 3
 /* pre goes here */
+/* this is just the comment I was hoping for. :)  Might be useful to
+ * put all of these in an enum so the values are done automatically,
+ * don't you think? -Otto
+ */
 
 struct _GzillaHtmlState {
   char *tag;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]