% % \iffalse meta-comment % % Copyright 2024 Brian Dunn % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % \fi % % \iffalse %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{verifycommand} % [2024/01/11 v1.00 Verify definitions have not changed.] % %<*driver> \documentclass{ltxdoc} \newcommand*{\mypackagename}{verifycommand} \newcommand{\quicksummary}{Verifies definitions have not changed.} % \usepackage{lmodern} \usepackage{erewhon} \usepackage{roboto} % \usepackage{sourcesanspro} \usepackage{inconsolata} % \usepackage{libertine} \usepackage[T1]{fontenc} \usepackage[utf8]{inputenc} \usepackage{textcomp} % provides \degree, \textquotesingle, \textmu \newcommand*{\TakeFourierOrnament}[1]{{% \fontencoding{U}\fontfamily{futs}\selectfont\char#1}} \newcommand*{\textwarning}{\TakeFourierOrnament{66}} % copy/paste special unicode symbols: \input{glyphtounicode} \pdfglyphtounicode{prime}{2032}% hex \pdfglyphtounicode{diameter}{2300}% diameter \pdfglyphtounicode{warningsign}{26A0}% warning sign \pdfgentounicode=1 \usepackage{newunicodechar} \newunicodechar{ff}{ff} \newunicodechar{fi}{fi} \newunicodechar{fl}{fl} \newunicodechar{ffi}{ffi} \newunicodechar{ffl}{ffl} % \newunicodechar{°}{\degree} \newunicodechar{ρ}{\ensuremath{\rho}} \newunicodechar{⨯}{\texttimes} \newunicodechar{⁄}{\textfractionsolidus} % \newunicodechar{®}{\textregistered} % \newunicodechar{©}{\textcopyright} \newunicodechar{—}{---} \newunicodechar{–}{--} % \newunicodechar{”}{''} % \newunicodechar{“}{``} % \newunicodechar{§}{\S} % \newunicodechar{¶}{\P} % \newunicodechar{†}{\dag} \newunicodechar{‡}{\ddag} \newunicodechar{⚠}{\textwarning} \usepackage{etoolbox} \usepackage{metalogox} \usepackage{microtype} \usepackage[svgnames]{xcolor} \definecolor{myurlcolor}{rgb}{0,0,.7} \definecolor{mylinkcolor}{rgb}{.7,0,0} \definecolor{codecolor}{rgb}{0,.4,.2} \definecolor{overviewcolor}{rgb}{0,.2,.4} %\usepackage{graphicx} %\graphicspath{{images/}} %\usepackage{enumitem} \usepackage{needspace} %\usepackage{array} %\usepackage{booktabs} %\usepackage{threeparttable} %\usepackage{fancybox}% must be loaded before fancyvrb %\usepackage{fancyvrb} %\usepackage{caption} %\usepackage{newfloat} %\captionsetup{labelfont={small,bf},textfont={small,bf}} %\captionsetup*[figure]{ % style=default, justification=centering, % margin=0pt, parskip=0pt, skip=2ex, % labelfont={small,bf},textfont={small,bf} %} %\captionsetup*[table]{ % style=default, justification=centering, % margin=0pt, parskip=0pt, skip=1ex, % labelfont={small,bf},textfont={small,bf}, % position=top %} %\captionsetup*[subfigure]{ % style=default, justification=centering, % margin=0pt, parskip=0pt, skip=2ex, % labelfont={small},textfont={small} %} %\captionsetup*[subtable]{ % style=default, justification=centering, % margin=0pt, parskip=0pt, skip=1ex, % labelfont={small},textfont={small}, % position=top %} %\captionsetup*[wrapfigure]{ % style=default, justification=centering, % margin=0pt, parskip=0pt, skip=2ex, % labelfont={small,bf},textfont={small,bf} %} %\captionsetup*[wraptable]{ % style=default, justification=centering, % margin=0pt, parskip=0pt, skip=1ex, % labelfont={small,bf},textfont={small,bf} %} %\usepackage{blindtext} %\usepackage{tikz} %\usetikzlibrary{positioning,fit,backgrounds,calc,shapes.geometric,shadows} %\usepackage[framemethod=tikz]{mdframed} %\mdfdefinestyle{boxroundshadow}{linewidth=1pt,innerleftmargin=0in,innerrightmargin=0in,% %innertopmargin=0in,innerbottommargin=0in,% %align=center,roundcorner=3pt,shadow=true,shadowcolor=black!50,shadowsize=4pt,% %leftmargin=0pt,rightmargin=0pt,% %frametitlebackgroundcolor=black!15,% %skipabove=0ex,skipbelow=0ex,% %frametitlerulewidth=1pt,frametitleaboveskip=5pt,% %} %\newmdenv[style=boxroundshadow,align=center]{mdtightframe} %\newmdenv[style=boxroundshadow,align=center,% % innertopmargin=3pt,innerbottommargin=3pt,% % innerleftmargin=3pt,innerrightmargin=3pt]{mdlooseframe} \usepackage[normalem]{ulem} %\usepackage{tocdata}[2019/03/21]% v2.02 or later \usepackage{tocloft} \setlength{\cftsubsecnumwidth}{3em} \setlength{\cftsubsubsecindent}{2.8em} \setlength{\cftsubsubsecnumwidth}{4em} \setlength{\cftbeforesubsecskip}{1ex} % \usepackage{titletoc} \usepackage{titleps} \newpagestyle{pageheadfoot}{ \headrule \sethead{\pkg{\mypackagename}}{}{\thepage} % \renewcommand{\makefootrule}{\rule[2.5ex]{\linewidth}{.4pt}} \setfoot{}{}{} } \pagestyle{pageheadfoot} % Indexing, logos, \Describexxxx, etc: \usepackage{dtxdescribe}[2023/01/03] \usepackage{splitidx} \newindex[Index of Objects]{idx} %\newindex[General Index]{gen} % \newindex[Troubleshooting Index]{trb} %\newindex[Index of Indexes]{meta} \makeindex \newcommand*{\gindex}[1]{\sindex[gen]{#1}\ignorespaces} % \trouble[watchout phrase]{index entry} \newcommand*{\trouble}[2][]{% \ifblank{#1}{}{% \watchout[#1]% }% % \sindex[trb]{#2}% \gindex{#2}% \ignorespaces% } \newcommand*{\MDfive}{\begingroup\textup{\acro{MD5}}\endgroup} %\setlength{\floatsep}{5ex plus 1ex minus 1ex} %\setlength{\dblfloatsep}{5ex plus 1ex minus 1ex} \usepackage{\mypackagename} \AtBeginDocument{ \hypersetup{% pdfinfo={% Title={The LaTeX \mypackagename\ package},% Author={Brian Dunn},% Subject={Verify LaTeX definitions are unchanged.},% Keywords={LaTeX}% colorlinks,% linkcolor=mylinkcolor,% urlcolor=myurlcolor,% pageanchor=true, }} \pdfstringdefDisableCommands{ \def\quad{ } \def\\{ } \def\pkg#1{#1} \def\cs#1{\textbackslash#1} \def\env#1{#1} \def\,{ } \def\prog#1{#1} \def\LuaLaTeX{LuaLaTeX} \def\XeLaTeX{XeLaTeX} \def\TeX{TeX} \def\LaTeX{LaTeX} \def\Dash{ --- } \def\dash{ -- } \def\element#1{#1} \def\attribute#1{#1} \def\MDfive{MD5} } }% AtBeginDocument \AddToHook{begindocument/before}{% Before .aux file is loaded. \usepackage{cleveref}% If needed. } \setlength{\marginparsep}{1em} \setlength{\marginparpush}{.7ex} \setlength{\IndexMin}{40ex} \setcounter{IndexColumns}{2} \DisableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{\mypackagename.dtx} \end{document} % % % % \fi % % \iffalse %<*package> % \fi % % \changes{v1.00}{2024/01/11}{\ 2024/01/11 Initial version.} % \GetFileInfo{\mypackagename.sty} % % \DoNotIndex{\newcommand,\renewcommand,\addtocounter,\begin,\end,\begingroup,\endgroup} % \DoNotIndex{\global,\ifbool,\ifthenelse,\isequivalentto,\let} % \DoNotIndex{\booltrue,\boolfalse} % \expandafter\DoNotIndex\expandafter{\detokenize{\(,\),\,,\\,\#,\$,\%,\^,\_,\~,\ ,\&,\{,\}}} % % % \thispagestyle{empty} % \begin{center} % \vfill % ^^A \includegraphics[width=.3\linewidth]{\mypackagename_logo.pdf} % \vfill % {\Huge The \LaTeX\\ % \pkg{\mypackagename}\\ % Package} % \bigskip % % \fileversion{} --- \filedate % % \bigskip % % {\small\textcopyright{} 2024} Brian Dunn\\ \small \url{https://github.com/bdtc/verifycommand} % % \vspace{.5in} % % {\Large \textup{\quicksummary}} % % % \vfill % % % ^^A % \title{The \pkg{verifycommand} package\thanks{This document % ^^A % corresponds to \pkg{verifycommand}~\fileversion, % ^^A % dated \filedate.}} % ^^A % \author{{\small\textcopyright{} 2016} Brian Dunn\\ \small \texttt{bd@BDTechConcepts.com}} % ^^A % \published{} % ^^A % \subtitle{\textup{Subtitle}} % ^^A % % ^^A % \maketitle % % \vfill % % % \begin{abstract} % \noindent % For package authors who patch code from other packages. % % To improve reliability, % the \pkg{verifycommand} package provides a way to verify that % macros or environments have not changed. % This allows a package author to check before patching a definition. % If a definition is not as expected, a warning is issued. % At the end of the compile, a list of all changed definitions is displayed. % % \vfill % % \footnotesize % \begin{description} % \item[License:] \ % % This work may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in % http://www.latex-project.org/lppl.txt % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % \end{description} % % \end{abstract} % % \vspace*{\fill} % \vspace*{\fill} % \vspace*{\fill} % \end{center} % \clearpage % % \tableofcontents % ^^A \listofdtxexamplefloats % ^^A \listoffigures % ^^A \listoftables % % % \thispagestyle{pageheadfoot} % % \clearpage % %^^A \part{verifycommand.sty} % % \section{Introduction} % % Patching a macro or environment from another package risks % the possibility that the other author has made an update % and changed something unexpected, % breaking your own package when it tries to apply the patch. % % The traditional way to check a definition you wish to modify % is to copy the expected definition into your package under a new name, % then compare to see if the current definition % is the same as it was when your package was first created. % For a few definitions this may work well, but as the number % of patches goes up things get more and more unwieldy. % % The \pkg{verifycommand} package uses \MDfive\ checksums instead of % copying entire definitions. % If something has changed, a warning is issued telling the % name of the defintion, and optionally telling the name of your % own package and the package being modified. % This improves code reliability, and allows package authors % to get an early warning when an author of some other package % has made an unexpected change. % % In many cases, the patch or replacement may still function correctly % even when the original has changed in some way. % For this reason, only a warning is issued, not an error. % % % \section{How it works} % % \cs{VerifyCommand} and \cs{VerifyEnvironment} are used to test % whether a definition has changed. % Each definition is given an \MDfive\ checksum, which is compared to % the expected checksum given as arguments of \cs{VerifyCommand} % and \cs{VerifyEnvironment}. % If a checksum does not match, a warning is issued, % flagging the definition for attention. % % The \MDfive\ checksum is of the text of the code part of the underlying definition, % as it would be displayed by the \cs{meaning} command. % For environments, the end code is checked separately. % The check detects changes in the replacement text of the definition, % and may or may not detect changes in the number or type of parameters, % \cs{long}, or type of robustness, depending on the type of definition. % Some definitions may have the same checksum if they have the same % replacement code but different argument types, for example % a \cs{NewDocumentCommand} with two mandatory arguments vs another with one optional % and one mandatory, if they both have the same replacement code. % % When something does not match, the current checksum is printed to % the terminal, and the author may copy/paste that into the parameter of % \cs{VerifyCommand} or \cs{VerifyEnvironment} to update the % expected values. % % % \clearpage % % \section{How to use \pkg{verifycommand}} % % \subsection{The user interface} % % \needspace{2\baselineskip} % \DescribeMacro{\VerifyCommand} \oarg{yourpackagename} \oarg{theirpackagename} % \marg{\cs{macroname}} \marg{\MDfive\ checksum} % % \needspace{3\baselineskip} % \DescribeMacro{\VerifyEnvironment} \oarg{yourpackagename} \oarg{theirpackagename} % \marg{\env{envname}} \\ % \fqquad \marg{begin \MDfive\ checksum} \marg{end \MDfive\ checksum} % % Use one of these macros just before patching a macro or environment, % as seen below. % % Note that there is one checksum for \cs{VerifyCommand}, but there % are two checksums for \cs{VerifyEnvironment}: once for the begin section % and one for the end section. % % If there is only one optional argument, it is used as your package name. % % % \subsection{Placing the macros} % % When first using \pkg{verifycommand}, use empty checksums, placing % \cs{VerifyCommand} or \cs{VerifyEnvironment} before each place % where something gets patched. % This is probably not required where things are entirely replaced, % or prepended or appended. % % \begin{sourceverb} % \VerifyCommand{\LaTeX}{} % % % \VerifyCommand[mypackage]{\textcolor}{} % % % \VerifyCommand[mypackage][graphics]{\rotatebox}{} % % % \VerifyEnvironment{tabbing}{}{} % % \end{sourceverb} % % % \subsection{Finding the checksums of the current definitions} % % In the above examples, testing \cs{LaTeX} would print a warning showing % the correct \MDfive\ checksum. % Testing \cs{textcolor} would do the same, but as a \cs{PackageWarning} from \pkg{mypackage}. % Testing \cs{rotatebox} would also mention the package being tested, \pkg{graphics}. % Testing \env{tabbing} issues a separate warning for the begin and end sections. % % % \begin{sourceverb} % Warning: Something may fail. A definition has changed: % \LaTeX % FAAAC6146C9A80F46A1F029B67923851 % on input line 464. % Package mypackage Warning: Something may fail. A definition has changed: % (mypackage) \textcolor % (mypackage) E1E2B5A908AA1BCDDF6BEA038596A381 % (mypackage) on input line 465. % Package mypackage Warning: Something may fail. A definition has changed: % (mypackage) graphics: \rotatebox % (mypackage) 2472999B02C97AC847128AF24C55D150 % (mypackage) on input line 466. % % Warning: Something may fail. A definition has changed: % tabbing % 1AD73B4527AD30969CF3219F2FB1306B % on input line 518. % % Warning: Something may fail. A definition has changed: % (end)tabbing % E8326AC43EE0A6E922A20F2A798BD177 % on input line 518. % \end{sourceverb} % % And at the end of the compile, a summary is given: % % \begin{sourceverb} % -------------------------------- % WARNING: Something may fail. % Definition changed: \LaTeX % Definition changed: FAAAC6146C9A80F46A1F029B67923851 % Definition changed: \textcolor % Definition changed: E1E2B5A908AA1BCDDF6BEA038596A381 % Definition changed: graphics: \rotatebox % Definition changed: 2472999B02C97AC847128AF24C55D150 % Definition changed: tabbing % Definition changed: 1AD73B4527AD30969CF3219F2FB1306B % Definition changed: (end)tabbing % Definition changed: E8326AC43EE0A6E922A20F2A798BD177 % -------------------------------- % \end{sourceverb} % % % \subsection{Assigning the checksums} % Copy the checksums from the warnings messages into the source. % When this is done, there are no more \pkg{verifycommand} warnings % unless one of these defintions changes: % % \begin{sourceverb} % \VerifyCommand{\LaTeX}{FAAAC6146C9A80F46A1F029B67923851} % % % \VerifyCommand[mypackage]{\textcolor} % {E1E2B5A908AA1BCDDF6BEA038596A381} % % % \VerifyCommand[mypackage][graphics]{\rotatebox} % {2472999B02C97AC847128AF24C55D150} % % % \VerifyEnvironment{tabbing} % {1AD73B4527AD30969CF3219F2FB1306B}% beginning code % {E8326AC43EE0A6E922A20F2A798BD177}% endind code % % \end{sourceverb} % % % \subsection{When a definition is changed} % % When something being verified changes at a later time, the resulting % warning will let the user know that the patches may not work % as expected. % Because the test is done before the patch, % this warning will be issued before the patch is even attempted. % % When testing many packages in bulk, a utility such as \cmds{grep} % can report the changed definitions. % Search the log file for ``Definition changed:''. % % % \subsection{Disabling the package} % % \pkg{verifycommand} relies on knowing the internal structure of % various kinds of definitions. It is possible that these may change some day, % causing endless warnings for that kind of definition. % Should that happen, it will be necessary to disable the \pkg{verifycommand} % package until it can be updated. % Use the \optn{disable} option to do so. % % \begin{sourceverb} % \usepackage[disable]{verifycommand} % \end{sourceverb} % % % % ^^A To trigger the checksums to be copied into the exmaples: % \VerifyCommand{\LaTeX}{} % \VerifyCommand[mypackage]{\textcolor}{} % \VerifyCommand[mypackage][graphics]{\rotatebox}{} % \VerifyEnvironment{tabbing}{}{} % % % \clearpage % % ^^A \StopEventually{\PrintChanges\PrintIndex} % % \makeatletter % % \StopEventually{ % ^^A \part{Change History and Index} % ^^A \part{Change History} % % % \pagestyle{plain} % % ^^A Each index has a prologue which creates its own \part, label, % ^^A and meta index entry. % \GlossaryPrologue{ % \part{Change History} % ^^A \section{Chg Hist} % \label{sec:changehistory} % ^^A \sindex[meta]{Change History} % \markboth{{Change History}}{{Change History}} % % ^^A For the most recent changes, see page \pageref{sec:changesend}. % % } % \PrintChanges % \phantomsection % \label{sec:changesend} % % % ^^A The instructions for the Index of Objects: % \IndexPrologue{ % \clearpage % \expandafter\part\expandafter{\indexname} % \label{sec:index\indexshortcut} % ^^A \sindex[meta]{\indexname} % \markboth{Index of Objects}{Index of Objects}% % % This is an index of macros, environments, booleans, counters, lengths, % packages, classes, options, keys, files, and various other programming objects. % Each is listed by itself, and also by category. % In some cases, they are further subdivided by [class]. % % Numbers written in italic refer to the page % where the corresponding entry is described; % numbers underlined refer to the % \ifcodeline@index % code line of the % \fi % definition. % ^^A ; numbers in roman refer to the % ^^A \ifcodeline@index % ^^A code lines % ^^A \else % ^^A pages % ^^A \fi % ^^A where the entry is used. % } % % \printindex[idx][Index of Objects] % % % ^^A The instructions for the General Index: % \IndexPrologue{ % \clearpage % \expandafter\part\expandafter{\indexname} % \label{sec:index\indexshortcut} % ^^A \sindex[meta]{\indexname} % % ^^A This is an index of instructions and concepts. % ^^A Look here when wondering how to do something, and % ^^A check the Troubleshooting Index when something goes wrong. % This is a general index, including how-to and troubleshooting. % } % % \printindex[gen][General Index] % % % ^^A% The instructions for the Troubleshooting Index: % ^^A% \IndexPrologue{ % ^^A% \clearpage % ^^A% \expandafter\part\expandafter{\indexname} % ^^A% \label{sec:index\indexshortcut} % ^^A% \sindex[meta]{\indexname} % ^^A% % ^^A% This index is a sorted reference of problems and solutions. % ^^A% In order to make it easier to locate a solution, % ^^A% the same issue may be addressed by more than one entry. % ^^A% % ^^A% Entries with higher page numbers are often duplicates of entries with % ^^A% lower page numbers, as the same warning may occur within the user manual % ^^A% and again within the source code for a given package. % ^^A% } % ^^A% % ^^A% \printindex[trb][Troubleshooting Index] % % % ^^A The meta index does not get a meta index entry pointing to itself: % \IndexPrologue{ % \clearpage % \expandafter\part\expandafter{\indexname} % \label{sec:index\indexshortcut} % } % % ^^A \printindex[meta][Index of Indexes] % % \typeout{--------------------------------} % \typeout{The following warning that} % \typeout{something may fail is an} % \typeout{example of the output of this} % \typeout{package, and is not evidence of} % \typeout{a problem with the verifycommand} % \typeout{manual or documentation.} % \typeout{--------------------------------} % % } % % \makeatother % % % % % \section{Code} % ^^A *source % % \subsection{Package requirements} % \begin{macrocode} \RequirePackage{etoolbox} \RequirePackage{iftex} % \end{macrocode} % % % \subsection{Package options} % % Package option to disable all functions. % % \DescribeBoolean{VERCMD@enable} Is the package enabled? % \begin{macrocode} \newbool{VERCMD@enable} \booltrue{VERCMD@enable} % \end{macrocode} % % \DescribeOption{disable} Turn off all functions. % \begin{macrocode} \DeclareOption{disable}{% \boolfalse{VERCMD@enable}% \typeout{----}% \typeout{Package verifycommand: Turned off by option 'disable'.}% \typeout{----}% } \ProcessOptions\relax % \end{macrocode} % % % \subsection{Support macros} % % \begin{macro}{\VERCMD@backslash} The literal |\| character. % % This is used later because some internal definitions use double |\\| as % part of their name. % \begin{macrocode} \catcode`\&=0 &catcode`&\=12 &def&VERCMD@backslash{\} &catcode`&\=0 \catcode`\&=4 % \end{macrocode} % \end{macro} % % % % % \subsection{\MDfive\ hashing} % % The \MDfive\ hash is used for \env{lateximage} filenames for \SVG\ math. % % \begin{macrocode} \newcommand{\VERCMD@mdfivesum}[1]{% \PackageError{verifycommand} {No MD5 macro was found} {% Verifycommand must find the macros \protect\pdfmdfivesum\space or \protect\mdfivesum.% } } % \end{macrocode} % % The default for \pdfLaTeX, \dviLaTeX, up\LaTeX, etc: % \begin{macrocode} \ifdef{\pdfmdfivesum} {\let\VERCMD@mdfivesum\pdfmdfivesum} {} % \end{macrocode} % % For \LuaLaTeX: % \begin{macrocode} \ifLuaTeX \RequirePackage{pdftexcmds} \let\VERCMD@mdfivesum\pdf@mdfivesum \fi % \end{macrocode} % % For \XeLaTeX: % \begin{macrocode} \ifXeTeX \@ifundefined{pdffivesum}{} {\let\VERCMD@mdfivesum\pdfmdfivesum} \@ifundefined{mdfivesum}{} {\let\VERCMD@mdfivesum\mdfivesum} \fi % \end{macrocode} % \begin{macro}{\VERCMD@mdfive} \marg{\cs{macroname}} \qquad % Compute \MDfive\ checksum, store in \cs{VERCMD@temp}. % \begin{macrocode} \def\VERCMD@mdfive#1{% \edef\VERCMD@temp{\VERCMD@mdfivesum{\meaning#1}}% } % \end{macrocode} % \end{macro} % % % \subsection{Issuing warnings} % % ^^A % \begin{macrocode} % ^^A \gdef\VERCMD@ProgError#1#2{% % ^^A \GenericError{% % ^^A (\jobname)\@spaces\@spaces\@spaces\@spaces % ^^A }{% % ^^A \jobname\ Error: #1% % ^^A }{% % ^^A Something has changed and the result may fail.% % ^^A }{#2}% % ^^A } % ^^A % \end{macrocode} % % % \begin{macro}{\VERCMD@whatchanged} Accumulates a list of changed definitions. % \begin{macrocode} \newcommand*{\VERCMD@whatchanged}{} % \end{macrocode} % \end{macro} % \begin{macro}{\VERCMD@addchanged} \marg{\MDfive sum} \marg{text} \qquad Add to the list of changed definitions. % \begin{macrocode} \newcommand*{\VERCMD@addchanged}[2]{% \ifdefempty{\VERCMD@whatchanged}% {}% {\apptocmd{\VERCMD@whatchanged}{^^J}{}{}}% \apptocmd{\VERCMD@whatchanged}{Definition changed: #2^^J}{}{}% \apptocmd{\VERCMD@whatchanged}{Definition changed: \space\space\space#1}{}{}% } % \end{macrocode} % \end{macro} % When the compile is finished, print the accumulated list of changed definitions. % \begin{macrocode} \AfterEndDocument{ \ifdefempty{\VERCMD@whatchanged}{}{% \typeout{--------------------------------}% \typeout{WARNING: Something may fail.}% \typeout{\VERCMD@whatchanged}% \typeout{--------------------------------}% } } % \end{macrocode} % \begin{macro}{\VERCMD@ProgWarning} \marg{text} \qquad Warning without a package name. % \begin{macrocode} \def\VERCMD@ProgWarning#1{% \GenericWarning{% % (\jobname)\@spaces\@spaces% \@spaces\@spaces }{% Warning: #1% }% } % \end{macrocode} % \end{macro} % \begin{macro}{\VERCMD@Warning} \marg{yourpackage} \marg{theirpackage} \marg{defn name} % % If no package names, print a general warning. % If package names are given, print a \cs{PackageWarning}. % \begin{macrocode} \newcommand*{\VERCMD@Warning}[3]{% \ifblank{#1}% {% \VERCMD@ProgWarning{% Something may fail. A definition has changed:\MessageBreak \ifblank{#2}{}{#2: }\string#3\MessageBreak \VERCMD@temp\MessageBreak } \expandafter\VERCMD@addchanged\expandafter{\VERCMD@temp}{\string#3}% }% {% \PackageWarning{#1}{% Something may fail. A definition has changed:\MessageBreak% \ifblank{#2}{}{#2: }% \string#3\MessageBreak% \VERCMD@temp\MessageBreak% }% \expandafter\VERCMD@addchanged\expandafter{\VERCMD@temp}{\ifblank{#2}{}{#2: }\string#3}% }% } % \end{macrocode} % \end{macro} % % % \begin{macrocode} \ExplSyntaxOn % \end{macrocode} % % % \subsection{User interface} % % \begin{macro}{\VerifyCommand} \oarg{yourpackage} \oarg{theirpackage} % \marg{\cs{commandname}} \marg{\MDfive\ checksum} % % Test for various kinds of definitions, and convert them to \MDfive\ checksums. % \begin{macrocode} \NewDocumentCommand{\VerifyCommand}{O{} O{} m m}{% % \end{macrocode} % % Only if the package is enabled: % \begin{macrocode} \ifbool{VERCMD@enable}{% % \end{macrocode} % % Default to an un-detected definition type: % \begin{macrocode} \edef\VERCMD@temp{Unknown~definition}% % \end{macrocode} % % For \cs{NewDocumentCommand}, the macro name is ``|\name code|'' with a space in the middle. % \begin{macrocode} % % NewDocumentCommand: \ifcsdef{\cs_to_str:N #3~code}% {% \expandafter\VERCMD@mdfive% \csname \cs_to_str:N #3~code\endcsname% }% {% % \end{macrocode} % % For \cs{DeclareRobustCommand} with an optional argument, % the macro name is ``|\\name |'' with a two backslashes and a trailing space. % \begin{macrocode} % % DeclareRobustCommmand with option: \ifcsdef{\VERCMD@backslash\cs_to_str:N #3~}% {% \expandafter\VERCMD@mdfive% \csname \cs_to_str:N #3~code\endcsname% }% {% % \end{macrocode} % % For \cs{DeclareRobustCommand}, the macro name is ``|\name |'' with a trailing space. % \begin{macrocode} % % DeclareRobustCommand: \ifcsdef{\cs_to_str:N #3~}% {% \expandafter\VERCMD@mdfive% \csname \cs_to_str:N #3~\endcsname% }% {% % \end{macrocode} % % For \cs{newcommand} with an option, the macro name is ``|\\name|'', with two backslashes. % \begin{macrocode} % % newcommand w/ option: \ifcsdef{\VERCMD@backslash\cs_to_str:N #3}% {% \expandafter\VERCMD@mdfive% \csname \VERCMD@backslash\cs_to_str:N #3\endcsname% }% % \end{macrocode} % % For \cs{newcommand}, the macro name is ``|\name|''. % % If none match, the default unknown definition warning is show in place of the checksum. % \begin{macrocode} {% % % newcommand: \ifdef{#3}% {\VERCMD@mdfive#3}% {}% }% }% }% }% % \end{macrocode} % % If the checksum does not match the expected value, issue a warning. % \begin{macrocode} \ifdefstring{\VERCMD@temp}{#4}% {}% {% \VERCMD@Warning{#1}{#2}{#3}% }% }% if package enabled {}% if package not enabled } % \end{macrocode} % \end{macro} % % % \begin{macro}{\VerifyEnvironment} \oarg{yourpackage} \oarg{theirpackage} % \marg{\cs{commandname}} % \marg{begin \MDfive\ checksum} % \marg{end \MDfive\ checksum} % % Test both the begin and end section of the environment. % \begin{macrocode} \NewDocumentCommand{\VerifyEnvironment}{O{} O{} m m m}{% % \end{macrocode} % % Only if the package is enabled: % \begin{macrocode} \ifbool{VERCMD@enable}{% % \end{macrocode} % % Default to an un-detected definition type: % \begin{macrocode} \edef\VERCMD@temp{Unknown~definition}% % \end{macrocode} % % For \cs{NewDocumentEnvironment}, the macro name is ``|\environment name code|'' with internal spaces. % \begin{macrocode} % % NewDocumentEnvironment: \ifcsdef{environment~#3~code}% {% \expandafter\VERCMD@mdfive% \csname environment~#3~code\endcsname% }% {% % \end{macrocode} % % For \cs{newenvironment} with an optional argument, % the macro name is ``|\\name|'', with two backslashes. % \begin{macrocode} % % newenvironment with option: \ifcsdef{\VERCMD@backslash#3}% {% \expandafter\VERCMD@mdfive% \csname \VERCMD@backslash#3\endcsname% }% {% % \end{macrocode} % % For \cs{newenvironment}, the macro name is ``|\name|''. % \begin{macrocode} % % newenvironment: \ifcsdef{#3}% {\expandafter\VERCMD@mdfive\csname #3\endcsname}% {}% }% }% % \end{macrocode} % % If the checksum does not match the expected value, issue a warning. % \begin{macrocode} \ifdefstring{\VERCMD@temp}{#4}% {}% {% \VERCMD@Warning{#1}{#2}{#3}% }% % \end{macrocode} % % Reset the default to an un-detected definition type: % \begin{macrocode} \edef\VERCMD@temp{Unknown~definition}% % \end{macrocode} % % For \cs{NewDocumentEnvironment}, the ending macro name % is ``|\environment name end aux |'', with spaces and a trailing space. % \begin{macrocode} % % end DocumentEnvironment: \ifcsdef{environment~#3~end~aux~}% {% \expandafter\VERCMD@mdfive \csname environment~#3~end~aux~\endcsname% }% {% % \end{macrocode} % % For \cs{newenvironment}, the ending macro name is ``|\endname|''. % \begin{macrocode} % % end newenvironment: \ifcsdef{end#3}% {% \expandafter\VERCMD@mdfive% \csname end#3\endcsname% }% {}% }% % \end{macrocode} % % If the checksum does not match the expected value, issue a warning. % \begin{macrocode} \ifdefstring{\VERCMD@temp}{#5}% {}% {% \VERCMD@Warning{#1}{#2}{(end)#3}% }% }% if package enabled {}% if package not enabled } % \end{macrocode} % \end{macro} % % \begin{macrocode} \ExplSyntaxOff % \end{macrocode} % % % % \clearpage % % \section{\pkg{verifycommand} package maintenance} % % To compile \filenm{verifycommand.sty} and \cs{verifycommand.pdf} % from \filenm{verifycommand.dtx} and \filenm{verifycommand.ins}: % % \begin{sourceverb} % pdflatex verifycommand.ins % pdflatex verifycommand.dtx % pdflatex verifycommand.dtx % makeindex -s gglo.ist -o verifycommand.gls verifycommand.glo % splitindex verifycommand.idx -- -s gind.ist % pdflatex verifycommand.dtx % pdflatex verifycommand.dtx % \end{sourceverb} % % % \iffalse % % \fi % % % % % % \clearpage % \pagestyle{plain} % % \renewcommand{\partname}{} % \renewcommand{\thepart}{} % ^^A \part{Change History and Index} % % % \Finale % \endinput