diff options
Diffstat (limited to 'macros/latex/contrib')
-rw-r--r-- | macros/latex/contrib/bibcop/README.md | 5 | ||||
-rw-r--r-- | macros/latex/contrib/bibcop/bibcop.1 | 2 | ||||
-rw-r--r-- | macros/latex/contrib/bibcop/bibcop.dtx | 17 | ||||
-rw-r--r-- | macros/latex/contrib/bibcop/bibcop.pdf | bin | 341825 -> 342237 bytes | |||
-rwxr-xr-x | macros/latex/contrib/bibcop/bibcop.pl | 63 |
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 Binary files differindex e6683a73bb..3acc1c3c70 100644 --- a/macros/latex/contrib/bibcop/bibcop.pdf +++ b/macros/latex/contrib/bibcop/bibcop.pdf 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"); } } } |