texinfo-commits
[Top][All Lists]
Advanced

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

[6056] parsetexi better support for commands in node names


From: Gavin D. Smith
Subject: [6056] parsetexi better support for commands in node names
Date: Wed, 21 Jan 2015 20:36:11 +0000

Revision: 6056
          http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=6056
Author:   gavin
Date:     2015-01-21 20:36:09 +0000 (Wed, 21 Jan 2015)
Log Message:
-----------
parsetexi better support for commands in node names

Modified Paths:
--------------
    trunk/parsetexi/ChangeLog
    trunk/parsetexi/Parsetexi/lib/Parsetexi.pm
    trunk/parsetexi/dump_perl.c
    trunk/parsetexi/end_line.c
    trunk/parsetexi/extra.c
    trunk/parsetexi/menus.c
    trunk/parsetexi/parser.h
    trunk/parsetexi/tree.c
    trunk/parsetexi/tree.h
    trunk/parsetexi/tree_types.h

Modified: trunk/parsetexi/ChangeLog
===================================================================
--- trunk/parsetexi/ChangeLog   2015-01-20 08:19:32 UTC (rev 6055)
+++ trunk/parsetexi/ChangeLog   2015-01-21 20:36:09 UTC (rev 6056)
@@ -1,3 +1,28 @@
+2015-01-21  Gavin Smith  <address@hidden>
+
+       * tree_types.h (enum extra_type): New values 'extra_node_spec',
+       'extra_node_spec_array'.
+       (NODE_SPEC_EXTRA): New type.
+       * extra.c (add_extra_node_spec, add_extra_node_spec_array): New
+       functions.
+       * dump_perl.c (dump_extra): Output these two new types of extra 
+       key.
+
+       * end_line.c (parse_node_manual): New function.
+
+       * menus.c (register_extra_menu_entry_information): Call 
+       parse_node_manual and call add_extra_node_spec with the result.
+       * end_line.c (end_line) <@node>: Create 'nodes_manuals' array 
+       and call add_extra_node_spec_array. 
+
+       * Parsetexi/lib/Parsetexi.pm (_find_menus_of_node): Don't set
+       any of the 'menu_entry_node' values.
+       (_complete_node_list): Don't set 'node_content' on any of the 
+       'nodes_manuals' entries.  Set 'normalized' on each node from
+       the first 'nodes_manuals' entry.
+
+       * tree.c (remove_from_contents): New function.
+
 2015-01-19  Gavin Smith  <address@hidden>
 
        * dump_perl.c (dump_extra) <extra_index_entry>: Don't output

Modified: trunk/parsetexi/Parsetexi/lib/Parsetexi.pm
===================================================================
--- trunk/parsetexi/Parsetexi/lib/Parsetexi.pm  2015-01-20 08:19:32 UTC (rev 
6055)
+++ trunk/parsetexi/Parsetexi/lib/Parsetexi.pm  2015-01-21 20:36:09 UTC (rev 
6056)
@@ -181,29 +181,29 @@
 }
 
 # Set the 'menu_entry' extra key on each menu entry.  This was the
-# return value of _parse_node_manual (line 2257, Parser.pm).
-sub _add_menu_entry_node_keys ($) {
-  my $menu = shift;
-  foreach my $entry (@{$menu->{'contents'}}) {
-    next if !$entry->{'type'} or $entry->{'type'} ne 'menu_entry';
-    foreach my $part (@{$entry->{'args'}}) {
-      if ($part->{'type'} eq 'menu_entry_node') {
-       #$entry->{'extra'}->{'menu_entry_node'}->{'manual_content'} = ...;
+## return value of _parse_node_manual (line 2257, Parser.pm).
+#sub _add_menu_entry_node_keys ($) {
+#  my $menu = shift;
+#  foreach my $entry (@{$menu->{'contents'}}) {
+#    next if !$entry->{'type'} or $entry->{'type'} ne 'menu_entry';
+#    foreach my $part (@{$entry->{'args'}}) {
+#      if ($part->{'type'} eq 'menu_entry_node') {
+#      #$entry->{'extra'}->{'menu_entry_node'}->{'manual_content'} = ...;
+#
+#      # In Texinfo::Parser::_parse_node_manual, a copy was taken of
+#      # the contents, and leading and trailing whitespace elements
+#      # removed with _trim_spaces_comment_from_content.
+#      $entry->{'extra'}->{'menu_entry_node'}->{'node_content'}
+#        = $part->{'contents'};
+#
+#      # TODO: Actually get normalized node name of target.
+#      $entry->{'extra'}->{'menu_entry_node'}->{'normalized'}
+#        = $part->{'contents'}[0]{'text'};
+#      }
+#    }
+#  }
+#}
 
-       # In Texinfo::Parser::_parse_node_manual, a copy was taken of
-       # the contents, and leading and trailing whitespace elements
-       # removed with _trim_spaces_comment_from_content.
-       $entry->{'extra'}->{'menu_entry_node'}->{'node_content'}
-         = $part->{'contents'};
-
-       # TODO: Actually get normalized node name of target.
-       $entry->{'extra'}->{'menu_entry_node'}->{'normalized'}
-         = $part->{'contents'}[0]{'text'};
-      }
-    }
-  }
-}
-
 # Look for a menu in the node, saving in the 'menus' array reference
 # of the node element
 # This array was built on line 4800 of Parser.pm.
@@ -214,7 +214,8 @@
           (@{$node->{'extra'}{'associated_section'}->{'contents'}}) {
     if ($child->{'cmdname'} and $child->{'cmdname'} eq 'menu') {
       push @{$node->{'menus'}}, $child;
-      _add_menu_entry_node_keys ($child);
+      # Disable - do this in the C code now.
+      #_add_menu_entry_node_keys ($child);
     }
   }
 }
@@ -228,28 +229,11 @@
 
   foreach my $child (@{$root->{'contents'}}) {
     if ($child->{'cmdname'} and $child->{'cmdname'} eq 'node') {
-      #printf "FOUND NODE\n";
       push $self->{'nodes'}, $child;
-      #print "CONTENTS are " . $child->{'contents'};
 
-      # TODO - actually normalize the name
       $child->{'extra'}->{'normalized'} = 
-       $child->{'args'}->[0]->{'contents'}->[1]->{'text'};
+       $child->{'extra'}{'nodes_manuals'}[0]{'normalized'};
 
-      #print "Normalized node name saved as " .
-      #$child->{'extra'}->{'normalized'} . "\n";
-
-      $child->{'extra'}->{'nodes_manuals'} = [];
-      foreach my $node_arg (@{$child->{'args'}}) {
-       push $child->{'extra'}->{'nodes_manuals'},
-         {'node_content' => $node_arg->{'contents'}};
-
-       # Set 'node_content' on the node element itself.
-       #if (!defined($child->{'extra'}->{'node_content'})) {
-       #  $child->{'extra'}->{'node_content'} =  $node_arg->{'contents'};
-       #}
-      }
-
       _find_menus_of_node ($child);
     }
   }

Modified: trunk/parsetexi/dump_perl.c
===================================================================
--- trunk/parsetexi/dump_perl.c 2015-01-20 08:19:32 UTC (rev 6055)
+++ trunk/parsetexi/dump_perl.c 2015-01-21 20:36:09 UTC (rev 6056)
@@ -161,6 +161,35 @@
   text_append (&fixup_dump, ";\n");
 }
 
+static void
+dump_node_spec (NODE_SPEC_EXTRA *value)
+{
+  printf ("{\n");
+  indent += 2;
+  if (value->manual_content)
+    {
+      dump_indent ();
+      printf ("'manual_content' => ");
+      dump_contents (value->manual_content);
+    }
+  if (value->node_content)
+    {
+      dump_indent ();
+      printf ("'node_content' => ");
+      dump_contents (value->node_content);
+    }
+  if (value->normalized)
+    {
+      dump_indent ();
+      printf ("'normalized' => '");
+      dump_string (value->normalized);
+      printf ("'\n");
+    }
+  indent -= 2;
+  dump_indent ();
+  printf ("},\n");
+}
+
 /* Dump a skeleton for the 'extra' key.  For each key, if the referenced 
    element has been dumped yet and we know its, append a line filling in the 
    value of the key to FIXUP_DUMP.  Otherwise, record the reference in the 
@@ -219,6 +248,27 @@
                 }
               printf ("],\n");
             }
+          else if (e->extra[i].type == extra_node_spec)
+            {
+              NODE_SPEC_EXTRA *value = (NODE_SPEC_EXTRA *) e->extra[i].value;
+
+              printf ("'%s' => ", e->extra[i].key);
+              dump_node_spec (value);
+            }
+          else if (e->extra[i].type == extra_node_spec_array)
+            {
+              NODE_SPEC_EXTRA **array = (NODE_SPEC_EXTRA **) e->extra[i].value;
+
+              printf ("'%s' => [\n", e->extra[i].key);
+              while (*array)
+                {
+                  dump_indent ();
+                  dump_node_spec (*array);
+                  array++;
+                }
+              dump_indent ();
+              printf ("],\n");
+            }
           else if (e->extra[i].value->parent_type == route_not_in_tree)
             {
               switch (e->extra[i].type)

Modified: trunk/parsetexi/end_line.c
===================================================================
--- trunk/parsetexi/end_line.c  2015-01-20 08:19:32 UTC (rev 6055)
+++ trunk/parsetexi/end_line.c  2015-01-21 20:36:09 UTC (rev 6056)
@@ -25,6 +25,8 @@
 #include "labels.h"
 #include "indices.h"
 
+// 5467, also in Common.pm 1334
+// TODO: Check the behaviour here is the same
 /* Return a new element whose contents are the same as those of ORIGINAL,
    but with some elements representing empty spaces removed.  Elements like 
    these are used to represent some of the "content" extra keys. */
@@ -54,6 +56,119 @@
   return trimmed;
 }
 
+// 2257
+/* NODE->contents is the Texinfo for the specification of a node.  This
+   function sets three fields on the returned object:
+
+     manual_content - Texinfo tree for a manual name extracted from the
+                      node specification.
+     node_content - Texinfo tree for the node name on its own
+     normalized - a string with the node name after HTML node name
+                  normalization is applied
+
+   Objects returned from this function are used as an 'extra' key in a
+   few places: the elements of a 'nodes_manuals' array (itself an extra key),
+   the 'menu_entry_node' key on a 'menu_entry' element (not to be confused
+   with an ET_menu_entry_node element, which occurs in the args of a 
+   'menu_entry' element), and in the 'node_argument' key of a cross-reference 
+   command (like @xref). */
+NODE_SPEC_EXTRA *
+parse_node_manual (ELEMENT *node)
+{
+  NODE_SPEC_EXTRA *result;
+  ELEMENT *trimmed;
+  ELEMENT *manual;
+
+  result = malloc (sizeof (NODE_SPEC_EXTRA));
+  result->manual_content = 0;
+  trimmed = trim_spaces_comment_from_content (node);
+
+  /* If the content starts with a '(', try to get a manual name. */
+  if (trimmed->contents.number > 0 && trimmed->contents.list[0]->text.end > 0
+      && trimmed->contents.list[0]->text.text[0] == '(')
+    {
+      /* The Perl code here accounts for matching parentheses in the manual 
+         name.  The Info reader also handles this, for whatever reason. */
+
+      ELEMENT *e;
+      char *closing_bracket;
+
+      manual = new_element (ET_NONE);
+
+      /* If the first contents element is "(" alone, discard it, otherwise
+         remove the leading "(". */
+      if (trimmed->contents.list[0]->text.end > 1)
+        {
+          /* Replace the first element with another element with the leading
+             "(" removed. */
+          ELEMENT *first;
+          first = malloc (sizeof (ELEMENT));
+          memcpy (first, trimmed->contents.list[0], sizeof (ELEMENT));
+          first->text.text = malloc (first->text.space);
+          memcpy (first->text.text,
+                  trimmed->contents.list[0]->text.text + 1,
+                  trimmed->contents.list[0]->text.end - 1);
+          first->text.end--;
+          trimmed->contents.list[0] = first;
+        }
+      else
+        {
+          (void) remove_from_contents (trimmed, 0);
+          /* Note the removed element still is present in the original
+             'node' argument. */
+        }
+
+      while (trimmed->contents.number > 0)
+        {
+          ELEMENT *e = remove_from_contents (trimmed, 0);
+
+          if (e->text.end == 0
+              || !(closing_bracket = strchr (e->text.text, ')')))
+            {
+              /* Put this element in the manual contents. */
+              add_to_element_contents (manual, e);
+            }
+          else /* ')' in text - possible end of filename component */
+            {
+              /* Split the element in two, putting the part before the "("
+                 in the manual name, leaving the part afterwards for the
+                 node name. */
+              ELEMENT *before, *after;
+
+              before = new_element (ET_NONE);
+              text_append_n (&before->text, e->text.text,
+                             closing_bracket - e->text.text);
+              add_to_element_contents (manual, before);
+
+              /* Skip ')' and any following whitespace.
+                 Note that we don't manage to skip any multibyte
+                 UTF-8 space characters here. */
+              closing_bracket++;
+              closing_bracket += strspn (closing_bracket, whitespace_chars);
+              if (*closing_bracket)
+                {
+                  after = new_element (ET_NONE);
+                  text_append_n (&after->text, closing_bracket,
+                                 e->text.text + e->text.end - closing_bracket);
+
+                  insert_into_contents (trimmed, after, 0);
+                }
+              break;
+            }
+        }
+
+      result->manual_content = manual;
+    }
+
+  /* If anything left, it is the node name. */
+  if (trimmed->contents.number > 0)
+    {
+      result->node_content = trimmed;
+      result->normalized = convert_to_normalized (trimmed);
+    }
+  return result;
+}
+
 /* 2610 */
 /* Actions to be taken when a whole line of input has been processed */
 ELEMENT *
@@ -365,17 +480,19 @@
           int i;
           ELEMENT *arg;
           ELEMENT *first_arg;
-          /* Construct 'nodes_manuals' array.  This would be an 'extra' 
-             reference to an array that doesn't exist anywhere else. */
 
-          /* This sets the 'node_content' and 'normalized' keys on each 
element 
-             in 'nodes_manuals'. */
-          //parse_node_manual ();
-          
+          NODE_SPEC_EXTRA **nodes_manuals;
+
+          /* Construct 'nodes_manuals' array.  This is an 'extra' reference to 
+             an array that doesn't exist anywhere else. */
+          nodes_manuals = malloc (sizeof (NODE_SPEC_EXTRA *) * 2);
+          nodes_manuals[1] = 0;
+
           first_arg = current->args.list[0];
-          arg = trim_spaces_comment_from_content (first_arg);
-          add_extra_key_contents (current, "node_content", arg);
+          nodes_manuals[0] = parse_node_manual (first_arg);
+          add_extra_node_spec_array (current, "nodes_manuals", nodes_manuals);
 
+
           /* Also set 'normalized' here.  The normalized labels are actually 
              the keys of "labels_information($parser)". */
 
@@ -384,9 +501,13 @@
             is not empty (_check_empty_node).  */
           //check_node_label ();
 
+          add_extra_key_contents (current, "node_content",
+                                  nodes_manuals[0]->node_content);
+
           /* This sets 'node_content' and 'normalized' on the node, among
-             other things (which were already set in parse_node_manual). */
-          register_label (current, arg);
+             other things (which were already set in parse_node_manual).
+             Are we normalizing the name twice? */
+          register_label (current, nodes_manuals[0]->node_content);
 
           current_node = current;
         }

Modified: trunk/parsetexi/extra.c
===================================================================
--- trunk/parsetexi/extra.c     2015-01-20 08:19:32 UTC (rev 6055)
+++ trunk/parsetexi/extra.c     2015-01-21 20:36:09 UTC (rev 6056)
@@ -74,6 +74,22 @@
   e->extra[e->extra_number - 1].type = extra_misc_args;
 }
 
+void
+add_extra_node_spec (ELEMENT *e, char *key, NODE_SPEC_EXTRA *value)
+{
+  add_extra_key (e, key, (ELEMENT *) value);
+  e->extra[e->extra_number - 1].type = extra_node_spec;
+}
+
+/* Used for 'node_manuals' array for the arguments given on a
+   @node line.  Argument is a null-terminated array of pointers. */
+void
+add_extra_node_spec_array (ELEMENT *e, char *key, NODE_SPEC_EXTRA **value)
+{
+  add_extra_key (e, key, (ELEMENT *) value);
+  e->extra[e->extra_number - 1].type = extra_node_spec_array;
+}
+
 KEY_PAIR *
 lookup_extra_key (ELEMENT *e, char *key)
 {

Modified: trunk/parsetexi/menus.c
===================================================================
--- trunk/parsetexi/menus.c     2015-01-20 08:19:32 UTC (rev 6055)
+++ trunk/parsetexi/menus.c     2015-01-21 20:36:09 UTC (rev 6056)
@@ -41,13 +41,12 @@
         }
       else if (arg->type == ET_menu_entry_node)
         {
+          NODE_SPEC_EXTRA *parsed_entry_node;
+
           isolate_last_space (arg, ET_space_at_end_menu_node);
 
-          // parsed_entry_node = parse_node_manual ();
-          // What kind of object is the "menu_entry_node" key?
-          // parse_node_manual returns another hash?
-          // add_extra_key_??? (current, "menu_entry_node",
-          //                    parsed_entry_node);
+          parsed_entry_node = parse_node_manual (arg);
+          add_extra_node_spec (current, "menu_entry_node", parsed_entry_node);
         }
       else if (arg->type == ET_menu_entry_description)
         {

Modified: trunk/parsetexi/parser.h
===================================================================
--- trunk/parsetexi/parser.h    2015-01-20 08:19:32 UTC (rev 6055)
+++ trunk/parsetexi/parser.h    2015-01-21 20:36:09 UTC (rev 6056)
@@ -16,6 +16,7 @@
                          ELEMENT **closed_element, enum command_id);
 
 /* In end_line.c */
+NODE_SPEC_EXTRA *parse_node_manual (ELEMENT *node);
 ELEMENT *end_line (ELEMENT *current);
 
 /* In debug.c */
@@ -67,6 +68,8 @@
 void add_extra_key_text (ELEMENT *e, char *key, ELEMENT *value);
 void add_extra_key_index_entry (ELEMENT *e, char *key, INDEX_ENTRY_REF *value);
 void add_extra_key_misc_args (ELEMENT *e, char *key, ELEMENT *value);
+void add_extra_node_spec (ELEMENT *e, char *key, NODE_SPEC_EXTRA *value);
+void add_extra_node_spec_array (ELEMENT *, char *, NODE_SPEC_EXTRA **value);
 KEY_PAIR *lookup_extra_key (ELEMENT *e, char *key);
 
 /* In menus.c */

Modified: trunk/parsetexi/tree.c
===================================================================
--- trunk/parsetexi/tree.c      2015-01-20 08:19:32 UTC (rev 6055)
+++ trunk/parsetexi/tree.c      2015-01-21 20:36:09 UTC (rev 6056)
@@ -105,7 +105,26 @@
   list->number++;
 }
 
+ELEMENT *
+remove_from_contents (ELEMENT *parent, int where)
+{
+  ELEMENT_LIST *list = &parent->contents;
+  ELEMENT *removed;
 
+  if (where < 0)
+    where = list->number + where;
+
+  if (where < 0 || where > list->number)
+    abort ();
+
+  removed = list->list[where];
+  memmove (&list->list[where], &list->list[where + 1],
+           (list->number - (where+1)) * sizeof (ELEMENT));
+  list->number--;
+  return removed;
+}
+
+
 ELEMENT *
 pop_element_from_args (ELEMENT *parent)
 {

Modified: trunk/parsetexi/tree.h
===================================================================
--- trunk/parsetexi/tree.h      2015-01-20 08:19:32 UTC (rev 6055)
+++ trunk/parsetexi/tree.h      2015-01-21 20:36:09 UTC (rev 6056)
@@ -18,6 +18,7 @@
 void add_to_element_contents (ELEMENT *parent, ELEMENT *e);
 void add_to_element_args (ELEMENT *parent, ELEMENT *e);
 void insert_into_contents (ELEMENT *parent, ELEMENT *e, int where);
+ELEMENT *remove_from_contents (ELEMENT *parent, int where);
 ELEMENT *last_args_child (ELEMENT *current);
 ELEMENT *last_contents_child (ELEMENT *current);
 ELEMENT *pop_element_from_args (ELEMENT *parent);

Modified: trunk/parsetexi/tree_types.h
===================================================================
--- trunk/parsetexi/tree_types.h        2015-01-20 08:19:32 UTC (rev 6055)
+++ trunk/parsetexi/tree_types.h        2015-01-21 20:36:09 UTC (rev 6056)
@@ -20,7 +20,7 @@
 
 typedef struct TEXT {
     char *text;
-    size_t space;
+    size_t space; /* Allocated bytes in 'text', including terminating null. */
     size_t end;
 } TEXT;
 
@@ -29,7 +29,9 @@
     extra_element_contents,
     extra_element_text,
     extra_index_entry,
-    extra_misc_args
+    extra_misc_args,
+    extra_node_spec,
+    extra_node_spec_array
 };
 
 typedef struct KEY_PAIR {
@@ -126,4 +128,10 @@
     int entry;
 } INDEX_ENTRY_REF;
 
+/* See parse_node_manual function. */
+typedef struct {
+    ELEMENT *manual_content;
+    ELEMENT *node_content;
+    char *normalized;
+} NODE_SPEC_EXTRA;
 




reply via email to

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