summaryrefslogtreecommitdiff
path: root/macros
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-12-19 03:03:02 +0000
committerNorbert Preining <norbert@preining.info>2022-12-19 03:03:02 +0000
commit8e3f2f40eaf97ca4b3f8023f4c58bdcd98f63e63 (patch)
treef79a719497b17b1d06c687e98364dc0e8695342a /macros
parent81dce26929e98696f622283b42f25c643dcfe565 (diff)
CTAN sync 202212190303
Diffstat (limited to 'macros')
-rw-r--r--macros/latex/contrib/bibcop/README.md5
-rw-r--r--macros/latex/contrib/bibcop/bibcop.12
-rw-r--r--macros/latex/contrib/bibcop/bibcop.dtx17
-rw-r--r--macros/latex/contrib/bibcop/bibcop.pdfbin341825 -> 342237 bytes
-rwxr-xr-xmacros/latex/contrib/bibcop/bibcop.pl63
5 files changed, 65 insertions, 22 deletions
diff --git a/macros/latex/contrib/bibcop/README.md b/macros/latex/contrib/bibcop/README.md
index 8a58d415f8..f3cf12395b 100644
--- a/macros/latex/contrib/bibcop/README.md
+++ b/macros/latex/contrib/bibcop/README.md
@@ -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)
diff --git a/macros/latex/contrib/bibcop/bibcop.1 b/macros/latex/contrib/bibcop/bibcop.1
index 5cc7f77c15..ad76da0bf0 100644
--- a/macros/latex/contrib/bibcop/bibcop.1
+++ b/macros/latex/contrib/bibcop/bibcop.1
@@ -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
diff --git a/macros/latex/contrib/bibcop/bibcop.dtx b/macros/latex/contrib/bibcop/bibcop.dtx
index de48e128ef..ce2e070d3e 100644
--- a/macros/latex/contrib/bibcop/bibcop.dtx
+++ b/macros/latex/contrib/bibcop/bibcop.dtx
@@ -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 @@ author = {Knuth, Donald E. and others}
%</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:
diff --git a/macros/latex/contrib/bibcop/bibcop.pdf b/macros/latex/contrib/bibcop/bibcop.pdf
index e6683a73bb..3acc1c3c70 100644
--- a/macros/latex/contrib/bibcop/bibcop.pdf
+++ b/macros/latex/contrib/bibcop/bibcop.pdf
Binary files differ
diff --git a/macros/latex/contrib/bibcop/bibcop.pl b/macros/latex/contrib/bibcop/bibcop.pl
index ef5ee1f457..9027dd483f 100755
--- a/macros/latex/contrib/bibcop/bibcop.pl
+++ b/macros/latex/contrib/bibcop/bibcop.pl
@@ -37,7 +37,7 @@ my %blessed = (
'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 @@ sub check_pages {
}
}
+# 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 @@ sub entries {
} 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,24 +430,28 @@ sub entries {
$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') {
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 @@ sub entries {
$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 @@ sub entries {
} 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 @@ sub error {
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 @@ if (@ARGV+0 eq 0 or exists $args{'--help'} or exists $args{'-?'}) {
" --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 @@ if (@ARGV+0 eq 0 or exists $args{'--help'} or exists $args{'-?'}) {
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 @@ if (@ARGV+0 eq 0 or exists $args{'--help'} or exists $args{'-?'}) {
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");
}
}
}