| 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/;