summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/phfcc/phfcc.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/phfcc/phfcc.dtx')
-rw-r--r--macros/latex/contrib/phfcc/phfcc.dtx1898
1 files changed, 1898 insertions, 0 deletions
diff --git a/macros/latex/contrib/phfcc/phfcc.dtx b/macros/latex/contrib/phfcc/phfcc.dtx
new file mode 100644
index 0000000000..3f957cb9bb
--- /dev/null
+++ b/macros/latex/contrib/phfcc/phfcc.dtx
@@ -0,0 +1,1898 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2021 by Philippe Faist, philippe.faist@bluewin.ch
+% -------------------------------------------------------
+%
+% This file 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
+%<*driver>
+\ProvidesFile{phfcc.dtx}
+%</driver>
+%<package>\NeedsTeXFormat{LaTeX2e}[2005/12/01]
+%<package>\ProvidesPackage{phfcc}
+%<*package>
+ [2021/10/06 v2.0 phfcc package]
+%</package>
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{xcolor}
+\usepackage{lipsum}
+\usepackage[preset=xpkgdoc]{phfnote}
+\usepackage{phfcc}
+
+\usepackage{needspace}
+
+\usepackage[normalem]{ulem}
+
+\def\eqsign@{=}
+\def\eqsign{\protect\eqsign@}
+\robustify\eqsign
+\makeatother
+
+\def\RevTeX{{\small R\raise-0.2ex\hbox{\textsc{ev}}}\TeX}
+
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+
+\begin{document}
+ \DocInput{phfcc.dtx}
+\end{document}
+%</driver>
+% \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 \~}
+%
+%
+% \changes{v1.0}{2020/04/02}{Initial version}
+%
+% \GetFileInfo{phfcc.dtx}
+%
+% \iffalse Bypass indexing for following commands: \fi
+% \DoNotIndex{\newcommand,\newenvironment,\renewcommand,\long,\def,\edef,\gdef,\xdef,\if,\else,\fi,\par,\relax,\vspace,\vskip,\hspace,\hskip,\vbox,\hbox}
+%
+% \title{\phfqitltxPkgTitle{phfcc}}
+% \author{Philippe Faist\quad\email{philippe.faist@bluewin.ch}}
+% \date{\pkgfmtdate\filedate}
+% \maketitle
+%
+% \begin{abstract}
+% \pkgname{phfcc}---A handy \LaTeX{} package for inline commenting in
+% collaborative LaTeX documents.
+% \end{abstract}
+%
+% \phantomsection\label{sec:toc}
+% \inlinetoc
+%
+% \section{Introduction}
+%
+% When elaborating documents, especially collaborative documents with multiple
+% authors, it is useful to leave inline comments and be able to mark text
+% changes. Often, authors will choose a text color and define a simple macro,
+% like this:
+% \begin{verbatim}
+% \newcommand{\phf}[1]{{\color{blue}Ph.F.: #1}} % Philippe Faist's comments
+% \end{verbatim}
+%
+% This rudimentary approach has a few drawbacks. The main drawback is when
+% highlighting long blocks of text. First of all, it can be hard to visually
+% find the matching closing brace in your editor. Then, the synchronization
+% between your viewer and the TeX source (|synctex|) will no longer point to the
+% correct source line within the highlighted block of text; you will always be
+% pointed at the beginning or the end of the entire block. The reason for this
+% behavior is that the entire text is passed as a macro argument to |\phf|, so
+% |synctex| only sees a single macro call. The fact that a long block of text
+% is passed as a macro argument can also lead to other issues, such as errors
+% with |\verb+...+|-type constructs.
+%
+% Also, it is occasionally desirable to make the difference between sections of
+% text that were added by an author, and an inline off-hand remark, which is not
+% part of the text itself. For instance, with the above macro, we could enclose
+% remarks in ``|[|'' and ``|]|'': %
+% \newcommand{\phfold}[1]{{\color{blue}(Ph.F.:) #1}}
+% \newcommand{\phfoldb}[1]{{\color{blue}\relax #1}}
+% \begin{verbatim}
+% ... \phf{Observe that $A\geq 0$ by definition.}
+% \phf{[I added this sentence because I felt that it wasn't
+% clear from the context that $A\geq 0$]} ...
+% \end{verbatim}
+% to obtain:
+%
+% {\itshape%
+% ... \phfold{Observe that $A\geq 0$ by definition.}
+% \phfold{[I added this sentence because I felt that it wasn't
+% clear from the context that $A\geq 0$]} ...
+% }
+%
+% Observe how the off-hand remark blends with the text. Wouldn't it be nicer
+% if it stood out clearly, and if the initials were perhaps \emph{inside} the
+% brackets, like so?
+%
+% {\itshape%
+% ... \phfoldb{Ph.F.: Observe that $A\geq 0$ by definition.}
+% \phfoldb{\sffamily\bfseries [(Ph.F.:) I added this sentence because
+% I felt that it wasn't
+% clear from the context that $A\geq 0$]} ...
+% }
+%
+% \relax
+%
+% Of course, we could have defined a different macro for the off-hand remark,
+% say |\phfremark|. But typing a different macro name is not convenient,
+% Wouldn't it be nicer if the off-hand remark could be typed with the syntax
+% |\phf[...]|, using square brackets?
+%
+% Also the initials don't have to be repeated at every macro call, it suffice to
+% associate the color to the author perhaps once per page or so. They could
+% also be displayed in the margin, to avoid cluttering the text.
+%
+% Furthermore, to avoid the aforementioned issues with long blocks of text, we
+% could imagine marking text with the syntax |\begin{phf} ... \end{phf}| or even
+% |\phf ... \endphf|.
+%
+% And while we're at it, wouldn't it be cool to mark text removals, as well?
+% We could use the syntax |\phf*{text to be removed}|.
+%
+% And because I definitely didn't have time to spare but still got distracted
+% into programming \LaTeX{} macros to implement the above features, I have the
+% pleasure to present:
+%
+% \textit{\bfseries Introducing \ldots\ the \pkgname{phfcc} package.}\par
+%
+% With \pkgname{phfcc}, you simply define your multi-functional commenting
+% command using the |\phfMakeCommentingCommand| macro.
+%
+% \phfMakeCommentingCommand[initials={A.E.}]{AlE}%
+% \phfMakeCommentingCommand[initials={J.B.}]{JB}%
+% \phfMakeCommentingCommand[initials={PhF}]{phf}%
+% Let's start with a simple example. Suppose two authors, Albert Einstein and
+% John Bell, are commenting on the same document. They might define the
+% commenting commands |\AlE| and |\JB|:
+% \begin{verbatim}
+% \phfMakeCommentingCommand[initials={A.E.}]{AlE}
+% \phfMakeCommentingCommand[initials={J.B.}]{JB}
+% \end{verbatim}
+% Suppose they edit a paragraph of text, with multiple rounds of editing by both
+% authors; they mark their latest changes while leaving comments for the other
+% author as follows:
+% \begin{verbatim}
+% Quantum mechanics developed quickly in the 1920's thanks to the
+% works of Schr\"odinger, Heisenberg, and Dirac, who drew inspiration
+% from earlier ideas by Planck \AlE{and Einstein} \AlE[@JB, you forgot
+% about me!]. Quantum mechanics appears to allow spooky action at a
+% distance via some strange thing called ``entanglement,'' \JB*{but
+% this can be explained with hidden variables}\JB{which has
+% revolutionized our understanding of local realism.} \JB[@Albert,
+% we talked about this...]
+% \end{verbatim}
+% which gives:
+%
+% {\itshape%
+% Quantum mechanics developed quickly in the 1920's thanks to the
+% works of Schr\"odinger, Heisenberg, and Dirac, who drew inspiration
+% from earlier ideas by Planck \AlE{and Einstein} \AlE[@JB, you forgot
+% about me!]. Quantum mechanics appears to allow spooky action at a
+% distance via some strange thing called ``entanglement,'' \JB*{but
+% this can be explained with hidden variables}\JB{which has
+% revolutionized our understanding of local realism.} \JB[@Albert,
+% we talked about this...]%
+% }
+%
+% Read on to learn more about how these commands can be used, what their main
+% features are, how to customize them, and more.
+%
+% As an alternative to \pkgname{phfcc}, you can consider the package
+% \pkgname{todonotes}\footnote{\url{https://ctan.org/pkg/todonotes}}. The
+% commands defined in this package are designed for minimal effort by the
+% commenter (e.g., they only have to type |\phf{...}| or |\phf[...]|). On the
+% other hand \pkgname{todonotes} offers pretty boxes and more flexibility.
+%
+%
+% \section{Syntax of commenting commands}
+%
+% Here is the full syntax of the commenting commands generated with
+% |\phfMakeCommentingCommand|. Suppose the command |\AlE| was defined by
+% issuing |\phfMakeCommentingCommand[initials={A.E.}]{AlE}|. You can write:
+%
+%
+% |\AlE{some text here}| --- \AlE{some text here} --- typeset the given text in
+% color, perhaps to mark an addition by author |AlE| to the document. By
+% default, the initials associated with the command (here, ``A.E.'') will be
+% issued in the margin once per page.
+%
+% |\AlE[please revise this]| --- \AlE[please revise this] --- typeset an inline
+% comment in a different font. This is meant for comments that are not a
+% portion of document text itself but rather an inline remark that refers to the
+% text around it.
+%
+% You can use the |footcomments| style to have your comment typeset as a
+% footnote. (See also \autoref{sec:styles} below.)
+%
+% |\AlE*{text to be removed}| --- \AlE*{text to be removed} --- typeset the
+% given text in a way to indicate that the text should be suppressed.
+%
+% If you use Lua\LaTeX, you can get proper text strikethrough accross entire
+% chunks of text by using the argument |style={rmstrikethrough}| to
+% |\phfMakeCommentingCommand|. (See also \autoref{sec:styles} below.)
+%
+% |\AlE!{important piece of text}| --- \AlE!{important piece of text}
+% --- typeset the given text marking it as important.
+%
+% |\AlE![a really important comment]| --- \AlE![a really important comment] ---
+% typeset the given comment and mark it as important.
+%
+% In each of these cases (except for comments in square brackets),
+% you can use the syntax |\AlE .... \endAlE| instead of specifying the
+% argument using curly brackets:\\
+% |\AlE text here\endAlE| --- \AlE text here\endAlE \\
+% |\AlE! important\endAlE| --- \AlE! important\endAlE \\
+% |\AlE* remove\endAlE| --- \AlE* remove\endAlE
+%
+% For simple text, you can also use the |\begin|/|\end| syntax:\\
+% |\begin{AlE} text here\end{AlE}| --- \begin{AlE} text here\end{AlE}
+%
+% \begin{pkgtip}
+% Note that in contrast to optional arguments in many LaTeX macros, the
+% argument is allowed to contain matching square brackets, for instance
+% \relax%
+% |\AlE[inner brackets [like this] work as you'd expect]| \AlE[inner brackets
+% [like this] work as you'd expect]
+%
+% In any case you can protect the argument as usual with curly braces:
+% |\AlE[{this is [weird}]| \AlE[{this is [weird}]
+% \end{pkgtip}
+%
+% \section{Defining your commenting command}
+%
+% Now let's see exactly how to define your customized |\AlE| command.
+% \DescribeMacro{\phfMakeCommentingCommand} The command
+% |\phfMakeCommentingCommand| takes the following syntax:
+%
+% |\phfMakeCommentingCommand|\oarg{key=value,key2=value2,...}\marg{cmd name}
+%
+% The \marg{command name} should be given as a text name (e.g.,
+% |{AlE}|), and not as a macro. They key-value pairs may be one of the following:
+%
+%
+% \phfMakeCommentingCommand[color=phfcolor,initials={PhF},formatinitials=box]{phfbox}
+% \phfMakeCommentingCommand[color=phfcolor,initials={PhF},formatinitials=nobox]{phfnobox}
+% \phfMakeCommentingCommand[color=phfcolor,initials={PhF},formatinitials=hide]{phfhideinitials}
+% \phfMakeCommentingCommand[color=green!50!blue,initials={Philippe Faist},formatinitials=footnote]{phffootnote}
+%
+% \begin{cmdoptions}
+% \item[color=\marg{color specification}] The color of the comments generated by
+% the new commenting command. By default, a new suitable color is chosen for
+% each new commenting command defined.
+%
+% The color specification may be a name such as |red|, |green|, etc., but also
+% a mixture like |blue!40!green| (\textcolor{blue!40!green}{which stands for
+% 40\% of blue and 60\% of green}). You can specify any argument you could
+% specify to |\colorlet| from the \pkgname{xcolor} package. (The
+% \pkgname{xcolor} package is automatically loaded.)
+%
+% \item[initials=\marg{your initials}] Your name initials, which will by typeset
+% at the beginning of a comment (typically in a small box in the margin),
+% allowing to identify different comment colors with different people. By
+% default, the initials are set to the name of the command itself.
+%
+% \item[formatinitials=\meta{keyword or command}] The command that will be used
+% to format the initials. By default (|formatinitials=default| or
+% |formatinitials=margin|), the initials are displayed on the margin of the
+% paragraph the first time the change occurs on a given page \phf[like this
+% and like in the examples above]. You may also specify |formatinitials=box|
+% to typeset the initials inline immediately before your annotation
+% \phfbox[like this]. Specify |formatinitials=nobox| to remove the frame
+% \phfnobox[like this]. Or specify |formatinitials=hide| to hide the initials
+% altogether \phfhideinitials[like this]. You can also specify
+% |formatinitials=footnote| to hide the initials at the point of text but with
+% a footnote to associate colored comments with the name (for this to work
+% more nicely, specify your full name as argument to |initials={...}|)
+% \phffootnote[Here is an example]. [See
+% \autoref{sec:customize-initials-formatting} for customizing the formatting of
+% the margin initials for the |margin| style or for changing the text in the
+% footnote in the |footnote| style.]
+%
+% You may also specify as a value to the |formatinitials=| option any \LaTeX{}
+% command, which will then be used to format the initials. The macro should
+% accept a single argument, the initials.
+%
+% The default initials formatting style (|formatinitials=margin|) requires the
+% \pkgname{marginnote} package, which is loaded automatically. If you do not
+% want to load the \pkgname{marginnote} package, specify the package option
+% |usemarginnote=false| and set a different |formatinitials=...| style.
+%
+% \item[style=\marg{style name(s)}] Load one or more existing style(s) for the
+% commenting command. The styles must either be predefined, or must have been
+% defined using |\phfDefineCommentingStyle|. Separate style names with a
+% comma.
+%
+% \item[font=\marg{LaTeX commands}] The font commands to invoke when typesetting
+% annotations, regardless of type. By default, \phf{the font is unchanged
+% other than having the author-specific color set}. Also, the font is not
+% reset, so if you type an annotation somewhere where the font is large, the
+% annotation's font will match that font by default. (Different annotation
+% types may set their own font, see below.)
+% \item[spacing=\meta{length}] Spacing to add around normal annotations. This
+% amount of horizontal space is added before and after the annotation.
+% \item[begin=\marg{LaTeX text and/or commands}] Stuff to typeset at the
+% beginning of a general annotation. Nothing is typeset by default.
+% \item[end=\marg{LaTeX text and/or commands}] Stuff to typeset at the end of a
+% general annotation. Nothing is typeset by default.
+%
+% \item[cfont=\marg{LaTeX commands}] The font commands to invoke when
+% typesetting an in-line comment. By default, use \phf[the default sans serif
+% typeface, like this].
+% \item[cspacing=\meta{length}] Spacing to add around comments. This amount of
+% horizontal space is added before and after the comment.
+% \item[cbegin=\marg{LaTeX text and/or commands}] Stuff to typeset at
+% the beginning of a commment. By default, an opening square
+% bracket (with some spacing adjustments).
+% \item[cend=\marg{LaTeX text and/or commands}] Stuff to typeset at
+% the end of a commment. By default, a closing square bracket (with
+% some spacing adjustments).
+%
+% \item[rmfont=\marg{LaTeX commands}] The font commands to issue when
+% typesetting text that is to be removed. \phf*{By default, the text is in
+% italics like this} (If you're using Lua\LaTeX, it's recommended to use the
+% |rmstrikethrough| style for proper strikethrough text; see
+% \autoref{sec:styles}.)
+% \item[rmspacing=\meta{length}] Spacing to add around text that is marked to be
+% removed. This amount of horizontal space is added before and after.
+% \item[rmbegin=\marg{LaTeX text and/or commands}] Stuff to typeset at the
+% beginning of a piece of text to be removed. By default, a line overlapping
+% with the text, to suggest removal.
+% \item[rmend=\marg{LaTeX text and/or commands}] Stuff to typeset at the end of
+% a piece of text to be removed. By default, a line overlapping with the
+% text, to suggest removal.
+%
+% \item[ifont=\marg{LaTeX commands}] The font commands to issue when
+% typesetting important text. \phf!{By default, the text is in
+% larger boldface format like this}
+% \item[ispacing=\meta{length}] Spacing to add around important text. This
+% amount of horizontal space is added before and after.
+% \item[ibegin=\marg{LaTeX text and/or commands}] Stuff to typeset at
+% the beginning of a piece of important text. By default, three
+% exclamation marks.
+% \item[iend=\marg{LaTeX text and/or commands}] Stuff to typeset at
+% the end of a piece of important text. By default, three
+% exclamation marks.
+% \end{cmdoptions}
+%
+% After invoking |\phfMakeCommentingCommand|, the colors |xxxcolor|,
+% |xxxrmcolor| and |xxxrmcolorlink| are automatically defined (where |xxx| is to
+% be replaced by your commenting macro name). These are used respectively for
+% a usual comment color, text to be removed, and for links in text to be
+% removed. You may redefine these colors afterwards with |\colorlet| if you
+% wish:
+% \begin{verbatim}
+% \colorlet{AlErmcolor}{gray}
+% \end{verbatim}
+%
+% \DescribeMacro{\phfDisableCommentingCommands}
+% The command |\phfDisableCommentingCommands| disables all commenting commands,
+% and causes them to emit an error. Use this command when approaching the final
+% version of a long document to ensure that no commenting commands are left in
+% the document.
+%
+% \subsection{Commenting Styles}
+% \label{sec:styles}
+%
+% \emph{Styles} regroup a collection of definitions that alter the overall
+% behavior and appearance of commenting commands issued with
+% |\phfMakeCommentingCommand|. You can assign one or more styles to a
+% commenting command definition by using the |style=| keyword:
+% \begin{verbatim}
+% \phfMakeCommentingCommand[style={footcomments}]{JD} % \JD
+% \end{verbatim}
+%
+% You can combine style names with commas, for instance:
+%
+% \begin{verbatim}
+% \phfMakeCommentingCommand[style={rmstrikethrough,footcomments}]{JD} % \JD
+% \end{verbatim}
+%
+% \phfMakeCommentingCommand[rmbegin={},rmend={},rmspacing=2pt,initials={ZZ}]{dummycmd}
+% \phfMakeCommentingCommand[style={footcomments},initials={YY}]{dummyYY}
+% The following styles are predefined:
+% \begin{itemize}
+% \item \leavevmode\PrintMarginLabel{footcomments} The |footcomments| style
+% arranges for in-line comments to be typeset as footnotes.
+%
+% \begin{verbatim}
+% \phfMakeCommentingCommand[style={footcomments}]{YY}
+%
+% For instance, \YY[This would be an example of a comment
+% typeset as a footnote.] this text might be suitable to
+% comment on.
+% \end{verbatim}
+% gives:
+%
+% ``For instance, \dummyYY[This would be an example of a comment typeset as a
+% footnote.] this text might be suitable to comment on.''
+%
+% This style can be convenient to place comments without interrupting the
+% natural flow of the text.
+%
+% You can redefine |\phfccfootcommentwrapfnmark{..}| to customize the
+% appearance of the footnote mark, and |\phfccfootcommenttextstyle| to get
+% some handle on the commands issued within the footnote contents.
+% \begin{verbatim}
+% \renewcommand\phfccfootcommentwrapfnmark[1]{[[#1]]}
+% \renewcommand\phfccfootcommenttextstyle{\bfseries}
+% \end{verbatim}
+%
+% \item \leavevmode\PrintMarginLabel{rmstrikethrough} For Lua\LaTeX\ users, the
+% style |rmstrikethrough| is available to make text marked for removal drawn
+% in strikethrough font, \dummycmd*{\sout{kind of like this}}. You can cross
+% out entire paragraphs of text which include display equations. Simply use:
+% \begin{verbatim}
+% \phfMakeCommentingCommand[style=rmstrikethrough]{ZZ} % requires LuaLaTeX
+%
+% ... \ZZ*{text to be removed} ... or also ... \ZZ* more
+% text that I want to remove\endZZ ...
+% \end{verbatim}
+%
+% The implementation uses the |lua-ul| package, which requires Lua\LaTeX. To
+% apply this style to all definitions, use
+% |\phfSetDefaultCommentingStyle{style=rmstrikethrough}| (see below).
+%
+% (We do not support strikethrough for regular \LaTeX\ because we weren't able
+% to find an implementation that worked reliably even for large blocks of
+% text. For instance, using the |\sout| from the \pkgname{ulem} package, you
+% cannot strikethrough multiple paragraphs with displayed equations. Plus, to
+% support the extended syntax of |\phfcc|'s commenting commands, we need the
+% strikethrough to be implemented by a state change macro (like |\itshape|) or
+% an environment, and not by a macro that accepts an argument.)
+%
+% \item We'll probably add more predefined styles in the future.
+% \end{itemize}
+%
+% \DescribeMacro{\phfDefineCommentingStyle}
+% You can define a style using |\phfDefineCommentingStyle|:
+% \begin{verbatim}
+% \phfDefineCommentingStyle{mystyle}{
+% font={\fontfamily{phv}\selectfont}, % phv = Helvetica
+% cfont={\bfseries\large},
+% cbegin={{\ensuremath{\bigl\langle}}~},
+% cend={{~\ensuremath{\bigr\rangle}}}
+% }
+% \end{verbatim}
+% You can then define your commenting command invoking this style:
+% \begin{verbatim}
+% \phfMakeCommentingCommand[style=mystyle]{me}
+% \end{verbatim}
+%
+% \phfDefineCommentingStyle{mystyle}{
+% font={\fontfamily{phv}\selectfont},
+% cfont={\bfseries\large},
+% cbegin={{\ensuremath{\bigl\langle}}~},
+% cend={{~\ensuremath{\bigr\rangle}}}
+% }
+% \phfMakeCommentingCommand[style=mystyle]{me}
+%
+% Then \me{for example}, (which was typeset using |\me{for example}|,) the code
+% |\me[A comment]| becomes: \me[A comment].
+%
+% Styles are loaded in the order they are specified (separate style names with
+% commas). Style definitions may themselves contain |style=...| keys to load
+% other styles. Styles are always loaded before user keys, regardless of where
+% the `|style|' key appears in the definition. When styles are loaded, and when
+% the users' keys are set, later keys are overwrite earlier
+% ones.\footnote{Except for an as-of-yet undocumented \phfverb{startcmds} and
+% \phfverb{endcmds} keys which might be relevant if you'd like to develop a
+% style which requires you to issue definitions at the beginning of every
+% annotation.}
+%
+% \DescribeMacro{\phfSetDefaultCommentingStyle} Instead of defining named styles
+% which have to be invoked explicitly, you can also preset the style of all
+% future calls of |\phfMakeCommentingCommand|. You can achieve this result with
+% the |\phfSetDefaultCommentingStyle| command:
+% \begin{verbatim}
+% \phfSetDefaultCommentingStyle{
+% font={\large}
+% }
+% % all annotations defined from here on will appear larger
+% \phfMakeCommentingCommand{AB}
+% \end{verbatim}
+%
+% You can also use |\phfMakeCommentingCommand| to set one or more default
+% style(s) for all future commenting command definitions:
+% \begin{verbatim}
+% \phfSetDefaultCommentingStyle{
+% style={rmstrikethrough,footcomments}
+% }
+% % all annotations defined from here on will have these styles set
+% \phfMakeCommentingCommand{AB}
+% \end{verbatim}
+%
+% \subsection{Customizing the formatting of the initials label}
+% \label{sec:customize-initials-formatting}
+%
+% \paragraph{For the \phfverb{formatinitials=margin} style:}
+%
+% You can customize the appearance of the initials in the margin when using the
+% |formatinitials=margin| initials style by redefining the following macros.
+% Changes affect all margin labels (i.e., changes affect all commenting commands
+% using the |margin| initials formatting style).
+%
+% \DescribeMacro{\phfccformatmargininitials} The |\phfccformatmargininitials| is
+% used to format the initials in the margin. You can redefine it if you'd like
+% the initials to appear differently. Adapt the following, which contains the
+% default definition, to your liking:
+% \begin{verbatim}
+% \renewcommand{\phfccformatmargininitials}[1]{%
+% \fbox{\normalfont\sffamily\footnotesize #1}%
+% }
+% \end{verbatim}
+% (Technical note: the |\fboxsep| length has been set to |1pt| prior to calling
+% this macro.)
+%
+% \DescribeMacro{\phfccmargininitialssep} The |\phfccmargininitialssep| length
+% is the minimal vertical separation between two initials labels. This is a
+% length, so you should change it with |\setlength|:
+% \begin{verbatim}
+% \setlength{\phfccmargininitialssep}{2pt}
+% \end{verbatim}
+%
+% \paragraph{For the \phfverb{formatinitials=box} and
+% \phfverb{formatinitials=nobox} styles:}
+%
+% \DescribeMacro{\phfccformatboxinitials} For the |formatinitials=box| and
+% |formatinitials=nobox| initials style, you can redefine the command
+% |\phfccformatboxinitials| to typeset the initials, like so:
+% \begin{verbatim}
+% \renewcommand{\phfccformatboxinitials}[1]{%
+% \normalfont\sffamily\tiny#1%
+% }
+% \end{verbatim}
+%
+% \paragraph{For the \phfverb{formatinitials=footnote} style:}
+%
+% \DescribeMacro{\phfCCChangesBy} When using the |formatinitials=footnote|
+% initials formatting style, you may redefine |\phfCCChangesBy| to change the
+% text in the footnote:
+% \begin{verbatim}
+% \renewcommand{\phfCCChangesBy}[1]{Changes in this color are by #1}
+% \end{verbatim}
+%
+% \section{Package Options}
+%
+% This package requires the \pkgname{marginnote} package to generate initials
+% labels when using the |margin| initials style (the default style). If you do
+% not want to load the \pkgname{marginnote} package, you may use the package
+% option |usemarginnote=false| (but then you cannot use the |margin| initials
+% style):
+% \begin{verbatim}
+% \usepackage[usemarginnote=false]{phfcc}
+% \end{verbatim}
+%
+% \section{Known limitations}
+%
+% There are some cases where it's hard to get everything right. The
+% \pkgname{phfcc} commands do their best to get stuff right and to avoid
+% generating obscure \LaTeX{} errors, but there might be times where not
+% everything works as expected.
+%
+% \begin{itemize}
+% \item If you place a comment inside certain contructs that are processed twice
+% by \LaTeX{} (e.g., a figure caption when using e.g. the \pkgname{caption}
+% package, etc.) then the margin initials will not appear even if the comment
+% is the first of the page. This is because the margin label is produced the
+% first time they are typeset, per page; if that happened to be in a temporary
+% \TeX{} box that was then discarded, the margin note gets discarded along
+% with it.
+%
+% In the case of AMS equations, there's a hack that make the labels appear
+% right. Feel free to send pull requests to address other cases.
+%
+% \phf[FIXME: A better solution might be to write to the AUX file at each
+% comment, so that the information is written when the comment is actually
+% typeset, and then process where to put margin labels on the second run of
+% \LaTeX{}.
+%
+% As a bonus, this would enable stuff like ``list of comments'' like the
+% \pkgname{todonotes} package does. Even though I don't think it's necessary
+% for the standard use case of this package.]
+%
+% \item Initials in the margin might overlap in some edge cases. See my
+% comments and footnotes in the implementation documentation below.
+%
+% \item Initials in the margin might not appear if the comment immediately
+% follows a page break, because the comment might have been processed while
+% \LaTeX{} was on the previous page before deciding to start a new page. See
+% my comments and footnotes in the implementation doc below.
+% \end{itemize}
+%
+%
+%
+% \StopEventually{\PrintChangesAndIndex}
+%
+% \section{Implementation}
+%
+% Load these internally required packages.
+%
+% \begin{macrocode}
+\RequirePackage{xkeyval}
+\RequirePackage{kvoptions}
+\RequirePackage{etoolbox}
+\RequirePackage{xparse}
+% \end{macrocode}
+%
+% Ensure we have the \pkgname{xcolor} package to manage text colors. We need
+% \pkgname{xcolor} and not \pkgname{color} because we use |\colorlet|.
+% \begin{macrocode}
+\RequirePackage{xcolor}
+% \end{macrocode}
+%
+%
+% \subsection{Set up default settings}
+%
+% \begin{macro}{\phfCommentingDefault...}
+% Provide sensible defaults for commenting formatting.
+%
+% Bold or semibold CFont sounds like a good idea, but comments would seem more
+% aggressive like that, so keep them normal by default.
+% \begin{macrocode}
+\def\phfCommentingDefaultStartCmds{}
+\def\phfCommentingDefaultEndCmds{}
+\def\phfCommentingDefaultFont{}
+\def\phfCommentingDefaultSpacing{0pt}
+\def\phfCommentingDefaultBegin{}
+\def\phfCommentingDefaultEnd{}
+\def\phfCommentingDefaultCFont{\normalfont\sffamily}
+\def\phfCommentingDefaultCSpacing{0.2em}
+\def\phfCommentingDefaultCBegin{[\,}
+\def\phfCommentingDefaultCEnd{\,]}
+\def\phfCommentingDefaultRmFont{\small\itshape}%\itshape\notesmaller[0.9]}
+\def\phfCommentingDefaultRmSpacing{.3em}
+\def\phfCommentingDefaultRmBegin{%
+ \mbox{}\vrule height .55ex depth -.45ex width 1.4em\relax\hspace*{0.2em}%
+ \vrule height .55ex depth -.45ex width 0.6em\relax
+ \hspace*{-2em}}
+\def\phfCommentingDefaultRmEnd{%
+ \hspace*{-2em}%
+ \vrule height .55ex depth -.45ex width 0.6em\relax\hspace*{0.2em}%
+ \vrule height .55ex depth -.45ex width 1.4em\relax}
+\def\phfCommentingDefaultIFont{\large\bfseries}
+\def\phfCommentingDefaultISpacing{0.25em}
+\def\phfCommentingDefaultIBegin{!\hspace*{0.1em}!\hspace*{0.1em}!~}
+\def\phfCommentingDefaultIEnd{~!\hspace*{0.1em}!\hspace*{0.1em}!}
+% \end{macrocode}
+% \end{macro}
+%
+% A default list of colors for commenting, and a minimal tool to select the next
+% available color. The macro |\phf@cc@usedcolors| stores a
+% vertical-bar-separated list of color names that have been already used and
+% which should not be used again.
+% \begin{macrocode}
+\definecolor{phfcc0}{RGB}{0,148,240} % blue-y
+\definecolor{phfcc1}{RGB}{242,108,13} % orange-brown-y
+\definecolor{phfcc2}{RGB}{65,149,42} % green-y
+\definecolor{phfcc3}{RGB}{128,55,134} % purple-y
+\definecolor{phfcc4}{RGB}{0,129,129} % blue-green-y
+\definecolor{phfcc5}{RGB}{148,7,24} % dark red / burgundy
+\definecolor{phfcc6}{RGB}{160,120,0} % brownish
+\definecolor{phfcc7}{RGB}{35,195,155} % aqua-ish
+\csdef{phf@cc@presetcolor@0}{phfcc0}
+\csdef{phf@cc@presetcolor@1}{phfcc1}
+\csdef{phf@cc@presetcolor@2}{phfcc2}
+\csdef{phf@cc@presetcolor@3}{phfcc3}
+\csdef{phf@cc@presetcolor@4}{phfcc4}
+\csdef{phf@cc@presetcolor@5}{phfcc5}
+\csdef{phf@cc@presetcolor@6}{phfcc6}
+\csdef{phf@cc@presetcolor@7}{phfcc7}
+\def\phf@cc@usedcolors{|}
+\def\phf@cc@nextcolor@#1{%
+ \ifcsname phf@cc@presetcolor@#1\endcsname% try preset
+ \edef\phf@tmp@testxx{%
+ \noexpand\in@{|\csname phf@cc@presetcolor@#1\endcsname|}{\phf@cc@usedcolors}}%
+ \phf@tmp@testxx
+ \ifin@% color already used, try next
+ \expandafter\phf@cc@nextcolor@\expandafter{\the\numexpr#1+1\relax}%
+ \else
+ \def\phf@cc@thecolor{\csname phf@cc@presetcolor@#1\endcsname}% good, use
+ \fi
+ \else% out of colors, fallback to red
+ \def\phf@cc@thecolor{red}%
+ \fi
+}
+% \end{macrocode}
+% Read the argument. If non-empty, set |\phf@cc@thecolor| to the argument
+% value. If empty, choose the next available preset color and set
+% |\phf@cc@thecolor| to that.
+% \begin{macrocode}
+\def\phf@cc@getcolor#1{%
+ \edef\phf@tmp@xyz{#1}%
+ \if\relax\detokenize\expandafter{\phf@tmp@xyz}\relax
+ \phf@cc@nextcolor@{0}%
+ \else
+ \edef\phf@cc@thecolor{#1}%
+ \fi}
+% \end{macrocode}
+%
+%
+%
+% Define the keys for |\setkeys| with \pkgname{xkeyval} package, and set the
+% overall defaults.
+% \begin{macrocode}
+\def\phfcc@hook@phfmkccstyle@setstyle@noop#1{}
+\let\phfcc@hook@phfmkccstyle@setstyle\phfcc@hook@phfmkccstyle@setstyle@noop
+\define@cmdkey{phfmkccstyle}{style}{\phfcc@hook@phfmkccstyle@setstyle{#1}}
+
+\define@cmdkey{phfmkcc}{color}{}
+\define@cmdkey{phfmkcc}{initials}{}
+\define@cmdkey{phfmkcc}{formatinitials}{}
+\newtoks\cmdKV@phfmkcc@startcmds
+\newtoks\cmdKV@phfmkcc@endcmds
+\define@key{phfmkcc}{startcmds}{%
+ \cmdKV@phfmkcc@startcmds=\expandafter{\the\cmdKV@phfmkcc@startcmds#1}%
+}
+\define@key{phfmkcc}{endcmds}{%
+ \edef\x{\unexpanded{#1}\the\cmdKV@phfmkcc@endcmds}%
+ \cmdKV@phfmkcc@endcmds=\expandafter{\x}%
+}
+\define@cmdkey{phfmkcc}{font}{}
+\define@cmdkey{phfmkcc}{spacing}{}
+\define@cmdkey{phfmkcc}{begin}{}
+\define@cmdkey{phfmkcc}{end}{}
+\define@cmdkey{phfmkcc}{cfont}{}
+\define@cmdkey{phfmkcc}{cspacing}{}
+\define@cmdkey{phfmkcc}{cbegin}{}
+\define@cmdkey{phfmkcc}{cend}{}
+\define@cmdkey{phfmkcc}{rmfont}{}
+\define@cmdkey{phfmkcc}{rmspacing}{}
+\define@cmdkey{phfmkcc}{rmbegin}{}
+\define@cmdkey{phfmkcc}{rmend}{}
+\define@cmdkey{phfmkcc}{ifont}{}
+\define@cmdkey{phfmkcc}{ispacing}{}
+\define@cmdkey{phfmkcc}{ibegin}{}
+\define@cmdkey{phfmkcc}{iend}{}
+\define@cmdkey{phfmkcc}{groupcmd}{}
+% \end{macrocode}
+%
+% Factory defaults refer to the |\phfCommentingDefault***| commands.
+% \begin{macrocode}
+\presetkeys{phfmkcc}{%
+ color={},%
+ initials={},%
+ formatinitials={default},%
+ startcmds={\phfCommentingDefaultStartCmds},%
+ endcmds={\phfCommentingDefaultEndCmds},%
+ font={\phfCommentingDefaultFont},%
+ spacing={\phfCommentingDefaultSpacing},%
+ begin={\phfCommentingDefaultBegin},%
+ end={\phfCommentingDefaultEnd},%
+ cfont={\phfCommentingDefaultCFont},%
+ cspacing={\phfCommentingDefaultCSpacing},%
+ cbegin={\phfCommentingDefaultCBegin},%
+ cend={\phfCommentingDefaultCEnd},%
+ rmfont={\phfCommentingDefaultRmFont},%
+ rmspacing={\phfCommentingDefaultRmSpacing},%
+ rmbegin={\phfCommentingDefaultRmBegin},%
+ rmend={\phfCommentingDefaultRmEnd},%
+ ifont={\phfCommentingDefaultIFont},%
+ ispacing={\phfCommentingDefaultISpacing},%
+ ibegin={\phfCommentingDefaultIBegin},%
+ iend={\phfCommentingDefaultIEnd},%
+ groupcmd={\@firstofone}%
+}{}
+% \end{macrocode}
+%
+% \subsection{Helpers and handlers for styles}
+%
+% \begin{macro}{\phfDefineCommentingStyle}
+% User interface for defining custom comment styles.
+% \begin{macrocode}
+\newcommand\phfDefineCommentingStyle[2]{%
+ \csdef{phfcc@style@#1}{#2}%
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\phfSetDefaultCommentingStyle}
+% User interface for defining the default settings for all commenting commands
+% declared from now on. Keep note of |style=| keywords separately (in
+% |\phfcc@default@style|), because we cannot place them as |\presetkeys| in
+% the main options family.
+% \begin{macrocode}
+\def\phfcc@default@style{}
+\def\phfcc@hook@phfmkccstyle@setstyle@savestyle#1{%
+ \xdef\phfcc@default@style{#1}%
+}
+\newcommand\phfSetDefaultCommentingStyle[1]{%
+ \let\phfcc@hook@phfmkccstyle@setstyle\phfcc@hook@phfmkccstyle@setstyle@savestyle
+ \setkeys*{phfmkccstyle}{#1}%
+ \let\phfcc@hook@phfmkccstyle@setstyle\phfcc@hook@phfmkccstyle@setstyle@noop
+ \edef\x{\noexpand\presetkeys{phfmkcc}{\expandonce\XKV@rm}{}}%
+ \x
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Internal helpers for loading styles}
+%
+% \begin{macro}{\phfcc@expandstylekeys}
+% Helpers to expand style= instructions in a set of key=vals.
+%
+% The helper macro |\phfcc@expandstylekeys| accepts two arguments. The
+% argument |#1| is a list of style names and |#2| is a collection of key=value
+% pairs. This macro computes all the key=value settings that should be
+% applied from the style definitions, plus all the remaining user key=value
+% settings. We will recursively look for style=... keywords so that styles
+% can load other styles.
+%
+% The final expanded key=value pairs is set in the token register
+% |\phfcc@val@expanded@keyval|.
+% \begin{macrocode}
+\newtoks\phfcc@val@expanded@keyval
+\def\phfcc@expandstylekeys#1#2{%
+ \def\phfcc@val@expanded@preexpandstyles{#1}%
+ \phfcc@val@expanded@keyval={#2}%
+ \loop
+ \phfcc@expandstylekeys@once
+ \def\phfcc@val@expanded@preexpandstyles{}%
+ \ifnum\phfcc@val@expanded@needmore=1\repeat
+}
+% \end{macrocode}
+%
+% The implementation of |\phfcc@expandstylekeys| proceeds by iterating single
+% expansions until there are no more |style={}| values left. A single iteration
+% is implemented here. The following macro reads its input from
+% |\phfcc@val@expanded@preexpandstyles| and |\phfcc@val@expanded@keyval|, and it
+% sets the macros |\phfcc@val@expanded@keyval| and
+% |\phfcc@val@expanded@needmore|.
+% \begin{macrocode}
+\def\phfcc@expandstylekeys@once{%
+ \def\cmdKV@phfmkccstyle@style{}
+ \edef\x{\noexpand\setkeys*{phfmkccstyle}{\the\phfcc@val@expanded@keyval}}%
+ \x
+% \end{macrocode}
+% The |style={...}| values is stored in the macro |\cmdKV@phfmkccstyle@style|.
+% If it is empty, there is no style to set and we're done.
+% \begin{macrocode}
+ \if\relax\detokenize\expandafter{\cmdKV@phfmkccstyle@style}\relax
+ \def\phfcc@val@expanded@needmore{0}%
+ \else
+ \def\phfcc@val@expanded@needmore{1}%
+ \fi
+% \end{macrocode}
+% We might have one or more styles to expand. Iterate over the comma-separated
+% list of styles and we'll append the collected style-specific key=value
+% definitions in the macro |\phfcc@val@fullstylekeyvals| for now. Include also
+% the predefined style names to expand before the user-specified styles.
+% \begin{macrocode}
+ \def\phfcc@val@fullstylekeyvals{}%
+ \edef\phfcc@tmp@thestylelist{%
+ \phfcc@val@expanded@preexpandstyles,\cmdKV@phfmkccstyle@style}%
+ \@for\phfcc@tmp@next:=\phfcc@tmp@thestylelist \do{%
+% \end{macrocode}
+% At this point we're requested to expand the style whose name is stored in
+% |\phfcc@tmp@next|. Collect the key=value definitions in the macro named
+% |\phfcc@style@STYLENAME| or produce an error if such macro does not exist.
+% Also, if the style provides a macro named |\phfcc@styleused@STYLENAME|, then
+% invoke it at this point, in case the style would like to load any additional
+% packages or execute any other preamble-time setup steps. In the following
+% |\phfcc@tmp@stylekeyvals| is defined so that its immediate expansion yields
+% the styles' key=value definitions.
+% \begin{macrocode}
+ \ifcsname phfcc@style@\phfcc@tmp@next \endcsname
+ \ifcsname phfcc@styleused@\phfcc@tmp@next \endcsname
+ \csname phfcc@styleused@\phfcc@tmp@next \endcsname
+ \fi
+ \edef\phfcc@tmp@stylekeyvals{%
+ \expandafter\expandonce\csname phfcc@style@\phfcc@tmp@next \endcsname}%
+ \edef\phfcc@val@fullstylekeyvals{%
+ \expandonce\phfcc@val@fullstylekeyvals,%
+ \expandonce\phfcc@tmp@stylekeyvals}%
+ \else
+ \if\relax\detokenize\expandafter{\phfcc@tmp@next}\relax
+ \else
+ \PackageError{phfcc}{Requested commenting style `\phfcc@tmp@next' %
+ is not defined}{}%
+ \fi
+ \fi
+ }%
+% \end{macrocode}
+% Now we can collect the definitions from the styles and merge them with the
+% remaining non-style-related user key/values. The macro |\XKV@rm| is set by
+% \pkgname{xkeyval} to those key/values not processed by |\setkeys*|.
+% \begin{macrocode}
+ \edef\x{\noexpand\phfcc@val@expanded@keyval={%
+ \expandonce\phfcc@val@fullstylekeyvals,%
+ \expandonce\XKV@rm}}%
+ \x
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection{The \phfverb{rmstrikethrough} predefined style}
+%
+% \begin{macro}{\phfcc@style@rmstrikethrough}
+% The definition of the |rmstrikethrough| style is fairly straightforward.
+% \begin{macrocode}
+\gdef\phfcc@styleused@rmstrikethrough{%
+ \RequirePackage{lua-ul}
+ \newunderlinetype\beginPhfccStrikeThrough{%
+ \leaders\vrule height .55ex depth -.45ex}
+ \gdef\phfcc@styleused@rmstrikethrough{}% auto-destruct/only run once
+}
+\def\phfcc@style@rmstrikethrough{%
+ rmfont={\beginPhfccStrikeThrough},
+ rmbegin={},
+ rmend={},
+ rmspacing={2pt}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{The \phfverb{footcomments} predefined style}
+%
+% \begin{macro}{\phfcc@style@footcomments}
+% The |footcomments| style uses |startcmds| and |endcmds| to collect material
+% and then typeset it into a footnote.
+% \begin{macrocode}
+\def\phfcc@style@footcomments{%
+ startcmds={\phfcc@collectcommentfootnote},
+ endcmds={\phfcc@endcollectcommentfootnote},
+}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\phfccfootcommenttextstyle}
+% The macro |\phfccfootcommenttextstyle| can be redefined to customize the
+% footnote text appearance.
+% \begin{macrocode}
+\def\phfccfootcommenttextstyle{\footnotesize}
+% \end{macrocode}
+% \end{macro}
+%
+% Now we define helpers to collect the contents of the footnote, and then
+% typeset it.
+%
+% \begin{macro}{\phfcc@collectcommentfootnote}
+% \begin{macro}{\phfcc@endcollectcommentfootnote}
+% The entry point to these helpers are the macros
+% |\phfcc@collectcommentfootnote| and |\phfcc@endcollectcommentfootnote|: They
+% check whether this annotation is a comment and then call our main helpers if
+% that's the case.
+% \begin{macrocode}
+\def\phfcc@collectcommentfootnote{%
+ \if@phfcc@iscomment
+ \expandafter\phfcc@collectfootnote
+ \fi}
+\def\phfcc@endcollectcommentfootnote{%
+ \if@phfcc@iscomment
+ \expandafter\phfcc@endcollectfootnote
+ \fi}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\phfcc@collectfootnote}
+% \begin{macro}{\phfcc@endcollectfootnote}
+% \begin{macro}{\phfcc@startfootnote}
+% The helper |\phfcc@collectfootnote| collects the material and builds the
+% footnote. I had to copy some footnote-building code from |latex.ltx|
+% unfortunately: We can't call |\footnote{}| because it requires a macro
+% argument; we need begin/end macros to feed all the footnote contents and
+% material as \TeX\ parses it. Recall that \LaTeX's |\footnote| basically (1)
+% steps the footnote counter (the counter name is stored in |\@mpfn| and the
+% printable value is given by |\thempfn|) and prints the footnote mark
+% (|\@footnotemark|), and (2) collects material in the |\insert| called
+% |\footins|. The code relevant to (1) is collected in
+% |\phfcc@startfootnote|. The code relevant to (2) is collected and adapted
+% below between |\phfcc@collectfootnote| and |\phfcc@endcollectfootnote|.
+% \begin{macrocode}
+\def\phfcc@collectfootnote{%
+ \phfcc@startfootnote
+ \insert\footins\bgroup%
+ \reset@font\footnotesize
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\footnotesep
+ \splitmaxdepth \dp\strutbox \floatingpenalty \@MM
+ \hsize\columnwidth \@parboxrestore
+ \protected@edef\@currentlabel{%
+ \csname p@footnote\endcsname\@thefnmark
+ }%
+ \color@begingroup
+ \@makefntext{%
+ \rule\z@\footnotesep\@finalstrut\strutbox\phfcc@hackrevtex@skippar}%
+ \ignorespaces
+ \footnotesize
+ \color{\phf@cc@val@cur color}%
+ \phfccfootcommenttextstyle
+}
+\def\phfcc@endcollectfootnote{%
+ \unskip
+ \color@endgroup
+ \egroup
+}
+\def\phfcc@startfootnote{%
+ \stepcounter\@mpfn
+ \protected@xdef\@thefnmark{\thempfn}%
+ \phfccfootcommentwrapfnmark{\@footnotemark}%
+}
+\def\phfccfootcommentwrapfnmark#1{%
+ [#1]%
+}
+% \end{macrocode}
+% Above, we used the class-provided |\@makefntext| macro to make comment
+% footnotes look like the other document-provided footnotes, but we invoke that
+% macro with dummy content because remember, we haven't collected the footnote
+% contents yet. But some latex classes, like Rev\TeX, this macro add a
+% paragraph; so we need to eliminate that paragraph break that would otherwise
+% appear at the beginning of the footnote:
+% \begin{macrocode}
+\def\phfcc@hackrevtex@skippar{%
+ \@ifnextchar\par\@gobble\relax
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Define styles for initials formatting}
+%
+% Define the implementations for the different initials formatting. These are
+% by default the small boxes that appear in the margin that match color to
+% comment owner.
+%
+% Define the |margin| initials style as the default:
+% \begin{macrocode}
+\def\phf@cc@formatinitialsstyle@default{\phf@cc@formatinitialsstyle@margin}
+% \end{macrocode}
+%
+% \subsubsection{Define styles \phfverb{hide}, \phfverb{box}, \phfverb{nobox}}
+%
+% \begin{macro}{\phf@cc@formatinitialsstyle@hide}
+% Define the no-op |hide| style first.
+% \begin{macrocode}
+\def\phf@cc@formatinitialsstyle@hide#1{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\phf@cc@formatinitialsstyle@box}
+% \begin{macro}{\phf@cc@formatinitialsstyle@nobox}
+% Define the |box|, and |nobox| styles. In either cases, the label can be
+% customized by redefining |\phfccformatboxinitials|.
+% \begin{macrocode}
+\def\phf@cc@formatinitialsstyle@box#1{%
+ \hspace{0.25em}\relax
+ \raisebox{1pt}{{\fboxsep=1pt\relax\fbox{\phfccformatboxinitials{#1}}}}%
+ \hspace{0.25em}}
+\def\phf@cc@formatinitialsstyle@nobox#1{%
+ \hspace{0.25em}\relax
+ {\phfccformatboxinitials{#1}}%
+ \hspace{0.25em}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\phfccformatboxinitials}
+% \begin{macrocode}
+\def\phfccformatboxinitials#1{%
+ \normalfont\sffamily\tiny#1%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Define the style \phfverb{footnote}}
+%
+% Define the |footnote| style. Note you can redefine |\phfCCChangesBy| to
+% whatever you please, and it can even take the name as |#1| argument.
+% \begin{macrocode}
+\def\phf@cc@formatinitialsstyle@footnote#1{%
+ \ifcsname phf@cc@valfmtinitialsfootnote@intlspage@\phf@cc@val@cur @\roman{page}\endcsname
+ % already displayed on this page, don't repeat
+ \else
+ \csgdef{phf@cc@valfmtinitialsfootnote@intlspage@\phf@cc@val@cur @\roman{page}}{1}%
+ \def\phf@cc@tmp@zz{\gdef\@thefnmark{}\@footnotetext}%
+ \expandafter\phf@cc@tmp@zz\expandafter{\expandafter{%
+ \expandafter\color\expandafter{\phf@cc@val@cur color}\phfCCChangesBy{#1}}}%
+ \fi
+}
+\robustify\phf@cc@formatinitialsstyle@footnote
+\def\phfCCChangesBy{Changes by\ }
+% \end{macrocode}
+%
+% \subsubsection{Define the style \phfverb{margin}}
+%
+% \begin{macro}{\phf@cc@formatinitialsstyle@margin}
+% Define the |margin| style now. This one is a little tricky.
+% \begin{macrocode}
+\def\phf@cc@formatinitialsstyle@margin#1{%
+% \end{macrocode}
+%
+% First thing, we define an auxiliary global macro to remember whenever we've
+% already displayed the margin note on a given page. If the label was already
+% displayed on this page (as witnessed by the following test macro being
+% defined), don't repeat the label display and skip altogether.\footnote{There
+% are some edge cases here I'm not sure I want to spend the effort to fix. For
+% instance, if the comment appears right after a page break, it might have been
+% processed by \TeX\space while on the previous page and this test might get the
+% page number wrong. Oh well, the label was on last page already so you should
+% know whose comment this is.}
+% \begin{macrocode}
+ \ifcsname phf@cc@valfmtinitialsmargin@intlspage@\phf@cc@val@cur
+ @\roman{page}\endcsname
+ \else
+% \end{macrocode}
+%
+% Check for any other reasons why we shouldn't emit a margin note (e.g. for some
+% known two-pass environments); this is done by |\phf@cc@margin@ifchecks|. Then
+% actually create the margin note with |\phf@cc@margin@emit|.
+% \begin{macrocode}
+ \phf@cc@margin@ifchecks{%
+ \phf@cc@margin@emit{#1}%
+ }%
+ \fi
+}
+\robustify\phf@cc@formatinitialsstyle@margin
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\phf@cc@margin@ifchecks}
+% Detects if we're in a first pass in an AMS equation, for instance, to only
+% emit the label in the second pass (actual typesetting).
+% \begin{macrocode}
+\def\phf@cc@margin@ifchecks#1{%
+ \phf@cc@ififexists{ifmeasuring@}{%
+ \message{Detected first pass in environment, not emitting margin
+ initials label this time.}%
+ }{%
+ \phf@cc@ififexists{if@inlabel}{%
+ \message{Detected comment in latex item label, not emitting margin
+ initials at this time to avoid messing up everything.}%
+ }{%
+ #1%
+ }%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\phf@cc@ififexists}
+% A helper macro. The |\phf@cc@ififexists|\marg{if-cs-name}\marg{commands if
+% true}\marg{commands if false} macro checks if the command |\ifXXXX| exists,
+% where the name |ifXXXX| is the first argument of |\phf@cc@ififexists|. If it
+% exists, then it checks that ``if'' condition and executes \marg{commands if
+% true} or \marg{commands if false} as appropriate. If the ``if'' macro doesn't
+% exist, then executes \marg{commands if false}.
+% \begin{macrocode}
+\def\phf@cc@ififexists#1#2#3{%
+ \ifcsname #1\endcsname
+ \def\x{\phf@cc@ififexists@{#1}{#2}{#3}}%
+ \else
+ \def\x{#3}%
+ \fi
+ \x
+}
+\def\phf@cc@ififexists@#1#2#3{%
+ \csname #1\endcsname
+ #2%
+ \else
+ #3%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% At this point, we are all set to display the initials in the margin. It seems
+% like there should be nothing wrong with simply emitting a |\marginpar|, but
+% those don't work in footnotes and figure captions, where one would also like
+% to be able to introduce comments. One could use the \pkgname{marginnote}
+% package instead, which is more reliable, but then we can get overlapping
+% margin labels which are not very nice.
+%
+% {\itshape On the subject of |\marginnote| vs |\marginpar|:} The strategy here
+% is use |\marginnote| all the time. Originally I used |\marginpar|, but it
+% doesn't work in footnotes and figure captions, where one often wants to
+% comment things. It's really hard to detect all cases where |\marginpar| is
+% problematic. (|\ifinner| detects minipages/equations, value of |\@captype|
+% detects figure captions, but I didn't manage to detect footnotes reliably, and
+% I anticipate other problematic situations coming up). So I use
+% \pkgname{marginnote} instead, which is more reliable. We could have some
+% complex process to decide whether to use |\marginpar| or |\marginnote|, but
+% only if we can find a really reliable algorithm. When collaborators are
+% commenting on a document in the final hours before a deadline, we really don't
+% want to generate obscure LaTeX errors because they happened to hit an edge
+% case by placing a comment somewhere I hadn't anticipated. So for now,
+% universally use |\marginnote|. If you don't want to load the
+% \pkgname{marginnote} package for whatever reason, use a different initials
+% label style and specify the |usemarginnote=false| package option.
+%
+% To avoid margin notes overlapping with \pkgname{marginnote}, we use custom
+% code with a simple algorithm to shift the margin notes vertically so that they
+% don't overlap. The code is a bit ugly, but it seems to work and it doesn't
+% rely on too specific hacks, so it is hopefully not too prone to edge cases.
+%
+% \begin{macro}{\phf@cc@margin@emit}
+% This is the macro that actually creates the margin note. First we create a
+% |\hbox| with the label so that we can measure its height. Then we defer to
+% |\phf@cc@createmarginnote| to produce the margin note with the formatted
+% initials.
+% \begin{macrocode}
+\newbox\phf@cc@margin@labelbox
+\newdimen\phf@cc@margin@labelboxhgt
+\def\phf@cc@margin@emit#1{%
+ \setbox\phf@cc@margin@labelbox=\hbox{\strut
+ \expandafter\color\expandafter{\phf@cc@val@cur color}%
+ \fboxsep=1pt\relax
+ \phfccformatmargininitials{#1}}%
+ \phf@cc@margin@labelboxhgt=\ht\phf@cc@margin@labelbox
+ \phf@cc@createmarginnote
+ \csgdef{phf@cc@valfmtinitialsmargin@intlspage@\phf@cc@val@cur%
+ @\roman{page}}{1}%
+}%
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\phfccformatmargininitials}
+% The |\phfccformatmargininitials|\marg{initials} can be redefined to change the
+% appearance of the margin intials box.
+% \begin{macrocode}
+\def\phfccformatmargininitials#1{%
+ \fbox{\normalfont\sffamily\footnotesize #1}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\phf@cc@createmarginnote}
+% The tricky thing with \pkgname{marginnote} is that labels will overlap if
+% they are emitted on the same line. Here we use a workaround: We check
+% |\pdflastypos| and add some vertical spacing if we are too close to the last
+% note's y position on the same page. But the issue is that |\pdfsavepos| and
+% |\pdflatexypos| only work while shipping out, so basically all we can do is
+% write the values to the AUX file and use them next time latex is run. Here
+% we use the same mechanism as \pkgname{marginnote}: define a new \LaTeX\space
+% label printing a |\newphfccmarginnote| in the AUX file with the relevant
+% meta-info. We use the internal counters |\@mn@thispage| (current absolute
+% page number) and |\@mn@atthispage| (number of note on current page) because
+% we also need to track which notes are on which page, and there's no use
+% duplicating all that code (I do hope those counters don't change, though).
+% \begin{macrocode}
+\def\phf@cc@createmarginnote{%
+ \marginnote[{\copy\phf@cc@margin@labelbox}]{\copy\phf@cc@margin@labelbox}[%
+ \phf@cc@marginextractvshift]%
+ \phf@cc@savepos
+ \protected@write\@auxout{}{%
+ \string\newphfccmarginnote{%
+ {\@mn@thispage}%
+ {\@mn@atthispage}%
+ {\noexpand\number\phf@cc@lastypos sp}%
+ {\number\phf@cc@margin@labelboxhgt sp}%
+ }%
+ }%
+}
+\ifcsname pdfsavepos\endcsname
+ \let\phf@cc@savepos\pdfsavepos
+ \let\phf@cc@lastypos\pdflastypos
+\else
+ \ifcsname savepos\endcsname
+ \let\phf@cc@savepos\savepos
+ \let\phf@cc@lastypos\lastypos
+ \else
+ \PackageError{phfcc}{Cannot find appropriate \string\pdfsavepos\space
+ command, neither \string\pdfsavepos\space nor\string\savepos\space
+ are defined.}{}
+ \fi
+\fi
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\phf@cc@marginextractvshift}
+% The macro |\phf@cc@marginextractvshift| is responsible for extracting the
+% required vertical shift from the corresponding label created from the
+% information saved in the AUX file. \emph{This macro is fully expandable,
+% and is meant to be used as the value of the optional vertical-shift argument
+% in \phfverb{\marginnote}.} The current note is identified by the internal
+% \pkgname{marginnote} counters |\@mn@thispage| (current absolute page number)
+% and |\@mn@atthispage| (current note number on this page).
+%
+% The label |\csname phfccmn@\@mn@thispage.\@mn@atthispage\endcsname|
+% generated by |\newphfccmarginnote| expands to |{|\marg{pdf y-pos of the
+% point in text}\marg{label box height}|}|\relax |{|\marg{requried vertical
+% shift to adjust this note}|}|. The first group of fields are the two last
+% arguments specified to |\newphfccmarginnote| written to the AUX file (the
+% two first are already in the label/macro name), and the second group
+% contains the values (only one currently) computed when calling
+% |\newphfccmarginnote|.
+%
+% Used as |\marginnote|'s vertical shift length. Expands to the vertical
+% shift needed to correct the current note. Remember: no assignments in here,
+% this command must be fully expandable.
+% \begin{macrocode}
+\def\phf@cc@marginextractvshift{%
+ \ifcsname phfccmn@\@mn@thispage.\@mn@atthispage\endcsname
+ \expandafter\expandafter\expandafter\expandafter\expandafter
+ \expandafter\expandafter\@firstofone
+ \expandafter\expandafter\expandafter\@secondoftwo
+ \csname phfccmn@\@mn@thispage.\@mn@atthispage\endcsname
+ \else
+ \z@
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\newphfccmarginnote}
+% The |\newphfccmarginnote| command defines the margin label in the AUX file.
+% It's not meant as public API, it's only written in the AUX file to be
+% re-read on next run. Here is where all the calculations are done.
+%
+% In this macro we get the page number, y position, and box height of a margin
+% note written by the previous run of \LaTeX. We need to compute the vertical
+% shift to avoid overlapping with other boxes.
+%
+% The algorithm is pretty dumb. For each margin note, we loop over all
+% already-processed margin notes on the same page. If an overlap is detected,
+% we advance the y-position of the margin note according to the height of the
+% existing overlapping margin note, and re-start the loop.
+%
+% This is also the main entry point into our vertical shift calculating
+% algorithm. Set the |\phf@cc@marginvshift| to zero, this is where the
+% calculated total vertical shift will be stored. Then call our algorithm
+% main routine unless we're the first note on the page.\footnote{There's an
+% edge case here that I haven't dealt with: In the case of footnotes or figure
+% captions, the notes can appear out of order in the AUX file. Our algorithm
+% only checks for overlap with note numbers that are less than the current
+% note number. So if note 1.1 appears in the AUX file after note 1.2, then
+% first 1.2 is processed, no shift is added (it ignores the fact that 1.1
+% doesn't exist yet), then 1.1 is processed and thinks it's the first note so
+% doesn't add a shift either. If this ends up really being a problem there
+% are ways to fix this but now I don't feel it's worth the effort. So you
+% might have a note in a figure caption somehow overlapping with another note
+% if they happen to be in different environments and yet on the same line.}
+% \begin{macrocode}
+\def\phf@cc@marginlastmarginnoteypos{}
+\newdimen\phf@cc@marginvshift
+\def\newphfccmarginnote#1{\newphfccmarginnote@#1}
+\def\newphfccmarginnote@#1#2#3#4{%
+ \phf@cc@marginvshift=\z@
+ \ifnum#2>0\relax
+ \phf@cc@margin@calculatevshift{#1}{#2}{#3}{#4}%
+ \else\fi
+ \csxdef{phfccmn@#1.#2}{%
+ {{#3}{#4}}{\number\phf@cc@marginvshift sp}%
+ }%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\phfccmargininitialssep}
+% The dimension |\phfccmargininitialssep| is the minimum vertical separation
+% between two margin notes initials. Redefine this length to whatever you
+% like (e.g., |\phfccmargininitialssep=1mm\relax| or
+% |\setlength{\phfccmargininitialssep}{1mm}|).
+% \begin{macrocode}
+\newdimen\phfccmargininitialssep
+\phfccmargininitialssep=2\p@
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\phf@cc@margin@calculatevshift}
+% This is our note vertical-shifting algorithm. Compute the vertical shift by
+% looping through existing notes on the present page. The temporary counter
+% |\phf@cc@tmp@cntiter| is the iteration counter and iterates over the notes
+% on the present page up to the current note. (If a note with earlier note is
+% undefined, skip it, this can happen if the note is in a footnote or figure
+% caption; see earlier footnote.)
+%
+% The total vertical shift that needs to be applied to the present note
+% (positive shift = downwards shift) is stored in the dimen
+% |\phf@cc@marginvshift|, to be picked up by |\newphfccmarginnote|. Here
+% |#1|=absolute page no., |#2|=current note no., |#3|=current note y position,
+% |#4|=current note box height.
+% \begin{macrocode}
+\newcount\phf@cc@tmp@cntiter
+\def\phf@cc@margin@calculatevshift#1#2#3#4{%
+ \phf@cc@marginvshift=\z@
+ \phf@cc@tmp@cntiter=0
+ \phf@cc@margin@calculatevshift@{#1}{#2}{#3}{#4}%
+}
+\def\phf@cc@margin@calculatevshift@#1#2#3#4{%
+ \ifnum\phf@cc@tmp@cntiter<#2\relax
+ \ifcsname phfccmn@#1.\the\phf@cc@tmp@cntiter\endcsname
+ \expandafter\let\expandafter
+ \phf@cc@tmp\csname phfccmn@#1.\the\phf@cc@tmp@cntiter\endcsname
+ \edef\phf@cc@tmp@otherypos{%
+ \expandafter\expandafter\expandafter\@firstoftwo
+ \expandafter\@firstoftwo \phf@cc@tmp}%
+ \edef\phf@cc@tmp@otherhgt{%
+ \expandafter\expandafter\expandafter\@secondoftwo
+ \expandafter\@firstoftwo \phf@cc@tmp}%
+ \edef\phf@cc@tmp@othervshift{%
+ \expandafter\expandafter\expandafter\@firstofone
+ \expandafter\@secondoftwo \phf@cc@tmp}%
+ \ifdim\dimexpr\phf@cc@tmp@otherypos-\phf@cc@tmp@othervshift
+ >\dimexpr#3-#4-\phf@cc@marginvshift\relax
+ \ifdim\dimexpr\phf@cc@tmp@otherypos-\phf@cc@tmp@otherhgt-\phf@cc@tmp@othervshift
+ <\dimexpr#3-\phf@cc@marginvshift\relax
+% \end{macrocode}
+% At this point, an overlap is detected between the current note that we're
+% adjusting (note number |#2| on page |#1|) and an earlier processed note (note
+% number |\phf@cc@tmp@cntiter| on the same page). So we shift the current note
+% so that it appears below the other note. The vertical shift is accumulated in
+% the |\phf@cc@marginvshift| dimen, this will be stored into the label after
+% we're done computing. Note: the y-position reported by |\pdflastypos| is from
+% the \emph{bottom}, not the top, so ``higher on the page than'' is ``|>|''; but
+% a positive margin vertical shift in \pkgname{marginnote} shifts the margin
+% note \emph{downwards}.
+%
+% Then reset the iteration counter to zero, so that we re-loop over all existing
+% notes on the same page to re-check (with the new vertical shift) that we
+% didn't generate an overlap with any earlier note (e.g., could happen on a
+% two-column page with comments in both columns).
+% \begin{macrocode}
+ \@tempdima=\dimexpr
+ \phfccmargininitialssep
+ +(#3-\phf@cc@marginvshift)%
+ -(\phf@cc@tmp@otherypos-\phf@cc@tmp@otherhgt-\phf@cc@tmp@othervshift)%
+ \relax
+ %\message{*** phfcc DEBUG: overlap detected of note #1.#2 with
+ % note #1.\the\phf@cc@tmp@cntiter, increasing vshift of note
+ % number #2 on page #1 by \the\@tempdima \space ***}%
+ \advance\phf@cc@marginvshift \@tempdima
+ \phf@cc@tmp@cntiter=\z@\relax
+ \else\fi
+ \else\fi
+ \else\fi
+ \advance\phf@cc@tmp@cntiter 1\relax
+ \phf@cc@margin@calculatevshift@{#1}{#2}{#3}{#4}%
+ \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{The main \phfverb{\phfMakeCommentingCommand} macro}
+%
+% \begin{macro}{\phfMakeCommentingCommand}
+% Implementation of |\phfMakeCommentingCommand|. See main package
+% documentation for usage details. The inner command definitions are kinda
+% tricky because of all the possible syntax options.
+% |\phfMakeCommentingCommand|\oarg{color=blue,...}\marg{cmdname}
+% \begin{macrocode}
+\newcommand\phfMakeCommentingCommand[2][]{%
+ \cmdKV@phfmkcc@startcmds={}%
+ \cmdKV@phfmkcc@endcmds={}%
+ \edef\x{\noexpand\phfcc@expandstylekeys{\phfcc@default@style}{\unexpanded{#1}}}%
+ \x
+ %\setrmkeys{phfmkcc}%
+ \edef\x{\noexpand\setkeys{phfmkcc}{\the\phfcc@val@expanded@keyval}}%
+ \x
+ \phf@cc@getcolor{\cmdKV@phfmkcc@color}%
+ \colorlet{#2color}{\phf@cc@thecolor}%
+ \edef\phf@tmp@xxappcmd{\noexpand\appto\noexpand\phf@cc@usedcolors{\phf@cc@thecolor|}}%
+ \phf@tmp@xxappcmd
+ \colorlet{#2rmcolor}{#2color!70!gray!55!white}%
+ \colorlet{#2rmcolorlink}{blue!40!#2rmcolor}%
+ \edef\phf@tmp@xxx{\cmdKV@phfmkcc@initials}%
+ \if\relax\detokenize\expandafter{\phf@tmp@xxx}\relax
+ \csedef{phf@cc@val@#2@initials}{#2}%
+ \else
+ \csedef{phf@cc@val@#2@initials}{\cmdKV@phfmkcc@initials}%
+ \fi
+ \ifcsname phf@cc@formatinitialsstyle@%
+ \detokenize\expandafter{\cmdKV@phfmkcc@formatinitials}\endcsname%
+ \expandafter\def\expandafter\phf@cc@tmp@xzx\expandafter{%
+ \csname phf@cc@formatinitialsstyle@%
+ \detokenize\expandafter{\cmdKV@phfmkcc@formatinitials}\endcsname}%
+ \csedef{phf@cc@val@#2@formatinitials}{\expandonce\phf@cc@tmp@xzx}%
+ \else
+ \csedef{phf@cc@val@#2@formatinitials}{\expandonce\cmdKV@phfmkcc@formatinitials}%
+ \fi
+ \csedef{phf@cc@val@#2@startcmds}{\the\cmdKV@phfmkcc@startcmds}%
+ \csedef{phf@cc@val@#2@endcmds}{\the\cmdKV@phfmkcc@endcmds}%
+ %\message{***** STARTCMDS ARE \detokenize\expandafter{\the\cmdKV@phfmkcc@startcmds} *****}%
+ %\message{***** ENDCMDS ARE \detokenize\expandafter{\the\cmdKV@phfmkcc@endcmds} *****}%
+ \csedef{phf@cc@val@#2@font}{\expandonce\cmdKV@phfmkcc@font}%
+ \csedef{phf@cc@val@#2@spacing}{\expandonce\cmdKV@phfmkcc@spacing}%
+ \csedef{phf@cc@val@#2@begin}{\expandonce\cmdKV@phfmkcc@begin}%
+ \csedef{phf@cc@val@#2@end}{\expandonce\cmdKV@phfmkcc@end}%
+ \csedef{phf@cc@val@#2@cfont}{\expandonce\cmdKV@phfmkcc@cfont}%
+ \csedef{phf@cc@val@#2@cspacing}{\expandonce\cmdKV@phfmkcc@cspacing}%
+ \csedef{phf@cc@val@#2@cbegin}{\expandonce\cmdKV@phfmkcc@cbegin}%
+ \csedef{phf@cc@val@#2@cend}{\expandonce\cmdKV@phfmkcc@cend}%
+ \csedef{phf@cc@val@#2@rmfont}{\expandonce\cmdKV@phfmkcc@rmfont}%
+ \csedef{phf@cc@val@#2@rmspacing}{\expandonce\cmdKV@phfmkcc@rmspacing}%
+ \csedef{phf@cc@val@#2@rmbegin}{\expandonce\cmdKV@phfmkcc@rmbegin}%
+ \csedef{phf@cc@val@#2@rmend}{\expandonce\cmdKV@phfmkcc@rmend}%
+ \csedef{phf@cc@val@#2@ifont}{\expandonce\cmdKV@phfmkcc@ifont}%
+ \csedef{phf@cc@val@#2@ispacing}{\expandonce\cmdKV@phfmkcc@ispacing}%
+ \csedef{phf@cc@val@#2@ibegin}{\expandonce\cmdKV@phfmkcc@ibegin}%
+ \csedef{phf@cc@val@#2@iend}{\expandonce\cmdKV@phfmkcc@iend}%
+ \csedef{phf@cc@val@#2@groupcmd}{\expandonce\cmdKV@phfmkcc@groupcmd}%
+% \end{macrocode}
+%
+% Once all the information was gathered and stored, define the commenting command
+% itself (as well as its |\end*| counterpart). Make them robust.
+% \begin{macrocode}
+ \csdef{#2}{\phf@cc@do{#2}}%
+ \expandafter\robustify\csname #2\endcsname%
+ \csdef{end#2}{\phf@cc@end}%
+ \expandafter\robustify\csname end#2\endcsname%
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\phfDisableCommentingCommands}
+% This command causes any commenting command declared with
+% |\phfMakeCommentingCommand| to emit an error.
+% \begin{macrocode}
+\newif\ifphf@cc@disabled
+\phf@cc@disabledfalse
+\def\phfDisableCommentingCommands{%
+ \phf@cc@disabledtrue
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Implementation of the commenting commands}
+%
+% Overall, the implementation of a commenting command goes as follows. First,
+% gather all the info about the command invocation (e.g., important? starred?
+% comment?) and then ultimately call |\phf@cc@begin| and |\phf@cc@end| which
+% execute the formatting options.
+%
+% Within each comment, the following flags are set by the parsing mechanism.
+% \begin{macrocode}
+\newif\if@phfcc@iscomment
+\newif\if@phfcc@isremoved
+\newif\if@phfcc@isimportant
+% \end{macrocode}
+%
+% Everything happens within |\begingroup|\ldots|\endgroup|. The group is opened
+% at |\phf@cc@do| (the commenting command itself), and is closed by |\phf@cc@end|.
+%
+% \begin{macro}{\phf@cc@begin}
+% The helper macro |\phf@cc@begin| is responsible for issuing all the
+% necessary definitions for the comment to be typeset correctly, including
+% initials, depending on whether it is a regular text addition, a text removal
+% comment, an important comment, a commenting comment, etc. It inspects
+% |\if@phfcc@iscomment|, |\if@phfcc@isremoved|, and |\if@phfcc@isimportant| to
+% determine the comment type.
+%
+% This is not the main comment entry point, the main entropy point is
+% |\phf@cc@do| and |\phf@cc@begin| is called internally from there. {\itshape
+% Execution is already enclosed in a local \TeX\ group; a |\begingroup| has
+% already been issued by |\phf@cc@do|.}
+% \begin{macrocode}
+\def\phf@cc@begin{%
+% \end{macrocode}
+%
+% First, we set the author's color so that by default everything we do will use
+% that color.
+% \begin{macrocode}
+ \color{\phf@cc@val@cur color}%
+% \end{macrocode}
+%
+% Issuing \phfverb\leavevmode\ here is annoying because it adds vertical space
+% if the command is issued in vertical mode right before an equation or theorem;
+% but it is needed immediately after section and paragraph headings so that the
+% comment style (eg sans font along with color etc.) is not applied to the
+% section/paragraph heading itself.
+% \begin{macrocode}
+ \leavevmode% beurk, see above
+% \end{macrocode}
+%
+% The comment typesetting is constructed in layers, each time adding commands to
+% execute at the start and corresponding commmands to execute at the end. The
+% start commands are executed in the specified order, with the end commands in
+% the reverse order at the end. We use the |\phf@cc@helper@pushgrpcmds| helper
+% to this effect.
+%
+% Introducing the necessary spacing, and issuing the initials. The amount of
+% spacing will depend on the type of comment; |\phf@cc@val@spacing| will be set
+% appropriately below when setting comment-type specific settings.
+% \begin{macrocode}
+ \phf@cc@helper@pushgrpcmds{%
+ \csname phf@cc@val@\phf@cc@val@cur @startcmds\endcsname
+ \hspace{\phf@cc@val@spacing}%
+ \phf@cc@showinitials%
+ }{%
+ \hspace{\phf@cc@val@spacing}%
+ \csname phf@cc@val@\phf@cc@val@cur @endcmds\endcsname
+ }%
+% \end{macrocode}
+%
+% See what comment type we're dealing with, and set the appropriate settings.
+%
+% First, check if we have a commenting-comment. If so, see whether or not it is
+% additionally marked as important and issue the relevant commands. Also set
+% the relevant spacing.
+% \begin{macrocode}
+ \if@phfcc@iscomment
+ \if@phfcc@isimportant
+ \phf@cc@helper@pushgrpcmdsX{%
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @font\endcsname
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @cfont\endcsname
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @ifont\endcsname
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @cbegin\endcsname
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @ibegin\endcsname
+ }{%
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @iend\endcsname
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @cend\endcsname
+ }%
+ \edef\phf@cc@val@spacing{\csname phf@cc@val@\phf@cc@val@cur @ispacing\endcsname}%
+ \else
+ \phf@cc@helper@pushgrpcmdsX{%
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @font\endcsname
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @cfont\endcsname
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @cbegin\endcsname
+ }{%
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @cend\endcsname
+ }%
+ \edef\phf@cc@val@spacing{\csname phf@cc@val@\phf@cc@val@cur @cspacing\endcsname}%
+ \fi
+ \else
+% \end{macrocode}
+% Now check if we have an important comment (which is not a commenty-comment).
+% \begin{macrocode}
+ \if@phfcc@isimportant
+ \phf@cc@helper@pushgrpcmdsX{%
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @font\endcsname
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @ifont\endcsname
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @ibegin\endcsname
+ }{%
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @iend\endcsname
+ }%
+ \edef\phf@cc@val@spacing{%
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @ispacing\endcsname%
+ }%
+ \else
+% \end{macrocode}
+% Not a comment, not important. Could be a piece of text marked for removal.
+% \begin{macrocode}
+ \if@phfcc@isremoved
+ \phf@cc@helper@pushgrpcmdsX{%
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @font\endcsname
+ \noexpand\color{\phf@cc@val@cur rmcolor}%
+ \noexpand\colorlet{docnotelinkcolor}{\phf@cc@val@cur rmcolorlink}%
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @rmfont\endcsname
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @rmbegin\endcsname
+ }{%
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @rmend\endcsname
+ }%
+ \edef\phf@cc@val@spacing{\csname phf@cc@val@\phf@cc@val@cur @rmspacing\endcsname}%
+ \else
+% \end{macrocode}
+% We've got just a plain, old, inline marked text.
+% \begin{macrocode}
+ \phf@cc@helper@pushgrpcmdsX{%
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @font\endcsname
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @begin\endcsname
+ }{%
+ \expandafter\noexpand\csname phf@cc@val@\phf@cc@val@cur @end\endcsname
+ }%
+ \edef\phf@cc@val@spacing{\csname phf@cc@val@\phf@cc@val@cur @spacing\endcsname}%
+ \fi
+ \fi
+ \fi
+% \end{macrocode}
+%
+% Actually issue these commmands and kick off the typesetting of the comment.
+% \begin{macrocode}
+ \phf@cc@val@grpcmds
+}
+\def\phf@cc@helper@pushgrpcmds#1#2{%
+ \appto\phf@cc@val@grpcmds{#1}%
+ \preto\phf@cc@val@grpendcmds{#2}%
+}
+\def\phf@cc@helper@pushgrpcmdsX#1#2{% expands arguments with edef
+ \edef\phfcc@tmp@x{\noexpand\phf@cc@helper@pushgrpcmds{#1}{#2}}%
+ \phfcc@tmp@x
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\phf@cc@end}
+% Here we execute closing commands and close the group. |\phf@cc@end| is the
+% last macro executed when the user invokes a comment, in any case.
+% \begin{macrocode}
+\def\phf@cc@end{%
+ \phf@cc@val@grpendcmds
+ \endgroup
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\phf@cc@showinitials}
+% This helper macro prints out the initials, if any.
+% \begin{macrocode}
+\def\phf@cc@showinitials{%
+ \edef\phf@cc@tmpx{%
+ \expandafter\expandonce\csname phf@cc@val@\phf@cc@val@cur @initials\endcsname}%
+ \expandafter\notblank\expandafter{\phf@cc@tmpx}{%
+ \csname phf@cc@val@\phf@cc@val@cur @formatinitials%
+ \expandafter\endcsname\expandafter{\phf@cc@tmpx}}{}%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\phf@cc@do}
+% {\bfseries The macro |\phf@cc@do| is the main entry point of a commenting
+% command.} Actually, the user-instantiated commenting commands are an alias
+% of this command, with the user macro name as first argument. So the |\AlE|
+% command defined in the main documentation of this package was in fact
+% defined as an alias to |\phf@cc@do{AlE}|. This is were everything starts.
+% \begin{macrocode}
+\def\phf@cc@do#1{%
+% \end{macrocode}
+% First, we need to check if commenting commands were disabled with
+% |\phfDisableCommentingCommands|. If this is the case, generate an error.
+% \begin{macrocode}
+ \ifphf@cc@disabled
+ \PackageError{phfcc}{Commenting commands have been disabled
+ with \string\phfDisableCommentingCommands.}{}%
+ \fi
+% \end{macrocode}
+% Now we start for real. First, we open the \TeX\ group. Then we start parsing
+% the invocation syntax.
+%
+% \begin{macrocode}
+ \begingroup
+ \@phfcc@iscommentfalse
+ \@phfcc@isremovedfalse
+ \@phfcc@isimportantfalse
+% \end{macrocode}
+%
+% The macros |\phf@cc@val@grp*cmds| store the commands to be executed in
+% |\phf@cc@begin| and |\phf@cc@end|. By default, they are empty. They are
+% filled by relevant code when parsing the command invocation.
+%
+% By default, there are no commands at group begin (|\phf@cc@val@grpcmds|), no
+% commands at group end (|\phf@cc@val@grpendcmds|), and no spacing on either
+% side of the typeset comment (|\phf@cc@val@spacing|).
+% \begin{macrocode}
+ \def\phf@cc@val@grpcmds{}%
+ \def\phf@cc@val@grpendcmds{}%
+ \def\phf@cc@val@spacing{0pt}%
+% \end{macrocode}
+%
+% Store the name of the commenting command so we can look up the relevant
+% comment settings. This is the name that was given to the commenting command
+% itself, e.g. |phf|.
+% \begin{macrocode}
+ \edef\phf@cc@val@cur{#1}%
+% \end{macrocode}
+%
+% Here we start the parsing of the type of comment. First, check for a star
+% (e.g., |\phf*{...}|) to see if we're dealing with a removed block of text.
+% \begin{macrocode}
+ \@ifstar\phf@cc@star\phf@cc@nostar%
+}
+% \end{macrocode}
+%
+% If we don't have a star, continue parsing to see if we have an important piece
+% of text or comment (|\phf!| sytnax).
+% \begin{macrocode}
+\def\phf@cc@nostar{\@ifnextchar!\phf@cc@important\phf@cc@grp}
+% \end{macrocode}
+%
+% At this point, we have determined whether the invocation is starred (removed
+% text) or important. The next execution points are |\phf@cc@star|,
+% |\phf@cc@important|, or |\phf@cc@grp|.
+% \end{macro}
+%
+% \begin{macro}{\phf@cc@star}
+% \begin{macro}{\phf@cc@important}
+% If starred or if important, set up the inner group execution commands to the
+% corresponding settings, and defer to |\phf@cc@grp|.
+% \begin{macrocode}
+\long\def\phf@cc@star{%
+ \@phfcc@isremovedtrue
+ \phf@cc@grp}
+\long\def\phf@cc@important!{%
+ \@phfcc@isimportanttrue
+ \phf@cc@grp}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\phf@cc@grp}
+% The command |\phf@cc@grp| parses how the argument content is given. Is it a
+% comment (``|[ ... ]|''), a single \LaTeX{} argument group (``|{ ... }|''),
+% or should we expect it to end with |\endXXX|?
+% \begin{macrocode}
+\def\phf@cc@grp{%
+ \@ifnextchar[\phf@cc@comment\phf@cc@grpnocomment%]
+}
+\def\phf@cc@grpnocomment{%
+ \@ifnextchar\bgroup{\phf@cc@grpwarg}{\phf@cc@begin}}
+% \end{macrocode}
+% \end{macro}
+%
+% The main commenting command has already defined the |\endXXX| command as an
+% alias of |\phf@cc@end|, so in the case of the syntax |\AlE ... \endAlE| we can
+% call |\phf@cc@begin| directly.
+%
+% Now at this point we have determined how the argument is given, and we are
+% calling one of |\phf@cc@comment|, |\phf@cc@grpwarg| (with argument), or
+% |\phf@cc@begin| directly.
+%
+% \begin{macro}{\phf@cc@grpwarg}
+% Format a simple comment specified as a normal \LaTeX{} block, i.e., provided
+% as an argument to the commenting command. (Like |\AlE{text here}| or
+% |\AlE!{important text}| or |\AlE*{some stuff to remove}|.)
+% \begin{macrocode}
+\long\def\phf@cc@grpwarg#1{%
+ \phf@cc@begin
+ \csname phf@cc@val@\phf@cc@val@cur @groupcmd\endcsname
+ {#1}%
+ \phf@cc@end
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\phf@cc@comment}
+% If the argument is a comment, set up the comment font, begin/end chars, and
+% go. Use |xparse| to get the argument in square brackets to ensure that the
+% argument itself can contain matched square brackets.
+% \begin{macrocode}
+\NewDocumentCommand\phf@cc@comment{+O{}}{%
+ \@phfcc@iscommenttrue
+ \phf@cc@begin%
+ #1%
+ \phf@cc@end%
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Process package options}
+%
+% Initialization code for \pkgname{kvoptions} for our package options.
+% \begin{macrocode}
+\SetupKeyvalOptions{
+ family=phfcc,
+ prefix=phfcc@opt@
+}
+\DeclareBoolOption[true]{usemarginnote}
+% \end{macrocode}
+%
+% Process package options.
+% \begin{macrocode}
+\ProcessKeyvalOptions*
+% \end{macrocode}
+%
+% Load the \pkgname{marginnote} package unless requested not to. This package
+% is required for the |margin| initials style.
+% \begin{macrocode}
+\ifphfcc@opt@usemarginnote
+ \RequirePackage{marginnote}
+\fi
+% \end{macrocode}
+%
+%\Finale
+\endinput