% \iffalse meta-comment
% SPDX-FileCopyrightText: Copyright (c) 2022-2026 Yegor Bugayenko
% SPDX-License-Identifier: MIT
% \fi

% \CheckSum{0}
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}

% \GetFileInfo{bibcop.dtx}
% \DoNotIndex{\endgroup,\begingroup,\let,\else,\s,\n,\r,\\,\1,\fi}

% \iffalse
%<*driver>
\ProvidesFile{bibcop.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{bibcop}
%<*package>
[2026-08-29 0.0.35 Style Checker of Bibliography Files]
%</package>
%<*driver>
\documentclass{ltxdoc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{fail-fast}
\usepackage{silence}
\WarningFilter{latex}{Empty bibliography}
\usepackage[maxnames=1,minnames=1,maxbibnames=1,natbib=true,citestyle=authoryear,bibstyle=authoryear,doi=false,url=false,isbn=false,isbn=false]{biblatex}
\addbibresource{bibcop.bib}
\usepackage{microtype}
\AddToHook{env/verbatim/begin}{\microtypesetup{protrusion=false}}
\PassOptionsToPackage{hyperindex=false}{hyperref}
\usepackage{href-ul}
\usepackage{bookmark}
\renewcommand{\RerunFileCheck}[3]{\AddToHook{enddocument/info}{#2}}
\usepackage{xcolor}
\usepackage{graphicx}
\PageIndex
\EnableCrossrefs
\CodelineIndex
\RecordChanges
\begin{document}
  \DocInput{bibcop.dtx}
  \PrintChanges
  \PrintIndex
\end{document}
%</driver>
% \fi

% \title{\includegraphics[height=1in]{bibcop-logo.pdf} \\ |bibcop|: \LaTeX{} Package \\ for Style Checking of |.bib| Files\thanks{The sources are in GitHub at \href{https://github.com/yegor256/bibcop}{yegor256/bibcop}}}
% \author{Yegor Bugayenko \\ \texttt{yegor256@gmail.com}}
% \date{\filedate, \fileversion}
%
% \maketitle
%
% \textbf{\color{red}NB!}
% The \TeX{} processor must be invoked with the |--shell-escape| option,
% and \href{https://www.perl.org}{Perl} must be installed on the system.
% This package does not operate on Windows.

% \section{Introduction}
%
% This package scans a |.bib| file for stylistic errors and emits
% warning messages whenever issues are detected (the package must be included before
% all other bibliography-related packages):
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\documentclass{article}
\usepackage{bibcop}
\begin{document}
\bibliographystyle{plain}
\bibliography{main}
\end{document}
\end{verbatim}
%\iffalse
%</verb>
%\fi
% Warnings, if any, appear in the \TeX{} log.
% Once the issues in the |main.bib| file have been resolved, the warnings cease.

% Bibcop is largely indifferent to the formatting of the |.bib| file. It does not emit
% warnings when a comma is omitted after the final tag of a \BibTeX{} entry, nor when the tags
% and their equals symbols are misaligned. Bibcop's attention is reserved for the content
% of the tags and the inconsistencies that may arise within them.

% Whenever the |.sty| file is used directly (without installation into the \TeX{} tree),
% the |bibcop.pl| file must accompany it---it is the Perl script that performs the actual
% checking of |.bib| files. The |.sty| serves merely as a thin wrapper around it.

% The |\usepackage{bibcop}| declaration must immediately follow |\usepackage{biblatex}|
% (whenever Bib\LaTeX{} is in use); otherwise no warnings will be issued by |bibcop|.

% \section{Package Options}

% The behaviour of the package may be configured by means of several package options:

% \DescribeMacro{verbose}
% The |verbose| package option prints all debugging messages to the \TeX{} log:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage[verbose]{bibcop}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{script}
% The package relies upon the |bibcop.pl| file, a Perl script that performs all of the work. This file is expected to reside either in the current directory or within the |texmf-dist/scripts/bibcop/| directory. By means of the |script| option, the location of the script may be specified explicitly (the option is not recommended unless a particular need arises):
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage[script=my-perl-script.pl]{bibcop}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{no*}
% Specific rules may be suppressed by means of one of the |no*| package options:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
\usepackage[nodoi,nowraps]{bibcop}
\end{verbatim}
%\iffalse
%</verb>
%\fi
% The following options are available:
% \begin{itemize}\setlength\itemsep{0pt}
% \item |nocaps| allows arbitrary capitalization in titles;
% \item |nowraps| allows titles to have no double curly braces;
% \item |nodoi| allows the absence of the |doi| tag in all entries;
% \item |noinproc| allows the |booktitle| tag in |@inproceedings| entries to not start with ``Proceedings of the'';
% \item |noorg| allows mentioning of ACM/IEEE in the |booktitle| tag;
% \item |notags| allows any tags and allows missing important tags.
% \end{itemize}

% \section{The Rules}

% The following constitutes a substantially complete enumeration of the rules enforced on a |.bib| file:

% \DescribeMacro{types}
% Only the |@article|, |@book|, |@inproceedings|, |@phdthesis|, |@incollection|, and |@misc| types of \BibTeX{} entries are admitted.
% All other types, such as |@manual|, |@inbook|, and \href{https://www.bibtex.com/e/entry-types/}{many others}, are forbidden.
% The aforementioned six suffice for every conceivable purpose.

% \DescribeMacro{tags}
% Each type of \BibTeX{} entry has a tightly constrained list of admissible tags. Tags
% absent from the list are forbidden.

% \DescribeMacro{doi}
% Every \BibTeX{} entry must contain a |doi| tag, namely the unique
% \href{https://www.doi.org}{Digital Object Identifier}
% of the cited material. To forestall ambiguity, it is sound practice to record the DOI in every case.
% The \href{https://ctan.org/pkg/doi}{doi} package is likewise recommended,
% as it converts all ``|doi|'' fields into hyperlinks.

% \DescribeMacro{caps}
% Within the |title|, |booktitle|, and |journal| tags, every major word must be capitalised,
% as \href{https://apastyle.apa.org/style-grammar-guidelines/capitalization/title-case}{recommended} by the APA:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
title = {A Preliminary Architecture for a Basic Data-Flow Processor}
\end{verbatim}
%\iffalse
%</verb>
%\fi
% Here, the leading ``|A|'' is capitalised because it opens the title.
% The word ``|for|'' and the article ``|a|'' are minor words and therefore appear in lower case.
% Both components of the composite word ``|Data-Flow|'' are capitalised.
% This rule may occasionally be relaxed where a custom capitalisation is preserved
% as imposed by the author of the paper. In such cases, the words bearing custom capitalisation
% must be enclosed in curly brackets, for example:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
title = {Structured Programming {with} Go {To} Statements}
\end{verbatim}
%\iffalse
%</verb>
%\fi
% An entire value may be protected in the same manner, by one extra pair
% of curly brackets around it (the pair that these three tags demand anyway does not count):
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
title = {{{lowercase title of a paper}}}
\end{verbatim}
%\iffalse
%</verb>
%\fi
% This rule may be disabled by means of the |nocaps| package option.

% \DescribeMacro{author}
% The |author| field must contain a list of authors separated by ``|and|''. Each author
% must comprise two components separated by a comma: the first denotes the surname of the author,
% the second a list of given names separated by spaces, for example:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
author = {Knuth, Donald E. and Duane, Bibby}
\end{verbatim}
%\iffalse
%</verb>
%\fi
% Where the list of authors is exceedingly long, ``|and others|'' may be employed:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
author = {Knuth, Donald E. and others}
\end{verbatim}
%\iffalse
%</verb>
%\fi
% Whenever given names are abbreviated to a single letter, a trailing full stop is required.
% An author name with bespoke formatting may be enclosed in curly brackets, whereupon Bibcop disregards it:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
author = {{Some author} and {I}}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{shorts}
% Abbreviation of words is permitted only within the |author| tag; the following, for instance, is impermissible:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
journal = {J. Log. Compute}
\end{verbatim}
%\iffalse
%</verb>
%\fi
% It must instead be replaced by the following:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
journal = {Journal of Logic and Computation}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{brackets}
% The |title|, |booktitle|, and |journal| fields must be enclosed in double brackets, for example:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
title = {{A Survey of Symbolic Execution Techniques}}
\end{verbatim}
%\iffalse
%</verb>
%\fi
% This is necessary in order to prevent the down-casing of capitalised words, which certain
% bibliography styles otherwise perform.

% \DescribeMacro{year}
% The year may not appear within the title of a conference or a journal; the following, for instance,
% is impermissible:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
booktitle = {{1994 IEEE International Conference on Computer Languages}},
\end{verbatim}
%\iffalse
%</verb>
%\fi
% The year is to be recorded solely within the |year| tag, and nowhere else.
% Within the |year| tag, only numerals are admissible:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
year = {1994},
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{month}
% The |month| field may contain only a numeral:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
month = {12},
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{volume}
% The |volume| field may contain only a numeral:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
volume = {32},
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{number}
% The |number| field may contain only a numeral:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
number = {132},
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{pages}
% The |pages| field may contain either a single numeral or two numerals separated by a double dash:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
pages = {145--163},
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{proceedings}
% The |booktitle| within an |@inproceedings| entry must invariably begin with ``|Proceedings| |of| |the|'',
% as illustrated below:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
booktitle = {{Proceedings of the International
  Conference on Computer Languages}},
\end{verbatim}
%\iffalse
%</verb>
%\fi
% This rule may be disabled by means of the |noinproc| package option.

% \DescribeMacro{arXiv}
% Whenever |archivePrefix| is present, |eprint| and |primaryClass| must likewise be present and must conform to the formatting principles of \href{https://arxiv.org/help/arxiv_identifier}{arXiv identifiers}:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
@misc{bugayenko2021,
  archivePrefix = {arXiv},
  eprint = {2111.13384},
  primaryClass = {cs.PL},
}
\end{verbatim}
%\iffalse
%</verb>
%\fi

% \DescribeMacro{typography}
% All tags within each \BibTeX{} entry are inspected for compliance with elementary typographic conventions:
% \begin{itemize}
%   \item No space is admissible before a comma, semicolon, colon, full stop, question mark, or exclamation mark;
%   \item Text may not terminate in a full stop, comma, semicolon, colon, or dash;
%   \item A triple dash must be flanked on both sides by spaces.
% \end{itemize}

% \DescribeMacro{Unicode}
% Non-ASCII characters are prohibited throughout the |.bib| file,
% unless curled brackets protect them:
%\iffalse
%<*verb>
%\fi
\begin{verbatim}
@book{proust1913,
  author = {{Proust, Marcel}},
  title = {{{À la Recherche du Temps Perdu}}},
  publisher = {{Éditions Grasset}},
}
\end{verbatim}
%\iffalse
%</verb>
%\fi
% The brackets that delimit the value of a tag protect nothing,
% which is why one extra pair is required around the text itself
% (and yet one more around a |title|, since it demands its own pair anyway).
% This is how a bibliography in Cyrillic, Greek, Arabic, or Chinese may be kept,
% even though transliteration into Latin remains the safer choice.

% \StopEventually{}

% \section{Implementation}
% \changes{0.0.1}{2022/12/11}{First draft.}
% \changes{0.0.2}{2022/12/12}{Documentation extended, more rules added.}
% \changes{0.0.4}{2022/12/14}{Extra checks for the typography, together with more extensive Perl testing.}
% \changes{0.0.4}{2022/12/14}{The \texttt{--verbose} option introduced, to enable debugging information only on demand.}
% \changes{0.0.4}{2022/12/15}{Package options introduced, the \texttt{verbose} option enables detailed logging inside the \TeX{} log.}
% \changes{0.0.6}{2023/01/08}{The \texttt{script} package option introduced, to enable explicit configuration of the location of the \texttt{bibcop.pl} Perl script.}

% First, we include a few packages.
% We need \href{https://ctan.org/pkg/iexec}{iexec} for executing Perl scripts:
%    \begin{macrocode}
\RequirePackage{iexec}
%    \end{macrocode}

% Then, we process package options:
% \changes{0.0.12}{2023/05/20}{A few package options introduced to give users an ability to disable certain style rules: \texttt{nocaps}, \texttt{nowraps}, \texttt{notags}, \texttt{noorg}, \texttt{noinproc}, and \texttt{nodoi}. Also, a command line script gets a new set of options, which start from \texttt{--no:}, for example \texttt{--no:caps}.}
%    \begin{macrocode}
\RequirePackage{pgfopts}
\pgfkeys{
  /bibcop/.cd,
  notags/.store in=\bibcop@notags,
  noorg/.store in=\bibcop@noorg,
  noinproc/.store in=\bibcop@noinproc,
  nocaps/.store in=\bibcop@nocaps,
  nodoi/.store in=\bibcop@nodoi,
  nowraps/.store in=\bibcop@nowraps,
  verbose/.store in=\bibcop@verbose,
  script/.store in = \bibcop@script,
}
\ProcessPgfPackageOptions{/bibcop}
%    \end{macrocode}

% \begin{macro}{bibcop.pl}
% Then, we find the Perl script:
%    \begin{macrocode}
\makeatletter
\ifdefined\bibcop@script\else
  \IfFileExists{bibcop.pl}
    {\gdef\bibcop@script{perl ./bibcop.pl}}
    {\gdef\bibcop@script{bibcop}}
\fi
\message{bibcop: The Perl script is at '\bibcop@script'^^J}%
\makeatother
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\bibcop@exec}
% \changes{0.0.16}{2024/01/11}{When \texttt{-shell-escape} is not set, there is no validation performed.}
% Then, we define a supplementary command to execute the Perl script:
%    \begin{macrocode}
\RequirePackage{shellesc}
\makeatletter
\newcommand\bibcop@exec[1]{
  \iexec[maybe]{\bibcop@script\space
    \ifdefined\bibcop@verbose--verbose\fi\space
    \ifdefined\bibcop@notags--no:tags\fi\space
    \ifdefined\bibcop@noorg--no:org\fi\space
    \ifdefined\bibcop@noinproc--no:inproc\fi\space
    \ifdefined\bibcop@nodoi--no:doi\fi\space
    \ifdefined\bibcop@nocaps--no:caps\fi\space
    \ifdefined\bibcop@nowraps--no:wraps\fi\space
    --latex '#1'}%
  \message{bibcop: style checking finished for #1^^J}%
}
\makeatother

% \begin{macro}{\bibliography}
% Then, we re-define the |\bibliography| command:
%    \begin{macrocode}
\makeatletter
\ifdefined\bibliography
  \let\bibcop@oldbibliography\bibliography
  \renewcommand\bibliography[1]{%
    \bibcop@exec{#1.bib}%
    \bibcop@oldbibliography{#1}%
  }
\fi
\makeatother
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\addbibresource}
% Then, we re-define the |\addbibresource| command:
%    \begin{macrocode}
\makeatletter
\ifdefined\addbibresource
  \let\bibcop@oldaddbibresource\addbibresource
  \renewcommand\addbibresource[1]{%
    \bibcop@exec{#1}%
    \bibcop@oldaddbibresource{#1}%
  }
\fi
\makeatother
%    \end{macrocode}
% \end{macro}

%    \begin{macrocode}
\endinput
%    \end{macrocode}

% \Finale

% \clearpage
% \printbibliography
% \clearpage

% \PrintChanges
% \clearpage
% \PrintIndex
