texlive[65306] trunk: bibcop (18dec22)

commits+karl at tug.org commits+karl at tug.org
Sun Dec 18 21:53:55 CET 2022


Revision: 65306
          http://tug.org/svn/texlive?view=revision&revision=65306
Author:   karl
Date:     2022-12-18 21:53:55 +0100 (Sun, 18 Dec 2022)
Log Message:
-----------
bibcop (18dec22)

Modified Paths:
--------------
    trunk/Build/source/texk/texlive/linked_scripts/bibcop/bibcop.pl
    trunk/Master/texmf-dist/doc/latex/bibcop/README.md
    trunk/Master/texmf-dist/doc/latex/bibcop/bibcop.pdf
    trunk/Master/texmf-dist/doc/man/man1/bibcop.1
    trunk/Master/texmf-dist/doc/man/man1/bibcop.man1.pdf
    trunk/Master/texmf-dist/scripts/bibcop/bibcop.pl
    trunk/Master/texmf-dist/source/latex/bibcop/bibcop.dtx
    trunk/Master/texmf-dist/tex/latex/bibcop/bibcop.sty

Modified: trunk/Build/source/texk/texlive/linked_scripts/bibcop/bibcop.pl
===================================================================
--- trunk/Build/source/texk/texlive/linked_scripts/bibcop/bibcop.pl	2022-12-18 07:55:22 UTC (rev 65305)
+++ trunk/Build/source/texk/texlive/linked_scripts/bibcop/bibcop.pl	2022-12-18 20:53:55 UTC (rev 65306)
@@ -37,7 +37,7 @@
   'article' => ['doi', 'year', 'title', 'author', 'journal', 'volume', 'number', 'publisher?', 'pages?'],
   'inproceedings' => ['doi', 'booktitle', 'title', 'author', 'year', 'pages?', 'organization?', 'volume?'],
   'book' => ['doi', 'title', 'author', 'year', 'publisher'],
-  'misc' => ['title', 'author', 'year', 'eprint?', 'archiveprefix?', 'primaryclass?', 'publisher?', 'organization?', 'doi?'],
+  'misc' => ['title', 'author', 'year', 'eprint?', 'archiveprefix?', 'primaryclass?', 'publisher?', 'organization?', 'doi?', 'url?'],
 );
 
 # Check the presence of mandatory tags.
@@ -347,6 +347,23 @@
   }
 }
 
+# Check unescaped symbols.
+sub check_unescaped_symbols {
+  my (%entry) = @_;
+  my @symbols = ( '&' );
+  foreach my $tag (keys %entry) {
+    if ($tag =~ /^:.*/) {
+      next;
+    }
+    my $value = $entry{$tag};
+    foreach my $s (@symbols) {
+      if ($value =~ /^(.*[^\\{]|)\Q$s\E.*$/) {
+        return "The '$tag' contains a dangerous unescaped symbol (wrap it in curled brackets if you really need it)"
+      }
+    }
+  }
+}
+
 # Check one entry.
 sub process_entry {
   my (%entry) = @_;
@@ -387,10 +404,15 @@
     } elsif ($char eq "\n") {
       # ignore the EOL
       $lineno = $lineno + 1;
-    } elsif ($char eq '@' and $s eq 'top') {
-      %entry = ();
-      $s = 'start';
-      $acc = '';
+    } elsif ($s eq 'top') {
+      if ($char eq '@') {
+        %entry = ();
+        $s = 'start';
+        $acc = '';
+      } else {
+        warning("Each BibTeX entry must start with '\@', what is '$char'?");
+        last;
+      }
     } elsif ($char =~ /[a-z]/ and $s eq 'start') {
       # @article
     } elsif ($char eq '{' and $s eq 'start') {
@@ -408,14 +430,18 @@
       $entry{':name'} = $acc;
       $s = 'body';
     } elsif ($char eq '=' and $s eq 'tag') {
-      $tag = $acc;
+      my $t = lc($acc);
+      if (exists $entry{$t}) {
+        warning("The tag '$t' is seen more than once");
+      }
+      $tag = $t;
       $s = 'value';
       $acc = '';
     } elsif ($char eq ',' and $s eq 'value') {
-      if (not exists $entry{lc($tag)}) {
+      if (not exists $entry{$tag}) {
         my $tex = substr($acc, 1);
         $tex =~ s/\s//g;
-        $entry{lc($tag)} = $tex;
+        $entry{$tag} = $tex;
       }
       $s = 'body';
     } elsif ($char eq '}' and $s eq 'body') {
@@ -422,10 +448,10 @@
       push(@entries, { %entry });
       $s = 'top';
     } elsif ($char eq '}' and $s eq 'value') {
-      if (not exists $entry{lc($tag)}) {
+      if (not exists $entry{$tag}) {
         my $tex = substr($acc, 1);
         $tex =~ s/\s//g;
-        $entry{lc($tag)} = $tex;
+        $entry{$tag} = $tex;
       }
       push(@entries, { %entry });
       $s = 'top';
@@ -437,7 +463,7 @@
       $s = 'quote';
       $acc = '';
     } elsif ($char eq '"' and $s eq 'quote') {
-      $entry{lc($tag)} = substr($acc, 1);
+      $entry{$tag} = substr($acc, 1);
       $s = 'value';
     } elsif ($s eq 'quote') {
       # nothing
@@ -453,7 +479,7 @@
       } elsif ($char eq '}' and $escape ne 1) {
         $nest = $nest - 1;
         if ($nest eq 0) {
-          $entry{lc($tag)} = substr($acc, 1);
+          $entry{$tag} = substr($acc, 1);
           $s = 'value';
         }
       }
@@ -505,10 +531,11 @@
   my ($txt) = @_;
   if (exists $args{'--latex'}) {
     print "\\PackageError{bibcop}{$txt}\n";
+    exit 0;
   } else {
-    print $txt . "\n";
+    print STDERR $txt . "\n";
+    exit 1;
   }
-  exit 1;
 }
 
 # Print DEBUG message to the console.
@@ -554,13 +581,13 @@
     "      --latex     Report errors in LaTeX format using \\PackageWarningNoLine command\n\n" .
     "If any issues, report to GitHub: https://github.com/yegor256/bibcop");
 } elsif (exists $args{'--version'} or exists $args{'-v'}) {
-  info('0.0.4');
+  info('0.0.5');
 } else {
   my ($file) = grep { not($_ =~ /^--.*$/) } @ARGV;
   if (not $file) {
     error('File name must be specified');
   }
-  open(my $fh, '<', $file);
+  open(my $fh, '<', $file) or error('Cannot open file: ' . $file);
   my $bib; { local $/; $bib = <$fh>; }
   my @entries = entries($bib);
   if (exists $args{'--fix'}) {
@@ -568,7 +595,7 @@
       my %entry = %{ $entries[$i] };
       my $type = $entry{':type'};
       if (not exists $blessed{$type}) {
-        error("I don't know what to do with \@$type type of bibentry");
+        error("I don't know what to do with \@$type type of BibTeX entry");
       }
       my $tags = $blessed{$entry{':type'}};
       my %allowed = map { $_ => 1 } @$tags;
@@ -599,7 +626,7 @@
       my %entry = %{ $entries[$i] };
       debug("Checking $entry{':name'} (no.$i)...");
       foreach my $err (process_entry(%entry)) {
-        warning("$err, in the '$entry{':name'}' bib entry");
+        warning("$err, in the '$entry{':name'}' entry");
       }
     }
   }

Modified: trunk/Master/texmf-dist/doc/latex/bibcop/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/bibcop/README.md	2022-12-18 07:55:22 UTC (rev 65305)
+++ trunk/Master/texmf-dist/doc/latex/bibcop/README.md	2022-12-18 20:53:55 UTC (rev 65306)
@@ -6,8 +6,9 @@
 
 This LaTeX package checks the quality of your `.bib` file and
 emits warning message if any issues found. You may also like
-[biblint](https://github.com/Kingsford-Group/biblint) tool —
-it does almost the same but from the command line.
+[biblint](https://github.com/Kingsford-Group/biblint) and
+[biblatex-check](https://github.com/pezmc/biblatex-check) tools —
+they does almost the same but from the command line.
 
 First, [install it](https://en.wikibooks.org/wiki/LaTeX/Installing_Extra_Packages)
 from [CTAN](https://ctan.org/pkg/bibcop)

Modified: trunk/Master/texmf-dist/doc/latex/bibcop/bibcop.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/man/man1/bibcop.1
===================================================================
--- trunk/Master/texmf-dist/doc/man/man1/bibcop.1	2022-12-18 07:55:22 UTC (rev 65305)
+++ trunk/Master/texmf-dist/doc/man/man1/bibcop.1	2022-12-18 20:53:55 UTC (rev 65306)
@@ -1,4 +1,4 @@
-.TH bibcop 1 "2022-12-15"
+.TH bibcop 1 "2022-12-18"
 .SH NAME
 bibcop \- Style Checker and Fixer of BibTeX Files (.bib)
 .SH SYNOPSIS

Modified: trunk/Master/texmf-dist/doc/man/man1/bibcop.man1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/scripts/bibcop/bibcop.pl
===================================================================
--- trunk/Master/texmf-dist/scripts/bibcop/bibcop.pl	2022-12-18 07:55:22 UTC (rev 65305)
+++ trunk/Master/texmf-dist/scripts/bibcop/bibcop.pl	2022-12-18 20:53:55 UTC (rev 65306)
@@ -37,7 +37,7 @@
   'article' => ['doi', 'year', 'title', 'author', 'journal', 'volume', 'number', 'publisher?', 'pages?'],
   'inproceedings' => ['doi', 'booktitle', 'title', 'author', 'year', 'pages?', 'organization?', 'volume?'],
   'book' => ['doi', 'title', 'author', 'year', 'publisher'],
-  'misc' => ['title', 'author', 'year', 'eprint?', 'archiveprefix?', 'primaryclass?', 'publisher?', 'organization?', 'doi?'],
+  'misc' => ['title', 'author', 'year', 'eprint?', 'archiveprefix?', 'primaryclass?', 'publisher?', 'organization?', 'doi?', 'url?'],
 );
 
 # Check the presence of mandatory tags.
@@ -347,6 +347,23 @@
   }
 }
 
+# Check unescaped symbols.
+sub check_unescaped_symbols {
+  my (%entry) = @_;
+  my @symbols = ( '&' );
+  foreach my $tag (keys %entry) {
+    if ($tag =~ /^:.*/) {
+      next;
+    }
+    my $value = $entry{$tag};
+    foreach my $s (@symbols) {
+      if ($value =~ /^(.*[^\\{]|)\Q$s\E.*$/) {
+        return "The '$tag' contains a dangerous unescaped symbol (wrap it in curled brackets if you really need it)"
+      }
+    }
+  }
+}
+
 # Check one entry.
 sub process_entry {
   my (%entry) = @_;
@@ -387,10 +404,15 @@
     } elsif ($char eq "\n") {
       # ignore the EOL
       $lineno = $lineno + 1;
-    } elsif ($char eq '@' and $s eq 'top') {
-      %entry = ();
-      $s = 'start';
-      $acc = '';
+    } elsif ($s eq 'top') {
+      if ($char eq '@') {
+        %entry = ();
+        $s = 'start';
+        $acc = '';
+      } else {
+        warning("Each BibTeX entry must start with '\@', what is '$char'?");
+        last;
+      }
     } elsif ($char =~ /[a-z]/ and $s eq 'start') {
       # @article
     } elsif ($char eq '{' and $s eq 'start') {
@@ -408,14 +430,18 @@
       $entry{':name'} = $acc;
       $s = 'body';
     } elsif ($char eq '=' and $s eq 'tag') {
-      $tag = $acc;
+      my $t = lc($acc);
+      if (exists $entry{$t}) {
+        warning("The tag '$t' is seen more than once");
+      }
+      $tag = $t;
       $s = 'value';
       $acc = '';
     } elsif ($char eq ',' and $s eq 'value') {
-      if (not exists $entry{lc($tag)}) {
+      if (not exists $entry{$tag}) {
         my $tex = substr($acc, 1);
         $tex =~ s/\s//g;
-        $entry{lc($tag)} = $tex;
+        $entry{$tag} = $tex;
       }
       $s = 'body';
     } elsif ($char eq '}' and $s eq 'body') {
@@ -422,10 +448,10 @@
       push(@entries, { %entry });
       $s = 'top';
     } elsif ($char eq '}' and $s eq 'value') {
-      if (not exists $entry{lc($tag)}) {
+      if (not exists $entry{$tag}) {
         my $tex = substr($acc, 1);
         $tex =~ s/\s//g;
-        $entry{lc($tag)} = $tex;
+        $entry{$tag} = $tex;
       }
       push(@entries, { %entry });
       $s = 'top';
@@ -437,7 +463,7 @@
       $s = 'quote';
       $acc = '';
     } elsif ($char eq '"' and $s eq 'quote') {
-      $entry{lc($tag)} = substr($acc, 1);
+      $entry{$tag} = substr($acc, 1);
       $s = 'value';
     } elsif ($s eq 'quote') {
       # nothing
@@ -453,7 +479,7 @@
       } elsif ($char eq '}' and $escape ne 1) {
         $nest = $nest - 1;
         if ($nest eq 0) {
-          $entry{lc($tag)} = substr($acc, 1);
+          $entry{$tag} = substr($acc, 1);
           $s = 'value';
         }
       }
@@ -505,10 +531,11 @@
   my ($txt) = @_;
   if (exists $args{'--latex'}) {
     print "\\PackageError{bibcop}{$txt}\n";
+    exit 0;
   } else {
-    print $txt . "\n";
+    print STDERR $txt . "\n";
+    exit 1;
   }
-  exit 1;
 }
 
 # Print DEBUG message to the console.
@@ -554,13 +581,13 @@
     "      --latex     Report errors in LaTeX format using \\PackageWarningNoLine command\n\n" .
     "If any issues, report to GitHub: https://github.com/yegor256/bibcop");
 } elsif (exists $args{'--version'} or exists $args{'-v'}) {
-  info('0.0.4');
+  info('0.0.5');
 } else {
   my ($file) = grep { not($_ =~ /^--.*$/) } @ARGV;
   if (not $file) {
     error('File name must be specified');
   }
-  open(my $fh, '<', $file);
+  open(my $fh, '<', $file) or error('Cannot open file: ' . $file);
   my $bib; { local $/; $bib = <$fh>; }
   my @entries = entries($bib);
   if (exists $args{'--fix'}) {
@@ -568,7 +595,7 @@
       my %entry = %{ $entries[$i] };
       my $type = $entry{':type'};
       if (not exists $blessed{$type}) {
-        error("I don't know what to do with \@$type type of bibentry");
+        error("I don't know what to do with \@$type type of BibTeX entry");
       }
       my $tags = $blessed{$entry{':type'}};
       my %allowed = map { $_ => 1 } @$tags;
@@ -599,7 +626,7 @@
       my %entry = %{ $entries[$i] };
       debug("Checking $entry{':name'} (no.$i)...");
       foreach my $err (process_entry(%entry)) {
-        warning("$err, in the '$entry{':name'}' bib entry");
+        warning("$err, in the '$entry{':name'}' entry");
       }
     }
   }

Modified: trunk/Master/texmf-dist/source/latex/bibcop/bibcop.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/bibcop/bibcop.dtx	2022-12-18 07:55:22 UTC (rev 65305)
+++ trunk/Master/texmf-dist/source/latex/bibcop/bibcop.dtx	2022-12-18 20:53:55 UTC (rev 65306)
@@ -50,7 +50,7 @@
 %<package>\NeedsTeXFormat{LaTeX2e}
 %<package>\ProvidesPackage{bibcop}
 %<*package>
-[2022-12-15 0.0.4 Style Checker of Bibliography Files]
+[2022-12-18 0.0.5 Style Checker of Bibliography Files]
 %</package>
 %<*driver>
 \documentclass{ltxdoc}
@@ -108,6 +108,11 @@
 % Some warnings may be printed in the \TeX{} log.
 % Once the issues in the |main.bib| file are fixed, the warnings disappear.
 
+% Bibcop doesn't pay much attention the formatting of the |.bib| file. It doesn't emit
+% warnings if a comma is missed after the last tag in a \BibTeX{} entry or the tags
+% and their equation symbols are not aligned. Instead, Bibcop is focused on the content
+% of the tags and their possible inconsistencies.
+
 % If the |.sty| file is used directly (without installing it into the \TeX{} tree),
 % the |bibcop.pl| file must also be placed next to it --- it is the Perl script that does all the work
 % of checking your |.bib| files. The |.sty| is just a simple wrapper around it.
@@ -205,6 +210,16 @@
 %</verb>
 %\fi
 % When first names are shortened to a single letter, it has to have a tailing dot.
+% A specially pronounced author may be wrapped it in curled brackets, to make Bibcop ignore it:
+%\iffalse
+%<*verb>
+%\fi
+\begin{verbatim}
+author = {{Some author} and {I}}
+\end{verbatim}
+%\iffalse
+%</verb>
+%\fi
 
 % \DescribeMacro{shorts}
 % It is not allowed to shorten any words aside from the |author| tag, for example this is illegal:

Modified: trunk/Master/texmf-dist/tex/latex/bibcop/bibcop.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/bibcop/bibcop.sty	2022-12-18 07:55:22 UTC (rev 65305)
+++ trunk/Master/texmf-dist/tex/latex/bibcop/bibcop.sty	2022-12-18 20:53:55 UTC (rev 65306)
@@ -31,7 +31,7 @@
 
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesPackage{bibcop}
-[2022-12-15 0.0.4 Style Checker of Bibliography Files]
+[2022-12-18 0.0.5 Style Checker of Bibliography Files]
 
 
 
@@ -59,6 +59,7 @@
 
 
 
+
 \RequirePackage{iexec}
 
 \RequirePackage{pgfopts}



More information about the tex-live-commits mailing list.