texinfo-commits
[Top][All Lists]
Advanced

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

[5647] display dir entries on a single line


From: Gavin D. Smith
Subject: [5647] display dir entries on a single line
Date: Sun, 08 Jun 2014 19:19:17 +0000

Revision: 5647
          http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=5647
Author:   gavin
Date:     2014-06-08 19:19:15 +0000 (Sun, 08 Jun 2014)
Log Message:
-----------
display dir entries on a single line

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/info/dir.c
    trunk/info/info-utils.c
    trunk/info/nodes.h

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog     2014-06-08 18:45:25 UTC (rev 5646)
+++ trunk/ChangeLog     2014-06-08 19:19:15 UTC (rev 5647)
@@ -1,3 +1,19 @@
+2014-06-08  Gavin Smith  <address@hidden>
+
+       * info/nodes.h (N_IsDir): New flag.
+       * info/dir.c (build_dir_node): Set N_IsDir on flags for return node.
+       * info/info-utils.c (scan_reference_marker): Split out from
+       scan_node_contents.
+       (scan_reference_label): Arguments changed.  Don't create REFERENCE
+       object.  Don't skip whitespace at start of label.  Return value says
+       whether the syntax was valid.
+       (scan_reference_target) Look at flags field of NODE to tell
+       if it is an index node.  Look at type field of REFERENCE to
+       tell whether it is a menu entry.  [preprocess-nodes=On]: Display menu
+       item descriptions on same line if there is space.
+       (scan_node_contents): Call info_new_reference.  Check if reference
+       text was contained within parentheses.
+
 2014-06-08  Karl Berry  <address@hidden>
 
        * doc/texinfo.texi (Raw Formatter Commands): fix grammar.

Modified: trunk/info/dir.c
===================================================================
--- trunk/info/dir.c    2014-06-08 18:45:25 UTC (rev 5646)
+++ trunk/info/dir.c    2014-06-08 19:19:15 UTC (rev 5647)
@@ -139,6 +139,7 @@
 
   {
     char *old_contents = node->contents;
+    node->flags |= N_IsDir;
     scan_node_contents (0, &node);
     if (node->flags & N_WasRewritten)
       free (old_contents);

Modified: trunk/info/info-utils.c
===================================================================
--- trunk/info/info-utils.c     2014-06-08 18:45:25 UTC (rev 5646)
+++ trunk/info/info-utils.c     2014-06-08 19:19:15 UTC (rev 5647)
@@ -1140,69 +1140,173 @@
     }
 }
 
-/* Output reference label and create REFERENCE object.  inptr should be
-   on the first non-whitespace byte of label when this function is called. */
-static REFERENCE *
-scan_reference_label (char *label, long label_len, long start_of_reference,
-                      int found_menu_entry)
+/* Check if preceding word is a word like "see". BASE points before PTR in
+   a block of allocated memory. */
+static int
+avoid_see_see (char *ptr, char *base)
 {
-  REFERENCE *entry;
-  char *label_ptr;
-  char *nl_ptr;
+  /* TODO: Only do this for English-language files. */
+  static char *words_like_see[] = {
+    "see", "See", "In", "in", "of", "also"
+  };
+  int i;
+  int word_len = 0;
 
-  /* We definitely have a reference by this point.  Create
-     REFERENCE entity. */
-  entry = xmalloc (sizeof (REFERENCE));
-  entry->filename = NULL;
-  entry->nodename = NULL;
-  entry->label = xstrdup (label);
-  canonicalize_whitespace (entry->label);
-  entry->line_number = 0;
-  if (found_menu_entry)
-    entry->type = REFERENCE_MENU_ITEM;
+  if (ptr == base)
+    return 0;
+
+  /* Skip past whitespace, and then go to beginning of preceding word. */
+  ptr--;
+  while (ptr > base && (*ptr == ' ' || *ptr == '\n' || *ptr == '\t'))
+    ptr--;
+
+  while (ptr > base && !(*ptr == ' ' || *ptr == '\n' || *ptr == '\t'))
+    {
+      ptr--;
+      word_len++;
+    }
+
+  ptr++;
+
+  /* Check if it is in our list. */
+  for (i = 0; i < sizeof (words_like_see) / sizeof (char *); i++)
+    {
+      if (!strncmp (words_like_see[i], ptr, word_len))
+        return 1;
+    }
+  return 0;
+}
+
+/* Output, replace or hide text introducing a reference.  inptr starts on
+   the first byte of a sequence introducing a reference and finishes on the
+   first (non-whitespace) byte of the reference label. */
+static void
+scan_reference_marker (REFERENCE *entry)
+{
+  /* When preprocess_nodes is Off, we position the cursor on
+     the "*" when moving between references. */
+  if (!preprocess_nodes_p)
+    entry->start = inptr - input_start - output_bytes_difference;
+
+  /* Check what we found based on first character of match */
+  if (inptr[0] == '\n')
+    {
+      entry->type = REFERENCE_MENU_ITEM;
+      if (!preprocess_nodes_p)
+        entry->start++;
+    }
   else
     entry->type = REFERENCE_XREF;
 
-  /* Output any whitespace or newlines at start of reference label. */
-  label_ptr = label + skip_whitespace_and_newlines (label);
-  write_extra_bytes_to_output (label, label_ptr - label);
+  if (entry->type == REFERENCE_MENU_ITEM)
+    copy_input_to_output (strlen ("\n* "));
+  else
+    {
+      int previous_word_is_like_see = 0;
 
-  underlining_on ();
+      /* Cross-references can be generated by four different Texinfo
+         commands.  @inforef and @xref output "*Note " in Info format,
+         and "See" in HTML and print.  @ref and @pxref output "*note "
+         in Info format, and either nothing at all or "see" in HTML
+         and print.  Unfortunately, there is no easy way to distinguish
+         between these latter two cases.  We must make do with
+         displayed manuals occasionally containing "See see" and the
+         like. */
+      /* TODO: Internationalize these strings, but only if we know the
+         language of the document. */
+      if (inptr[1] == 'N')
+        write_extra_bytes_to_output ("See", 3);
+      else
+        {
 
-  /* Point reference to where we will put the displayed reference,
-     which could be after whitespace. */
-  if (preprocess_nodes_p)
-    entry->start = text_buffer_off (&output_buf);
+          previous_word_is_like_see = avoid_see_see (inptr, input_start);
+
+          if (!previous_word_is_like_see)
+            write_extra_bytes_to_output ("see", 3);
+        }
+
+      skip_input (strlen ("*Note"));
+      if (previous_word_is_like_see)
+        skip_input (skip_whitespace (inptr));
+    }
+
+  /* Copy any white space before label. */
+  copy_input_to_output (skip_whitespace_and_newlines (inptr));
+}
+
+/* Output reference label and update ENTRY.  inptr should be on the first
+   non-whitespace byte of label when this function is called.  It is left
+   at the first non-whitespace character after the colon terminating the
+   label.  Return 0 if invalid syntax is encountered. */
+static int
+scan_reference_label (REFERENCE *entry)
+{
+  char *nl_ptr;
+  char *end;
+  char *label = 0;
+  long label_len;
+
+  /* Search forward to ":" to get label name. */
+  /* Cross-references may have a newline in the middle. */
+  if (entry->type == REFERENCE_MENU_ITEM)
+    label_len = read_quoted_string (inptr, ":", &label);
   else
-    entry->start = start_of_reference - output_bytes_difference;
+    /* TODO: Limit lines label can cross. */
+    label_len = read_quoted_string (inptr, "\n:", &label);
+    
+  if (inptr[label_len] != ':')
+    return 0;
 
+  entry->label = label;
+  canonicalize_whitespace (entry->label);
+
 #ifdef QUOTE_NODENAMES
   if (inptr[0] == '\177')
-    skip_input (1);
+    {
+      skip_input (1);
+      label_len -= 2;
+    }
 #endif
 
+  end = inptr + label_len;
+
+  underlining_on ();
+
+  /* Must start underlining first so that entry->start points to a printable
+     character.  Otherwise the cursor can end up in the previous column. */
+  if (preprocess_nodes_p)
+    entry->start = text_buffer_off (&output_buf);
+
   /* Write text of label.  If there is a newline in the middle of
      a reference label, turn off underling until text starts again. */
-  while (nl_ptr = strchr (label_ptr, '\n'))
+  while (inptr < end)
     {
-      copy_input_to_output (nl_ptr - label_ptr);
+      nl_ptr = strchr (inptr, '\n');
+      if (!nl_ptr || nl_ptr >= end)
+        break;
 
+      copy_input_to_output (nl_ptr - inptr);
+
       /* Note we do this before the newline is output.  This way if
          the first half of the label is on the bottom line of the
          screen, underlining will not be left on. */
       underlining_off ();
 
       /* Output newline and any whitespace at start of next line. */
-      label_ptr = nl_ptr + 1 + skip_whitespace (nl_ptr + 1);
-      copy_input_to_output (label_ptr - nl_ptr);
+      copy_input_to_output (1 + skip_whitespace (nl_ptr + 1));
 
       underlining_on ();
     }
 
   /* Output rest of label */
-  copy_input_to_output (label + strlen (label) - label_ptr);
+  copy_input_to_output (end - inptr);
   underlining_off ();
 
+  if (preprocess_nodes_p)
+    entry->end = text_buffer_off (&output_buf);
+  else
+    entry->end = entry->start + label_len;
+
 #ifdef QUOTE_NODENAMES
   if (inptr[0] == '\177')
     skip_input (1);
@@ -1210,18 +1314,15 @@
 
   /* Colon after label. */
   skip_input (1);
+  /* Don't mess up the margin of a menu description. */
+  if (entry->type == REFERENCE_MENU_ITEM)
+    write_extra_bytes_to_output (" ", 1);
 
-  if (preprocess_nodes_p)
-    entry->end = text_buffer_off (&output_buf);
-  else
-    entry->end = entry->start + label_len;
-
-  return entry;
+  return 1;
 }
 
 static void
-scan_reference_target (REFERENCE *entry, int found_menu_entry,
-                       int in_index, int in_parentheses)
+scan_reference_target (REFERENCE *entry, NODE *node, int in_parentheses)
 {
   /* If this reference entry continues with another ':' then the reference is
      within the same file, and the nodename is the same as the label. */
@@ -1229,11 +1330,8 @@
     {
       skip_input (1);
 
-      if (found_menu_entry)
-        {
-          /* Output two spaces to match the length of "::" */
-          write_extra_bytes_to_output ("  ", 2);
-        }
+      if (entry->type == REFERENCE_MENU_ITEM)
+        write_extra_bytes_to_output (" ", 1);
 
       entry->filename = 0;
       entry->nodename = xstrdup (entry->label);
@@ -1246,22 +1344,8 @@
       int length; /* Length of specification */
       int i;
 
-      if (found_menu_entry)
+      if (entry->type != REFERENCE_MENU_ITEM)
         {
-          length = info_parse_node (inptr, PARSE_NODE_DFLT);
-          if (inptr[length] == '.') /* Include a '.' terminating the entry. */
-            length++;
-
-          if (in_index)
-            /* For index nodes, output the destination as well,
-               which will be the name of the node the index entry
-               refers to. */
-            copy_input_to_output (length);
-          else
-            skip_input (length);
-        }
-      else
-        {
           char saved_char;
           char *nl_off;
           int space_at_start_of_line = 0;
@@ -1326,13 +1410,64 @@
               skip_input (strspn (inptr, " "));
             }
         }
+      else /* entry->type == REFERENCE_MENU_ITEM */
+        {
+          int line_len;
 
-      if (found_menu_entry && !in_index)
-        /* Output spaces the length of the node specifier to avoid
-           messing up left edge of second column of menu. */
-        for (i = 0; i < length; i++)
-          write_extra_bytes_to_output (" ", 1);
+          if (node->flags & N_IsDir)
+            {
+              /* Set line_len to length of line so far. */
 
+              char *linestart;
+              linestart = memrchr (input_start, '\n', inptr - input_start);
+              if (!linestart)
+                linestart = input_start;
+              else
+                linestart++; /* Point to first character after newline. */
+              line_len = inptr - linestart;
+            }
+
+          length = info_parse_node (inptr, PARSE_NODE_DFLT);
+          if (inptr[length] == '.') /* Include a '.' terminating the entry. */
+            length++;
+
+          if (node->flags & N_IsIndex)
+            /* For index nodes, output the destination as well,
+               which will be the name of the node the index entry
+               refers to. */
+            copy_input_to_output (length);
+          else 
+            {
+              skip_input (length);
+              if (!(node->flags & N_IsDir)) 
+                {
+                  /* Output spaces the length of the node specifier to avoid
+                     messing up left edge of second column of menu. */
+                  for (i = 0; i < length; i++)
+                    write_extra_bytes_to_output (" ", 1);
+                }
+            }
+
+          if (node->flags & N_IsDir) 
+            {
+              if (inptr[strspn (inptr, " ")] != '\n')
+                {
+                  for (i = 0; i < length; i++)
+                    write_extra_bytes_to_output (" ", 1);
+                }
+              else
+                {
+                  /* For a dir node, if there is no more text in this line,
+                     check if there is a menu entry description in the next
+                     line to the right of the end of the label, and display it
+                     in this line. */
+                  skip_input (strspn (inptr, " "));
+                  if (line_len <= strspn (inptr + 1, " "))
+                    skip_input (1 + line_len);
+                }
+            }
+        }
+
       if (info_parsed_filename)
         entry->filename = xstrdup (info_parsed_filename);
 
@@ -1366,74 +1501,32 @@
   return ptr[index];
 }
 
-/* Check if preceding word is a word like "see". BASE points before PTR in
-   a block of allocated memory. */
-static int
-avoid_see_see (char *ptr, char *base)
-{
-  /* TODO: Only do this for English-language files. */
-  static char *words_like_see[] = {
-    "see", "See", "In", "in", "of", "also"
-  };
-  int i;
-  int word_len = 0;
-
-  if (ptr == base)
-    return 0;
-
-  /* Skip past whitespace, and then go to beginning of preceding word. */
-  ptr--;
-  while (ptr > base && (*ptr == ' ' || *ptr == '\n' || *ptr == '\t'))
-    ptr--;
-
-  while (ptr > base && !(*ptr == ' ' || *ptr == '\n' || *ptr == '\t'))
-    {
-      ptr--;
-      word_len++;
-    }
-
-  ptr++;
-
-  /* Check if it is in our list. */
-  for (i = 0; i < sizeof (words_like_see) / sizeof (char *); i++)
-    {
-      if (!strncmp (words_like_see[i], ptr, word_len))
-        return 1;
-    }
-  return 0;
-}
-
 /* Scan (*NODE_PTR)->contents and record location and contents of
    cross-references and menu items.  Convert character encoding of
    node contents to that of the user if the two are known to be
    different.  If preprocess_nodes_p == 1, remove Info syntax in contents.
    If the node is from the file described by FB, then NODE_PTR is an offset
-   into FB->tags. If the node has not come from a file, FB is a null
+   into FB->tags.  If the node has not come from a file, FB is a null
    pointer. */
 void
 scan_node_contents (FILE_BUFFER *fb, NODE **node_ptr)
 {
   SEARCH_BINDING s;
   char *search_string;
+  long position;
+  int in_menu = 0;
 
-  int found_menu_entry, in_index = 0;
-  int in_menu = 0;
   NODE *node = *node_ptr;
 
   REFERENCE **refs = NULL;
   size_t refs_index = 0, refs_slots = 0;
 
-  long position;
-
   /* Check that contents haven't already been processed. This shouldn't
      happen. */
   if (node->flags & N_WasRewritten)
     return;
 
-  if (preprocess_nodes_p)
-    rewrite_p = 1;
-  else
-    rewrite_p = 0;
+  rewrite_p = preprocess_nodes_p;
 
   init_output_stream (fb);
 
@@ -1452,9 +1545,7 @@
   /* Initialize refs to point to array of one null pointer in case
      there are no results.  This way we know if refs has been initialized
      even if it is empty. */
-  /* FIXME: Null might not be zero. */
   refs = calloc (1, sizeof *refs);
-
   refs_slots = 1;
 
   /* This should be the only time we assign to inptr in this function -
@@ -1477,23 +1568,12 @@
   s.flags = S_FoldCase;
 
 search_again:
-  while (regexp_search (search_string,
-                 &s, &position, 0) == search_success)
+  while (regexp_search (search_string, &s, &position, 0) == search_success)
     {
-      long label_len;
-      char *label = 0;
       int in_parentheses = 0;
-
-      /* Save offset of "*" starting link. When preprocess_nodes is Off,
-         we position the cursor on the * when moving between references. */
-      int start_of_reference; 
-
       REFERENCE *entry;
-      char *match;
+      char *match = s.buffer + position;
 
-      /* Pointer to search result */
-      match = s.buffer + position;
-
       /* Write out up to match */
       copy_input_to_output (match - inptr); 
 
@@ -1510,75 +1590,24 @@
           continue;
         }
 
-      /* Check what we found based on first character of match */
-      if (match[0] == '\n')
-        {
-          found_menu_entry = 1;
-          start_of_reference = position + 1;
+      /* Create REFERENCE entity. */
+      entry = info_new_reference (0, 0);
 
-          copy_input_to_output (strlen ("\n* "));
-        }
-      else
-        {
-          int previous_word_is_like_see = 0;
+      if (safe_string_index (inptr, -1, s.buffer, s.end) == '(')
+        in_parentheses = 1;
 
-          found_menu_entry = 0;
-          start_of_reference = position;
+      scan_reference_marker (entry);
 
-          /* Cross-references can be generated by four different Texinfo
-             commands.  @inforef and @xref output "*Note " in Info format,
-             and "See" in HTML and print.  @ref and @pxref output "*note "
-             in Info format, and either nothing at all or "see" in HTML
-             and print.  Unfortunately, there is no easy way to distinguish
-             between these latter two cases.  We must make do with
-             displayed manuals occasionally containing "See see" and the
-             like. */
-          /* TODO: Internationalize these strings, but only if we know the
-             language of the document. */
-          if (match[1] == 'N')
-            write_extra_bytes_to_output ("See", 3);
-          else
-            {
-              previous_word_is_like_see = avoid_see_see (inptr, s.buffer);
-
-              if (!previous_word_is_like_see)
-                write_extra_bytes_to_output ("see", 3);
-              if (safe_string_index (inptr, -1, s.buffer, s.end) == '(')
-                in_parentheses = 1;
-            }
-
-          skip_input (strlen ("*Note"));
-          if (previous_word_is_like_see)
-            skip_input (skip_whitespace (inptr));
-        }
-
-      /* Copy any white space before label. */
-      copy_input_to_output (skip_whitespace_and_newlines (inptr));
-
-      /* Search forward to ":" to get label name. */
-      /* Cross-references may have a newline in the middle. */
-      if (!found_menu_entry)
-        label_len = read_quoted_string (inptr, ":", &label);
-      else
-        label_len = read_quoted_string (inptr, "\n:", &label);
-          
-      if (inptr[label_len] != ':')
+      /* Read and output reference label (up until colon). */
+      if (!scan_reference_label (entry))
         {
           /* This is not a menu entry or reference. */
-          skip_input (1);
           s.start = inptr - s.buffer;
           continue;
         }
 
-      /* Read and output reference label (up until colon). */
-      entry = scan_reference_label
-        (label, label_len,
-        (s.buffer + start_of_reference) - node->contents,
-        found_menu_entry);
-      free (label);
-
       /* Get target of reference and update entry. */
-      scan_reference_target (entry, found_menu_entry, in_index, 
in_parentheses);
+      scan_reference_target (entry, node, in_parentheses);
 
       add_pointer_to_array (entry, refs_index, refs, refs_slots, 50);
 
@@ -1591,6 +1620,7 @@
      ("address@hidden address@hidden").  Process these and try again. */
   {
     char *p, *p1;
+    int in_index = 0;
 
     p = strchr (inptr, '\0');
     p1 = p;
@@ -1604,6 +1634,9 @@
         /* FIXME: bounds checking in tag_expand? */
         if (tag_expand (&p1, expansion, &in_index))
           {
+            if (in_index)
+              node->flags |= N_IsIndex;
+
             if (!rewrite_p)
               {
                 rewrite_p = 1;
@@ -1622,9 +1655,6 @@
                                 text_buffer_off (expansion));
             /* Skip past body of tag. */
             skip_input (p1 - inptr);
-
-            if (in_index)
-              node->flags |= N_IsIndex;
           }
         else
           {

Modified: trunk/info/nodes.h
===================================================================
--- trunk/info/nodes.h  2014-06-08 18:45:25 UTC (rev 5646)
+++ trunk/info/nodes.h  2014-06-08 19:19:15 UTC (rev 5647)
@@ -78,6 +78,7 @@
 #define N_FromAnchor   0x80     /* Synthesized for an anchor reference. */
 #define N_WasRewritten 0x100    /* NODE->contents can be passed to free(). */ 
 #define N_IsIndex      0x200    /* An index node. */
+#define N_IsDir        0x400    /* A dir node. */
 
 /* String constants. */
 #define INFO_FILE_LABEL                 "File:"




reply via email to

[Prev in Thread] Current Thread [Next in Thread]