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