% \iffalse meta-comment % % Copyright (C) 2005 by Ulrich M. Schwarz % % This file may be distributed and/or modified under the conditions of % the LaTeX Project Public License, either version 1.3a or, at your % option, any later version. The latest version of this license is in % % http://www.latex-project.org/lppl.txt % % \fi % %\iffalse %<*driver> \documentclass{ltxdoc} \usepackage[l2tabu]{nag} \GetFileInfo{nag.sty} \typeout{\fileversion} \usepackage[T1]{fontenc} \usepackage{bera}% much smaller pdf now. \EnableCrossrefs \CodelineIndex \RecordChanges \begin{document} \DocInput{nag.dtx} \end{document} % %<*l2tabunag> \ProvidesFile{l2tabu.nag}[2005/03/23 v1.7 l2tabu rules for nag.sty (ulmi)] %% %% The sins. %% %% Section numbers refer to l2tabuen 1.7 revised/enlarged dated 2004OCT24 %% \S 1.1 \ObsoletePackage{a4wide}{the \lq a4paper\rq\space class option} \ObsoletePackage{a4}{the \lq a4paper\rq\space class option} %% \S 1.2--1.5 cannot reasonably be checked programmatically %% \S 1.6 is handled by H.Harders' onlyamsmath package %% \S 1.7 cannot reasonably be checked programmatically %% \S 1.8 \sloppy is called by parbox, among others, and would %% give many spurious warnings. %% \S 2.1.1 \ObsoleteCS[an old LaTeX 2.09 command]{bf}{\protect\bfseries\space or \protect\textbf} \ObsoleteCS[an old LaTeX 2.09 command]{it}{\protect\itshape\space or \protect\textit} \ObsoleteCS[an old LaTeX 2.09 command]{rm}{\protect\rmfamily\space or \protect\textrm} \ObsoleteCS[an old LaTeX 2.09 command]{sc}{\protect\scshape\space or \protect\textsc} \ObsoleteCS[an old LaTeX 2.09 command]{sf}{\protect\sffamily\space or \protect\textsf} \ObsoleteCS[an old LaTeX 2.09 command]{sl}{\protect\slshape\space or \protect\textsl} \ObsoleteCS[an old LaTeX 2.09 command]{tt}{\protect\ttfamily\space or \protect\texttt} \ObsoleteCS[an old LaTeX 2.09 command]{cal}{\protect\mathcal}% Hmm, this is not in l2tabu? %% \S 2.1.2 \ObsoleteCS[TeX]{over}{\protect\frac} \ObsoleteCS[TeX]{choose}{\protect\frac\space or amsmath's \protect\binom} %% \S 2.1.3 \ObsoleteCS[TeX]{centerline}{\protect\centering\space or center environment} %% \S 2.2.1 \ObsoleteClass{scrlettr}{the scrlttr2 package} %% \S 2.2.2 \ObsoletePackage{epsf}{the graphicx package} \ObsoletePackage{psfig}{the graphicx package} \ObsoletePackage[deprecated]{epsfig}{the graphicx package directly} %% \S 2.2.3 \ObsoletePackage{doublespace}{the setspace package} %% \S 2.2.4 \ObsoletePackage{fancyheadings}{the fancyhdr or scrpage2 packages} \ObsoletePackage{scrpage}{the scrpage2 package} %% \S 2.2.5 \ObsoletePackage{isolatin}{the inputenc package with option latin1} \ObsoletePackage{umlaut}{the inputenc package with suitable option (latin1, utf8 ...)} \ObsoletePackage{isolatin1}{the inputenc package with option latin1} %% \S 2.2.6 \ObsoletePackage{t1enc}{the fontenc package with option T1} %% \S 2.2.7 we don't check for bst yet. %% (This is in l2tabu 1.8) \ObsoletePackage{caption2}{the caption package v3.0 or later} %% \S 2.3.1-3 \ObsoletePackage{times}{the mathptmx, helvet (option scaled=.9), courier packages} \ObsoletePackage{pslatex}{the mathptmx, helvet (option scaled=.9), courier packages} \ObsoletePackage{mathptm}{the mathptmx package} %% \S 2.3.4-5 \ObsoletePackage{palatino}{the mathpazo, helvet (option scaled=.95), courier packages} \ObsoletePackage{mathpple}{the mathpazo package} %% \S 2.3.6 can't be checked %% \S 2.3.7 \ObsoletePackage{euler}{the eulervm package} \ObsoletePackage{utopia}{the fourier package} %% \S 3.1 \g@addto@macro\nag@floats{,figure,table}% %% \S 3.2 \ObsoleteCS[a misuse]{endappendix}{% \protect\appendix\space as a switch, not an environment.\MessageBreak \protect\end{appendix} detected} %% \S 3.3 handled by onlyamsmath. %% \S 3.4 -- nothing to be done -- % % %<*abortnag> \ProvidesFile{abort.nag}[2005/05/08 v0.1 treat complaints as errors (ulmi)] \renewcommand\nag@warn[1]{% \addtocounter{nag@sins}{1}% \PackageError{nag}{#1}{#1}% } \renewcommand\nag@warnNoLine[1]{% \addtocounter{nag@sins}{1}% \PackageError{nag}{#1}{#1}% } % % %<*nagdemo> %% Test document: finding and complaining about obsolete macros. %% \RequirePackage[l2tabu]{nag} \documentclass{article} %% some usual culprits \usepackage{times, a4wide, epsfig, palatino} \begin{document} \typeout{Next: it and bf complaints} {\it f{\bf oo}f}highter \typeout{Next: center in float complaint} \begin{figure} \begin{center} Foo. \end{center} \caption{\label{fig}Higher!} \end{figure} \typeout{Next: no complaints: manually fake caption} \begin{figure} Foo. \makeatletter\nag@hascaptiontrue\makeatother \label{date} \end{figure} \typeout{Next: put-label-after-caption complaint} \begin{figure} Foo. \label{coconut}\caption{Bar.} \end{figure} \typeout{Next: no-caption complaint} \begin{figure} Foo. \end{figure} \begin{appendix} \begin{center} Foo. \end{center} \typeout{Next: over complaint, centerline complaint} \centerline{Ferner gilt $4\over 2=2$.} \typeout{Next: appendix complaints} \end{appendix} \typeout{You should get 13 warnings.} \end{document} % % %<*!(l2tabunag,abortnag,nagdemo)> %\fi % % \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 \~} %\CheckSum{169} % %\DoNotIndex{\if,\else,\fi,\PackageWarning,\PackageWarningNoLine,\typeout} %\DoNotIndex{\@for,\addtocounter,\arabic,\centering,\csname,\CurrentOption} %\DoNotIndex{\DeclareOption,\def,\do,\endcsname,\expandafter,\ifnum,\ifx} %\DoNotIndex{\InputIfFileExists,\let,\lq,\rq,\MessageBreak,\protect} %\DoNotIndex{\space,\stepcounter,\the,\value,\relax,\ProcessOptions} %\DoNotIndex{\ifcsname,\@ifundefined,\flo,\begingroup,\endgroup} % %\changes{0.1}{2005/03/29}{First official version.} %\changes{0.2}{2005/05/08}{Rephrased umlaut.sty warning, suggested by %Patrick Happel.} %\changes{0.2}{2005/05/08}{Added abort.nag, suggested by Michael Zedler} %\changes{0.3}{2005/07/07}{New ifdefined that won't relax the commands} % %\newcommand\pkg[1]{\textsf{#1}} %\title{The \pkg{nag} package\ignorespaces% % \thanks{This document corresponds to \pkg{nag}~\fileversion, % dated~\filedate.}} % \author{Ulrich Michael Schwarz\ignorespaces% % \thanks{\texttt{ulmi@users.sarovar.org}}} % % \maketitle % % \begin{abstract} % Old habits die hard. All the same, there are commands, classes and % packages which are outdated and superseded. \pkg{nag} provides % routines to warn the user about the use of those. As an example, we % provide an extension that detects many of the ``sins'' described in % \pkg{l2tabu}. % \end{abstract} % % \tableofcontents % % \section{User-side considerations.} % % \subsection{Installation.} % % Process \texttt{nag.ins} with \LaTeX\ to obtain four files: % \texttt{nag.sty} and \texttt{l2tabu.nag} must go to a place where % \LaTeX\ will find them, like the local TEXMF tree. (If all else fails and % you need it to work \emph{right now}, having them in the same % directory as the \LaTeX\ file you want to use them on may work under % many circumstances.) You can, as usual, run \LaTeX\ on % \texttt{nag.dtx} to obtain this documentation, including the % implemenation docs. (This is recommended if you plan to extend % \pkg{nag} to handle your own packages.) \texttt{nagdemo.tex} is % a horrible document that will show you many of the warnings that % \pkg{nag} can generate. % % \subsection{Usage.} % % Add the following to the beginning your main document (Comments and % |\listfiles| can be safely left before it, though): % \begin{verbatim} % \RequirePackage[l2tabu]{nag}\end{verbatim} % This will check for many common mistakes, and give some hints on what % to use instead. However, you should always refer to l2tabu for a more % detailed explanation of the whats and whys: it gives more information % than can be possibly pressed into two lines of error message. % % \subsection{\texttt{l2tabu.nag}} % % In a nutshell, \texttt{l2tabu.nag} detects the following: % \begin{itemize} % \item Usage of the 2.09-style font commands |\it|, |\bf|, |\rm|, % |\sc|, |\sl|, |\tt| and |\cal|. % \item Usage of the \TeX-style commands |\over| and |\choose|. % \item Usage of |\centerline|. % \item Usage of the outdated packages \pkg{epsfig}, \pkg{psfig}, % \pkg{epsf}, \pkg{doublespace}, \pkg{fancyheadings}, \pkg{scrpage}, % \pkg{umlaut}, \pkg{isolatin}, \pkg{isolatin1}, \pkg{t1enc}, % \pkg{caption2}, \pkg{psfonts}, \pkg{mathptm}, \pkg{times}, % \pkg{palatino}, \pkg{mathpple}, \pkg{euler} and \pkg{utopia}, and of % the outdated class \pkg{scrlttr}. % \item Figures and tables without caption (this is not technically % in l2tabu, but the people who have floats without captions tend % to ask ``Why is \LaTeX\ moving my pictures away from where I % put them?''), labels within floats % that do not reference the caption, and usage of the center % environment within floats. %\end{itemize} % % It is beyond the possibilities of this package to detect things like % use of \TeX\ assignment syntax, or direct change of paper % parameters, or reliable detection of user-issued |\sloppy|. % Outdated maths environments are not treated because those can % already be handled by Harald Harders' \pkg{onlyamsmath}. % % Be warned, hence, that this package will possibly balk at % legitimate use, and not find illegitimate use in all cases. It is a % tool, not a replacement for study of \pkg{l2tabu}. % % \subsection{\texttt{abort.nag}} % Requesting this nag file will turn all complaints into errors. % %\StopEventually{\PrintChanges} % \section{Author-side considerations and implementation.} % If you are a package or class author and want to extend the range % of \pkg{nag} (or prevent \pkg{nag} from criticizing % your macros), please see the description below, in % sections~\ref{sec:obsol-cmds} and following. It is % probably wise to group new rules in a seperate nag file: % users can request nag files by passing their name as a package % parameter, as shown above for the example of l2tabu. % % \subsection{Low-level tools.} % Identify ourselves. % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{nag}[2005/07/07 0.3 warning about nag things (ulmi)] % \end{macrocode} % First of all, two counters we need. The first is used to % generate running numbers for replacement macros, the latter is % stepped for each complaint we have, so that the user gets a % frighteningly high number, showing how sinful he or she is. % \begin{macrocode} \newcounter{nag@c} \newcounter{nag@sins} % \end{macrocode} % % \begin{macro}{\nag@prepend} % |\nag@prepend|\marg{cs}\marg{something}: % Prepend \meta{something} to the macro definition of |\|\meta{cs}. % % In reality, we do call indirection: save old macro away, % redefine macro to do the something, call old macro. % (With thanks to Juergen Goebel, Heiko Oberdiek and Rolf Niepraschk % (\pkg{savesym})) % % \begin{macrocode} \newcommand\nag@prepend[2]{% \expandafter\let \csname nag@@#1@\the\value{nag@c}\expandafter\endcsname \csname #1\endcsname \expandafter\nag@pr@p@nd\csname #1\expandafter\endcsname \csname nag@@#1@\the\value{nag@c}\endcsname{#2}% \stepcounter{nag@c}% } \newcommand\nag@pr@p@nd[3]{% \def#1{#3#2}% } % \end{macrocode} % \end{macro} % \begin{macro}{\nag@warn} % All complaints to the user run through one of these two macros, % with or without source line. % \begin{macrocode} \newcommand\nag@warn{% \addtocounter{nag@sins}{1}% \PackageWarning{nag}% } \newcommand\nag@warnNoLine{% \addtocounter{nag@sins}{1}% \PackageWarningNoLine{nag}% } % \end{macrocode} % \end{macro} % % \subsection{Obsoletifying commands.}\label{sec:obsol-cmds} % % (No, I do not think that is a proper word either.) % % \begin{macro}{\ObsoleteCS} % Usage: |\ObsoleteCS|\oarg{reason}\marg{CS}\marg{suggestions} % Mark |\|\meta{CS} as obsolete. \meta{reason} defaults to % obsolete. When the macro is used anyway, the following % warning is logged: % % \noindent|Command \|\meta{CS}| is |\meta{reason}|. Use |\meta{suggestions}| instead.| % \begin{macrocode} \newcommand\ObsoleteCS[3][obsolete]{% \AtBeginDocument{% \nag@prepend{#2}{% \nag@warn{% Command \expandafter\protect\csname #2\endcsname\space is #1. \MessageBreak Use #3 instead}% }% }% } % \end{macrocode} % \end{macro} % % \subsection{Obsoletifying packages and classes.} % % Checking for packages and classes is done by looking for % |ver@foo.sty|, which holds the version information that is also % displayed by |\listfiles|. This means that we're out of luck if % fontenc ever becomes obsolete, because that won't be detected. % % First, define a macro to check if a control sequence is defined. % Unlike |\@ifundefined|, this will not define the control sequence % to |\relax|, but the arguments will be executed in a group. For % our purposes, this doesn't matter, because we only give a warning % (and |\addtocounter| already is |\global|). % \begin{macrocode} \newcommand\nag@ifcsname[3]{% \begingroup\@ifundefined{#1}{#3}{#2}\endgroup } % \end{macrocode} % Just because we can, use $\epsilon$\TeX' |\ifcsname| if we can. This % bootstrapping gives me a big grin\dots Note we add an extra group % for compatibility with the non-$\epsilon$ case. % \begin{macrocode} \nag@ifcsname{ifcsname}{% \renewcommand*\nag@ifcsname[3]{% \begingroup \ifcsname #1\endcsname #2\else #3\fi \endgroup }% % \end{macrocode} % This way of escaping the grouping gives me an even % bigger grin. % \begin{macrocode} \global\let\nag@ifcsname\nag@ifcsname }{} % \end{macrocode} % % \begin{macro}{\ObsoletePackage} % Usage: |\ObsoletePackage|\oarg{reason}\marg{package}\marg{% % alternative}. Mark \meta{package} as obsolete. \meta{reason} defaults % to obsolete. If the \meta{package} is used anyway, at the end of % the compilation, the following warning will be displayed: % % \noindent|Package |\meta{package}| is |\meta{reason}|. Use | % \meta{alternative}| instead.| % \begin{macrocode} \newcommand\ObsoletePackage[3][obsolete]{% \AtEndDocument{% \nag@ifcsname{ver@#2.sty}{% \nag@warnNoLine{% Package #2 is #1.\MessageBreak Use #3 instead}% }{}% }% } % \end{macrocode} % \end{macro} % % \begin{macro}{\ObsoleteClass} % Usage: |\ObsoleteClass|\oarg{reason}\marg{class}\marg{% % alternative}. Mark \meta{class} as obsolete. \meta{reason} defaults % to obsolete. If the \meta{class} is used anyway, at the end of % the compilation, the following warning will be displayed: % % \noindent|Class |\meta{class}| is |\meta{reason}|. Use | % \meta{alternative}| instead.| % \begin{macrocode} \newcommand\ObsoleteClass[3][obsolete]{% \AtEndDocument{% \nag@ifcsname{ver@#2.cls}{% \nag@warnNoLine{% Class #2 is #1.\MessageBreak Use #3 instead}% }{}% }% } % \end{macrocode} % \end{macro} % % \subsection{Common float errors and no-nos.} % % We do the following: % \begin{itemize} % \item check for presence of a caption % \item check for absence of the center environment % \item check that a label comes only after a caption % \end{itemize} % % First of all, we define two ifs to memorize whether we have a % label and/or a caption in the float already. Package writers may % want to set these manually behind \pkg{nag}'s back. In this % way, they can suppress possible warnings if they know what % they're doing -- we only check at the end of the float % environment, which gives them plenty of time to call % |\csname nag@haslabeltrue\endcsname| et al. % (Thanks to Markus Kohm for pointing out this need.) % \begin{macrocode} \newif\ifnag@haslabel \newif\ifnag@hascaption % \end{macrocode} % Now, to the work proper: first, add the endcenter check, then, % prepare to set up the caption/label checks locally to the floats, % and finally, add the code that generates the warning. % \begin{macrocode} \newcommand\nag@hackfloat[1]{% \nag@prepend{#1}{% \nag@prepend{endcenter}{% \nag@warn% {\lq center\rq\space environment in #1.\MessageBreak Maybe you want \protect\centering\space instead} }% } \nag@prepend{#1}{% % \end{macrocode} % Add checks to all macros named by |\nag@labels| % and |\nag@captions|, respectively. % \changes{0.3}{2005/07/07}{Fixed missing globals} % The hascounter etc. information is now global. I don't think % those should be hidden by groups. In particular, a center or % minipage environment would hide the caption inside from a label % outside. % % \emph{Note:} we cannot exchange the order of the for loops here: % if a cs generates both a label and a caption, it shouldn't get % complained about. % \begin{macrocode} \@for\labelprovider:=\nag@labels\do{% \nag@prepend{\labelprovider}% {\nag@captioncheck\global\nag@haslabeltrue} }% \@for\captionprovider:=\nag@captions\do{% \nag@prepend{\captionprovider}{\global\nag@hascaptiontrue}% }% \global\nag@haslabelfalse\global\nag@hascaptionfalse }% \nag@prepend{end#1}{% \ifnag@hascaption\relax\else \nag@warn% {#1 with no \protect\caption}% \fi }% } \newcommand\nag@captioncheck{% \ifnag@hascaption\else \nag@warn{\protect\label\space in float, but not after \protect\caption}% \fi } % \end{macrocode} % Define the lists of commands that are floats, generate labels, % and generate captions, respectively. We don't start with defined % floats (that is for l2tabu.obs to set up), but keep the list % non-empty, so that we can always add to it with % |\g@addto@macro|\marg{list}|{,|\meta{things}|}|. % \begin{macrocode} \def\nag@floats{nag@dummy} \def\nag@labels{label} %% The latter two are used by KOMA-Script. \def\nag@captions{caption,captionabove,captionbelow} % \end{macrocode} % % We call the above for each float environment named via % |\nag@floats|: % \begin{macrocode} \newcommand\nag@floatsetup{% \@for\flo:=\nag@floats\do{% \expandafter\nag@hackfloat\expandafter{\flo}% }% } % \end{macrocode} % but only after all other packages get their chance to add to the % list: % \begin{macrocode} \AtBeginDocument{% \nag@floatsetup } % \end{macrocode} % % At the very end, we will display a running total of complaints. % This feature was more-or-less suggested by David Kastrup. % \begin{macrocode} \AtBeginDocument{% \AtEndDocument{% \ifnum\value{nag@sins}>0% \PackageWarningNoLine{nag}{\arabic{nag@sins} complaints in total}% \else \typeout{No complaints by nag.}% \fi }% } % \end{macrocode} % % Finally, we deal with package options. % This is simple: just try to input appropriate nag files. % \begin{macrocode} \DeclareOption*{% \InputIfFileExists{\CurrentOption.nag}{% \typeout{package nag: Loaded \CurrentOption.nag}% }{% \PackageWarningNoLine{nag}{Required ruleset \CurrentOption.nag, and it wasn't there} }% } \ProcessOptions* % \end{macrocode} %\PrintIndex %\Finale %\iffalse % %%X Local Variables: %%X mode: latex %%X End: %\fi