%\iffalse -*- doctex -*- \fi % %% \RCS$Id: pmn-fxme.sty,v 1.5 2004/08/27 23:47:17 turtle Exp $ %% \RCS$Revision: 1.5 $ %% \RCS$Date: 2004/08/27 23:47:17 $ % %\iffalse metacomment % -*- latex-mode -*- %% (C) 2004 Peter Møller Neergaard %% %% This program may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.2 %% 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.2 or later is part of all distributions of LaTeX %% version 1999/12/01 or later. % % This program consists of the file pmn-fxme.sty. % % To print the documentation (which for the moment is uninteresting) % remove (or comment out) the line % % \endinput % % occurring immediately after % % %<*documentation> % %\fi % % \CheckSum{13} % \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 \~} % % \MakeShortVerb{\"} % % \title{The \package{pmn-fxme} package\thanks % {This file has CVS revision \RCSRevision, dated \RCSDate.}} % \author{Peter Møller Neergaard} % \maketitle % % \begin{abstract} % This an enhancement of the \package{fixme} to allow a priority on % each fixme. The priority is used when printing the list of fixmes. % Each fixme is indented according to priority and fixme with a low % priority can be suppressed. % \end{abstract} % % This package extends the \package{fixme} package (loaded % automatically) which allows you to make fixme notes. It is loaded % using "\usepackage{pmn-fxme} and has the same options as % \package{fixme}. % % \DescribeMacro{\pmnfix} % \mcmd{\pmnfix}\oarg{time}\marg{priority}\marg{note} Makes a fixme note of % priority \meta{priority} (a positive integer). % % \DescribeMacro{\pmnlistoffixmes} list the fixmes in order of % priority. % % \DescribeMacro{pmnfixdepth} % The counter "pmnfixdepth" controls the deepest level of fixmes that % should be included in the list of fixmes (fixmes with a priority are % always included). % % \DescribeMacro{\pmnfixIndentation} % When using \package{fixme}'s \cmd{listoffixmes} the fixmes with % priority are indented according to the priority. The indentation % per level is controled by \cmd{\pmnfixIndentation}. % % \DescribeMacro{\pmnfixDefault} % \DescribeMacro{\cs{pmnfixFormat\meta{priority}}} % \mcmd{\pmnfixDefault}\marg{priority}\marg{note}\marg{pageno} is the % default macro to format an entry in the list of fixmes. The % standard entry uses \cmd{\pmnfixIndentation} as described above. If % you generally want to change the formatting you can modify this % macro. If you only want to change a single priority level, modify % \cs{pmnfixFormat\meta{priority}} where \meta{priority} is the level. % % \section{Package identification} % % We identify ourselves and load \package{fixme}. % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{pmn-fxme}[2004/07/06 v0.1 PMN improved insertion of fixme notes] \@ifpackageloaded{fixme}% {\DeclareOption*{}}% {\DeclareOption*{\PassOptionsToPackage\CurrentOption{fixme}}} \ProcessOptions* \@ifpackageloaded{fixme}{}% {\RequirePackage{fixme}} % \end{macrocode} % \changes{}{2004/08/25}{only loading fixme if not already loaded} % % \section{Inserting a fixme note} % We define the \cs{pmnfix} command which makes one of my priority % fixme notes. % \begin{macro}{\pmnfix} % \begin{macro}{\pmnfixFixmeCommand} % \mcnd{\pmnfx}\oarg{time}\marg{priority}\marg{note} makes a fixme \meta{note} of % \meta{priority}. % \begin{macrocode} \newcommand{\pmnfix}[3][]{% \pmnfixFixmeCommand{\protect\pfx@pri{#2} \pfx@time{#1} {#3}}} \let\pmnfixFixmeCommand\fixme \AtBeginDocument{% \let\pfx@nopriority\l@fixme \let\pfx@list@standard\l@fixme \def\l@fixme{\pmn@l@fixme}% \let\pfx@priority\pfx@test@in@range} % \end{macrocode} % It uses a standard \package{fixme} command (as chosen by % \cmd{\pmnfixFixmeCommand}. It uses % "\ifpmnfix@haspriority" to flag that this is note with priority. % \end{macro} ^^A \pmnfixFixmeCommand % \end{macro} ^^A \pmnfix % % \begin{macro}{\pfx@pri} % \begin{macro}{\pfx@pri@set} % \begin{macro}{\pfx@found@priority} % When it is a fixme note with priority we store priority using % "\pfx@pri{"\meta{priority}"}". Usually, we let % \cmd{\pfx@pri} be \cmd{\relax} so the priority is printed. % However, when checking for the existence of a priority we use % \cmd{\pfx@pri@set} which stores the priority in % \cmd{\pfx@found@priority}. % \begin{macrocode} \let\pfx@pri\relax \newcommand{\pfx@pri@set}[1]{\gdef\pfx@found@priority{#1}} % \end{macrocode} % \end{macro}^^A \pfx@found@priority % \end{macro}^^A \pfx@pri@set % \end{macro}^^A \pfx@pri % % \begin{macro}{\pfx@time} % \begin{macro}{\pfx@time@sum} % \begin{macro}{\pfx@found@time} % When it is a fixme note with priority we store time using % "\pfx@time{"\meta{time}"}". Usually, we let % \cmd{\pfx@time} be \cmd{\relax} so the time is simply printed. % However, when print the list of jobs, we let \cmd{\pfx@time} point % to \cmd{\pf@time@sum} which sums up the time annotations. % \begin{macrocode} \let\pfx@time\relax \newcommand{\pfx@time@sum}[1]{ #1% \pfx@time@sum@m{#1}% \pfx@time@sum@h{#1}% \pfx@time@sum@d{#1}% } \newcommand{\pfx@reset@sums}{} \newcommand{\pfx@print@sums}{\protect\pfx@print@sum@init} \def\pfx@make@time@sum@unit#1{% \expandafter\expandafter\expandafter\newdimen\@nameuse{pfx@time@#1}% \edef\pfx@reset@sums{\global\pfx@reset@sums\@nameuse{pfx@time@#1}=\z@}% \protected@edef\pfx@print@sums{\pfx@print@sums \protect\pfx@print@sum{#1}}% \@namedef{pfx@time@sum@#1}##1{% \@nameuse{pfx@time@sum@#1@i}##1#1\foo}% \@namedef{pfx@time@sum@#1@i}##1#1##2\foo{% \def\reserved@a{##2}% \ifx\reserved@a\@empty\else \global\advance\@nameuse{pfx@time@#1} by ##1pt \fi}} \pfx@make@time@sum@unit{d} \pfx@make@time@sum@unit{m} \pfx@make@time@sum@unit{h} \newcommand{\pfx@print@sum@init}{% \def\pfx@opt@totaltxt{\noindent Total: }} \newcommand{\pfx@print@sum}[1]{% \ifdim\@nameuse{pfx@time@#1}>\z@ \pfx@opt@totaltxt \let\pfx@opt@totaltxt\relax \edef\reserved@a{\@nameuse{pfx@time@#1}}% \expandafter\strip@pt\reserved@a#1 \fi} % \end{macrocode} % \end{macro}^^A \pfx@found@priority % \end{macro}^^A \pfx@time@set % \end{macro}^^A \pfx@time % % \section{List of Fixmes} % % We then make set up the printing of the list of fixmes. We first % define the general dispatching which takes an entry and decides % whether it should be listed. Then we have backend procedures to % actually list the entry if it passes the needle's eye. We can % therefore use the dispatching both for the regular list and with % individual lists. % % Concretely, we replace \cmd{\l@fixme} by \cmd{\pmn@l@fixme}. It % tests whether it as a standard fixme note (if it is formatted using % \cmd{\pfx@nopriority} which is usually the standard \cmd{l@fixme}); % otherwise it is formatted using \cmd{\pfx@priority}. Normally, % \cmd{\pfx@priority} invokes \cmd{\pfx@test@in@range} which tests % whether we are in the listable range and if so dispatch the formatting % procedure specified by \cmd{\pfx@list@in@range}. % % The many definable entries allow us to turn the processing on or off % in various ways: we can disable processing by letting % \cmd{\pfx@nopriority} or \cmd{\pfx@priority} gobble their % arguments. By changing \cmd{\pfx@list@in@range} we can either % output the entry directly or, when listing in decreasing priority, % do some further processing. % % \begin{macro}{pmnfixdepth} % The counter "pmnfixdepth" contains the maximum depth of fixme to % be included; a negative number means all. % \begin{macrocode} \newcounter{pmnfixdepth} \setcounter{pmnfixdepth}{-1} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmn@l@fixme} % \mcmd{\pmn@l@fixme}\marg{fixme note}\marg{page} is a replacement % for \cmd{\l@fixme} and therefore a standard contents line % formatting macro. % % It typesets the fixme note in box so the priority information, if % any, stored with \cmd{\pfx@priority} can be recovered. If there % is information we use \cmd{\pfx@priority} to typeset the content; % otherwise we use \cmd{\pfx@nopriority}. % \begin{macrocode} \newcommand{\pmn@l@fixme}[2]{% \let\pfx@found@priority\relax \let\pfx@pri\pfx@pri@set \setbox\@tempboxa\vbox{#1}% \ifx\pfx@found@priority\relax \expandafter\@secondoftwo \else \expandafter\@firstoftwo\fi {\let\pfx@pri\@gobble \pfx@priority{\pfx@found@priority}{#1}{#2}}% {\pfx@nopriority{#1}{#2}}} \newcommand{\pmn@l@fixme@parse}{} \def\pmn@l@fixme@parse#1\pfx@hasprioritytrue#2 #3#4{% \pfx@priority{#2}{#3}{#4}} % \end{macrocode} % \end{macro}^^A \pmn@l@fixme@parse % \end{macro}^^A \pmn@l@fixme % % \begin{macro}{\pfx@test@in@range} % \mcmd{\pfx@test@in@range}\marg{priority}\marg{note}\marg{page} is % the usual macro to process fixme with priority information. It % tests whether the priority is in the range that should be listed % and if so lists it using \cmd{\pfx@list@in@range}. \newcommand{\pfx@test@in@range}[3]{% % \end{macrocode} % "if pmnfixdepth < 0 % \begin{macrocode} \ifnum \c@pmnfixdepth<\z@ \expandafter\@secondoftwo \else \expandafter\@iden \fi % \end{macrocode} % " or #1 <= pmnfixdepth then % \begin{macrocode} {\ifnum \c@pmnfixdepth<#1\relax \expandafter\@gobble \else \expandafter\@iden \fi}% % \end{macrocode} % " begin" % \begin{macrocode} {\pfx@list@in@range{#1}{#2}{#3}}} % \end{macrocode} % % \begin{macro}{\pfx@list@default@or@spec} % \mcmd{\pfx@list@default@or@spec}\marg{priority} dispatches either the % default formatting or an individual formatting macro for the given % priority. It is the normal value of \cmd{\pfx@list@in@range}. % \begin{macrocode} \newcommand{\pfx@list@default@or@spec}[1]{% \@ifundefined{pmnfixFormat\romannumeral#1}% {\pmnfixDefault{#1}}% {\csname pmnfixFormat\romannumeral#1\endcsname{#1}}} % \end{macrocode} % " end" % \end{macro}^^A \pmn@list@default@or@spec % % \begin{macro}{\pfx@list@in@range}% % \cmd{\pfx@list@in@range} is the placeholder for the command to % proceed a priority fixme in the listable range. % \begin{macrocode} \let\pfx@list@in@range\pfx@list@default@or@spec % \end{macrocode} % \end{macro} % % \section{Indented entry} % % This part handles presenting entry indented according to its % priority. % % \begin{macro}{\pmnfixIndentation} % \mcmd{\pmnfixIndentation} defines the indentation for each level % of priority. % \begin{macrocode} \newlength{\pmnfixIndentation} \setlength{\pmnfixIndentation}{2em} % \end{macrocode} % \end{macro} % % \begin{macro}{\pmnfixDefault} % \mcmd{\pmnfixDefault}\marg{priority}\marg{note}\marg{pageno} is % the default formatting of an entry. The entry is indented % proportionally to the priority. We change the margins so the text % can span several lines and finally dots out to the page number. % \begin{macrocode} \newcommand{\pmnfixDefault}[3]{% \medskip % \vskip \z@ \@plus.2\p@ % \end{macrocode} % Reduce left margin according to priority and right margin according % to table of contents settings. % \begin{macrocode} {\@tempdima -\pmnfixIndentation \advance\@tempdima #1\pmnfixIndentation \leftskip \@tempdima\relax \rightskip \@tocrmarg \parindent\z@ \parfillskip -\rightskip % \end{macrocode} % Then set the text followed by a numbered line. % \begin{macrocode} \leavevmode #2\nobreak \leaders\hbox{$\m@th \mkern \@dotsep mu\hbox{.}\mkern \@dotsep mu$}\hfill \nobreak \hb@xt@\@pnumwidth{\hfil\normalfont \normalcolor #3}% \par}} % \end{macrocode} % This is very much adapted from \cmd{\dottedtocline}. % \end{macro} % % \section{List of fixmes by priority} % % We define the command to \cmd{\pmnlistoffixmes} to list all the % fixmes in descending priority. It runs over the list of fixmes % repeated until all fixmes have been processed. % % \begin{macro}{\pmnlistoffixmes} % \mcmd{\pmnlistoffixmes} lists all the fixmes in descending % priority. It is implemented by running over the list over fixmes % repeatedly. % \begin{macrocode} \newcounter{pfx@next@priority} \newcounter{pfx@current@priority} \newif\ifpfx@normalfixmes \newcommand{\pmnlistoffixmes}{% \section*{\listfixmename} {% % \end{macrocode} % First set up so we ignore fixmes with no priority and only process % fixmes with an actual priority. % \begin{macrocode} \let\pfx@nopriority\pfx@gobble@nopriority@flag \let\pfx@priority\pfx@test@in@range \let\pfx@list@in@range\pmn@list@current@priority \setlength{\pmnfixIndentation}{0pt} % \end{macrocode} % Then start the looping where we read through the table of fixmes % stored in a file (we use \cmd{\fileswfalse} to off having the file % overwritten). Each time we read over the file "pfx@next@priority" % is updated to contain the smallest priority greater than % "pfx@current@priority" (or $-1$). % \begin{macrocode} \@fileswfalse \let\contentsline\pfx@ctl \global\pfx@normalfixmesfalse \setcounter{pfx@current@priority}{-1} \loop \setcounter{pfx@next@priority}{-1} \pfx@reset@sums \@starttoc{lox} {\bfseries \pfx@print@sums} \ifnum \c@pfx@next@priority>\c@pfx@current@priority \subsection*{\listfixmename\ \arabic{pfx@next@priority}} \setcounter{pfx@current@priority}{\c@pfx@next@priority} \repeat % \end{macrocode} % We then output any fixmes without priority % \begin{macrocode} \ifpfx@normalfixmes \let\pfx@nopriority\pfx@list@standard \let\pfx@list@in@range\pfx@gobble@priority \subsection*{\listfixmename} \@starttoc{lox} \fi }% % \end{macrocode} % And finally we make a single scan to get the file started. % \begin{macrocode} \let\pfx@nopriority\pfx@gobble@nopriority \let\pfx@priority\pfx@gobble@priority \@starttoc{lox}} % \end{macrocode} % \end{macro}^^A \pmnlistoffixmes % % \begin{macro}{\pfx@gobble@priority} % \begin{macro}{\pfx@gobble@nopriority} % \begin{macro}{\pfx@gobble@nopriority@flag} % \cmd{\pmn@list@gobble} ignores a priority entry % \begin{macrocode} \def\pfx@gobble@nopriority@flag{% \global\pfx@normalfixmestrue\pfx@gobble@nopriority} \let\pfx@gobble@nopriority\@gobbletwo \newcommand{\pfx@gobble@priority}[3]{} % \end{macrocode} % \end{macro}^^A \pfx@gobble@nopriority@flag % \end{macro}^^A \pfx@gobble@nopriority % \end{macro}^^A \pfx@gobble@priority % % \begin{macro}{\pmn@list@current@priority} % \mcmd{\pmn@list@current@priority}\marg{priority}\marg{note}\marg{page} % lists a priority entry if it has the priority specified by % "pfx@current@priority". It also updates the "pfx@nextpriority" % counter so it contains the lowest priority we have encountered. % \begin{macrocode} \newcommand{\pmn@list@current@priority}[3]{% \ifnum #1=\thepfx@current@priority \let\pfx@time\pfx@time@sum \pfx@list@default@or@spec{#1}{#2}{#3}% \global\let\pfx@time\relax \fi \ifnum #1>\c@pfx@current@priority \ifnum #1<\c@pfx@next@priority \setcounter{pfx@next@priority}{#1} \fi \ifnum \thepfx@next@priority<0 \setcounter{pfx@next@priority}{#1} \fi \fi} % \end{macrocode} % \end{macro} % % \section{Removing \package{fixme} information from % \cmd{\contentsline}} % % \package{fixme} inserts some extra information in front of the user % supplied text when adding it to the list of fixmes. When present % the list in priority we do not want that. This is handled by the % following macros. % \begin{macro}{\pfx@ctl} % \mcmd{\pfx@ctl}\marg{type}\marg{text} is a replacement for % \cmd{\contentsline} which look whether it is a contentsline for % \package{fixme} and remove any extra text added by % \package{fixme}. We cannot simple change \cmd{\l@fixme} since % package{hyperref} for instance changes \contentsline. % \begin{macrocode} \newcommand{\pfx@ctl}[2]{% \def\reserved@a{#1}% \ifx\reserved@a\pfx@fixmetext\expandafter\@firstoftwo \else\expandafter\@secondoftwo \fi {\pfx@ctl@parse{#1}#2\pfx@pri\pfx@pri}% {\pfx@svd@ctl{#1}{#2}}} % \end{macrocode} % \end{macro}^^A \pfx@ctl % \begin{macro}{\pfx@ctl@parse} % If it is a \package{fixme} line, we use \cmd{\pfx@ctl@parse} to % scan for \cmd{\pfx@pri} in the fixme note. % \begin{macrocode} \def\pfx@ctl@parse#1#2\pfx@pri#3\pfx@pri{% \def\reserved@a{#3}% \ifx\reserved@a\@empty\expandafter\@firstoftwo \else\expandafter\@secondoftwo \fi {\pfx@svd@ctl{#1}{#2}}% {\pfx@savedctl@gobble{#1}{\pfx@pri#3}}} % \end{macrocode} % \end{macro}^^A \pfx@ctl@parse % \begin{macro}{\pfx@ctl@parse} % If we find \cmd{\pfx@pri} in the note, we have the end % delimiting \cmd{\pfx@pri} to be removed. This is accomplished % by \cmd{\pfx@savedctl@gobble} which then continues with the % original \cmd{\contentsline} command stored in \cmd{\pfx@svd@ctl}. % \begin{macrocode} \newcommand{\pfx@savedctl@gobble}[3]{\pfx@svd@ctl{#1}{#2}} % \end{macrocode} % \end{macro}^^A \pfx@ctl@parse % \begin{macrocode} \AtBeginDocument{\let\pfx@svd@ctl\contentsline} \def\pfx@fixmetext{fixme} % \end{macrocode} % We use \cmd{\def} to define \cmd{\pfx@fixmetext} to get the correcet % setting of \cmd{\global} and \cmd{\outer} when we use comparison % with \cmd{\ifx}. % \StopEventually{} % % And the commands to typeset the documentation. All enclosed in % "<*documentation>"$\ldots$"" so we exclude it if we % ever make a docstrip file. For now, we simply stop input with % \cmd{\endinput} so the file can be used directly as a package file. % \begin{macrocode} %<*documentation> \endinput \makeatother \def\UseOption{} \documentclass{pmn-ldoc} \newcommand{\docdate}{2003/11/02} \usepackage[latin1]{inputenc} % \OnlyDescription % \DisableCrossrefs \begin{document} \DocInput{pmn-fxme.sty} \end{document} % % \end{macrocode} % \Finale \sloppy \PrintChanges % ^^A LocalWords: fixme