Ilya Zakharevich on Tue, 21 Nov 2023 11:43:15 +0100


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

An enhancement to gphelp.pl: allow extra filtering


When fighting with inverse/reverse bug in the docs¹⁾, I needed to
massage what the option -k of gphelp (used in the
      ???topic
gp’s command) can do.  The patch (on top of the bug fix patch in
      https://pari.math.u-bordeaux.fr/cgi-bin/bugreport.cgi?bug=2499PARI/GP#35
) is attached and included below.

  ¹⁾ See https://pari.math.u-bordeaux.fr/cgi-bin/bugreport.cgi?bug=2505PARI/GP

Essentially, it (**first**) allows adding (via -f FILTER) option extra
filters=patterns to apply when looking for the relevant sections of
the docs.  **Second**, it allows an automatic creation of such extra filters
by splitting one search pattern into several (the splitting happens on
whitespace) if the option -k is replaced by -K.

In particular, if gp uses the version with -K in ????, then
  ???? "inverse function"
would find all chunks with “inverse” which contain “function” as
well.  (As opposed to looking for a substring "inverse function".)

Alternatively, one can just abandon the current semantic of
  ??? "inverse function"
and use the option -K all the time (instead of the current -k).

Ilya

   P.S.  This also fixes a very minor bug in handling malformed options -cb etc.

--- gphelp.pl-ok	2023-11-20 22:31:19.961606800 -0800
+++ gphelp.pl	2023-11-21 02:33:02.495880900 -0800
@@ -22,7 +22,9 @@ $datadir= "@";
 # Usage: gphelp keyword
 #
 # Command line options:
-#  -k: apropos (list of relevant GP functions)
+#  -k: apropos (list of relevant words to search)
+#  -K: same       (with auto-split to apropos-filters)
+#  -f apropos-filter: extra word to require to be present in the reported chunks
 #  -detex      (-d): don't use TeX + xdvi (implicit when DISPLAY is not set).
 #  -color_help (-ch) <number>: use color "number" (same scheme as in GP)
 #  -color_bold (-cb) <number>: display bold in color "number"
@@ -76,22 +78,29 @@ sub cleanexit {
 }
 
 sub help {
-  print "Usage: $0 [-k] [-detex] [-ch c1] [-cb c2] [-cu c3] keyword\n";
+  print "Usage: $0 [-k] [-K] [-detex] [-ch c1] [-cb c2] [-cu c3] [-f extra-keyword] keyword\n";
   print "where c1,c2,c3 denote background, bold and underline color\n";
   exit(1);
 }
 
+my(@extra);
+
 sub options {
   $utf8 = $raw = $detex = $fromgp = $apropos = $noskip = 0;
   $ch = $cb = $cu = '';
+  my ($split);
+
   while ($_ = $ARGV[0])
   {
-    last if (! /^-[a-z]/);
+    last if (! /^-[a-zK]/);
     shift(@ARGV);
+    die "Option $_ requires an argument" if /^-(f|c[hbu]|color_(help|bold|underline))$/ and @ARGV<1;
     if ($_ eq "-fromgp")
       { $fromgp = 1; }
-    elsif ($_ eq "-k")
-      { $apropos = $detex = 1; }
+    elsif ($_ eq "-k" or $_ eq "-K")
+      { $apropos = $detex = 1; $split = $_ eq "-K"; }
+    elsif ($_ eq "-f")
+      { push @extra, shift(@ARGV); }
     elsif ($_ eq "-balloon")
       { $balloon = 1; }
     elsif ($_ eq "-detex" || $_ eq "-d")
@@ -111,6 +120,18 @@ sub options {
     else
       { &help(); }
   }
+  die "Option -f requires option -k" if @extra and not $apropos;
+  if ($split) {
+    my(@S);
+    if (@ARGV) {		# process only the first argument (to preserve “ORing of arguments”)
+        my $k = shift(@ARGV);
+        $k =~ s/^ *_DOUBQUOTE(.*)_DOUBQUOTE/$1/;	# cf. unprotect_pat()
+        @S = split /\s+/, $k;
+        unshift @ARGV, shift @S;
+    }
+    push @extra, @S;
+  }
+
   $ch = "\e[m$ch";
   $cu .= $cu ? "\e[1m": "\e[4m";
   $cb .= "\e[1m";
@@ -253,13 +274,19 @@ sub is_op
   $_ = 'GP operators@2'; &choose_chap;
 }
 
+sub unprotect_pat {	# changes it in the parent.  In very old perl may have problems when called on $_ ???
+  s/_QUOTE/'/g,  s/_BACKQUOTE/`/g,  s/_DOUBQUOTE/"/g,  s/^ *"(.*)"([^"]*) *$/$1$2/ for @ARGV;
+}
+
+sub protect_special {
+  s/(\W)/\\$1/g,  ( /^se\\:/ or s/_/\\\\_/g ) for @ARGV;
+}
+
 sub treat {
   my($help);
   $_ = $_[0];
-  s/_QUOTE/'/g;
-  s/_BACKQUOTE/`/g;
-  s/_DOUBQUOTE/"/g;
-  s/^ *"(.*)"([^"]*) *$/$1$2/;
+  unprotect_pat($_, @extra);
+  
   if (s/\@$//)
   {
     $found = 0;
@@ -292,8 +319,7 @@ sub treat {
     if ($transl{$_}) { $_ = $transl{$_}; &choose_chap; }
   }
 
-  s/(\W)/\\$1/g;
-  s/_/\\\\_/g if (!/^se\\:/);
+  protect_special($_, @extra);
       ($pipe && open(DOC,"$pipe $docfile |"))
   || (!$pipe && open(DOC,"$docfile")) || die "Cannot open $docfile: $!";
   return &apropos($_) if ($apropos);
@@ -388,7 +414,7 @@ sub apropos_final_print {
 sub apropos_check {
   my($line, $current, $pattern) = @_;
   $line =~ s/\n/ /g;
-  return if ($line !~ /$pattern/i);
+  return if ($line !~ /$pattern/i or grep $line !~ /$_/i, @extra);
 
   local($_) = $current;
   s/\\b\{(.)\}/\\$1/;

--- gphelp.pl-ok	2023-11-20 22:31:19.961606800 -0800
+++ gphelp.pl	2023-11-21 02:33:02.495880900 -0800
@@ -22,7 +22,9 @@ $datadir= "@";
 # Usage: gphelp keyword
 #
 # Command line options:
-#  -k: apropos (list of relevant GP functions)
+#  -k: apropos (list of relevant words to search)
+#  -K: same       (with auto-split to apropos-filters)
+#  -f apropos-filter: extra word to require to be present in the reported chunks
 #  -detex      (-d): don't use TeX + xdvi (implicit when DISPLAY is not set).
 #  -color_help (-ch) <number>: use color "number" (same scheme as in GP)
 #  -color_bold (-cb) <number>: display bold in color "number"
@@ -76,22 +78,29 @@ sub cleanexit {
 }
 
 sub help {
-  print "Usage: $0 [-k] [-detex] [-ch c1] [-cb c2] [-cu c3] keyword\n";
+  print "Usage: $0 [-k] [-K] [-detex] [-ch c1] [-cb c2] [-cu c3] [-f extra-keyword] keyword\n";
   print "where c1,c2,c3 denote background, bold and underline color\n";
   exit(1);
 }
 
+my(@extra);
+
 sub options {
   $utf8 = $raw = $detex = $fromgp = $apropos = $noskip = 0;
   $ch = $cb = $cu = '';
+  my ($split);
+
   while ($_ = $ARGV[0])
   {
-    last if (! /^-[a-z]/);
+    last if (! /^-[a-zK]/);
     shift(@ARGV);
+    die "Option $_ requires an argument" if /^-(f|c[hbu]|color_(help|bold|underline))$/ and @ARGV<1;
     if ($_ eq "-fromgp")
       { $fromgp = 1; }
-    elsif ($_ eq "-k")
-      { $apropos = $detex = 1; }
+    elsif ($_ eq "-k" or $_ eq "-K")
+      { $apropos = $detex = 1; $split = $_ eq "-K"; }
+    elsif ($_ eq "-f")
+      { push @extra, shift(@ARGV); }
     elsif ($_ eq "-balloon")
       { $balloon = 1; }
     elsif ($_ eq "-detex" || $_ eq "-d")
@@ -111,6 +120,18 @@ sub options {
     else
       { &help(); }
   }
+  die "Option -f requires option -k" if @extra and not $apropos;
+  if ($split) {
+    my(@S);
+    if (@ARGV) {		# process only the first argument (to preserve �ORing of arguments�)
+        my $k = shift(@ARGV);
+        $k =~ s/^ *_DOUBQUOTE(.*)_DOUBQUOTE/$1/;	# cf. unprotect_pat()
+        @S = split /\s+/, $k;
+        unshift @ARGV, shift @S;
+    }
+    push @extra, @S;
+  }
+
   $ch = "\e[m$ch";
   $cu .= $cu ? "\e[1m": "\e[4m";
   $cb .= "\e[1m";
@@ -253,13 +274,19 @@ sub is_op
   $_ = 'GP operators@2'; &choose_chap;
 }
 
+sub unprotect_pat {	# changes it in the parent.  In very old perl may have problems when called on $_ ???
+  s/_QUOTE/'/g,  s/_BACKQUOTE/`/g,  s/_DOUBQUOTE/"/g,  s/^ *"(.*)"([^"]*) *$/$1$2/ for @ARGV;
+}
+
+sub protect_special {
+  s/(\W)/\\$1/g,  ( /^se\\:/ or s/_/\\\\_/g ) for @ARGV;
+}
+
 sub treat {
   my($help);
   $_ = $_[0];
-  s/_QUOTE/'/g;
-  s/_BACKQUOTE/`/g;
-  s/_DOUBQUOTE/"/g;
-  s/^ *"(.*)"([^"]*) *$/$1$2/;
+  unprotect_pat($_, @extra);
+  
   if (s/\@$//)
   {
     $found = 0;
@@ -292,8 +319,7 @@ sub treat {
     if ($transl{$_}) { $_ = $transl{$_}; &choose_chap; }
   }
 
-  s/(\W)/\\$1/g;
-  s/_/\\\\_/g if (!/^se\\:/);
+  protect_special($_, @extra);
       ($pipe && open(DOC,"$pipe $docfile |"))
   || (!$pipe && open(DOC,"$docfile")) || die "Cannot open $docfile: $!";
   return &apropos($_) if ($apropos);
@@ -388,7 +414,7 @@ sub apropos_final_print {
 sub apropos_check {
   my($line, $current, $pattern) = @_;
   $line =~ s/\n/ /g;
-  return if ($line !~ /$pattern/i);
+  return if ($line !~ /$pattern/i or grep $line !~ /$_/i, @extra);
 
   local($_) = $current;
   s/\\b\{(.)\}/\\$1/;