b970e10
Index: info/nodes.c
b970e10
===================================================================
b970e10
--- info/nodes.c	(revision 5245)
b970e10
+++ info/nodes.c	(revision 5246)
b970e10
@@ -563,6 +563,7 @@
b970e10
       /* Okay, we have isolated the node name, and we know where the
b970e10
          node starts.  Remember this information. */
b970e10
       entry = xmalloc (sizeof (TAG));
b970e10
+      entry->content_cache = NULL;
b970e10
       entry->nodename = xmalloc (1 + (end - start));
b970e10
       strncpy (entry->nodename, nodeline + start, end - start);
b970e10
       entry->nodename[end - start] = 0;
b970e10
@@ -667,6 +668,7 @@
b970e10
         break;
b970e10
 
b970e10
       entry = xmalloc (sizeof (TAG));
b970e10
+      entry->content_cache = NULL;
b970e10
 
b970e10
       /* Find the beginning of the node definition. */
b970e10
       tmp_search->start += name_offset;
b970e10
@@ -981,7 +983,12 @@
b970e10
 	node->filename    = subfile->fullpath;
b970e10
 	node->parent      = NULL;
b970e10
 	node->nodename    = tag->nodename;
b970e10
-	node->contents    = subfile->contents + tag->nodestart;
b970e10
+	
b970e10
+	if (tag->content_cache)
b970e10
+	  node->contents = tag->content_cache;
b970e10
+	else
b970e10
+	  node->contents    = subfile->contents + tag->nodestart;
b970e10
+
b970e10
 	node->display_pos = 0;
b970e10
 	node->flags       = 0;
b970e10
 	node_set_body_start (node);
b970e10
@@ -1049,6 +1056,12 @@
b970e10
 	    node_body.end = buff_end - node_body.buffer;
b970e10
 	    node_body.flags = 0;
b970e10
 	    tag->nodelen = get_node_length (&node_body);
b970e10
+	    /* Expand eventual \b[...\b] constructs in the contents.
b970e10
+	       If found, update node->contents to point to the resulting
b970e10
+	       buffer. */
b970e10
+	    if (tags_expand (node->contents, tag->nodelen,
b970e10
+			     &tag->content_cache, &tag->nodelen))
b970e10
+	      node->contents = tag->content_cache;
b970e10
 	    node->nodelen = tag->nodelen;
b970e10
 	  }
b970e10
 	else if (tag->nodelen == 0) /* anchor, return containing node */
b970e10
@@ -1173,7 +1186,8 @@
b970e10
 free_info_tag (TAG *tag)
b970e10
 {
b970e10
   free (tag->nodename);
b970e10
-
b970e10
+  free (tag->content_cache);
b970e10
+  
b970e10
   /* We don't free tag->filename, because that filename is part of the
b970e10
      subfiles list for the containing FILE_BUFFER.  free_info_tags ()
b970e10
      will free the subfiles when it is appropriate. */
b970e10
Index: info/tag.c
b970e10
===================================================================
b970e10
--- info/tag.c	(revision 5245)
b970e10
+++ info/tag.c	(revision 5246)
b970e10
@@ -113,6 +113,8 @@
b970e10
 	  if (state == state_delim)
b970e10
 	    continue;
b970e10
 	}
b970e10
+      else if (state == state_delim)
b970e10
+	state = state_kw;
b970e10
       cur_len = mb_len (mbi_cur (iter));
b970e10
       cur_ptr = mbi_cur_ptr (iter);
b970e10
       
b970e10
@@ -125,6 +127,8 @@
b970e10
 	  switch (*cur_ptr)
b970e10
 	    {
b970e10
 	    case '=':
b970e10
+	      if (state != state_kw)
b970e10
+		break;
b970e10
 	      text_buffer_add_char (&tmpbuf, 0);
b970e10
 	      kw = tmpbuf.base;
b970e10
 	      if (!mbi_avail (iter))
b970e10
@@ -197,22 +201,29 @@
b970e10
   return NULL;
b970e10
 }
b970e10
 
b970e10
-void
b970e10
-tags_expand (char **pbuf, size_t *pbuflen)
b970e10
+/* Expand \b[...\b] constructs in INPUT (of INPUTLEN bytes).  If encountered,
b970e10
+   put the expanded text into PBUF, store its length in PBUFLEN, and return
b970e10
+   1.  Otherwise, don't touch neither of the latter and return 0. */
b970e10
+int
b970e10
+tags_expand (char *input, size_t inputlen, char **pbuf, size_t *pbuflen)
b970e10
 {
b970e10
-  char *input = *pbuf;
b970e10
-  char *endp = input + *pbuflen;
b970e10
+  char *endp = input + inputlen;
b970e10
   struct text_buffer outbuf;
b970e10
+  int text_buffer_used = 0;
b970e10
   char *p;
b970e10
 
b970e10
-  text_buffer_init (&outbuf);
b970e10
-
b970e10
   while ((p = input + strlen (input)) < endp) /* go forward to null */
b970e10
     {
b970e10
       if (memcmp(p + 1, "\b[", 2) == 0)       /* opening magic? */
b970e10
 	{
b970e10
 	  char *q;
b970e10
 
b970e10
+	  if (!text_buffer_used)
b970e10
+	    {
b970e10
+	      text_buffer_init (&outbuf);
b970e10
+	      text_buffer_used = 1;
b970e10
+	    }
b970e10
+	  
b970e10
 	  p += 3;
b970e10
 	  q = p + strlen (p);                 /* forward to next null */
b970e10
 	  if (memcmp (q + 1, "\b]", 2) == 0)  /* closing magic? */
b970e10
@@ -227,10 +238,7 @@
b970e10
 		  while (p[len] == ' ' || p[len] == '\t')
b970e10
 		    ++len;                      /* move past whitespace */
b970e10
 	      
b970e10
-		  if (!text_buffer_off (&outbuf))
b970e10
-		    text_buffer_add_string (&outbuf, *pbuf, p - *pbuf - 3);
b970e10
-		  else
b970e10
-		    text_buffer_add_string (&outbuf, input, p - input - 3);
b970e10
+		  text_buffer_add_string (&outbuf, input, p - input - 3);
b970e10
 		  if (tp->handler (p + len, &outbuf) == 0)
b970e10
 		    {
b970e10
 		      input = q + 3;
b970e10
@@ -240,21 +248,21 @@
b970e10
 	    }
b970e10
 	}
b970e10
 
b970e10
-      if (text_buffer_off (&outbuf))
b970e10
-	{
b970e10
-	  text_buffer_add_string (&outbuf, input, p - input);
b970e10
-	}
b970e10
+      if (text_buffer_used)
b970e10
+	text_buffer_add_string (&outbuf, input, p - input);
b970e10
+
b970e10
       input = p + 1;
b970e10
     }
b970e10
 
b970e10
-  if (text_buffer_off (&outbuf))
b970e10
+  if (text_buffer_used && text_buffer_off (&outbuf))
b970e10
     {
b970e10
       if (input < endp)
b970e10
 	text_buffer_add_string (&outbuf, input, endp - input);
b970e10
-      free (*pbuf);
b970e10
       *pbuflen = text_buffer_off (&outbuf);
b970e10
       *pbuf = text_buffer_base (&outbuf);
b970e10
+      return 1;
b970e10
     }
b970e10
+  return 0;
b970e10
 }
b970e10
   
b970e10
 void
b970e10
Index: info/nodes.h
b970e10
===================================================================
b970e10
--- info/nodes.h	(revision 5245)
b970e10
+++ info/nodes.h	(revision 5246)
b970e10
@@ -90,6 +90,9 @@
b970e10
   char *nodename;               /* The node pointed to by this tag. */
b970e10
   long nodestart;               /* The offset of the start of this node. */
b970e10
   long nodelen;                 /* The length of this node. */
b970e10
+  char *content_cache;          /* Cache of the node contents; used if the
b970e10
+				   node contents must be preprocessed before
b970e10
+				   displaying it. */
b970e10
 } TAG;
b970e10
 
b970e10
 /* The following structure is used to remember information about the contents
b970e10
Index: info/filesys.c
b970e10
===================================================================
b970e10
--- info/filesys.c	(revision 5245)
b970e10
+++ info/filesys.c	(revision 5246)
b970e10
@@ -645,8 +645,6 @@
b970e10
      files are coming from some Windows system across a network.  */
b970e10
   fsize = convert_eols (contents, fsize);
b970e10
 
b970e10
-  tags_expand (&contents, &fsize);
b970e10
-
b970e10
   /* EOL conversion can shrink the text quite a bit.  We don't
b970e10
      want to waste storage.  */
b970e10
   contents = xrealloc (contents, 1 + fsize);
b970e10
Index: info/tag.h
b970e10
===================================================================
b970e10
--- info/tag.h	(revision 5245)
b970e10
+++ info/tag.h	(revision 5246)
b970e10
@@ -19,7 +19,7 @@
b970e10
 #ifndef TAG_H
b970e10
 #define TAG_H
b970e10
 
b970e10
-void tags_expand (char **pbuf, size_t *pbuflen);
b970e10
+int tags_expand (char *input, size_t inputlen, char **pbuf, size_t *pbuflen);
b970e10
 void handle_tag (char *tag);
b970e10
 
b970e10
 #endif