#!/usr/bin/env perl # $Id: txicmdcheck 5191 2013-02-23 00:11:18Z karl $ # Copyright 2008, 2011, 2012 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, # or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Original author: Karl Berry. # # Kludge of a script to check command lists in refcard vs. refman vs. # tp for consistency. exit (&main ()); sub main { my $no_common = $ARGV[0] eq "--no-common"; my @card_cmds = &read_refcard ("txirefcard.tex"); my @man_cmds = &read_refman ("../texinfo.txi"); my @tp_cmds = &read_tp ("../../util/txicmdlist"); # perhaps we should check against the manual's fnindex too. my (%card_cmds, %man_cmds, %tp_cmds); @card_cmds{@card_cmds} = (); @man_cmds{@man_cmds} = (); @tp_cmds{@tp_cmds} = (); my @found = (); for my $cc (@card_cmds) { if (exists $man_cmds{$cc} && exists $tp_cmds{$cc}) { push (@found, $cc); delete $man_cmds{$cc}; delete $card_cmds{$cc}; delete $tp_cmds{$cc}; } } printf (" common %d: @{[sort @found]}\n", @found + 0) unless $no_common; my @card_only = keys %card_cmds; printf "refcard only %s: @{[sort @card_only]}\n", @card_only + 0; my @man_only = keys %man_cmds; printf "refman only %s: @{[sort @man_only]}\n", @man_only + 0; my @tp_only = keys %tp_cmds; printf "tp only %s: @{[sort @tp_only]}\n", @tp_only + 0; return @card_only + @man_only + @tp_only; } # Return command names from the reference card. # sub read_refcard { my ($fname) = @_; my @ret = (); local *FILE; $FILE = $fname; open (FILE) || die "open($FILE) failed: $!"; while () { next unless /^\\txicmd/; chomp; my $xcmd = 0; s/\\txicmdarg{.*?}}?//; # first get rid of the arguments s/}{.*//; # then the descriptions s/^\\txicmdx{// && ($xcmd = 1); # used for the @def...x s/^\\txicmd{//; # finally the markup cmd itself s/\\ttbraced{}//g; # quote cmd list my (@cmds) = split (/,? +/, $_); # occasionally we combine cmds # we typeset these specially in TeX. if ("@cmds" eq "@#1footing") { @cmds = ('@oddfooting', '@evenfooting', '@everyfooting'); } elsif ("@cmds" eq "@#1heading") { @cmds = ('@oddheading', '@evenheading', '@everyheading'); } # add each command from this line to the return. for my $c (@cmds) { #warn "refcard $c\n"; #warn "refcard $c{x}\n" if $xcmd; next if $c eq "txicommandconditionals"; # variable not separate in manual if ($c eq '@\tildechar') { # TeX specialties, forcibly make them match $c = '@~'; } elsif ($c eq '@\var{whitespace}') { $c = '@var{whitespace}'; } $c = '@~' if $c eq '@\tildechar'; # TeX $c = '@\\' if $c eq '@\bschar'; # TeX $c = '@{' if $c eq '@\lbracechar'; # TeX $c = '@}' if $c eq '@\rbracechar'; # TeX push (@ret, $c); push (@ret, "${c}x") if $xcmd; } } push (@ret, '@end', '@uref', '@appendixsection'); # described in text push (@ret, '@,'); # our non-parsing above lost these push (@ret, qw(@atchar @lbracechar @rbracechar @backslashchar)); close (FILE) || warn "close($FILE) failed: $!"; return @ret; } # Return command names from the @-Command List # node in the reference manual. # sub read_refman { my ($fname) = @_; my @ret = (); local *FILE; $FILE = $fname; open (FILE) || die "open($FILE) failed: $!"; while () { last if /^\@appendix \@\@-Command List/; # ignore until right appendix } while () { last if /^\@end table/; # ignore again after the summary next unless s/^\@itemx? *\@//; # only want item[x]s in the table chomp; s/\@\{.+//; # remove braced arguments (but not @{) s/ .*//; # remove arguments following a space s/\@\@/@/g; # @@ -> @ next if $_ =~ /^\@(br|ctrl)$/; # @ignore-d in text push (@ret, $_); } push (@ret, '@{'); # our non-parsing above fails on this one close (FILE) || warn "close($FILE) failed: $!"; return @ret; } # Return command names implemented in the general parser. # The argument is the command to run to return the list. # sub read_tp { my ($prog) = @_; my @ret = (); local *FILE; $FILE = "$prog |"; open (FILE) || die "open($FILE) failed: $!"; while () { chomp; # excise @ commands from normal list. next if $_ eq '@ ' || $_ eq "\@\t" || $_ eq "" || $_ eq '@'; # obsolete and/or subsidiary commands we don't want to document as usual. next if $_ =~ /allow-recursion |columnfractions |cropmarks |ctrl |(even|every|odd)(foot|head)ingmarks |quote-arg |rmacro |shorttitle$ |\| /x; push (@ret, $_); } close (FILE) || warn "close($FILE) failed: $!"; push (@ret, '@var{whitespace}'); return @ret; }