summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/ifnextok
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2011-05-23 22:05:28 +0000
committerKarl Berry <karl@freefriends.org>2011-05-23 22:05:28 +0000
commit6c53c3bf9c486cd85be55144beb951ccbfde3453 (patch)
tree87fbc166fa1eb3f7e3776e69322a4f5c857965b5 /Master/texmf-dist/tex/latex/ifnextok
parent52a388b5dfbf9e9147a7c07878b135825cad4656 (diff)
new latex package ifnextok (23may11)
git-svn-id: svn://tug.org/texlive/trunk@22588 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/ifnextok')
-rw-r--r--Master/texmf-dist/tex/latex/ifnextok/ifnextok.sty320
1 files changed, 320 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/ifnextok/ifnextok.sty b/Master/texmf-dist/tex/latex/ifnextok/ifnextok.sty
new file mode 100644
index 00000000000..896c4e5e439
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/ifnextok/ifnextok.sty
@@ -0,0 +1,320 @@
+\NeedsTeXFormat{LaTeX2e}[1994/12/01]
+\ProvidesPackage{ifnextok}[2011/05/23 v0.1 next token test (UL)]
+
+%% Copyright (C) 2011 Uwe Lueck,
+%% http://www.contact-ednotes.sty.de.vu
+%% -- author-maintained in the sense of LPPL below --
+%%
+%% This file can be redistributed and/or modified under
+%% the terms of the LaTeX Project Public License; either
+%% version 1.3c of the License, or any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% We did our best to help you, but there is NO WARRANTY.
+%%
+%% Please report bugs, problems, and suggestions via
+%%
+%% http://www.contact-ednotes.sty.de.vu
+%%
+%% === Outline ===
+%% The 'ifnextok' package deals with the behavior of
+%% \LaTeX's internal `\@ifnextchar' to skip blank spaces.
+%% This sometimes has surprising or for some users really
+%% \emph{unwanted} effects, especially with brackets following
+%% `\\' where the user does \emph{not} intend to specify an
+%% optional argument, rather wants that brackets are \emph{printed.}
+%% The package offers commands and options for modifying this
+%% behavior, maybe limited to certain parts of the
+%% document source. They are described in the sections below
+%% together with the presentation of the implementation.
+%%
+%% As after multiletter commands blank spaces are skipped anyway
+%% (\TeX book p.~46f.), the package makes a difference only
+%% for one-symbol commands such as |\\|, or for active characters
+%% such as the double quote with \ctanpkgref{german}`.sty'
+%% and \ctanpkgref{babel}.
+%%
+%% A little \strong{overview:}
+%% \begin{enumerate}
+%% \item |\IfNextToken| is an alternative to `\@ifnextchar',
+%% not skipping spaces (Section~\ref{sec:main}).
+%% This macro is the \strong{low-level}
+%% backbone of all other modifications of \LaTeX\ commands.
+%% \item |\IfStarNextToken| is an alternative to `\@ifstar',
+%% not skipping spaces, using `\IfNextToken' in lieu of
+%% `\@ifnextchar' (Section~\ref{sec:star}).
+%% \item Some ``\strong{patching}" commands aim at modifying
+%% existing (\LaTeX) macros without specifying the resulting
+%% new definition explicitly
+%% (Sections~\ref{sec:patch} and \ref{sec:star}).
+%% As a package writer,
+%% you just must know which macros need to be modified
+%% and specify their names as arguments for the patching macros.
+%% \item There are low-level commands
+%% |\INTstore| and |\INTrestore|
+%% for undoing modifications of existing macros
+%% (Section~\ref{sec:stored}).
+%% \item There are \strong{high-level} commands for modifying
+%% |\\| and selecting \LaTeX\ \strong{environments}
+%% to be affected (Section~\ref{sec:break}).
+%% Package \strong{options} execute some of them.
+%% \end{enumerate}
+%% (TODO: how command names are composed) %% 2011/05/23, v0.1
+%%
+%% === Caveats ===
+%% Only a few of the commands have been tested so far,
+%% and usage together with \ctanpkgref{amsmath}
+%% may require special care or fail altogether.
+%%
+%% Switching into ``don't-skip-spaces" mode
+%% \emph{two times} without switching back into normal mode
+%% in between won't work with this version (v0.1)
+%% of the package (TODO: permanent aliases).
+%% You will get the
+%% \[\texttt{Argument of <patching> has an extra }`}.'\]
+%% error. This also applies to commands that have been issued
+%% by package options.
+%%
+%% === The Main Command \cs{IfNextToken} ===
+%% \label{sec:main}
+%% |IfNextToken<match>{<if>}{<else>}| is the obvious variant
+%% of \LaTeX's internal `\@ifnextchar' executing <if>
+%% if actually the \emph{``very next"} token is <mathc>
+%% and executing <else> otherwise. If <match> is \emph{not}
+%% a \emph{space token} (\LaTeX's `\@sptoken') but
+%% the next token \emph{is}, <else> is executed;
+%% while `\@ifnextchar' tries matching the next token
+%% after ensuing space tokens.
+\newcommand{\IfNextToken}[3]{%
+ \let\nextok@match=#1\def\nextok@if{#2}\def\nextok@else{#3}%
+ \futurelet\@let@token\nextok@decide}
+\def\nextok@decide{%
+ \ifx\@let@token\nextok@match \expandafter\nextok@if
+ \else \expandafter\nextok@else
+ \fi}
+%% |\NoNextSkipping| now switches into ``don't-skip-spaces"
+%% mode ``altogether" (however ...):
+\newcommand*{\NoNextSkipping}{\let\@ifnextchar\IfNextToken}
+%% This appears so dangerous to me that I don't want to support it
+%% much right now. |\RestoreNextSkipping| just switches back
+%% to \LaTeX's original version, so some support for
+%% \ctanpkgref{amsmath} may be missing here.
+\newcommand*{\RestoreNextSkipping}{%
+ \let\@ifnextchar\kernel@ifnextchar}
+%% Actually, because `\NoNextSkipping' does not affect
+%% `\kernel@ifnextchar', those of \LaTeX's commands using the latter
+%% still will skip spaces (with package version v0.1).
+%%
+%% === Patching Commands ===
+%% \label{sec:patch}
+%% |\INTpatch<replacer><macro>| replaces
+%% something in the definition of <macro> according to
+%% the replacement macro <replacer>.
+%% This seems to work with the macros I thought of.
+%% It does \emph{not} work when
+%% (for replacing `\@ifnextchar')
+%% (a)~there are \emph{more} `\@ifnextchar's in the
+%% macro to patch, or when (b)~an `\@ifnextchar'
+%% is inside a pair of braces.
+\newcommand*{\INTpatch}[2]{%
+ \expandafter\expandafter\expandafter \def
+ \expandafter\expandafter\expandafter #2%
+ \expandafter\expandafter\expandafter {%
+ \expandafter #1#2#1}}
+%% |\NextTestPatch<macro>| replaces
+%% `\@ifnextchar' in the definition of <macro> by
+%% `\IfNextToken'.
+\newcommand*{\NextTestPatch}{\INTpatch\nextok@patch}
+\def\nextok@patch#1\@ifnextchar#2\nextok@patch{#1\IfNextToken#2}
+%%
+%% === Storing and Restoring ===
+%% \label{sec:stored}
+%% |\INTstore<macro>| stores the meaning of the macro <macro>
+%% in a special name space.
+\newcommand*{\INTstore}[1]{%
+ \expandafter\let\csname\INT@name#1\endcsname#1}
+\newcommand*{\INT@name}{INTstore.\expandafter\@gobble\string}
+%% |\INTrestore<macro>| \emph{re}stores the meaning of <macro>
+%% that is expected to having been stored with `\INTstore':
+\newcommand*{\INTrestore}[1]{%
+ \expandafter\let\expandafter#1\csname\INT@name#1\endcsname}
+%%
+%% === The Star Test ===
+%% \label{sec:star}
+%% Before a \LaTeX\ line-break command tests for an optional argument,
+%% it tests for a star using `\@ifstar', which in turn invokes
+%% `\@ifnextchar'. So already `\@ifstar' needs to be modified.
+%% We do not so much want to change `\@ifstar' altogether,
+%% rather we will replace it at some places by a non-skipping
+%% variant |\IfStarNextToken|, using the patching command
+%% |\StarTestPatch<macro>|.
+%% (`\@ifstar' has an argument and therefore cannot be patched as
+%% nicely as the line-break commands.)
+\newcommand*{\IfStarNextToken}[1]{\IfNextToken*{\@firstoftwo{#1}}}
+\newcommand*{\StarTestPatch}{\INTpatch\nextok@starpatch}
+%% The macro to be patched may contain a \cs{par}
+%% (`\@centercr' is an example), so we need `\long':
+\long\def\nextok@starpatch#1\@ifstar#2\nextok@starpatch{%
+ #1\IfStarNextToken#2}
+%% |\StoreStarSkipping| stores the current meaning of
+%% `\@ifstar' ...
+%% % is executed before changing `\@ifstar' temporarily:
+\newcommand*{\StoreStarSkipping}{\INTstore\@ifstar}
+%% ... so that it can be restored by |\RestoreStarSkipping|:
+\newcommand*{\RestoreStarSkipping}{\INTrestore\@ifstar}
+%% |\NoStarSkipping| renders `\@ifstar' non-skipping altogether:
+\newcommand*{\NoStarSkipping}{\let\@ifstar\IfStarNextToken}
+%% This again seems to be so dangerous that it will not be
+%% supported much with package version v0.1 (by a package option).
+%%
+%% === ``Manual" Line Breaks ===
+%% \label{sec:break}
+%% ==== Outline of Implementation ====
+%% In the first instance, the present package aims at rendering
+%% |\\| a command that interpretes a left-hand square bracket
+%% as a start of an optional argument only if the bracket is not
+%% preceded by any other token (apart from the star in `\\*'),
+%% especially not by a space token.
+%%
+%% Indeed, an author may expect that when a bracket opens in a
+%% \emph{different} line than the `\\', then it will be
+%% \emph{printed} rather than interpreted as an
+%% \emph{optional-argument delimiter}
+%% (the package author has been such an author some times).
+%% Now, when the bracket only is in a line \emph{following}
+%% the line carrying the `\\', the end-line character
+%% normally produces a space token (\TeX book p.~47),
+%% so the present idea of implementation will cover
+%% the case of a bracket in the next line.
+%%
+%% In `latex.ltx', the names of the commands implementing the
+%% line break have some ``pivot" part <pivot> that we can use
+%% to patch them in a uniform way. They are two in each case:
+%% The first starts with `\@<pivot>' and invokes `\@ifstar',
+%% the second starts with `\@x<pivot>' and invokes the
+%% left-hand-bracket test. Both of them need to be patched.
+%%
+%% ==== ``Normal" Manual Line Breaks ====
+%% \label{sec:newline}
+%% If I had been aware of the difficulties of this part,
+%% I probably would not have started writing this package,
+%% hoping it would be the work of about an hour.
+%%
+%% `\@xnewline' must be patched in order to get a non-skipping
+%% version of the bracket test, and this patch suffices for the
+%% optional-argument goal.
+%%
+%% The `\@ifstar' call is in `\@normalcr'; the latter is invoked
+%% by the robust version of `\\'. However, \LaTeX\ defines
+%% `\@normalcr' by a `\let' referring to the result of
+%% `\DeclareRobustCommand\\' ...
+%%
+%% Things seem to be easier when |\\| calls `\@normalcr'
+%% instead of `\\ ' (the latter is the effect of
+%% `\DeclareRobustCommand'),
+%% we are \textcolor{blue}{\strong{interchanging}}
+%% the roles of `\\ ' and `\@normalcr'
+%% (\textcolor{blue}{\strong{caution!}}).
+%% Then we just need to control `\@normalcr':
+\def\\{\x@protect\\\protect\@normalcr}
+%% (Another \strong{Caveat:} I do not understand `\x@protect'.) %% v0.1
+%%
+%% |\StoreNewlineSkipping| \emph{stores} the skipping behavior of |\\|
+%% outside special environments:
+\newcommand*{\StoreNewlineSkipping}{%
+ \INTstore\@normalcr \INTstore\@xnewline}
+%% |\RestoreNewlineSkipping| \emph{re}stores the skipping behavior of |\\|
+%% outside special environments:
+\newcommand*{\RestoreNewlineSkipping}{%
+ \INTrestore\@normalcr \INTrestore\@xnewline}
+%% |\NoNewlineSkipping| \emph{suppresses} skipping blank spaces with
+%% |\\| outside special environments:
+\newcommand*{\NoNewlineSkipping}{%
+ \StarTestPatch\@normalcr \NextTestPatch\@xnewline}
+%%
+%% ==== Manual Line Breaks in \LaTeX\ Environments ====
+%% \label{sec:envs}
+%% The macros in the present section should modify \LaTeX's |\\|
+%% in environments (<env> being one of:)
+%% |center|, |tab|, |array|, and |tabular|.
+%% These \emph{environment names} are the expected
+%% \emph{arguments} of those macros.
+%% However, argument |center| also affects the
+%% |flushleft| and |flushright| environments,
+%% and |array| and |tabular| should also affect
+%% their enhanced variants from other \LaTeX\ packages.
+%% When this internal structure of \LaTeX\ changes,
+%% the present section may become obsolete ...
+%%
+%% |\INTactOnEnv{<action1>}{<action2>}{<env>}|
+%% is the backbone of these macros.
+%% <action1> and <action2> are one of
+%% \[`\INTstore', `\INTrestore', `\StarTestPatch',
+%% `\NextTestPatch'.\]
+%% <action1> deals with `\@ifstar',
+%% <action2> deals with `\@ifnextchar':
+\newcommand*{\INTactOnEnv}[3]{%
+ \expandafter#1\csname @#3cr\endcsname
+ \expandafter#2\csname @x#3cr\endcsname}
+%% |\StoreSkippingCRs{<env>}| \emph{stores} the skipping behavior
+%% of |\\| in environments <env>:
+\newcommand*{\StoreSkippingCRs}{%
+ \INTactOnEnv\INTstore\INTstore}
+%% |\RestoreSkippingCRs{<env>}| \emph{re}stores the skipping behavior
+%% of |\\| in environments <env>:
+\newcommand*{\RestoreSkippingCRs}{%
+ \INTactOnEnv\INTrestore\INTrestore}
+%% |\NotSkippingCRs{<env>}| \emph{suppresses} space skipping
+%% of |\\| in environments <env>:
+\newcommand*{\NotSkippingCRs}{%
+ \INTactOnEnv\StarTestPatch\NextTestPatch}
+%% % \NotSkippingCRs{center}
+%% \begin{center}
+%% Do these commands work?\\ [\,Or do they not?\,]
+%% \end{center}
+%%
+%% === Package Options ===
+%% \label{sec:options}
+%% ==== Behavior \emph{without} Options ====
+%% If the package is called without any option,
+%% it only defines `\IfNextToken', `\IfStarNextToken'
+%% and the other package-writer or user commands,
+%% without actually changing behavior of any \LaTeX\ command.
+%%
+%% ==== Option `newline' ====
+%% Package option |newline| stores and disables space skipping for
+%% |\\| in ``normal" mode according to Section~\ref{sec:newline}:
+\DeclareOption{newline}{\StoreNewlineSkipping\NoNewlineSkipping}
+%%
+%% ==== Environments ====
+%% The next package options are just the environment names
+%% according to Section~\ref{sec:envs}
+%% (|center|, |tab|, |array|, |tabular|).
+%% Option |<env>| stores and disables the skipping behavior
+%% of |\\| in <env> environments.
+%% We abuse the our temporary macro `\nextok@match' from
+%% Section~\ref{sec:main}:
+\def\nextok@match#1{%
+ \DeclareOption{#1}{\StoreSkippingCRs{#1}\NotSkippingCRs{#1}}}
+\nextok@match{center}
+\nextok@match{tab}
+\nextok@match{array}
+\nextok@match{tabular}
+%% ==== ``All Options" ====
+%% Package Option |all| has the same effect as
+%% using the `newline' option and the environment package options
+%% `center', `tab', `array', and `tabular' at once.
+\def\nextok@match#1{\csname ds@#1\endcsname}
+%% (... must not be changed before `\ProcessOptions' ...)
+\DeclareOption{all}{%
+ \nextok@match{newline} \nextok@match{center}
+ \nextok@match{tab} \nextok@match{array} \nextok@match{tabular}}
+%%
+%%
+%% === Processing Options and Leaving the Package ===
+\ProcessOptions
+\endinput
+%%
+%% === VERSION HISTORY ===
+
+v0.1 2011/05/23 very first